Skip to main content

EOR Helpers

Employer of Record (EOR) filter management utilities for managing EOR company selections and filters in the WorkPayCore frontend application.

Overview​

The EOR helpers provide utilities for managing EOR filter state in localStorage, specifically for company selection filters with synchronization between single and multi-select modes.

Core Functions​

getEorFilter<K>(key)​

Retrieves a specific EOR filter value from localStorage.

Parameters:

  • key (keyof TEorFilters): The filter key to retrieve

Returns:

  • TEorFilters[K]: The filter value or undefined if not found

Example:

import { getEorFilter } from '@/utils/helpers/eor-helpers';

// Get single company selection
const selectedCompany = getEorFilter('eOR_company_single_select');
console.log(selectedCompany);
// Returns: { value: 123, label: 'Company Name', flag: 'US' }

// Get multiple company selections
const selectedCompanies = getEorFilter('eor_companies_multi_select');
console.log(selectedCompanies);
// Returns: [
// { value: 123, label: 'Company A', flag: 'US' },
// { value: 456, label: 'Company B', flag: 'CA' }
// ]

// Get country selection
const selectedCountry = getEorFilter('country_select');
console.log(selectedCountry);
// Returns: { value: 1, label: 'United States', flag: 'US' }

Use Cases:

  • Loading saved filter state
  • Restoring user preferences
  • Filter state synchronization
  • Initial component state

handleChangeEorFilter(params)​

Updates an EOR filter value with automatic synchronization between related filters.

Parameters:

  • params (object): An object containing the key and value.
    • key (keyof TEorFilters): The filter key to update
    • value (TEorFilters[K]): The new filter value

Returns:

  • void: No return value

Example:

import { handleChangeEorFilter } from '@/utils/helpers/eor-helpers';

// Update single company selection (automatically updates multi-select)
handleChangeEorFilter({
key: 'eor_company_single_select',
value: {
value: 123,
label: 'Acme Corp',
flag: 'US',
// Additional company data...
},
});

// Update multiple company selection
handleChangeEorFilter({
key: 'eor_companies_multi_select',
value: [
{ value: 123, label: 'Company A', flag: 'US' },
{ value: 456, label: 'Company B', flag: 'CA' },
],
});

// Update country selection
handleChangeEorFilter({
key: 'country_select',
value: {
value: 1,
label: 'United States',
flag: 'US',
},
});

Use Cases:

  • Filter selection updates
  • User preference persistence
  • Multi-filter synchronization
  • Form state management

Filter Synchronization​

How Synchronization Works​

The EOR helpers automatically synchronize related filters:

  • Single → Multi: When eor_company_single_select is updated, eor_companies_multi_select is automatically set to contain the same company
  • Data Cleaning: Only specific properties (value, label, flag) are preserved
  • Empty Handling: Empty or null selections clear related filters

Synchronization Example​

// Before synchronization
const currentState = {
eor_company_single_select: null,
eor_companies_multi_select: [{ value: 999, label: 'Old Company' }],
};

// Update single selection
handleChangeEorFilter({
key: 'eor_company_single_select',
value: {
value: 123,
label: 'New Company',
flag: 'US',
extra_data: 'will be removed',
},
});

// After synchronization
const newState = {
eor_company_single_select: {
value: 123,
label: 'New Company',
flag: 'US',
},
eor_companies_multi_select: [
{
value: 123,
label: 'New Company',
flag: 'US',
},
],
};

Advanced Usage Examples​

React Hook for EOR Filters​

import {
getEorFilter,
handleChangeEorFilter,
} from '@/utils/helpers/eor-helpers';

const useEorFilters = () => {
const [filters, setFilters] = useState(() => ({
singleCompany: getEorFilter('eor_company_single_select'),
multiCompanies: getEorFilter('eor_companies_multi_select'),
country: getEorFilter('country_select'),
}));

const updateFilter = (key, value) => {
handleChangeEorFilter({ key, value });

// Update local state for immediate UI feedback
setFilters(prev => ({
...prev,
singleCompany: getEorFilter('eor_company_single_select'),
multiCompanies: getEorFilter('eor_companies_multi_select'),
country: getEorFilter('country_select'),
}));
};

return { filters, updateFilter };
};

// Usage in component
const EorDashboard = () => {
const { filters, updateFilter } = useEorFilters();

const handleCompanyChange = selectedCompany => {
updateFilter('eor_company_single_select', selectedCompany);
};

return (
<div>
<CompanySelector
value={filters.singleCompany}
onChange={handleCompanyChange}
/>

<CountrySelector
value={filters.country}
onChange={country => updateFilter('country_select', country)}
/>
</div>
);
};

Filter Form Component​

import {
getEorFilter,
handleChangeEorFilter,
} from '@/utils/helpers/eor-helpers';

const EorFilterForm = ({ onFiltersChange }) => {
const [localFilters, setLocalFilters] = useState({
company: getEorFilter('eor_company_single_select'),
companies: getEorFilter('eor_companies_multi_select'),
country: getEorFilter('country_select'),
});

const handleFilterChange = (filterKey, value) => {
// Update persistent storage
handleChangeEorFilter({ key: filterKey, value });

// Update local state
setLocalFilters(prev => ({
...prev,
[filterKey.replace('eor_', '').replace('_select', '')]: value,
}));

// Notify parent component
onFiltersChange?.({
company: getEorFilter('eor_company_single_select'),
companies: getEorFilter('eor_companies_multi_select'),
country: getEorFilter('country_select'),
});
};

const clearFilters = () => {
handleChangeEorFilter({ key: 'eor_company_single_select', value: null });
handleChangeEorFilter({ key: 'eor_companies_multi_select', value: [] });
handleChangeEorFilter({ key: 'country_select', value: null });

setLocalFilters({
company: null,
companies: [],
country: null,
});
};

return (
<form>
<div>
<label>EOR Company</label>
<Select
value={localFilters.company}
onChange={value =>
handleFilterChange('eor_company_single_select', value)
}
options={eorCompanyOptions}
/>
</div>

<div>
<label>Countries</label>
<Select
value={localFilters.country}
onChange={value => handleFilterChange('country_select', value)}
options={countryOptions}
/>
</div>

<button type='button' onClick={clearFilters}>
Clear All Filters
</button>
</form>
);
};

Data Loading with Filters​

import { getEorFilter } from '@/utils/helpers/eor-helpers';

const useEorData = () => {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);

const loadData = useCallback(async () => {
setLoading(true);

try {
// Get current filter state
const selectedCompany = getEorFilter('eor_company_single_select');
const selectedCountry = getEorFilter('country_select');

// Build API parameters from filters
const params = new URLSearchParams();

if (selectedCompany?.value) {
params.append('company_id', selectedCompany.value.toString());
}

if (selectedCountry?.value) {
params.append('country_id', selectedCountry.value.toString());
}

// Fetch filtered data
const response = await fetch(`/api/eor/data?${params}`);
const result = await response.json();

setData(result.data || []);
} catch (error) {
console.error('Failed to load EOR data:', error);
setData([]);
} finally {
setLoading(false);
}
}, []);

// Reload data when filters change
useEffect(() => {
loadData();
}, [loadData]);

return { data, loading, refetch: loadData };
};

Filter State Management​

import {
getEorFilter,
handleChangeEorFilter,
} from '@/utils/helpers/eor-helpers';

class EorFilterManager {
static getAllFilters() {
return {
singleCompany: getEorFilter('eor_company_single_select'),
multiCompanies: getEorFilter('eor_companies_multi_select'),
country: getEorFilter('country_select'),
};
}

static clearAllFilters() {
handleChangeEorFilter({ key: 'eor_company_single_select', value: null });
handleChangeEorFilter({ key: 'eor_companies_multi_select', value: [] });
handleChangeEorFilter({ key: 'country_select', value: null });
}

static applyFilterPreset(preset) {
switch (preset) {
case 'us_companies':
handleChangeEorFilter({
key: 'country_select',
value: { value: 1, label: 'United States', flag: 'US' },
});
break;

case 'ca_companies':
handleChangeEorFilter({
key: 'country_select',
value: { value: 2, label: 'Canada', flag: 'CA' },
});
break;

default:
this.clearAllFilters();
}
}

static exportFilters() {
const filters = this.getAllFilters();
return JSON.stringify(filters, null, 2);
}

static importFilters(filtersJson) {
try {
const filters = JSON.parse(filtersJson);

if (filters.singleCompany) {
handleChangeEorFilter({
key: 'eor_company_single_select',
value: filters.singleCompany,
});
}

if (filters.country) {
handleChangeEorFilter({
key: 'country_select',
value: filters.country,
});
}

return true;
} catch (error) {
console.error('Failed to import filters:', error);
return false;
}
}
}

// Usage
const AdminFilters = () => {
const [preset, setPreset] = useState('');

const handlePresetChange = newPreset => {
EorFilterManager.applyFilterPreset(newPreset);
setPreset(newPreset);
};

return (
<div>
<select value={preset} onChange={e => handlePresetChange(e.target.value)}>
<option value=''>Select Preset</option>
<option value='us_companies'>US Companies</option>
<option value='ca_companies'>Canadian Companies</option>
</select>

<button onClick={() => EorFilterManager.clearAllFilters()}>
Clear All
</button>
</div>
);
};

Data Structure​

TEorFilters Type Definition​

type TEorFilters = {
eor_company_single_select: {
value: number;
label: string;
flag?: string;
[prop: string]: unknown;
};

eor_companies_multi_select: Array<{
value: number;
label: string;
flag?: string;
[prop: string]: unknown;
}>;

country_select: {
value: number;
label: string;
flag?: string;
[prop: string]: unknown;
};
};

Stored Data Example​

// localStorage['eor_filters']
{
"eor_company_single_select": {
"value": 123,
"label": "Workpay EOR Services Inc.",
"flag": "US"
},
"eor_companies_multi_select": [
{
"value": 123,
"label": "Workpay EOR Services Inc.",
"flag": "US"
}
],
"country_select": {
"value": 1,
"label": "United States",
"flag": "US"
}
}

Best Practices​

  1. Data Consistency: Use the helpers to maintain consistent data structure
  2. Null Handling: Check for null/undefined values when using filter data
  3. Synchronization: Rely on automatic synchronization between single/multi selects
  4. Performance: Batch filter updates when possible
  5. Error Handling: Wrap filter operations in try-catch blocks


TypeScript Definitions​

type TEorFilters = {
eor_company_single_select: {
value: number;
label: string;
[prop: string]: unknown;
};
eor_companies_multi_select: {
value: number;
label: string;
[prop: string]: unknown;
}[];
country_select: {
value: number;
label: string;
[prop: string]: unknown;
};
};

export function getEorFilter&lt;K extends keyof TEorFilters&gt;(
key: K,
): TEorFilters[K] | undefined;

export function handleChangeEorFilter&lt;K extends keyof TEorFilters&gt;(params: {
key: K;
value: TEorFilters[K];
}): void;

Dependencies​

  • hooks/local-storage-store: For localStorage operations
  • utils/objectArrayUtils: For data manipulation (IsEmpty, removeFalsy)