Skip to main content

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 options
    • region (string): Filter by region
    • continent (string): Filter by continent
    • currency (string): Filter by currency
    • sortBy (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 format
  • currencyCode (string): ISO currency code
  • options (object, optional): Formatting options
    • showSymbol (boolean): Include currency symbol
    • showCode (boolean): Include currency code
    • locale (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​

  1. Cache Country Data: Store frequently accessed country information
  2. Validate Inputs: Always validate country and currency codes
  3. Handle Missing Data: Provide fallbacks for unknown countries
  4. Localization: Use appropriate locale for formatting
  5. Currency Updates: Regularly update exchange rates and formatting rules


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