/** * TypeScript types for the leave management module. */ // ── Leave Types ────────────────────────────────────────────── export interface LeaveType { id: string; organisation_id: string; name: string; default_days_per_year: number; is_paid: boolean; created_at: string; } // ── Leave Requests ─────────────────────────────────────────── export type LeaveRequestStatus = "pending" | "approved" | "rejected" | "cancelled"; export interface LeaveRequest { id: string; employee_id: string; organisation_id: string; leave_type_id: string; start_date: string; end_date: string; days_count: number; reason: string | null; status: LeaveRequestStatus; approved_by: string | null; rejected_reason: string | null; created_at: string; updated_at: string; } export interface LeaveRequestWithDetails extends LeaveRequest { employee: { id: string; first_name: string; last_name: string; email: string; job_title: string | null; }; leave_type: LeaveType; approver: { first_name: string; last_name: string; } | null; } // ── Leave Balances ─────────────────────────────────────────── export interface LeaveBalance { leave_type_id: string; leave_type_name: string; total_days_per_year: number; used_days: number; approved_days: number; remaining_days: number; is_paid: boolean; } // ── Form Inputs ────────────────────────────────────────────── export interface CreateLeaveRequestInput { employee_id: string; leave_type_id: string; start_date: string; end_date: string; days_count: number; reason?: string; } export interface ApproveLeaveRequestInput { leaveRequestId: string; action: "approve" | "reject"; rejectedReason?: string; } // ── Helpers ────────────────────────────────────────────────── export const STATUS_LABELS: Record = { pending: "Pending", approved: "Approved", rejected: "Rejected", cancelled: "Cancelled", }; export const STATUS_COLORS: Record = { pending: "bg-amber-100 text-amber-700 border-amber-200", approved: "bg-emerald-100 text-emerald-700 border-emerald-200", rejected: "bg-red-100 text-red-700 border-red-200", cancelled: "bg-gray-100 text-gray-600 border-gray-200", }; export const DEFAULT_LEAVE_TYPES = [ { name: "Annual Leave", default_days_per_year: 20, is_paid: true }, { name: "Sick Leave", default_days_per_year: 10, is_paid: true }, { name: "Personal Leave", default_days_per_year: 5, is_paid: true }, { name: "Bereavement Leave", default_days_per_year: 3, is_paid: true }, { name: "Unpaid Leave", default_days_per_year: 0, is_paid: false }, ]; /** * Calculate working days between two dates (excludes weekends). */ export function calculateWorkingDays(startDate: string, endDate: string): number { const start = new Date(startDate + "T00:00:00"); const end = new Date(endDate + "T00:00:00"); if (end < start) return 0; let days = 0; const current = new Date(start); while (current <= end) { const dayOfWeek = current.getDay(); if (dayOfWeek !== 0 && dayOfWeek !== 6) { days++; } current.setDate(current.getDate() + 1); } return days; } export function formatDate(dateStr: string): string { return new Date(dateStr + "T00:00:00").toLocaleDateString("en-AU", { day: "numeric", month: "short", year: "numeric", }); } export function formatDateShort(dateStr: string): string { return new Date(dateStr + "T00:00:00").toLocaleDateString("en-AU", { day: "numeric", month: "short", }); }