Skip to main content

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&lt;SettingsBreadcrumbProps&gt; = ({
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'),
};

Migration Notes​

When updating settings constants:

  1. Maintain backward compatibility for existing routes
  2. Update TypeScript definitions when adding new sections
  3. Test navigation flows after changes
  4. Update documentation for new settings sections
  5. Consider feature flag integration for new settings