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