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)