Country Helpers
Country data management and geographical utilities for international operations in the WorkPayCore frontend application.
Overviewβ
The country helpers provide utilities for managing country data, currency information, timezone handling, and regional configurations for global HR and payroll operations.
Core Functionsβ
getCountryByCode(countryCode)β
Retrieves comprehensive country information by ISO country code.
Parameters:
countryCode(string): ISO 3166-1 alpha-2 country code
Returns:
object: Country data object or null if not found
Example:
import { getCountryByCode } from '@/utils/helpers/country';
// Get US country data
const usCountry = getCountryByCode('US');
console.log(usCountry);
// Returns: {
// code: 'US',
// name: 'United States',
// fullName: 'United States of America',
// currency: 'USD',
// currencySymbol: '$',
// flag: 'πΊπΈ',
// continent: 'North America',
// region: 'Northern America',
// dialCode: '+1',
// timezones: ['America/New_York', 'America/Chicago', 'America/Denver', 'America/Los_Angeles']
// }
// Get Kenyan country data
const keCountry = getCountryByCode('KE');
console.log(keCountry);
// Returns: {
// code: 'KE',
// name: 'Kenya',
// fullName: 'Republic of Kenya',
// currency: 'KES',
// currencySymbol: 'KSh',
// flag: 'π°πͺ',
// continent: 'Africa',
// region: 'Eastern Africa',
// dialCode: '+254',
// timezones: ['Africa/Nairobi']
// }
Use Cases:
- Country selection forms
- International payroll setup
- Currency conversion
- Timezone calculations
getAllCountries(options?)β
Returns a list of all supported countries with optional filtering.
Parameters:
options(object, optional): Filtering and sorting optionsregion(string): Filter by regioncontinent(string): Filter by continentcurrency(string): Filter by currencysortBy(string): Sort field ('name', 'code', 'region')
Returns:
array: Array of country objects
Example:
import { getAllCountries } from '@/utils/helpers/country';
// Get all countries
const allCountries = getAllCountries();
console.log(allCountries.length); // Returns: 195
// Get countries by region
const africanCountries = getAllCountries({ continent: 'Africa' });
console.log(africanCountries.length); // Returns: 54
// Get countries using USD
const usdCountries = getAllCountries({ currency: 'USD' });
console.log(usdCountries);
// Returns countries that use USD
// Get sorted countries
const sortedCountries = getAllCountries({ sortBy: 'name' });
console.log(sortedCountries[0].name); // Returns: 'Afghanistan'
Use Cases:
- Dropdown population
- Regional reporting
- Currency grouping
- Administrative boundaries
getCountriesByRegion(region)β
Gets all countries in a specific geographical region.
Parameters:
region(string): Region name (e.g., 'Eastern Africa', 'Western Europe')
Returns:
array: Array of countries in the region
Example:
import { getCountriesByRegion } from '@/utils/helpers/country';
// Get East African countries
const eastAfrica = getCountriesByRegion('Eastern Africa');
console.log(eastAfrica);
// Returns: [Kenya, Uganda, Tanzania, Rwanda, ...]
// Get Western European countries
const westEurope = getCountriesByRegion('Western Europe');
console.log(westEurope);
// Returns: [France, Germany, UK, Netherlands, ...]
Use Cases:
- Regional operations
- Compliance grouping
- Market analysis
- Service availability
getCurrencyInfo(currencyCode)β
Retrieves detailed currency information including formatting rules.
Parameters:
currencyCode(string): ISO 4217 currency code
Returns:
object: Currency information object
Example:
import { getCurrencyInfo } from '@/utils/helpers/country';
// Get USD currency info
const usdInfo = getCurrencyInfo('USD');
console.log(usdInfo);
// Returns: {
// code: 'USD',
// name: 'US Dollar',
// symbol: '$',
// symbolPosition: 'before',
// decimalPlaces: 2,
// decimalSeparator: '.',
// thousandsSeparator: ',',
// countries: ['US', 'EC', 'SV', ...]
// }
// Get KES currency info
const kesInfo = getCurrencyInfo('KES');
console.log(kesInfo);
// Returns: {
// code: 'KES',
// name: 'Kenyan Shilling',
// symbol: 'KSh',
// symbolPosition: 'before',
// decimalPlaces: 2,
// decimalSeparator: '.',
// thousandsSeparator: ',',
// countries: ['KE']
// }
Use Cases:
- Currency formatting
- Financial calculations
- Payment processing
- Payroll configuration
formatCurrency(amount, currencyCode, options?)β
Formats monetary amounts according to currency-specific rules.
Parameters:
amount(number): Monetary amount to formatcurrencyCode(string): ISO currency codeoptions(object, optional): Formatting optionsshowSymbol(boolean): Include currency symbolshowCode(boolean): Include currency codelocale(string): Locale for formatting
Returns:
string: Formatted currency string
Example:
import { formatCurrency } from '@/utils/helpers/country';
// Format USD amounts
formatCurrency(1234.56, 'USD'); // Returns: '$1,234.56'
formatCurrency(1234.56, 'USD', { showCode: true }); // Returns: '$1,234.56 USD'
// Format KES amounts
formatCurrency(150000, 'KES'); // Returns: 'KSh150,000.00'
// Format EUR amounts
formatCurrency(1234.56, 'EUR'); // Returns: 'β¬1,234.56'
// Custom locale formatting
formatCurrency(1234.56, 'USD', { locale: 'en-GB' }); // Returns: '$1,234.56'
Use Cases:
- Salary display
- Invoice generation
- Financial reporting
- E-commerce pricing
Timezone and Regional Functionsβ
getTimezonesByCountry(countryCode)β
Gets all timezones for a specific country.
Parameters:
countryCode(string): ISO country code
Returns:
array: Array of timezone identifiers
Example:
import { getTimezonesByCountry } from '@/utils/helpers/country';
// Get US timezones
const usTimezones = getTimezonesByCountry('US');
console.log(usTimezones);
// Returns: [
// 'America/New_York',
// 'America/Chicago',
// 'America/Denver',
// 'America/Los_Angeles',
// 'America/Anchorage',
// 'Pacific/Honolulu'
// ]
// Get UK timezones
const ukTimezones = getTimezonesByCountry('GB');
console.log(ukTimezones);
// Returns: ['Europe/London']
Use Cases:
- Employee scheduling
- Meeting coordination
- Payroll timing
- Report generation
getWorkingDays(countryCode)β
Gets standard working days configuration for a country.
Parameters:
countryCode(string): ISO country code
Returns:
object: Working days configuration
Example:
import { getWorkingDays } from '@/utils/helpers/country';
// Get US working days
const usWorkingDays = getWorkingDays('US');
console.log(usWorkingDays);
// Returns: {
// weekdays: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
// startDay: 'Monday',
// endDay: 'Friday',
// hoursPerDay: 8,
// hoursPerWeek: 40,
// publicHolidays: [...],
// weekendDays: ['Saturday', 'Sunday']
// }
// Get Middle Eastern working days
const aeWorkingDays = getWorkingDays('AE');
console.log(aeWorkingDays);
// Returns: {
// weekdays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday'],
// startDay: 'Sunday',
// endDay: 'Thursday',
// hoursPerDay: 8,
// hoursPerWeek: 40,
// publicHolidays: [...],
// weekendDays: ['Friday', 'Saturday']
// }
Use Cases:
- Payroll calculations
- Leave management
- Scheduling systems
- Compliance management
Advanced Usage Examplesβ
Country Selector Componentβ
import { getAllCountries, getCountryByCode } from '@/utils/helpers/country';
const CountrySelector = ({ value, onChange, filter = {} }) => {
const [countries, setCountries] = useState([]);
const [searchTerm, setSearchTerm] = useState('');
useEffect(() => {
const allCountries = getAllCountries(filter);
setCountries(allCountries);
}, [filter]);
const filteredCountries = useMemo(() => {
if (!searchTerm) return countries;
return countries.filter(
country =>
country.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
country.code.toLowerCase().includes(searchTerm.toLowerCase()),
);
}, [countries, searchTerm]);
const selectedCountry = value ? getCountryByCode(value) : null;
return (
<div className='country-selector'>
<div className='selected-country'>
{selectedCountry && (
<span>
{selectedCountry.flag} {selectedCountry.name}
</span>
)}
</div>
<input
type='text'
placeholder='Search countries...'
value={searchTerm}
onChange={e => setSearchTerm(e.target.value)}
/>
<div className='country-list'>
{filteredCountries.map(country => (
<div
key={country.code}
className='country-option'
onClick={() => onChange(country.code)}
>
<span className='flag'>{country.flag}</span>
<span className='name'>{country.name}</span>
<span className='code'>({country.code})</span>
</div>
))}
</div>
</div>
);
};
Multi-Currency Payroll Systemβ
import {
getCountryByCode,
getCurrencyInfo,
formatCurrency,
} from '@/utils/helpers/country';
const useMultiCurrencyPayroll = () => {
const [baseCurrency, setBaseCurrency] = useState('USD');
const [exchangeRates, setExchangeRates] = useState({});
const calculateSalary = employee => {
const country = getCountryByCode(employee.countryCode);
const currency = getCurrencyInfo(country.currency);
let salaryAmount = employee.baseSalary;
// Convert from base currency if needed
if (country.currency !== baseCurrency) {
const rate = exchangeRates[country.currency] || 1;
salaryAmount = employee.baseSalary * rate;
}
// Apply local adjustments
const localAdjustments = getLocalAdjustments(employee.countryCode);
salaryAmount += localAdjustments.allowances;
salaryAmount -= localAdjustments.deductions;
return {
employee,
country,
currency,
grossSalary: salaryAmount,
formattedSalary: formatCurrency(salaryAmount, country.currency),
taxInfo: calculateTaxes(salaryAmount, employee.countryCode),
workingDays: getWorkingDays(employee.countryCode),
};
};
const processBulkPayroll = employees => {
return employees.map(calculateSalary);
};
const generatePayrollSummary = payrollData => {
const byCurrency = {};
payrollData.forEach(item => {
const currency = item.currency.code;
if (!byCurrency[currency]) {
byCurrency[currency] = {
currency: item.currency,
totalGross: 0,
totalNet: 0,
employeeCount: 0,
countries: new Set(),
};
}
byCurrency[currency].totalGross += item.grossSalary;
byCurrency[currency].totalNet += item.grossSalary - item.taxInfo.totalTax;
byCurrency[currency].employeeCount += 1;
byCurrency[currency].countries.add(item.country.code);
});
return Object.values(byCurrency).map(summary => ({
...summary,
countries: Array.from(summary.countries),
formattedGross: formatCurrency(summary.totalGross, summary.currency.code),
formattedNet: formatCurrency(summary.totalNet, summary.currency.code),
}));
};
return {
baseCurrency,
setBaseCurrency,
calculateSalary,
processBulkPayroll,
generatePayrollSummary,
};
};
Regional Compliance Managerβ
import {
getCountriesByRegion,
getWorkingDays,
getAllCountries,
} from '@/utils/helpers/country';
const useRegionalCompliance = () => {
const getComplianceRules = countryCode => {
const country = getCountryByCode(countryCode);
const workingDays = getWorkingDays(countryCode);
// Mock compliance rules - in real app would come from API
const rules = {
dataProtection: getDataProtectionRules(countryCode),
employment: getEmploymentLaws(countryCode),
taxation: getTaxationRules(countryCode),
workingTime: workingDays,
publicHolidays: getPublicHolidays(countryCode),
};
return {
country,
rules,
lastUpdated: new Date().toISOString(),
};
};
const validateEmployeeData = (employee, countryCode) => {
const compliance = getComplianceRules(countryCode);
const violations = [];
// Check working hours compliance
if (employee.hoursPerWeek > compliance.rules.workingTime.maxHoursPerWeek) {
violations.push({
type: 'working_hours',
message: `Exceeds maximum working hours for ${compliance.country.name}`,
});
}
// Check minimum wage compliance
if (employee.hourlyRate < compliance.rules.employment.minimumWage) {
violations.push({
type: 'minimum_wage',
message: `Below minimum wage for ${compliance.country.name}`,
});
}
return {
isCompliant: violations.length === 0,
violations,
compliance,
};
};
const getRegionalOverview = region => {
const countries = getCountriesByRegion(region);
return countries.map(country => ({
country,
compliance: getComplianceRules(country.code),
businessEnvironment: {
easeOfBusiness: getBusinessRanking(country.code),
laborLaws: getLaborComplexity(country.code),
taxBurden: getTaxBurden(country.code),
},
}));
};
return {
getComplianceRules,
validateEmployeeData,
getRegionalOverview,
};
};
International Time Managementβ
import {
getTimezonesByCountry,
getCountryByCode,
} from '@/utils/helpers/country';
const useInternationalTime = () => {
const [userTimezone, setUserTimezone] = useState(
Intl.DateTimeFormat().resolvedOptions().timeZone,
);
const convertTimeToCountry = (date, targetCountryCode) => {
const country = getCountryByCode(targetCountryCode);
const timezones = getTimezonesByCountry(targetCountryCode);
// Use primary timezone (first in list)
const targetTimezone = timezones[0];
return {
original: date,
converted: new Date(
date.toLocaleString('en-US', { timeZone: targetTimezone }),
),
timezone: targetTimezone,
country: country,
offset: getTimezoneOffset(targetTimezone),
};
};
const scheduleGlobalMeeting = (dateTime, participantCountries) => {
const schedule = participantCountries.map(countryCode => {
const converted = convertTimeToCountry(dateTime, countryCode);
const workingDays = getWorkingDays(countryCode);
return {
...converted,
isWorkingDay: isWorkingDay(converted.converted, workingDays),
isWorkingHours: isWorkingHours(converted.converted, workingDays),
localTimeString: converted.converted.toLocaleString(),
};
});
return {
originalTime: dateTime,
schedule,
conflicts: schedule.filter(s => !s.isWorkingHours),
optimal: schedule.every(s => s.isWorkingHours),
};
};
const getWorkingHoursOverlap = countries => {
// Find overlapping working hours across multiple countries
const workingHours = countries.map(countryCode => {
const workingDays = getWorkingDays(countryCode);
const timezones = getTimezonesByCountry(countryCode);
return {
country: getCountryByCode(countryCode),
timezone: timezones[0],
startHour: 9, // 9 AM local time
endHour: 17, // 5 PM local time
workingDays: workingDays.weekdays,
};
});
// Calculate overlap (simplified)
return findTimeOverlap(workingHours);
};
return {
userTimezone,
setUserTimezone,
convertTimeToCountry,
scheduleGlobalMeeting,
getWorkingHoursOverlap,
};
};
Data Sources and Standardsβ
ISO Standards Complianceβ
- ISO 3166-1: Country codes (alpha-2, alpha-3, numeric)
- ISO 4217: Currency codes
- IANA Time Zone Database: Timezone identifiers
- Unicode CLDR: Locale data and formatting rules
Regional Classificationsβ
- UN M49: United Nations statistical regions
- World Bank: Income and development classifications
- IMF: Currency and economic data
Best Practicesβ
- Cache Country Data: Store frequently accessed country information
- Validate Inputs: Always validate country and currency codes
- Handle Missing Data: Provide fallbacks for unknown countries
- Localization: Use appropriate locale for formatting
- Currency Updates: Regularly update exchange rates and formatting rules
Related Utilitiesβ
- Phone Number Helpers - For international phone validation
- String Utilities - For text formatting
- Date & Time Utilities - For timezone handling
TypeScript Definitionsβ
interface Country {
code: string;
name: string;
fullName: string;
currency: string;
currencySymbol: string;
flag: string;
continent: string;
region: string;
dialCode: string;
timezones: string[];
}
interface Currency {
code: string;
name: string;
symbol: string;
symbolPosition: 'before' | 'after';
decimalPlaces: number;
decimalSeparator: string;
thousandsSeparator: string;
countries: string[];
}
interface WorkingDays {
weekdays: string[];
startDay: string;
endDay: string;
hoursPerDay: number;
hoursPerWeek: number;
publicHolidays: Date[];
weekendDays: string[];
}
export function getCountryByCode(countryCode: string): Country | null;
export function getAllCountries(options?: {
region?: string;
continent?: string;
currency?: string;
sortBy?: string;
}): Country[];
export function getCountriesByRegion(region: string): Country[];
export function getCurrencyInfo(currencyCode: string): Currency | null;
export function formatCurrency(
amount: number,
currencyCode: string,
options?: {
showSymbol?: boolean;
showCode?: boolean;
locale?: string;
},
): string;
export function getTimezonesByCountry(countryCode: string): string[];
export function getWorkingDays(countryCode: string): WorkingDays;
Dependenciesβ
- Country data: Static country information database
- Currency data: ISO 4217 currency information
- Timezone data: IANA timezone database
- Intl API: Browser internationalization support