Compare commits
2 Commits
bc537f583f
...
22ee92190d
| Author | SHA1 | Date | |
|---|---|---|---|
| 22ee92190d | |||
| e065e222ec |
7
public/mockApi/master-data/summary.json
Normal file
7
public/mockApi/master-data/summary.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"totalCompanies": 1,
|
||||
"totalBranches": 3,
|
||||
"totalDepartments": 5,
|
||||
"totalDesignations": 4,
|
||||
"totalEmployees": 245
|
||||
}
|
||||
@ -9,9 +9,9 @@ import LeaveRouter from '../../features/leave/routes/LeaveRouter';
|
||||
import ApprovalRouter from '../../features/leave/routes/ApprovalRouter';
|
||||
import AttendanceSummaryRouter from '../../features/attendance/routes/AttendanceSummaryRouter';
|
||||
import LeaveSummaryRouter from '../../features/leave/routes/LeaveSummaryRouter';
|
||||
import ManageEmployeesRouter from '../../features/dashboard/routes/ManageEmployeesRouter';
|
||||
import ManageAdminsRouter from '../../features/dashboard/routes/ManageAdminsRouter';
|
||||
import PolicyRouter from '../../features/dashboard/routes/PolicyRouter';
|
||||
import MasterDataRouter from '../../features/employee-management/routes/MasterDataRouter'; // New Import
|
||||
|
||||
export default function MainLayout() {
|
||||
const [isCollapsed, setIsCollapsed] = useState(false);
|
||||
@ -40,7 +40,7 @@ export default function MainLayout() {
|
||||
<Route path="/approval" element={<ApprovalRouter />} />
|
||||
<Route path="/attendance-summary/*" element={<AttendanceSummaryRouter />} />
|
||||
<Route path="/leave-summary" element={<LeaveSummaryRouter />} />
|
||||
<Route path="/manage-employees" element={<ManageEmployeesRouter />} />
|
||||
<Route path="/master-data/*" element={<MasterDataRouter />} />
|
||||
<Route path="/manage-admins" element={<ManageAdminsRouter />} />
|
||||
<Route path="/policies" element={<PolicyRouter />} />
|
||||
|
||||
|
||||
@ -5,13 +5,15 @@ import { getSidebarItems, type NavItem } from './types/sidebarConfig';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
import {
|
||||
LayoutDashboard, CalendarCheck, Plane, CheckCircle, BarChart3, ClipboardList,
|
||||
Menu, Users, ShieldUser, ScrollText, ChevronDown, FileText, CalendarDays, ClipboardCheck // Added ClipboardCheck
|
||||
Menu, Users, ShieldUser, ScrollText, ChevronDown, FileText, CalendarDays, ClipboardCheck,
|
||||
Database, Building, Network, Briefcase, Tag // Added new icons
|
||||
} from 'lucide-react';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const iconMap: Record<string, any> = {
|
||||
LayoutDashboard, CalendarCheck, Plane, CheckCircle, BarChart3, ClipboardList,
|
||||
Users, ShieldUser, ScrollText, FileText, CalendarDays, ClipboardCheck // Added ClipboardCheck
|
||||
Users, ShieldUser, ScrollText, FileText, CalendarDays, ClipboardCheck,
|
||||
Database, Building, Network, Briefcase, Tag // Added new icons
|
||||
};
|
||||
|
||||
export default function Sidebar({ isCollapsed, setIsCollapsed }: { isCollapsed: boolean; setIsCollapsed: (v: boolean) => void }) {
|
||||
@ -43,7 +45,8 @@ export default function Sidebar({ isCollapsed, setIsCollapsed }: { isCollapsed:
|
||||
{hasChildren ? (
|
||||
<button
|
||||
onClick={() => toggleDropdown(item.name)}
|
||||
className={`w-full flex items-center px-4 py-3 transition-colors duration-200 text-left ${isChildActive ? 'text-white' : 'text-blue-100 hover:bg-sidebar-hover hover:text-white'
|
||||
className={`w-full flex items-center px-4 py-3 transition-colors duration-200 text-left ${
|
||||
isChildActive ? 'text-white' : 'text-blue-100 hover:bg-sidebar-hover hover:text-white'
|
||||
} border-l-4 ${isChildActive ? 'border-action' : 'border-transparent'}`}
|
||||
>
|
||||
{Icon && <Icon size={20} className="flex-shrink-0" />}
|
||||
@ -55,7 +58,8 @@ export default function Sidebar({ isCollapsed, setIsCollapsed }: { isCollapsed:
|
||||
) : (
|
||||
<Link
|
||||
to={item.path!}
|
||||
className={`flex items-center px-4 py-3 transition-colors duration-200 text-left ${isActive ? 'bg-sidebar-active text-white border-l-4 border-action' : 'text-blue-100 hover:bg-sidebar-hover hover:text-white border-l-4 border-transparent'
|
||||
className={`flex items-center px-4 py-3 transition-colors duration-200 text-left ${
|
||||
isActive ? 'bg-sidebar-active text-white border-l-4 border-action' : 'text-blue-100 hover:bg-sidebar-hover hover:text-white border-l-4 border-transparent'
|
||||
}`}
|
||||
>
|
||||
{Icon && <Icon size={20} className="flex-shrink-0" />}
|
||||
|
||||
@ -18,9 +18,7 @@ export const getSidebarItems = (role: UserRole): NavItem[] => {
|
||||
return [...baseItems, { name: 'Approval', icon: 'CheckCircle', path: '/approval' }];
|
||||
}
|
||||
|
||||
if (role === 'admin') {
|
||||
return [
|
||||
...baseItems,
|
||||
const adminItems: NavItem[] = [
|
||||
{
|
||||
name: 'Attendance Summary',
|
||||
icon: 'BarChart3',
|
||||
@ -28,30 +26,33 @@ export const getSidebarItems = (role: UserRole): NavItem[] => {
|
||||
{ name: 'Dashboard', icon: 'LayoutDashboard', path: '/attendance-summary/dashboard' },
|
||||
{ name: 'Monthly Report', icon: 'FileText', path: '/attendance-summary/monthly' },
|
||||
{ name: 'Daily Report', icon: 'CalendarDays', path: '/attendance-summary/daily' },
|
||||
{ name: 'Regularization', icon: 'ClipboardCheck', path: '/attendance-summary/regularization' }, // New Item
|
||||
...(role === 'admin' ? [{ name: 'Regularization', icon: 'ClipboardCheck', path: '/attendance-summary/regularization' }] : [])
|
||||
]
|
||||
},
|
||||
{ name: 'Leave Summary', icon: 'ClipboardList', path: '/leave-summary' },
|
||||
{ name: 'Manage Employees', icon: 'Users', path: '/manage-employees' },
|
||||
{
|
||||
name: 'Master Data',
|
||||
icon: 'Database',
|
||||
children: [
|
||||
{ name: 'Dashboard', icon: 'LayoutDashboard', path: '/master-data/dashboard' },
|
||||
{ name: 'Manage Company', icon: 'Building', path: '/master-data/company' },
|
||||
{ name: 'Manage Branches', icon: 'Network', path: '/master-data/branches' },
|
||||
{ name: 'Manage Departments', icon: 'Briefcase', path: '/master-data/departments' },
|
||||
{ name: 'Manage Designations', icon: 'Tag', path: '/master-data/designations' },
|
||||
{ name: 'Manage Employees', icon: 'Users', path: '/master-data/employees' },
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
if (role === 'admin') {
|
||||
return [...baseItems, ...adminItems];
|
||||
}
|
||||
|
||||
if (role === 'superadmin') {
|
||||
return [
|
||||
...baseItems,
|
||||
{
|
||||
name: 'Attendance Summary',
|
||||
icon: 'BarChart3',
|
||||
children: [
|
||||
{ name: 'Dashboard', icon: 'LayoutDashboard', path: '/attendance-summary/dashboard' },
|
||||
{ name: 'Monthly Report', icon: 'FileText', path: '/attendance-summary/monthly' },
|
||||
{ name: 'Daily Report', icon: 'CalendarDays', path: '/attendance-summary/daily' },
|
||||
// SuperAdmin does not get Regularization based on your requirement
|
||||
]
|
||||
},
|
||||
{ name: 'Leave Summary', icon: 'ClipboardList', path: '/leave-summary' },
|
||||
...adminItems,
|
||||
{ name: 'Manage Admins', icon: 'ShieldUser', path: '/manage-admins' },
|
||||
{ name: 'Manage Employees', icon: 'Users', path: '/manage-employees' },
|
||||
{ name: 'Policy and Rules', icon: 'ScrollText', path: '/policies' },
|
||||
];
|
||||
}
|
||||
|
||||
17
src/features/employee-management/api/useMasterData.ts
Normal file
17
src/features/employee-management/api/useMasterData.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { fetchMockData } from '../../../api/client';
|
||||
|
||||
export interface MasterDataSummary {
|
||||
totalCompanies: number;
|
||||
totalBranches: number;
|
||||
totalDepartments: number;
|
||||
totalDesignations: number;
|
||||
totalEmployees: number;
|
||||
}
|
||||
|
||||
export const useMasterDataSummary = () => {
|
||||
return useQuery<MasterDataSummary>({
|
||||
queryKey: ['masterDataSummary'],
|
||||
queryFn: () => fetchMockData<MasterDataSummary>('master-data/summary.json'),
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,59 @@
|
||||
import { Building, Network, Briefcase, Tag, Users } from 'lucide-react';
|
||||
import Loader from '../../../components/ui/Loader';
|
||||
import ErrorState from '../../../components/ui/ErrorState';
|
||||
import StatCard from '../../attendance/components/summary/StatCard'; // Reusing StatCard
|
||||
import { useMasterDataSummary } from '../api/useMasterData';
|
||||
|
||||
export default function MasterDataDashboard() {
|
||||
const { data: summary, isLoading, isError } = useMasterDataSummary();
|
||||
|
||||
if (isLoading) return <Loader message="Loading master data..." />;
|
||||
if (isError) return <ErrorState message="Failed to load master data." />;
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="bg-app-card p-6 rounded-lg shadow-sm">
|
||||
<h2 className="text-xl font-bold text-text-primary">Master Data Dashboard</h2>
|
||||
<p className="text-sm text-text-muted mt-2">Overview of organizational structure.</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<StatCard
|
||||
title="Total Companies"
|
||||
value={summary?.totalCompanies || 0}
|
||||
Icon={Building}
|
||||
colorClass="text-primary"
|
||||
bgClass="bg-primary/10"
|
||||
/>
|
||||
<StatCard
|
||||
title="Total Branches"
|
||||
value={summary?.totalBranches || 0}
|
||||
Icon={Network}
|
||||
colorClass="text-primary"
|
||||
bgClass="bg-primary/10"
|
||||
/>
|
||||
<StatCard
|
||||
title="Total Departments"
|
||||
value={summary?.totalDepartments || 0}
|
||||
Icon={Briefcase}
|
||||
colorClass="text-primary"
|
||||
bgClass="bg-primary/10"
|
||||
/>
|
||||
<StatCard
|
||||
title="Total Designations"
|
||||
value={summary?.totalDesignations || 0}
|
||||
Icon={Tag}
|
||||
colorClass="text-primary"
|
||||
bgClass="bg-primary/10"
|
||||
/>
|
||||
<StatCard
|
||||
title="Total Employees"
|
||||
value={summary?.totalEmployees || 0}
|
||||
Icon={Users}
|
||||
colorClass="text-primary"
|
||||
bgClass="bg-primary/10"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
24
src/features/employee-management/routes/MasterDataRouter.tsx
Normal file
24
src/features/employee-management/routes/MasterDataRouter.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import { Routes, Route, Navigate } from 'react-router-dom';
|
||||
import MasterDataDashboard from '../pages/MasterDataDashboard';
|
||||
|
||||
// Placeholder for future pages
|
||||
const Placeholder = ({ title }: { title: string }) => (
|
||||
<div className="bg-app-card p-6 rounded-lg shadow-sm">
|
||||
<h2 className="text-xl font-bold text-text-primary">{title}</h2>
|
||||
<p className="text-text-muted mt-2">{title} UI will be implemented here.</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default function MasterDataRouter() {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/" element={<Navigate to="/master-data/dashboard" replace />} />
|
||||
<Route path="/dashboard" element={<MasterDataDashboard />} />
|
||||
<Route path="/company" element={<Placeholder title="Manage Company" />} />
|
||||
<Route path="/branches" element={<Placeholder title="Manage Branches" />} />
|
||||
<Route path="/departments" element={<Placeholder title="Manage Departments" />} />
|
||||
<Route path="/designations" element={<Placeholder title="Manage Designations" />} />
|
||||
<Route path="/employees" element={<Placeholder title="Manage Employees" />} />
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user