Settings Constants
Navigation organization constants for settings module routing structure.
Overview
The Settings Constants provide a structured way to organize and match different settings sections within the WorkPayCore application. These constants define the routing structure and navigation organization for various settings modules.
Constants
Organization Match
Maps organization-related settings sections:
export const organizationMatch = {
departments: 'departments',
job_titles: 'job_titles',
organization: 'organization',
};
Payroll Data Match
Maps payroll-related settings sections:
export const payrollDataMatch = {
salary_rates: 'salary_rates',
muster_roll: 'muster_roll',
payroll_processing: 'payroll_processing',
nssf_rate: 'nssf_rate',
multi_currency: ' multi_currency',
market_lending_rate: 'market_lending_rate',
shares: 'shares',
payslips: 'payslips',
nhis: 'nhis',
cra: 'cra',
salary_advance: 'salary_advance',
gross_breakdown: 'gross_breakdown',
third_net_pay_rule: 'third_net_pay_rule',
};
Users Match
Maps user management settings sections:
export const usersMatch = {
users: 'users',
roles: 'roles',
};
Attendance Match
Maps attendance-related settings:
export const attendanceMatch = {
attendance: 'attendance',
};
Billing Match
Maps billing-related settings:
export const billingMatch = {
payment_method: 'payment_method',
};
Leaves Policy Match
Maps leave management settings sections:
export const leavesPolicyMatch = {
leave_policies: 'leave_policies',
leave_balances: 'leave_balances',
leave_approval_levels: 'leave_approval_levels',
paid_leaves: 'paid_leaves',
leave_settings: 'leave_settings',
};
Payments Match
Maps payment-related settings:
export const paymentsMatch = {
transaction_policy: 'transaction_policy',
favorites: 'favorites',
};
Categories Match
Maps category management settings:
export const categoriesMatch = {
allowances: 'allowances',
deductions: 'deductions',
expenses: 'expenses',
loans: 'loans',
savings: 'savings',
trainings: 'trainings',
assets: 'assets',
documents: 'documents',
};
BSC Match
Maps Balance Score Card settings:
export const bscMatch = {
performance_rating: 'performance_rating',
review_period: 'review_period',
};
Timesheets Match
Maps timesheet-related settings:
export const timesheetsMatch = {
atteandance: 'attendance',
};
Payslip Match
Maps payslip-related settings:
export const payslipMatch = {
payslips: 'payslips',
};
Employee Portal Match
Maps employee portal settings:
export const employeePortalMatch = {
employee_portal: 'employee_portal',
};
Usage Examples
Basic Navigation Matching
import {
organizationMatch,
payrollDataMatch,
} from '@/utils/constants/settings';
// Check if current route matches organization settings
const isOrganizationRoute = (route: string) => {
return Object.values(organizationMatch).includes(route);
};
// Get payroll section identifier
const getPayrollSection = (section: keyof typeof payrollDataMatch) => {
return payrollDataMatch[section];
};
Settings Navigation Component
import React from 'react';
import {
organizationMatch,
usersMatch,
payrollDataMatch,
categoriesMatch,
} from '@/utils/constants/settings';
interface SettingsNavProps {
currentSection: string;
onSectionChange: (section: string) => void;
}
const SettingsNav: React.FC<SettingsNavProps> = ({
currentSection,
onSectionChange,
}) => {
const settingsSections = [
{ title: 'Organization', items: organizationMatch },
{ title: 'Users', items: usersMatch },
{ title: 'Payroll', items: payrollDataMatch },
{ title: 'Categories', items: categoriesMatch },
];
return (
<nav className='settings-navigation'>
{settingsSections.map(section => (
<div key={section.title} className='nav-section'>
<h3>{section.title}</h3>
<ul>
{Object.entries(section.items).map(([key, value]) => (
<li key={key}>
<button
className={currentSection === value ? 'active' : ''}
onClick={() => onSectionChange(value)}
>
{key.replace(/_/g, ' ').toUpperCase()}
</button>
</li>
))}
</ul>
</div>
))}
</nav>
);
};
export default SettingsNav;
Route Validation Hook
import { useMemo } from 'react';
import {
organizationMatch,
payrollDataMatch,
usersMatch,
leavesPolicyMatch,
categoriesMatch,
} from '@/utils/constants/settings';
export const useSettingsRouteValidation = (currentRoute: string) => {
const allSettingsRoutes = useMemo(() => {
return [
...Object.values(organizationMatch),
...Object.values(payrollDataMatch),
...Object.values(usersMatch),
...Object.values(leavesPolicyMatch),
...Object.values(categoriesMatch),
];
}, []);
const isValidSettingsRoute = useMemo(() => {
return allSettingsRoutes.includes(currentRoute);
}, [currentRoute, allSettingsRoutes]);
const getSettingsCategory = useMemo(() => {
if (Object.values(organizationMatch).includes(currentRoute)) {
return 'organization';
}
if (Object.values(payrollDataMatch).includes(currentRoute)) {
return 'payroll';
}
if (Object.values(usersMatch).includes(currentRoute)) {
return 'users';
}
if (Object.values(leavesPolicyMatch).includes(currentRoute)) {
return 'leaves';
}
if (Object.values(categoriesMatch).includes(currentRoute)) {
return 'categories';
}
return null;
}, [currentRoute]);
return {
isValidSettingsRoute,
settingsCategory: getSettingsCategory,
allSettingsRoutes,
};
};
Settings Breadcrumb Component
import React from 'react';
import {
organizationMatch,
payrollDataMatch,
usersMatch,
} from '@/utils/constants/settings';
interface SettingsBreadcrumbProps {
currentRoute: string;
}
const SettingsBreadcrumb: React.FC<SettingsBreadcrumbProps> = ({
currentRoute,
}) => {
const getBreadcrumbPath = (route: string) => {
const allMatches = {
Organization: organizationMatch,
Payroll: payrollDataMatch,
Users: usersMatch,
};
for (const [category, matches] of Object.entries(allMatches)) {
const matchKey = Object.keys(matches).find(
key => matches[key as keyof typeof matches] === route,
);
if (matchKey) {
return {
category,
section: matchKey.replace(/_/g, ' ').toUpperCase(),
};
}
}
return null;
};
const breadcrumb = getBreadcrumbPath(currentRoute);
if (!breadcrumb) return null;
return (
<nav className='breadcrumb'>
<span>Settings</span>
<span className='separator'>/</span>
<span>{breadcrumb.category}</span>
<span className='separator'>/</span>
<span className='current'>{breadcrumb.section}</span>
</nav>
);
};
export default SettingsBreadcrumb;
TypeScript Definitions
// Settings match types
export type OrganizationMatchKeys = keyof typeof organizationMatch;
export type PayrollDataMatchKeys = keyof typeof payrollDataMatch;
export type UsersMatchKeys = keyof typeof usersMatch;
export type LeavesPolicyMatchKeys = keyof typeof leavesPolicyMatch;
export type CategoriesMatchKeys = keyof typeof categoriesMatch;
// Settings section type
export type SettingsSection =
| (typeof organizationMatch)[OrganizationMatchKeys]
| (typeof payrollDataMatch)[PayrollDataMatchKeys]
| (typeof usersMatch)[UsersMatchKeys]
| (typeof leavesPolicyMatch)[LeavesPolicyMatchKeys]
| (typeof categoriesMatch)[CategoriesMatchKeys];
// Settings category type
export type SettingsCategory =
| 'organization'
| 'payroll'
| 'users'
| 'leaves'
| 'categories'
| 'attendance'
| 'billing'
| 'payments'
| 'bsc'
| 'timesheets'
| 'payslip'
| 'employee_portal';
Best Practices
1. Consistent Naming
// ✅ Good - consistent snake_case
export const settingsMatch = {
user_profile: 'user_profile',
account_settings: 'account_settings',
};
// ❌ Bad - mixed naming conventions
export const settingsMatch = {
userProfile: 'user_profile',
'account-settings': 'account_settings',
};
2. Route Validation
// ✅ Good - validate routes before navigation
const navigateToSettings = (route: string) => {
const allRoutes = Object.values(organizationMatch);
if (allRoutes.includes(route)) {
navigate(`/settings/${route}`);
} else {
console.warn(`Invalid settings route: ${route}`);
}
};
3. Type Safety
// ✅ Good - use typed keys
const getOrganizationRoute = (key: OrganizationMatchKeys) => {
return organizationMatch[key];
};
// ❌ Bad - untyped string keys
const getOrganizationRoute = (key: string) => {
return organizationMatch[key]; // Type error
};
Performance Considerations
1. Memoization
// Cache route lookups for better performance
const routeCache = new Map<string, SettingsCategory | null>();
export const getSettingsCategory = (route: string): SettingsCategory | null => {
if (routeCache.has(route)) {
return routeCache.get(route)!;
}
// Perform lookup logic...
const category = performLookup(route);
routeCache.set(route, category);
return category;
};
2. Lazy Loading
// Lazy load settings sections
const settingsModules = {
organization: () => import('./OrganizationSettings'),
payroll: () => import('./PayrollSettings'),
users: () => import('./UsersSettings'),
};
Related Utilities
- Feature Flags - For conditional settings visibility
- Session Keys - For settings state management
- Options - For settings form options
- EOR Portal Constants - For EOR-specific settings
Migration Notes
When updating settings constants:
- Maintain backward compatibility for existing routes
- Update TypeScript definitions when adding new sections
- Test navigation flows after changes
- Update documentation for new settings sections
- Consider feature flag integration for new settings