Interactive Leave Management System built with React, TypeScript, and MUI to manage, approve, validate, and load-test employee leave requests.
- 10,000+ seeded leave requests (Faker) persisted in browser local storage.
- Role-aware workflow (
Employee/Manager) with statuses:SubmittedApprovedRejectedCancelled
- Audit trail per request, including create/edit/approve/reject/cancel/import events.
- Dashboard table with:
- Global keyword search
- User/date/status filtering
- Column sorting
- Optional grouping summary by client
- Request details drawer actions:
- Edit request
- Approve request (Manager)
- Reject request (Manager)
- Cancel request (Employee)
- Delete request (Manager)
- Leave balance tracking by leave type quota:
- Personal: 7 days
- Sick: 10 days
- Vacation: 15 days
- Bereavement: 5 days
- Balance-aware validation blocks requests that exceed remaining quota.
- Business-day duration calculation excludes weekends and configured company holidays.
- CSV import/export for bulk operations:
- Export filtered rows to CSV
- Import CSV (upsert by
id) from Manager role - Download CSV template for faster onboarding
- Row-level import validation error report auto-download (
leave-import-errors-*.csv) - Import guardrails: CSV-only extension and max 2MB file size
- CSV formula-injection hardening for exported values
- PDF export for reporting:
- Export filtered rows to a paginated PDF report
- Includes generated timestamp, active filters, sort mode, role, and table rows
- PDF libraries are lazy-loaded on demand to reduce initial bundle size
- Build output compression:
- Gzip (
.gz) and Brotli (.br) assets generated viavite-plugin-compression
- Gzip (
- Cache strategy:
- Long-cache rules for static assets provided in
public/_headers - HTML pages are set to
must-revalidate
- Long-cache rules for static assets provided in
Validation runs on submit/save and blocks if:
- Request overlaps with another active period for the same user.
- Start date is in the past.
- End date is before start date.
- Reason is empty.
- Calculated duration is zero/negative.
- Leave type or user is missing.
- Requested duration exceeds remaining leave balance.
- React + Vite
- TypeScript
- MUI (Material UI)
- Faker (
@faker-js/faker) - Vitest (unit tests)
- jsPDF + jspdf-autotable (PDF reports)
- Node.js 20+
- npm
npm installnpm run devnpm run buildnpm testTests are included for:
- Date utilities in src/lib/date.test.ts
- floor-to-2-decimal behavior
- business-day duration behavior (weekends/holidays excluded)
- Validation logic in src/lib/validation.test.ts
- overlap detection behavior
- cancelled overlap exclusion
- required field/date rules
- leave balance limit enforcement
- used-balance aggregation logic
Import/export CSV columns:
iduserIdleaveTypestartDateendDatereasonstatuscreatedAtupdatedAt
Notes:
- Unknown users/leave types are skipped during import.
- Imported rows are appended or updated by
id. - Import validation issues are exported as a downloadable CSV report.
Workflow file:
On push to main (or manual trigger), the workflow:
- Runs
npm ci - Runs
npm test - Runs
npm run build - Deploys
dist/to GitHub Pages
- Set Pages source to GitHub Actions in repository settings.
- Main dashboard UI is split into focused components:
- Local storage key:
leave-requests-v1. - Company holidays are configured in src/lib/constants.ts.
- SEO metadata and social tags are set in index.html.
- Search crawler rules are set in public/robots.txt.
- Privacy/security policy page: public/privacy-security.html.