Compare commits

...

2 Commits

8 changed files with 67 additions and 14 deletions

View File

@ -0,0 +1,4 @@
[
{ "id": "A001", "leaveType": "Casual Leave", "applicationDate": "2026-05-10", "fromDate": "2026-06-10", "toDate": "2026-06-11", "leaveDays": 2, "status": "Approved", "reason": "Medical appointment." },
{ "id": "A002", "leaveType": "Casual Leave", "applicationDate": "2026-06-20", "fromDate": "2026-07-01", "toDate": "2026-07-02", "leaveDays": 2, "status": "Withdrawn", "reason": "Changed plans." }
]

View File

@ -0,0 +1,4 @@
[
{ "leaveType": "Casual Leave", "credited": 15, "utilized": 5, "lapsed": 0, "balance": 10 },
{ "leaveType": "Optional Holiday", "credited": 4, "utilized": 0, "lapsed": 0, "balance": 4 }
]

View File

@ -0,0 +1,4 @@
[
{ "id": "M001", "leaveType": "Casual Leave", "applicationDate": "2026-06-12", "fromDate": "2026-07-04", "toDate": "2026-07-05", "leaveDays": 2, "status": "Approved", "reason": "Family function." },
{ "id": "M002", "leaveType": "Optional Holiday", "applicationDate": "2026-06-18", "fromDate": "2026-07-14", "toDate": "2026-07-14", "leaveDays": 1, "status": "Pending", "reason": "Personal work." }
]

View File

@ -0,0 +1,4 @@
[
{ "leaveType": "Casual Leave", "credited": 12, "utilized": 4, "lapsed": 0, "balance": 8 },
{ "leaveType": "Optional Holiday", "credited": 4, "utilized": 1, "lapsed": 0, "balance": 3 }
]

View File

@ -0,0 +1,3 @@
[
{ "id": "S001", "leaveType": "Optional Holiday", "applicationDate": "2026-06-22", "fromDate": "2026-07-21", "toDate": "2026-07-21", "leaveDays": 1, "status": "Pending", "reason": "Festival." }
]

View File

@ -0,0 +1,4 @@
[
{ "leaveType": "Casual Leave", "credited": 20, "utilized": 2, "lapsed": 0, "balance": 18 },
{ "leaveType": "Optional Holiday", "credited": 4, "utilized": 2, "lapsed": 0, "balance": 2 }
]

View File

@ -1,27 +1,57 @@
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useSelector } from 'react-redux';
import { fetchMockData, postMockData } from '../../../api/client';
import type { RootState } from '../../../store/store';
import type { UserRole } from '../../../store/roleSlice';
import type { LeaveSummary, LeaveRequestPayload, LeaveHistoryRecord } from '../types/leave';
const LEAVE_ENDPOINTS: Record<UserRole, { summary: string, history: string }> = {
employee: {
summary: 'leave/employee_leave_summary.json',
history: 'leave/employee_leave_history.json',
},
manager: {
summary: 'leave/manager_leave_summary.json',
history: 'leave/manager_leave_history.json',
},
admin: {
summary: 'leave/admin_leave_summary.json',
history: 'leave/admin_leave_history.json',
},
superadmin: {
summary: 'leave/superadmin_leave_summary.json',
history: 'leave/superadmin_leave_history.json',
},
};
export const useLeaveSummary = () => {
const role = useSelector((state: RootState) => state.role.currentRole);
return useQuery<LeaveSummary[]>({
queryKey: ['leaveSummary', 'employee'],
queryFn: () => fetchMockData<LeaveSummary[]>('leave/employee_leave_summary.json'),
queryKey: ['leaveSummary', role],
queryFn: () => fetchMockData<LeaveSummary[]>(LEAVE_ENDPOINTS[role].summary),
});
};
export const useApplyLeave = () => {
const role = useSelector((state: RootState) => state.role.currentRole);
const queryClient = useQueryClient();
return useMutation({
mutationFn: (payload: LeaveRequestPayload) => postMockData('leave/employee_leave_requests', payload),
// In a real backend, this would be a POST to /api/v1/leave/apply
mutationFn: (payload: LeaveRequestPayload) => postMockData(`leave/${role}_leave_requests`, payload),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['leaveSummary', 'employee'] });
// Refetch the summary for the specific role that just applied
queryClient.invalidateQueries({ queryKey: ['leaveSummary', role] });
},
});
};
export const useLeaveHistory = () => {
const role = useSelector((state: RootState) => state.role.currentRole);
return useQuery<LeaveHistoryRecord[]>({
queryKey: ['leaveHistory', 'employee'],
queryFn: () => fetchMockData<LeaveHistoryRecord[]>('leave/employee_leave_history.json'),
queryKey: ['leaveHistory', role],
queryFn: () => fetchMockData<LeaveHistoryRecord[]>(LEAVE_ENDPOINTS[role].history),
});
};

View File

@ -2,18 +2,18 @@ import { useSelector } from 'react-redux';
import type { RootState } from '../../../store/store';
import EmployeeLeave from '../pages/EmployeeLeave';
// Dummy components for Manager/Admin for now
const ManagerLeave = () => <div className="bg-app-card p-6 rounded-lg shadow"><h2 className="text-2xl font-bold text-primary">Team Leave Calendar</h2></div>;
const AdminLeave = () => <div className="bg-app-card p-6 rounded-lg shadow"><h2 className="text-2xl font-bold text-primary">All Leave Requests</h2></div>;
export default function LeaveRouter() {
const role = useSelector((state: RootState) => state.role.currentRole);
// Since the hooks dynamically fetch based on role,
// the EmployeeLeave component works perfectly for all roles!
switch (role) {
case 'employee': return <EmployeeLeave />;
case 'manager': return <ManagerLeave />;
case 'employee':
case 'manager':
case 'admin':
case 'superadmin': return <AdminLeave />;
default: return <div>Unauthorized</div>;
case 'superadmin':
return <EmployeeLeave />;
default:
return <div>Unauthorized</div>;
}
}