Process Friction
Leave requests bounce between email threads, spreadsheets, and chat apps. Every hand-off adds delay and a fresh chance for requests to slip through the cracks.
As a frontend developer, implement the Navbar section for the Landing page. Build the `Navbar` component using `useState` for `scrolled` and `menuOpen` state, and `useEffect` with a passive scroll listener that toggles the `nv-scrolled` class when `window.scrollY > 8`. Render the `CalendarCheck` lucide icon in the logo mark alongside `nv-logo-name` and `nv-logo-sub` text spans. Map over `NAV_LINKS` array (Features, How It Works, Pricing, Docs) to render desktop `nv-link` anchors and mobile `nv-mobile-link` anchors with `closeMenu` handler. Include `nv-actions` block with ghost Login and primary Sign Up buttons linking to `/Login`. Implement the hamburger `nv-hamburger` button with three `nv-bar` spans and `nv-open` toggle class. Render the `nv-mobile` drawer with `nv-mobile-open` class controlled by `menuOpen`. Import `Navbar.css`. Note: this component may already exist from a previous page and should be reused if so.
As a Backend Developer, implement authentication API endpoints using FastAPI. Create POST /api/auth/login (accepts email/password, returns JWT access token and user profile with role), POST /api/auth/logout (invalidates token), GET /api/auth/me (returns current user profile). Integrate with JWT middleware for token validation. This task supports LoginForm which POSTs to /api/auth/login. Note: basic login/auth setup is already done; this task covers the specific endpoint contracts required by the frontend LoginForm component.
As a Backend Developer, define all SQLAlchemy ORM models and Alembic migrations for the leave-approve system. Models: User (id, name, email, hashed_password, role: admin/manager/employee, status: active/inactive, manager_id FK, date_joined), LeaveType (id, name, description, default_days, is_paid), LeaveRequest (id, employee_id FK, leave_type_id FK, start_date, end_date, duration_days, status: pending/approved/rejected/cancelled, reason, manager_notes, created_at, updated_at, reviewed_by FK, reviewed_at), LeavePolicy (id, key, value), NotificationRecord (id, user_id FK, type, title, snippet, detail, read, related_href, created_at), LeaveBalance (id, user_id FK, leave_type_id FK, year, allocated, used). Create initial Alembic migration and seed data for demo users (admin, 2 managers, 5 employees) and default leave types (Annual 20d, Sick 14d, Personal 5d, Maternity 90d, Unpaid 0d).
As a Frontend Developer, set up global state management and API client for the React frontend. Implement: (1) React Context or lightweight state store (Zustand/Context API) for current user, role, and auth token; (2) Axios or fetch-based API client configured with base URL, Authorization header injection from stored JWT, and 401 redirect to /Login on token expiry; (3) custom hooks: useAuth (login/logout, current user), useLeaveRequests, useNotifications for data fetching; (4) localStorage persistence for auth token and role (key: 'leave-approve-role' as referenced in DashboardWelcome); (5) role-based route guards as React components wrapping protected pages. This is a cross-cutting concern required by all frontend pages that call real APIs.
As a Frontend Developer, set up the global design system and theme tokens for the leave-approve React app. Create a global CSS file or theme config exporting all SRD color tokens as CSS custom properties: --primary: #1A73E8, --primary-light: #E8F0FE, --secondary: #FF7043, --accent: #F4B400, --highlight: #FBBC05, --bg: #FFFFFF, --surface: rgba(250,250,250,0.8), --text: #202124, --text-muted: #5F6368, --border: rgba(218,220,224,0.2). Configure framer-motion global settings for the parallax/static interaction model split (landing uses parallax, internal pages use static). Set up base typography (Inter font), responsive breakpoints, and shared animation variant exports (fadeInUp, staggerContainer) reused across pages.
As a frontend developer, implement the LandingHero section for the Landing page. Use `useRef` for `rootRef`, `useScroll` with `target: rootRef` and `offset: ['start start', 'end start']` to derive `scrollYProgress`. Create three parallax motion values: `bgY` (0%→30%), `midY` (0%→60%), `visualY` (0%→-12%) via `useTransform`. Implement a hue-shift gradient overlay using `useMotionTemplate` with `hue` transitioning from 212→232. Render `lh-bg-layer` with animated blobs (`lh-blob-1/2/3`) and `lh-mid-layer` with rings and dot grid. Build the copy column using `containerVariants` (staggerChildren: 0.12, delayChildren: 0.1) and `itemVariants` (opacity 0→1, y 28→0, duration 0.6, cubic-bezier easing) with `whileInView` and `viewport={{ once: true, amount: 0.3 }}`. Render eyebrow, headline, sub-copy, CTA buttons (primary + ghost with Play icon), and `TRUST` stats array (12k+, 320+, 99.9%). Render the decorative calendar using `CAL_DAYS` array with `today`, `leave`, `coral`, and `muted` day variants, with `WEEKDAYS` header row. Import `LandingHero.css`, `framer-motion`, and lucide icons `CalendarCheck`, `ArrowRight`, `Play`, `CheckCircle2`.
As a frontend developer, implement the ProblemStatement section for the Landing page. Build the `ProblemStatement` component using `useRef` for `gridRef` and `useInView` with `{ once: true, amount: 0.3 }` to gate counter animation. Implement the `Counter` child component using `useEffect` with `requestAnimationFrame` loop: delayed start via `startDelay = delay * 1000`, cubic ease-out formula `1 - Math.pow(1 - progress, 3)`, 1400ms duration, and `Math.round` display value rendered as `ps-stat-num` + `ps-stat-suffix` spans. Map over the `PROBLEMS` array (friction 73%, visibility 6x, overhead 11h) rendering each card with the corresponding lucide icon (`Workflow`, `EyeOff`, `ClipboardList`), title, and descriptive text. Render decorative `ps-blob-bg`, `ps-blob-mid`, and `ps-ring` divs with CSS custom property `--scroll` parallax transforms. Import `ProblemStatement.css` and `framer-motion` (`motion`, `useInView`).
As a frontend developer, implement the InteractiveCalendarDemo section for the Landing page. Build the `InteractiveCalendarDemo` component with `useState` for `hovered`, `selected`, `dragStart`, `dragEnd`, and `committedRange`, plus a `useRef` for `isDragging`. Implement `buildGrid()` to prepend `FIRST_WEEKDAY` (1) null cells before days 1–30. Render calendar cells with pointer event handlers: `handlePointerDown` sets drag start, `handlePointerMove` updates drag end, `handlePointerUp` commits range and clears drag state. Use `useCallback` for `inRange(day)` checking `rangeLow`/`rangeHigh`. Overlay `SAMPLE_REQUESTS` leave entries (Priya, Marcus, Dana, Aiden, Sofia) on their respective days with color-coded dots from `LEAVE_TYPES` (vacation #1A73E8, sick #FF7043, personal #F4B400, remote #34A853). Render `WEEKDAYS` header row (Sun–Sat). Use `framer-motion` `AnimatePresence` and `LayoutGroup` for the detail panel that appears when `selected` is set — showing name, type, dates, reason, and status badge. Include `CalendarDays`, `X`, `Sparkles` lucide icons. Import `InteractiveCalendarDemo.css`.
As a frontend developer, implement the LandingFeatures section for the Landing page. Build the `LandingFeatures` component mapping over the `FEATURES` array (4 items: employee-requests, manager-approvals, admin-control, realtime-notifications) using `framer-motion` `motion` for entrance animations. Each feature card renders: a kicker label, title, lucide icon (`FileText`, `CheckCircle2`, `SlidersHorizontal`, `BellRing`) in a gradient orb, a rich `desc` array with mixed plain and highlighted/emphasized spans (using `cls: 'lf-hl'` and `cls: 'lf-em'`), a `points` list with `Check` icons, and a CTA anchor using the feature's `href`. Implement the `IllustrationStage` component with a `stage` prop that renders different illustration layouts for `'request'`, `'approve'`, `'admin'`, and `'notify'` stages. Apply `tint` background color to each card. Import `LandingFeatures.css`, `framer-motion`, and lucide icons `FileText`, `CheckCircle2`, `SlidersHorizontal`, `BellRing`, `Check`, `ArrowRight`.
As a frontend developer, implement the UserPersonas section for the Landing page. Build the `UserPersonas` component with `useState` for tracking which persona is hovered (`hoveredId`). Map over `PERSONAS` array (employee, manager, administrator) and render `PersonaCard` components. Each `PersonaCard` uses `framer-motion` `motion.div` with `whileHover={{ rotateY: 180 }}` (duration 0.6, cubic ease) to create a CSS 3D card flip. The front face (`up-front`) renders the lucide icon (`User`, `ShieldCheck`, `Settings2`) in `up-avatar`, name, role, responsibilities list, and a flip hint tag with `RotateCcw` icon. The back face (`up-back`) renders the user flow steps with numbered `up-flow-dot` badges. Apply `up-active` class to non-dimmed cards on hover. Use `AnimatePresence` for mobile accordion expand/collapse via `ChevronDown` icon. Import `UserPersonas.css` and `framer-motion` (`motion`, `AnimatePresence`).
As a frontend developer, implement the HowItWorks section for the Landing page. Build the `HowItWorks` component with `useRef` for `sectionRef` and `timelineRef`, and `useInView` with `{ once: true, amount: 0.3 }` to trigger count-up animations. Implement `CountUpNumber` child component using `useMotionValue`, `useTransform` (rounded), and `animate` from framer-motion — subscribing to `rounded.on('change', ...)` for display updates with `delay: value * 0.12` stagger and `easeOut` easing. Render the `STEPS` array (5 steps: Submit Request, Manager Reviews, Approval Decision, Notification, View Status) as a `hiw-timeline` with step numbers and lucide icons (`FileText`, `UserCheck`, `CheckCircle2`, `BellRing`, `Eye`). Render decorative `hiw-blob-1`, `hiw-blob-2`, and `hiw-dotgrid` spans with CSS `--scroll` variable parallax transforms (0.3x and 0.5x). Include eyebrow, h2 title with `<em>` emphasis, and subtitle paragraph. Import `HowItWorks.css` and `ChevronRight` lucide icon.
As a frontend developer, implement the LandingCTA section for the Landing page. Build the `LandingCTA` component with `useState` for `formOpen`, `email`, and `status` ({ type, msg }). Implement the `MagneticButton` sub-component using `useRef`, `useMotionValue` (x, y), `useSpring` (stiffness: 220, damping: 18) for magnetic hover effect — `handlePointerMove` calculates relative cursor offset and multiplies by 0.35/0.45 factors (disabled on mobile < 640px). `handleClick` generates 14 particles evenly distributed by angle (dist 60–100px) from `PARTICLE_COLORS` array, animates them outward with framer-motion `AnimatePresence`, then clears after 750ms. The main CTA button links to `/Login` with `whileHover` scale 1.08 and golden box-shadow, `whileTap` scale 0.96. Render the email capture inline form with `validateEmail` regex, blur validation, and `status.type` feedback states. Include `CalendarClock`, `Mail`, `CheckCircle2`, `ArrowRight` lucide icons. Import `LandingCTA.css` and `framer-motion` (`motion`, `AnimatePresence`, `useMotionValue`, `useSpring`).
As a frontend developer, implement the Footer section for the Landing page. Build the `Footer` component rendering a `ftr-top` grid with a brand block and four navigation column groups. The brand block includes: a `CalendarCheck` lucide icon logo linking to `/Landing`, tagline paragraph, and social icon row mapping over `socials` array (`Twitter`, `Linkedin`, `Github`, `Mail` lucide icons each linking to `/Landing`). Map over the `columns` array (Product, Resources, Company, Legal — each with 4 links) rendering `<nav>` with `h4` title and `<ul>` link list. Render a horizontal rule and copyright bar displaying `new Date().getFullYear()` dynamically. Import `Footer.css` and all required lucide icons. Note: this component may already exist from a previous page and should be reused if so.
As a frontend developer, implement the LoginHero section for the Login page. This section renders a `<section className="lh-root">` with a centered inner div containing three sequentially animated elements using `framer-motion` `fadeInUp` variants (opacity 0→1, y 16→0, duration 0.55s easeOut): (1) a `CalendarCheck` lucide icon (size 26, strokeWidth 2) wrapped in `motion.div` with no delay, (2) a `motion.h1` headline 'Welcome back to leave-approve' with `lh-headline-accent` span styling at 0.08s delay, (3) a `motion.p` subheadline describing leave management at 0.16s delay, and (4) a `motion.div` trust badge with `Shield` icon (size 14, strokeWidth 2.2) and 'Encrypted enterprise-grade authentication' text at 0.24s delay. All animations use `initial='hidden'` / `animate='visible'` pattern. Apply LoginHero.css (2044 chars) for layout and design tokens.
As a Backend Developer, implement the leave requests API using FastAPI. Endpoints: POST /api/leave-requests (employee submits new request with leave_type, start_date, end_date, reason), GET /api/leave-requests (list with filters: status, employee_id, leave_type, date_from, date_to, search, page, per_page), GET /api/leave-requests/{id} (detail), PUT /api/leave-requests/{id}/approve (manager approves with optional notes), PUT /api/leave-requests/{id}/reject (manager rejects with notes), DELETE /api/leave-requests/{id} (cancel own request). Include pagination metadata in responses. These endpoints support LeaveRequestForm, LeaveRequestsList, LeaveRequestsModal, LeaveRequestsFilters, DashboardPending, and MyLeavesTable components.
As a Backend Developer, implement notifications API using FastAPI. Endpoints: GET /api/notifications (paginated list with filters: type, status, date_from, date_to, sort, search), GET /api/notifications/unread-count (returns integer count), PUT /api/notifications/{id}/read (mark single notification as read), PUT /api/notifications/mark-all-read (mark all notifications read). Notification types: approval, decision, system, reminder. These endpoints support NotificationsList, NotificationsHeader (unread count badge), and NotificationsFilters components.
As a Backend Developer, implement user management API endpoints. GET /api/users (admin: paginated list with filters: search, role, status, sort), GET /api/users/{id} (user detail), PUT /api/users/{id}/role (admin assigns role: admin/manager/employee), PUT /api/users/{id}/status (admin activates/deactivates), GET /api/users/me (current user profile). These endpoints support UsersTable, UsersFiltersPanel, UsersToolbar, and UsersRoleModal components.
As a Backend Developer, implement settings API endpoints for admin configuration. GET /api/settings/leave-types (list configured leave types), POST /api/settings/leave-types (create new leave type), PUT /api/settings/leave-types/{id} (update), DELETE /api/settings/leave-types/{id} (delete). GET /api/settings/leave-policies (get all policy configs), PUT /api/settings/leave-policies (bulk update policies). GET /api/settings/notifications (notification preferences), PUT /api/settings/notifications (update preferences). These endpoints support LeaveTypesSection, LeavePoliciesSection, NotificationPrefsSection, and SaveActionsSection components.
As a Backend Developer, implement FastAPI JWT authentication middleware and role-based access control (RBAC) dependency injection. Create get_current_user dependency that validates Bearer tokens from Authorization header, decodes JWT (PyJWT), and returns user object. Create role guard dependencies: require_employee, require_manager, require_admin. Apply to all protected routes. Configure CORS middleware for React frontend origin. Add request logging middleware. This is a cross-cutting concern required by all backend API tasks.
As a frontend developer, implement the LoginForm section for the Login page. This section manages six state hooks: `email`, `password`, `remember` (checkbox), `showPassword` (toggle), `errors` (field-level validation object), `apiError` (string), and `loading` (boolean). The `validate()` function checks email format via regex and password minimum length (6 chars). The `handleSubmit` async handler POSTs to `/api/auth/login` with `{email, password}` JSON body; on success redirects to `/Dashboard` via `window.location.href`; on failure sets `apiError` from `data.detail`. The form is a `motion.form` with `initial={{opacity:0,y:24}}` → `animate={{opacity:1,y:0}}` (0.45s easeOut). Uses `AnimatePresence` to animate the `lf-api-error` banner (height 0→auto, opacity) containing an `AlertCircle` icon. Email field uses `Mail` icon prefix; password field uses `Lock` icon prefix with `Eye`/`EyeOff` toggle button controlling `showPassword`. Each field calls `clearError(field)` on change to remove stale validation messages. Submit button shows `LogIn` icon and `loading` spinner state. Apply LoginForm.css (5372 chars).
As a frontend developer, implement the LoginFooter section for the Login page. This section renders a `<footer className="lfr-root">` containing a single `motion.div` with `initial={{opacity:0,y:12}}` → `animate={{opacity:1,y:0}}` (duration 0.5s, delay 0.3s, easeOut). Inside, three sub-elements are rendered: (1) `lfr-links` row with anchor tags to `/Privacy` (Privacy Policy), `/Terms` (Terms of Service), and `/Settings` (Security) separated by `lfr-separator` spans with `aria-hidden="true"`, (2) `lfr-security-note` div with `ShieldCheck` lucide icon (strokeWidth 2.2, aria-hidden) and TLS encryption message, (3) `lfr-copy` span displaying dynamic copyright year via `new Date().getFullYear()`. Apply LoginFooter.css (1613 chars). Note: this is a page-specific footer distinct from the shared Landing Footer component.
As a frontend developer, implement the DashboardHeader section for the Dashboard page. This section renders a top header bar with a personalized greeting ('Welcome back, Alex'), an h1 title 'Dashboard', and a dynamic role badge (dh-badge-employee/manager/admin) with a colored dot. It includes a Settings icon button (lucide-react) that toggles a framer-motion AnimatePresence dropdown (opacity/y fade, 0.18s easeOut) anchored via a dropdownRef. The dropdown contains 'My Profile' (User icon), 'Role: Manager' (Shield icon), a divider, and a 'Quick Settings' link to /Settings, plus a LogOut item. Click-outside detection is handled via a mousedown useEffect listener on document. State: dropdownOpen (useState). CSS class: dh-root. Note: this component may coexist alongside DashboardSidebar as part of the layout shell.
As a frontend developer, implement the DashboardSidebar section for the Dashboard page. This section renders a role-based aside navigation with three ROLE_NAV configurations (employee, manager, admin), each defining labeled nav groups with lucide-react icons (LayoutDashboard, Calendar, ClipboardList, Bell, Clock, Users, BarChart3, Settings). State: menuOpen (useState) for mobile collapse toggling, activeLink (useState) for highlight tracking. A Menu icon button triggers framer-motion AnimatePresence-driven expand/collapse on mobile (ds-nav-open class). Nav items include optional numeric badge overlays (e.g., badge: 5 for Pending Requests). A user profile stub (MOCK_USER with name, role, initials) and ROLE_COLORS map drive the bottom user card's background/text styling. handleLinkClick closes the mobile menu on tap when window.innerWidth <= 768. CSS class: ds-root.
As a frontend developer, implement the DashboardWelcome section for the Dashboard page. This section renders a time-aware greeting (getTimeGreeting() returns 'Good morning/afternoon/evening' based on current hour) with a wave emoji (👋), the user's name 'Alex', and a dynamic role badge (daw-role-badge with daw-role-dot). Role is read from localStorage key 'leave-approve-role' via a useState initializer. A useMemo computes nextLeave (next Saturday or 'Tomorrow' label) and displays it in a du-next-leave card with Calendar icon. A CTA button dynamically renders either a Plus icon linking to /LeaveRequest (employee) or ClipboardCheck icon linking to /LeaveRequests (manager/admin). Framer-motion containerStagger (staggerChildren: 0.1) animates child elements via animFadeUp (opacity/y) and animFadeRight (opacity/x) variants. CSS class: daw-root.
As a frontend developer, implement the DashboardMetrics section for the Dashboard page. This section renders four MetricCard components from a METRICS array (Leave Balance, Approved Requests, Total Users, System Health). Each card uses a custom useAnimatedCounter hook that drives a framer-motion useSpring (stiffness: 80, damping: 18) subscribed via spring.on('change') to produce a smoothly incrementing display number. Cards implement cursor-tilt 3D effects using useMotionValue + useSpring for rotateX/rotateY (stiffness: 200, damping: 22), updated in handleMouseMove by computing normalized offsets from card center via getBoundingClientRect. Mouse gradient position (mx, my state) tracks cursor within the card. The System Health card renders a status dot (dm-status-dot--ok/warn) with 'Operational' label instead of a counter. Icons: CalendarDays, CheckCircle2, Users, Activity from lucide-react. CSS class: dm-root.
As a frontend developer, implement the DashboardQuickActions section for the Dashboard page. This section renders three role-tagged action cards from the ACTIONS array: 'Request Leave' (FileText icon, /LeaveRequest, employee), 'Approve Requests' (CheckSquare icon, /LeaveRequests, manager), 'Configure Leave Types' (Settings icon, /Settings, admin). Each card is a framer-motion motion.a with whileTap scale: 0.97 and a spring-based magnet animation (stiffness: 280, damping: 28) that offsets cards by x: magnet.x * 0.02, y: magnet.y * 0.025 based on global mouse position within the section. Magnet state (x, y, active) is tracked via useRef on the section and mousemove/mouseleave handlers using getBoundingClientRect. Card variants use dqa-card--request/approve/configure CSS modifier classes with ::before accent stripe pseudo-elements. ChevronRight arrow renders in dqa-arrow div. CSS class: dqa-root.
As a frontend developer, implement the DashboardUpcoming section for the Dashboard page. This section renders a card list of upcoming leave items from the leaveItems array (3 items: Sarah Chen vacation, Marcus Rivera sick, Priya Kapoor personal) with a header containing Calendar icon, title 'Upcoming Leave', subtitle 'Next 3 scheduled leaves', and a 'View All' link to /Calendar with ArrowRight icon. Each list item is a framer-motion motion.li with cardVariants (opacity/y: 0→1/0, 0.4s easeOut) staggered via listVariants (staggerChildren: 0.1, delayChildren: 0.05). Items display: initials avatar (du-avatar with du-avatar-manager modifier for isTeamMember), employee name (with '(You)' suffix if !isTeamMember), leave type badge, date range with Calendar icon, and a status pill (du-status-approved/pending). The ul has role='list' and aria-label for accessibility. CSS class: du-root.
As a frontend developer, implement the DashboardPending section for the Dashboard page. This section renders a filterable list of 6 mock PENDING_REQUESTS (vacation, sick, personal, maternity types) for manager/admin review. State: activeFilter (useState, default 'All'), toastMsg (useState for approve/reject feedback), and requests array (useState initialized from PENDING_REQUESTS) supporting inline approval/rejection. FILTERS array ('All', 'Vacation', 'Sick Leave', 'Personal', 'Maternity') renders as filter pill buttons. Each request card shows: an avatar with avatarColor() hash-based color from 8-color AVATAR_COLORS palette and initials() helper, employee name/department, TYPE_CONFIG-driven type badge with icon (Briefcase/Heart/User/Baby) and className (dp-type-vacation/sick/personal/maternity), formatted date range via fmtDate() and dayCount() helpers, submission date, and approve (CheckCircle) / reject (XCircle) action buttons. framer-motion AnimatePresence handles toast notification entry/exit. AlertTriangle icon used for conflict warnings. ArrowRight link to full /LeaveRequests view. CSS class: dp-root.
As a Backend Developer, implement employee-scoped leave history API endpoints. GET /api/my-leaves (returns paginated own leave requests with filters: status, leave_type, date_from, date_to, sort, search), GET /api/my-leaves/stats (returns balance, used, pending count, upcoming count for the authenticated employee). These endpoints support MyLeavesTable, MyLeavesFilters, and MyLeavesStats components. Note: depends on temp_backend_leave_requests for shared models.
As a Backend Developer, implement reports API endpoints. GET /api/reports/key-metrics (total/approved/rejected/pending counts), GET /api/reports/usage-chart (monthly and quarterly leave usage by type for chart), GET /api/reports/leave-breakdown (per leave type: totalUsed, totalAllocated, remaining, percentUsed), GET /api/reports/trends (trend analysis insights), GET /api/reports/export (generates PDF/CSV/Excel export with filters: start_date, end_date, leave_type, department, manager, status). These endpoints support KeyMetrics, UsageChart, LeaveBreakdown, TrendAnalysis, ExportActions, and ReportsFilters components.
As a Backend Developer, implement calendar API endpoints. GET /api/calendar/leaves (returns all visible leave entries for a given month/year as date ranges with type, status, requester info for rendering multi-day spans), GET /api/calendar/leaves/{id} (full detail for CalendarLeaveDetail panel including requester, reason, managerNotes, timeline, isManagerView flag). Supports CalendarGrid (leave bars), CalendarSidebar (leave type breakdown, balance items), and CalendarLeaveDetail components.
As a Backend Developer, implement dashboard summary API endpoints. GET /api/dashboard/metrics (returns leave balance, approved count, total users, system health status for DashboardMetrics), GET /api/dashboard/upcoming-leaves (next 3 upcoming leaves for team/self for DashboardUpcoming), GET /api/dashboard/pending-requests (paginated pending requests for manager DashboardPending with approve/reject actions). These endpoints support DashboardMetrics, DashboardUpcoming, DashboardPending, and DashboardWelcome components.
As a frontend developer, implement the SettingsNav section for the Settings page. Build a sidebar navigation component using `useState` for `expanded`, `activeItem`, and `mobileOpen` state. Render `NAV_SECTIONS` array containing General, Leave Types, Leave Policies, Notifications, and Security items with Lucide icons (Settings, Calendar, FileText, Bell, Shield, ChevronRight, Menu). Implement `toggleExpand` (useCallback) for collapsible sub-items using `AnimatePresence` from framer-motion. Handle `handleItemClick` and `handleSubClick` to set `activeItem` and auto-close mobile menu on small screens (< 768px). Include a mobile hamburger Menu icon toggle via `mobileOpen` state. Apply active state detection via `isActive` helper checking both parent and sub-item ids. Use CSS from SettingsNav.css with animated expand/collapse for sub-navigation groups.
As a frontend developer, implement the ReportsHeader section for the Reports page. This section renders a full-width header with a character-by-character animated title ('Leave Reports') using framer-motion `charVariants` with staggered `opacity`, `y`, `rotateX`, and `blur` transitions per letter. Includes `subtitleVariants` and `controlsVariants` for fade-in sub-elements. State hooks manage `activePreset` (null or string), `startDate`, and `endDate` (formatted via `formatDateStr`). The `PRESET_RANGES` array (This Week / This Month / Last 3 Months / This Year) drives preset toggle buttons that call `getDateRange(days)` to set date state; clicking an active preset deselects it. Two `<input type='date'>` fields for manual date range override, which clears `activePreset`. Uses `.rh-root`, `.rh-title-block`, `.rh-title`, `.rh-title-char` CSS classes. Note: Navbar component may already exist from the Dashboard page.
As a frontend developer, implement the UsersHeader section for the Users page. Build the `UsersHeader` component using `framer-motion` with `headerVariants` (opacity/y -12→0, 0.45s easeOut) and `itemVariants` (opacity/y -6→0, 0.35s easeOut) animations. Render a `<header className='ush-root'>` containing: (1) an animated `<nav className='ush-breadcrumb'>` with a link to `/Dashboard` and current page label 'Users', (2) an animated `.ush-header-row` with `<h1 className='ush-title'>Team Members</h1>` and a badge with `.ush-badge-dot` indicator and 'Manage Users' text, (3) an animated `.ush-desc` paragraph describing user management, and (4) a `.ush-divider`. Apply staggered `initial='hidden' animate='visible'` on the wrapper and `variants={itemVariants}` on child elements. Note: DashboardHeader may already exist from the Dashboard page.
As a frontend developer, implement the CalendarTopBar section for the Calendar page. This section renders a top navigation bar using `useState` hooks for `currentMonth`, `currentYear`, `activeView`, `filterActive`, and `legendOpen`. It includes: (1) a left nav group with `ChevronLeft`/`ChevronRight` motion buttons that handle month wraparound via `handlePrevMonth`/`handleNextMonth`, a month label display (`MONTHS[currentMonth] + currentYear`), and a 'Today' button with `whileTap` scale animation; (2) a center view toggle rendering VIEWS array (`month`, `week`, `day`) as motion buttons with active state styling; (3) right-side `Filter` and `Eye` (legend) icon buttons with `filterActive` and `legendOpen` toggle states; (4) an `AnimatePresence`-wrapped legend dropdown rendering `LEGEND_ITEMS` with colored dot indicators (`ctb-legend-approved`, `ctb-legend-pending`, `ctb-legend-rejected`, `ctb-legend-holiday`). Uses `framer-motion`, `lucide-react` (`ChevronLeft`, `ChevronRight`, `Calendar`, `Filter`, `Eye`), and `CalendarTopBar.css`. This section should receive page-level dependency from Dashboard's DashboardHeader task.
As a frontend developer, implement the CalendarSidebar section for the Calendar page. This section renders a collapsible sidebar using `useState` (`drawerOpen`, `viewYear`, `viewMonth`, `selectedDay`, `activeFilter`) and `useMemo` for computing `calendarDays`. It includes: (1) a mini calendar with month navigation via `ChevronLeft`/`ChevronRight`, rendering a 7-column grid using `DAY_NAMES` headers and computed cells from `daysInMonth`/`startDayOfWeek` helpers, with today highlighting via `isToday()`, dot indicators from `getLeaveDates()` for leave days, and `selectedDay` click state; (2) a leave type breakdown list rendering `LEAVE_TYPES` array (Annual, Sick, Personal, Maternity/Paternity, Unpaid) with colored dot badges and leave counts; (3) leave balance progress bars from `BALANCE_ITEMS` showing `used/total` with color-coded fills; (4) quick filter chips from `QUICK_FILTERS` array with `activeFilter` toggle state; (5) an `AnimatePresence`-wrapped `drawerOpen` collapsible section with `ChevronDown` indicator. Uses `framer-motion`, `lucide-react`, and `CalendarSidebar.css`.
As a frontend developer, implement the CalendarGrid section for the Calendar page. This section renders a full monthly calendar grid using `useState` (`currentYear`, `currentMonth`, `selectedDay`, `hoveredLeave`) and `useCallback` for event handlers. Key implementation details: (1) `buildMonthData(year, month)` computes cells including leading/trailing days from adjacent months, `isToday` flags, and day-of-week values; (2) `SAMPLE_LEAVES` array (10 entries: vacation, sick, personal, bereavement, maternity, paternity types) with `start`/`end` day ranges and `status` (approved/pending/rejected) mapped to cells; (3) leave bars rendered as multi-day spanning colored strips using `LEAVE_COLORS` map keyed by leave type; (4) `AnimatePresence`-wrapped hover tooltip showing leave details on `hoveredLeave` state; (5) 7-column grid header with `DAY_NAMES`/`FULL_DAY_NAMES`, current-month vs. out-of-month cell dimming, today cell highlight ring; (6) `motion` cell animations on mount. Uses `framer-motion` and `CalendarGrid.css`. This is the largest section (16KB JSX) requiring careful multi-day leave span calculation logic.
As a frontend developer, implement the CalendarLeaveDetail section for the Calendar page. This section renders a leave detail modal/panel using `useState` (`leave`, `isOpen`, `confirmDelete`). Key implementation details: (1) `MOCK_LEAVE` data object with fields `id`, `type`, `startDate`, `endDate`, `status`, `requester` (name, department, initials), `reason`, `managerNotes`, `submittedAt`, `totalDays`, `isManagerView`; (2) `AnimatePresence`-wrapped panel with two motion variant sets — `panelVariants` (desktop: `y: 30→0` fade-in) and `mobileVariants` (mobile: `y: 100%→0` slide-up) toggled by `window.innerWidth < 768`; (3) `overlayVariants` for backdrop fade; (4) `LEAVE_TYPES` map with lucide icons (`Briefcase`, `Clock`, `User`, `FileText`) per type; (5) `STATUS_LABELS` badge rendering with `cld-status--{status}` dynamic class; (6) `handleApprove`/`handleReject` updating leave status in state with `CheckCircle`/`XCircle` buttons shown in `isManagerView` mode; (7) `confirmDelete` two-step delete flow with `Trash2` icon; (8) `Edit3` edit button; (9) `formatDate` helper for `en-US` locale display; (10) `X` close button calling `handleClose`. Uses `framer-motion`, `lucide-react`, and `CalendarLeaveDetail.css`.
As a frontend developer, implement the LeaveRequestsHeader section for the LeaveRequests page. Build the `LeaveRequestsHeader` component with: (1) role-aware title row using a `ROLES` config object with manager/employee/admin variants, each with a distinct icon (Briefcase, BadgeCheck, Shield) and CSS class (`lrh-role-manager`, `lrh-role-employee`, `lrh-role-admin`); (2) animated role badge using `motion.span` with spring animation (stiffness 360, damping 22, delay 0.12) containing a live dot, role icon, and label; (3) dynamic subtitle text based on `currentRole` ('manager' default); (4) desktop summary chips row with three items (Pending=8, Approved=23, Total=34) using Clock, CheckCircle2, FileText icons, each chip animated via `motion.div` with staggered delay (0.15 + i*0.08); (5) `useState(false)` for `summaryExpanded` toggling mobile summary visibility; (6) action buttons for Export (Download icon) and View All (Eye icon). Apply `LeaveRequestsHeader.css` with BEM-style `lrh-*` classes. Note: Navbar/shared layout may already exist from Dashboard page.
As a frontend developer, implement the `LeaveRequestsFilters` component with a sticky/scrollable filter bar. Build: (1) six pieces of controlled state via `useState`: `status`, `employee`, `leaveType`, `dateFrom`, `dateTo`, `search`; (2) `stuck` state driven by a `useEffect` scroll listener (`window.scrollY > 64`) that adds a sticky shadow class; (3) `panelOpen` state toggling a mobile slide-in filter panel using `AnimatePresence`; (4) `filterCount()` helper computing the number of active filters displayed as a badge on the SlidersHorizontal toggle button; (5) `clearFilters` via `useCallback` resetting all six fields; (6) desktop filter bar with Status select (STATUS_OPTIONS: All/Pending/Approved/Rejected), Employee select (9 employees), Leave Type select (7 types: Vacation/Sick/Personal/Maternity/Paternity/Bereavement), date range inputs (dateFrom/dateTo), and Search input with Search icon; (7) active filter pills showing clear (X) buttons per active filter; (8) animated mobile panel using `AnimatePresence` + `motion.div`. Apply `LeaveRequestsFilters.css` with `lrf-*` classes including `lrf-active` modifier for filled selects.
As a frontend developer, implement the `LeaveRequestsList` component with paginated leave request cards. Build: (1) `MOCK_REQUESTS` array of 8+ leave request objects (id, employeeName, department, initials, leaveType, startDate, endDate, days, status, notes); (2) `useMemo`-driven pagination slicing requests into pages of `ITEMS_PER_PAGE = 6`; (3) `useState` for `currentPage` and `expandedId` (for notes accordion); (4) each request card rendered with employee avatar initials circle, name + department, leaveType badge, date range with Calendar icon, duration with Clock icon, status chip (`pending`/`approved`/`rejected`) with distinct color classes; (5) expandable notes section toggled by `expandedId === item.id` using `AnimatePresence` + `motion.div` height animation; (6) pagination controls with ChevronLeft/ChevronRight buttons and page number indicators; (7) empty state using the Inbox icon when no requests match; (8) manager action buttons (Approve/Reject) shown only on `pending` cards. Apply `LeaveRequestsList.css` with `lrl-*` classes.
As a frontend developer, implement the MyLeavesHero section for the MyLeaves page. This section renders a hero banner using framer-motion animations with a staggered entrance sequence: the mlh-icon-wrap (FileText icon) scales from 0.85 to 1 with opacity fade, the mlh-title animates from y:12 to y:0, the mlh-desc paragraph follows at delay 0.16, and the mlh-bottom-row at delay 0.24. The bottom row contains a motion.a CTA button linking to '/LeaveRequest' with spring-based whileHover (scale 1.03) and whileTap (scale 0.97) effects using the Plus icon, alongside a mlh-quick-stats bar rendering three stat pills (Approved: 8, Pending: 3, Remaining: 16) each with a colored dot (mlh-stat-dot--approved, mlh-stat-dot--pending, mlh-stat-dot--remaining), value, and label. Includes a decorative mlh-accent-strip at the top. Import MyLeavesHero.css for styling. Note: Navbar/Header component may already exist from the Dashboard page.
As a Tech Lead, verify the end-to-end integration between the Login frontend implementation and the Auth backend API. Ensure the LoginForm POSTs correctly to /api/auth/login, JWT token is stored and injected into subsequent requests via the API client, role is persisted to localStorage under 'leave-approve-role', successful login redirects to /Dashboard, and error responses (401, validation) are surfaced in the lf-api-error banner. Verify logout clears token and redirects to /Login.
As a Tech Lead, verify the end-to-end integration between the Dashboard frontend sections and the Dashboard backend API. Ensure DashboardMetrics fetches real values from GET /api/dashboard/metrics (leave balance, approved count, total users, system health), DashboardUpcoming fetches from GET /api/dashboard/upcoming-leaves, DashboardPending fetches from GET /api/dashboard/pending-requests and inline approve/reject actions call the correct leave request endpoints, and DashboardWelcome reads role from JWT/localStorage correctly. Verify role-based rendering (employee vs manager vs admin) matches actual user role from API.
As a frontend developer, implement the SettingsHeader section for the Settings page. Build a static header component rendering a breadcrumb nav (`seh-breadcrumb`) with items array containing Dashboard (href='/Dashboard') and Settings (current=true). Map breadcrumb items using React.Fragment with a '/' separator span (`seh-breadcrumb-sep`). Render the current item as a plain span with `seh-breadcrumb-item--current` class and previous items as anchor tags. Below the breadcrumb, render an `seh-header-row` containing `seh-title-group` with an h1 ('Settings') and descriptive paragraph about configuring leave types, policies, notifications, and security. Use CSS from SettingsHeader.css.
As a frontend developer, implement the LeaveTypesSection for the Settings page. Manage `leaveTypes` array state (initialLeaveTypes: Annual, Sick, Casual, Maternity, Unpaid), `modalOpen` boolean, `editingId` (null or id), and `form` object (name, description, defaultDays, isPaid) via useState. Implement `openAdd`, `openEdit`, `closeModal`, `handleDelete`, and `handleSave` callbacks. `handleSave` trims and parses form inputs, updates existing entry or appends new entry with auto-incremented id. Animate list rows using `rowVariants` with staggered `custom` index delays (x: -12 to 0). Render an Add button that opens a modal. Modal uses `modalVariants` (scale + y + opacity) and `overlayVariants` for backdrop, wrapped in AnimatePresence. Form inside modal has controlled inputs for name, description, defaultDays (number), and isPaid (checkbox). Each row shows name, description, defaultDays, isPaid badge, and Edit/Delete action buttons. Use CSS from LeaveTypesSection.css.
As a frontend developer, implement the LeavePoliciesSection for the Settings page. Manage `formState` object with keys: max_days_per_year (30), carry_over_enabled (true), carry_over_max (10), minimum_notice_period ('3'), auto_approve_threshold (2), holiday_conflict_check (true), consecutive_days_limit (14). Also manage `saved` boolean state. Render `policyData` array of 6 policy configs (max_days_per_year, carry_over_enabled, minimum_notice_period, auto_approve_threshold, holiday_conflict_check, consecutive_days_limit) — each with a title, help tooltip text (Info icon from lucide-react), and a type-specific control: 'number' input, 'toggle' switch, or 'radio' group. Implement `handleNumberChange` (parseInt, reject NaN/negatives), `handleToggle`, and `handleRadioChange` handlers. carry_over_enabled toggle shows a sub-input for carry_over_max days when enabled. Include a Save button (Save icon from lucide-react) that sets `saved` to true and shows a Check icon confirmation, animated via framer-motion. Use ChevronDown for potential accordion UI. Use CSS from LeavePoliciesSection.css.
As a frontend developer, implement the NotificationPrefsSection for the Settings page. Manage `toggles` state (email: true, approval_reminders: true, rejection_alerts: true, leave_expiry: false), `expandedId` (null or string), and `details` state for granular sub-preference toggles (new_request, status_change, weekly_digest, daily_reminder, urgent_nudge, in_app_rejection, email_rejection, expiry_30_days, expiry_7_days, expired_today) via useState and useCallback. Render `notificationToggles` array of 4 notification categories (email with Mail icon, approval_reminders with Clock, rejection_alerts with XCircle, leave_expiry with AlertTriangle — all from lucide-react). Each card has a master toggle, ChevronDown expand button, and an animated collapsible `details` sub-list using `collapsedVariants` (height: 0 to 'auto', opacity) with AnimatePresence. Sub-items each have their own checkbox/toggle from `details` state. Bell icon used for section header. Use CSS from NotificationPrefsSection.css.
As a frontend developer, implement the SecuritySection for the Settings page. Manage state: `tfaEnabled` (false), `sessionNotifications` (true), `sessionTimeout` ('30'), `passwordMinLength` ('8'), `passwordRequireSpecial` (true), `passwordRequireNumbers` (true), `showResetDialog` (false), `showRevokeDialog` (false), `samplePassword` ('') via useState. Compute `passwordStrength` via useMemo — scoring algorithm checks length >= 8/12, uppercase, lowercase, digits, special chars, returning level (1-4) and label (Weak/Fair/Good/Strong) with `strengthClass` for CSS. Render PERMISSIONS matrix (8 rows × 3 roles: admin, manager, employee) as a read-only grid. Render TFA toggle, session timeout selector, session notification toggle, password policy controls (min length input, require-special and require-numbers checkboxes), and a live password tester input wired to `samplePassword`. Show `showResetDialog` and `showRevokeDialog` confirmation modals animated via AnimatePresence. Inline SVG icons: ShieldIcon, LockIcon, KeyIcon and others defined as sub-components. Use CSS from SecuritySection.css.
As a frontend developer, implement the ReportsFilters section for the Reports page. This section renders a filter panel with four `filterConfigs` (leaveType, department, manager, status), each backed by static option arrays (`leaveTypes`, `departments`, `managers`, `statuses`). Uses `useState` to track local `filters` object initialized from `activeFilters` prop or `initialFilters`. Each filter group is a staggered `motion.div` (delay: `0.08 + i * 0.06`). Lucide icons `ChevronDown`, `Search`, and `RotateCcw` are used in UI controls. `handleApply` calls `onApply(filters)` prop; `handleReset` resets to `initialFilters` and calls `onReset()`. `hasChanges` boolean derived from filter values drives conditional styling. `AnimatePresence` used for dropdown animations. Uses `.rf-root`, `.rf-inner`, `.rf-group` CSS classes.
As a frontend developer, implement the KeyMetrics section for the Reports page. This section renders a 4-card grid with static `metrics` data: Total Leave Requests (847), Approved Requests (712), Rejected Requests (94), and Pending Approvals (41). Each `motion.div` uses `cardVariants` with `custom={i}` for staggered `whileInView` animations (`once: true`, `amount: 0.3`), triggering `opacity` and `y` transitions with delays of `i * 0.1`. Each card displays a label, numeric value via `toLocaleString()`, a trend indicator (`↑`, `↓`, or `−`) with direction-specific class (`km-trend-up`, `km-trend-down`, `km-trend-neutral`), and a sub-label. Card accent classes (`km-card-accent-total`, `-approved`, `-rejected`, `-pending`) drive color theming. Uses `.km-root`, `.km-inner`, `.km-grid`, `.km-card` CSS classes.
As a frontend developer, implement the UsageChart section for the Reports page. This section renders a Chart.js `Bar` chart via `react-chartjs-2` with registered modules (`CategoryScale`, `LinearScale`, `BarElement`, `Title`, `Tooltip`, `Legend`). Two view modes — `monthly` and `quarterly` — are toggled via `useState('monthly')`. `useMemo` derives `chartData` (labels + datasets for vacation, sick, personal, bereavement series with hex colors and `borderRadius: 5`) and `chartOptions` (responsive, `interaction.mode: 'index'`, custom dark tooltip with `Inter` font, hidden legend). Lucide icons `TrendingUp`, `TrendingDown`, `Minus`, `BarChart3` used for summary trend indicators. `computeSummary` calculates grand totals and per-series totals; `trendArrow` returns icon/class/label. `AnimatePresence` wraps chart for mode-switch animation. Uses `.uc-change-up`, `.uc-change-down`, `.uc-change-neutral` CSS classes.
As a frontend developer, implement the TrendAnalysis section for the Reports page. This section renders a grid of 6 insight cards from the static `INSIGHTS` array, each with a Lucide icon (`TrendingUp`, `Clock`, `TrendingDown`, `Users`, `CheckCircle`, `CalendarDays`), `iconTone` variant class, title, description, a `badge` with `tone` variants (`highlight`, `positive`, `neutral`, `danger`) resolved via `badgeClass()`, and a `detail` string. Each card is a `motion.div` using `CARD_VARIANTS` with `custom={i}` for staggered `delay: i * 0.10` scroll-triggered animations (`scale` from 0.97, `y` from 28). Additional Lucide icons `AlertTriangle`, `BarChart3`, `Lightbulb`, `Info` imported for potential use. Uses `.ta-badge-highlight`, `.ta-badge-danger`, `.ta-badge-posit` CSS classes for badge tones.
As a frontend developer, implement the LeaveBreakdown section for the Reports page. This section renders a detailed table/list of 6 leave types (Annual, Sick, Maternity, Unpaid, Bereavement, Compensatory Off) with per-row `dotColor`, `totalUsed`, `totalAllocated`, `remaining`, and `percentUsed` data. `useState(false)` for `animated` is set to `true` after a 120ms `setTimeout` in `useEffect` to trigger CSS bar fill animations. `getPctColor(pct)` returns red/yellow/green hex based on thresholds (75%, 50%). Summary stats are computed via `reduce` for `totalUsedAll`, `totalAllocatedAll`, `totalRemainingAll`, and `overallPct`. Framer-motion `container` variant uses `staggerChildren: 0.09`; `rowAnim` fades rows in with `y: 14 → 0`. Lucide `Clock`, `TrendingUp`, `Percent` icons used in summary stats. Uses `.lb-root`, `.lb-inner`, `.lb-head`, `.lb-summary`, `.lb-stat` CSS classes.
As a frontend developer, implement the ExportActions section for the Reports page. This section renders export and delivery controls with a primary 'Export PDF' `motion.button` (`whileHover: scale 1.03`, `whileTap: scale 0.97`) using Lucide `Download` icon, and ghost format buttons mapped from `exportFormats` array (CSV with `FileSpreadsheet`, Excel with `FileType`). Secondary actions include 'Schedule Report' (`CalendarClock` icon) and an email button (`Mail` icon). All handlers call `showToast(message)` which sets `useState(null)` toast state and auto-clears after 2500ms via `setTimeout`. `useCallback` memoizes `showToast`. `AnimatePresence` wraps the toast notification for enter/exit animation. A decorative divider row with 'or' label separates primary and secondary action groups. Uses `.expa-root`, `.expa-inner`, `.expa-header`, `.expa-actions`, `.expa-btn-primary`, `.expa-btn-ghost`, `.expa-btn-secondary`, `.expa-divider-row` CSS classes.
As a frontend developer, implement the `UsersFiltersPanel` sidebar component with four controlled state hooks: `search` (useState ''), `role` (useState ''), `status` (useState ''), and `sort` (useState 'name'). Compute `hasActiveFilters` (boolean) and `activeFilterCount` (useMemo counting non-empty search/role/status). Render: (1) a header row with `SlidersHorizontal` icon (lucide-react, size 14) and an `AnimatePresence`-gated `motion.button` clear button (RotateCcw icon, size 11) that animates in/out with opacity+x:8 when `hasActiveFilters` is true; (2) a search group with a `Search` icon (size 16) overlaid in `.ufp-search-wrap` and a controlled text input; (3) a role `<select>` with options All Roles / Admin / Manager / Employee; (4) a status toggle group with chip buttons for All/Active/Inactive states. `clearFilters` resets all state. Uses `framer-motion` AnimatePresence for the clear button entrance/exit transition.
As a frontend developer, implement the `UsersToolbar` component with three state hooks: `searchTerm` (useState ''), `viewMode` (useState 'list'), and `selectedCount` (useState 0, read-only for now). Render `.ut-root` containing: (1) a `.ut-search-wrap` with an inline SVG search icon, a controlled text input with placeholder 'Search users by name, email, or role...', and a conditionally rendered clear button (X SVG) when `searchTerm` is non-empty; (2) a `.ut-actions` group showing a `.ut-selected-badge` when `selectedCount > 0`, an accent button 'Assign Role' with a person-check SVG (triggers `handleAssignRole` — modal trigger stub for parent/sibling integration), a danger button 'Deactivate' with a minus-circle SVG (`handleDeactivate` stub), a `.ut-divider`, and additional action buttons (export etc.). Wire `handleSearchChange` and `handleClearSearch` to the input. Bulk action handlers (`handleAssignRole`, `handleDeactivate`, `handleExport`) are stubs for parent-level wiring.
As a frontend developer, implement the `UsersTable` component with `initialUsers` array (8 users: Sarah Chen, Marcus Rivera, Priya Kapoor, James O'Brien, Emily Nakamura, David Okonkwo, Laura Schmidt, Carlos Mendez with id/name/email/role/status/dateJoined fields). State: `users` (useState), `selectedIds` (useState new Set()), `sortField` (useState 'name'), `sortDir` (useState 'asc'), `openMenuId` (useState null), `hoveredRowId` (useState null). Define `roleConfig` map (Admin/Manager/Employee → CSS class + label) and `statusConfig` (Active/Inactive). Implement `getInitials(name)` helper. Build a `SortIcon` sub-component accepting `active` and `direction` props rendering a dual-chevron SVG with `.ut-sort-icon`, `.ut-sort-active`, `.ut-sort-desc` classes. Apply `tableRowVariants` (hidden: opacity 0, x -12; visible: opacity 1, x 0; exit: opacity 0, x 12, 0.15s) via `AnimatePresence` on table rows and `dropdownVariants` (hidden: opacity 0, scale 0.92, y -4; visible: opacity 1, scale 1, y 0, 0.15s easeOut; exit: opacity 0, scale 0.95) on action dropdowns. Use `useCallback` for row interaction handlers. Render sortable column headers, avatar initials, role/status badges, per-row action menus, and select-all/individual checkboxes.
As a frontend developer, implement the `LeaveRequestsModal` component — a detail/action modal for reviewing individual leave requests. Build: (1) `useState` for `open` (boolean), `request` (initialized to `SAMPLE_REQUEST` with id, employeeName, email, dept, leaveType, dates, durationDays, status, reason, balance, timeline), and `managerNotes` string; (2) overlay + sheet animation using `overlayVariants` (opacity fade) and `sheetVariants` (y:60→0, scale:0.96→1, custom cubic-bezier ease) via `AnimatePresence`; (3) `LEAVE_TYPES` config mapping vacation/sick/personal/other to label, icon (Umbrella/Stethoscope/User/Briefcase), and `lrm-header-icon--*` color class; (4) `STATUS_CONFIG` mapping pending/approved/rejected to label + `lrm-status--*` class; (5) modal header with TypeIcon, employee avatar/initials, name, email (Mail icon), department (Building icon), status badge with StatusIcon (Check/XCircle/AlertCircle); (6) leave detail grid showing date range (Calendar), duration (Clock), leave type (Type icon); (7) reason/notes section with MessageSquare icon; (8) leave balance bar (total/used/remaining); (9) activity timeline list rendering `request.timeline` events; (10) `handleApprove` and `handleReject` handlers that append a new timeline event and update `request.status`; (11) manager notes textarea; (12) footer action buttons. Apply `LeaveRequestsModal.css` with `lrm-*` classes.
As a frontend developer, implement the MyLeavesFilters section for the MyLeaves page. This is a controlled filter bar component accepting props: search/setSearch, status/setStatus, leaveType/setLeaveType, dateFrom/setDateFrom, dateTo/setDateTo, onClearAll, filteredCount, and totalCount. It manages local sort state via React.useState('newest'). Renders a search input with a clear (X) button via handleClearSearch, a status dropdown (STATUS_OPTIONS: all/approved/pending/rejected/cancelled with dot indicators and counts), a leave type dropdown (LEAVE_TYPES: all/annual/sick/personal/bereavement/maternity/paternity/unpaid), date range inputs (dateFrom, dateTo), and a sort dropdown (SORT_OPTIONS: newest/oldest/date-range/status/type). Computes isFiltered boolean and builds an activeFilters array driving removable filter pills for each active filter (status, leaveType, dateFrom, dateTo, sort, search). handleClearAll resets all filters and calls onClearAll. Uses lucide-react icons: Search, X, ChevronDown, Filter, SlidersHorizontal. Import MyLeavesFilters.css.
As a frontend developer, implement the MyLeavesStats section for the MyLeaves page. Renders four StatCard components from a STATS array (balance: 24 days, used: 8 days, pending: 3 requests, upcoming: 2 scheduled) each with a colorKey variant (balance/used/pending/upcoming). Each StatCard uses motion.div with whileInView animation (opacity 0→1, y 24→0) with staggered delays (index * 0.1), viewport once:true margin:'-40px', and whileHover y:-4. Each card renders a colored mls-icon-wrap with the respective lucide-react icon (CalendarDays, Clock, Hourglass, CheckCircle2). The AnimatedNumber sub-component uses useRef, useState, useAnimation, and IntersectionObserver (threshold: 0.3) to trigger a requestAnimationFrame count-up animation with cubic ease-out (1 - Math.pow(1-progress, 3)) over durationMs, displaying the animated integer value. The motion.span uses the controls from useAnimation and derives its colorKey class by matching target value against STATS array. Import MyLeavesStats.css.
As a frontend developer, implement the LeaveRequestHero section for the LeaveRequest page. This section renders a `<section className='lrh-root'>` with a `motion.div` using `containerVariants` (staggerChildren: 0.12, delayChildren: 0.1) for orchestrated entry animations. Contains two animated children via `itemVariants` (opacity 0→1, y 12→0, duration 0.45, easeOut): (1) a `motion.nav` breadcrumb with three links — Dashboard (/Dashboard), Leave Requests (/LeaveRequests), and a static 'New Request' current crumb separated by `lrh-breadcrumb-sep` spans; (2) a `motion.div` text block with an `<h1 className='lrh-headline'>Submit Your Leave Request</h1>` and supporting `<p className='lrh-support'>` paragraph. Apply LeaveRequestHero.css styling. Note: this is a new page-level hero with no shared components from prior pages.
As a frontend developer, implement the NotificationsHeader section for the Notifications page. This section renders a breadcrumb nav using a BREADCRUMB array with Dashboard and Notifications links separated by ChevronRight icons. Includes a title row with an 'nh-title' h1 and an AnimatePresence-driven 'nh-badge' span that animates in/out via framer-motion spring (stiffness 500, damping 30) based on unreadCount state (initialized to 7). A 'nh-btn-mark-read' motion.button with CheckCheck icon triggers handleMarkAllRead, which sets unreadCount to 0 and markedAllRead to true. The button label toggles between 'Mark all read' and 'All read' via AnimatePresence with y-axis slide transitions (duration 0.2). Uses useState hooks for unreadCount and markedAllRead. Component may already exist if shared across pages.
As a Tech Lead, verify the end-to-end integration between the Calendar frontend and the Calendar backend API. Ensure CalendarGrid fetches leave data from GET /api/calendar/leaves?year=&month= and renders real multi-day spans (replacing SAMPLE_LEAVES), CalendarLeaveDetail fetches full detail from GET /api/calendar/leaves/{id} on cell click, handleApprove/handleReject in CalendarLeaveDetail call the leave request approval endpoints, and CalendarSidebar reflects real leave type breakdown and balance data. Verify month navigation triggers new API requests.
As a frontend developer, implement the SaveActionsSection for the Settings page. Manage `hasUnsavedChanges` (true), `isSaving` (false), and `toast` (null | { type: 'success' | 'error', message: string }) via useState. Use a `toastTimer` ref to auto-dismiss toast after 4000ms, with `clearToastTimer` and `showToast` useCallback helpers and a cleanup useEffect on unmount. Implement `handleSave` — guards against double-save via `isSaving`, simulates async save with setTimeout (900ms), sets `hasUnsavedChanges` to false, then calls `showToast('success', ...)`. Implement `handleCancel` — calls `showToast('error', ...)` and sets `hasUnsavedChanges` to false. Implement `handleDismissToast`. Render animated toast using `toastVariants` (opacity + y + height) with AnimatePresence in 'wait' mode, including an inline SVG checkmark for success and an X icon for error, plus a dismiss button. Render a pulsing unsaved-changes indicator using `dotVariants` (opacity pulse animation) when `hasUnsavedChanges` is true, plus Save and Cancel buttons — Save shows spinner text while `isSaving`. Use CSS from SaveActionsSection.css.
As a frontend developer, implement the `UsersRoleModal` component with state: `open` (useState true), `selectedRole` (useState 'employee'), `submitted` (useState false). Define a `roles` array of 3 objects: admin (Administrator — full access), manager (Manager — approve/reject leave), employee (Employee — submit requests). Define `overlayVariant` (opacity 0↔1) and `modalVariant` (spring stiffness 400, damping 30; hidden: opacity 0, y 24, scale 0.97; exit: opacity 0, y 16, scale 0.97, 0.18s easeIn). Render an `AnimatePresence`-gated `motion.div.urm-overlay` that closes on click, containing a `motion.div.urm-modal` (stopPropagation). Inside: (1) `.urm-header` with 'Assign Role' h3 and X close button (lucide-react, size 16, strokeWidth 2.5); (2) `.urm-user-display` with avatar initials div and user name/email for hardcoded user Sarah Chen (sarah.chen@leaveapprove.com, initials 'SC'); (3) `.urm-divider`; (4) `.urm-radio-group` mapping `roles` to radio-style label cards with active class when `selectedRole === role.value` and a Check icon (lucide-react) for the selected option; (5) a confirm button that calls `handleConfirm` — sets `submitted` true and closes modal after 900ms timeout.
As a frontend developer, implement the MyLeavesTable section for the MyLeaves page. This is a complex data table component using useState (sortField: 'startDate', sortDir: 'desc', page: 1, perPage: 10, selectedLeave: null, cancelConfirm: null) and useMemo/useCallback for performance. Implements multi-field client-side sorting via handleSort for fields: type, startDate, endDate, duration, status (with date parsing via new Date(), numeric coercion, and string normalization). Computes pagination: totalPages, safePage, and paged slice. Renders sortable column headers with ChevronUp/ChevronDown icons. Each row shows leave type, formatted dates (formatDate using toLocaleDateString 'en-US'), formatDuration helper, and status badge. Row actions include handleView (opens detail panel, clears cancelConfirm) and handleCancelRequest (sets cancelConfirm). Uses AnimatePresence for a detail panel modal/drawer (motion.div) showing full leave info with Eye, X, Calendar, Clock, Ban, FileText icons. A confirmCancel handler resets both selectedLeave and cancelConfirm. Pagination controls use a computed pages array with ellipsis logic for >7 pages. Accepts data and totalCount props. Import MyLeavesTable.css and framer-motion AnimatePresence.
As a frontend developer, implement the LeaveRequestForm section for the LeaveRequest page. This is the core multi-step form component using `useState`, `useCallback`, and `useMemo`. It has a 3-step wizard controlled by a `step` state ('Type', 'Dates', 'Details') with `STEP_ANIM` slide transitions (x: 30→0, exit x→-30) wrapped in `AnimatePresence`. Step 1 renders four `LEAVE_TYPES` cards (sick/vacation/personal/unpaid) each with a lucide icon (Stethoscope, Umbrella, User, Clock) and description. Step 2 renders a full custom `InteractiveCalendar` component with internal `viewYear`/`viewMonth` state, month navigation via `prevMonth`/`nextMonth`, grid rendering using `getDaysInMonth`/`getFirstDayOfMonth` helpers, range selection logic (startDate/endDate ISO strings), hover highlighting via `hoverDate`/`onHover`/`onHoverEnd`, and past-date disabling relative to `todayStr`. Helper functions `daysBetween`, `formatDateISO`, `isoToDateParts`, `datePartsToISO` handle date math. Step 3 renders a textarea/details field. Navigation uses `ChevronLeft`/`ChevronRight` and `Check` icons. Apply LeaveRequestForm.css (14927 chars). Exposes leaveType, startDate, endDate, dayCount, reason state upward for LeaveRequestPreview and LeaveRequestSubmit consumption.
As a frontend developer, implement the NotificationsFilters section for the Notifications page. This section manages six pieces of state via useState: search, activeTypes (default all three: approval/decision/system), statusFilter ('all'), dateFrom, dateTo, and sort ('newest'). Renders a search input row with a Search icon and animated X clear button (AnimatePresence, scale + opacity transition). TYPE_OPTIONS chips use colored dot indicators (nf-chip-dot-approval/decision/system CSS classes) with counts and toggle via useCallback toggleType that adds/removes keys from activeTypes array. STATUS_OPTIONS render as radio-style tab buttons. Date range inputs for dateFrom/dateTo and a ChevronDown sort dropdown for SORT_OPTIONS (newest/oldest). An active filter tags row is built dynamically into activeTags array — each tag has a dismiss handler to reset its filter. A 'Clear all' button appears when hasActiveFilters is true, triggering clearAll useCallback that resets all state. Tags animate in/out via AnimatePresence with layout prop.
As a frontend developer, implement the NotificationsList section for the Notifications page. Renders a NOTIFICATIONS array of 5+ notification objects (id, type, title, snippet, detail, sender, senderRole, timestamp, read, relatedHref, actionLabel, actionPrimary) covering approval/request/rejection/system/reminder types. Each notification card shows type-specific icons: CheckCircle (approval), XCircle (rejection), CalendarPlus (request/reminder), Info (system), Bell (fallback). Unread cards have a visual indicator. Cards support expand/collapse of 'detail' text via a ChevronDown toggle with AnimatePresence height animation. 'actionPrimary' flag controls primary vs secondary CTA button styling (e.g. 'Review Request' uses actionPrimary). Pagination controls render with ChevronLeft/ChevronRight and page number buttons. Expanded card state is tracked per notification id. AnimatePresence wraps list items for enter/exit animations. Uses useState for expanded item id and current page.
As a frontend developer, implement the NotificationsEmpty section for the Notifications page. This is a conditional empty state rendered when no notifications match the active filters. Uses containerVariants with staggerChildren (0.12) and delayChildren (0.08) on the motion.div wrapper with whileInView trigger (once: true, margin: -40px). Children use itemVariants with spring animation (stiffness 260, damping 23) for opacity/y/scale entrance. The BellOff icon is wrapped in 'ne-icon-wrap' which includes a motion.span 'ne-icon-ring' animated via ringVariants (scale from 0.6, rotate from -15, spring stiffness 200 damping 20, delay 0.2) and three decorative 'ne-dot' spans. Two ambient glow spans (ne-glow-1, ne-glow-2) are rendered outside the motion container. An 'ne-heading' h2, 'ne-subtext' p, and 'ne-cta' anchor linking to /Dashboard with a right-arrow span are all individual motion elements using itemVariants.
As a Tech Lead, verify the end-to-end integration between the LeaveRequests frontend (manager view) and the Leave Requests backend API. Ensure LeaveRequestsList fetches from GET /api/leave-requests with role-scoped results, LeaveRequestsModal loads detail from GET /api/leave-requests/{id}, handleApprove/handleReject call PUT /api/leave-requests/{id}/approve and /reject respectively, status updates reflect in the list after action, and notifications are triggered for the employee. Verify LeaveRequestsFilters parameters are correctly passed as query params.
As a Tech Lead, verify the end-to-end integration between the Reports frontend and the Reports backend API. Ensure KeyMetrics fetches from GET /api/reports/key-metrics, UsageChart fetches from GET /api/reports/usage-chart with monthly/quarterly mode param, LeaveBreakdown fetches from GET /api/reports/leave-breakdown, TrendAnalysis fetches from GET /api/reports/trends, ReportsFilters params are passed as query strings to all report endpoints, ReportsHeader date range presets correctly set query params, and ExportActions download button triggers GET /api/reports/export with active filters and streams the file correctly.
As a frontend developer, implement the LeaveRequestPreview section for the LeaveRequest page. This component accepts props `{ leaveType, startDate, endDate, dayCount, reason }` from the parent page state (fed by LeaveRequestForm). When `hasData` is false (any required field missing), it renders an empty-state `motion.div` with an `AlertCircle` (size 36) icon, 'No Request Drafted' title, and descriptive text with a fade-in animation (opacity 0→1, y 16→0). When `hasData` is true, it renders: a `motion.div` section header with `ClipboardList` icon and 'Request Preview' title (y: -8→0); a `motion.div` preview card using `cardVariants` (opacity/y/scale entrance, duration 0.45, cubic ease); staggered `rowVariants` rows (custom delay 0.15 + i*0.08) for leave type (`LEAVE_LABELS` map), start date (`CalendarDays` icon, `formatDate` helper), end date (`CalendarCheck` icon); an animated day-count badge using `countVariants` (scale 0→1, rotate -15→0, spring ease [0.34,1.56,0.64,1], delay 0.6); and an optional reason row. Layout uses `lrp-sidebar` at ~30% width desktop, stacked on mobile. Apply LeaveRequestPreview.css (7880 chars).
As a frontend developer, implement the LeaveRequestSubmit section for the LeaveRequest page. The component accepts `{ isComplete, onSubmit, onCancel }` props and renders nothing when `isComplete` is false. Internal state: `confirmed` (boolean checkbox), `submitted` (boolean post-submit), `loading` (boolean during 1400ms timeout). Uses `AnimatePresence mode='wait'` to toggle between two views: (1) the form view with `slideUp` animation — a confirmation checkbox row (`lrs-check-row`, toggled via `toggleConfirmed` useCallback, role='checkbox', aria-checked, keyboard accessible via Space/Enter) showing a `Check` (strokeWidth 3.5) icon and label text; action buttons row with 'Submit Request' button (disabled when !confirmed || loading, shows `lrs-spinner` span during loading) and a Cancel button that calls `onCancel?.() || window.history.back()`; `handleSubmit` useCallback calls `onSubmit?.()` then sets loading, resolves after 1400ms to setSubmitted(true); (2) a success view with `scaleIn` animation (scale 0.7→1) featuring `CalendarCheck` icon and confirmation messaging. Apply LeaveRequestSubmit.css (6092 chars).
As a Tech Lead, verify the end-to-end integration between the MyLeaves frontend and the My Leaves backend API. Ensure MyLeavesTable fetches paginated data from GET /api/my-leaves with sort/filter/page params from MyLeavesFilters, MyLeavesStats fetches from GET /api/my-leaves/stats and renders real balance/used/pending/upcoming values (replacing hardcoded values), and cancel request action calls DELETE /api/leave-requests/{id}. Verify AnimatedNumber in MyLeavesStats animates correctly on real data load.
As a Tech Lead, verify the end-to-end integration between the Notifications frontend and the Notifications backend API. Ensure NotificationsHeader fetches real unread count from GET /api/notifications/unread-count and the badge animates correctly, NotificationsList fetches paginated data from GET /api/notifications with filter params from NotificationsFilters, mark-all-read calls PUT /api/notifications/mark-all-read and updates badge to 0, and individual card expand triggers PUT /api/notifications/{id}/read. Verify NotificationsEmpty renders when API returns empty results.
As a Tech Lead, verify the end-to-end integration between the Users frontend and the Users Management backend API. Ensure UsersTable fetches paginated user data from GET /api/users with sort/filter params from UsersFiltersPanel and UsersToolbar search, UsersRoleModal calls PUT /api/users/{id}/role on confirm, deactivate action calls PUT /api/users/{id}/status, and the table re-fetches after mutations. Verify select-all checkbox and bulk actions wire correctly to selected user IDs.
As a Tech Lead, verify the end-to-end integration between the Settings frontend and the Settings backend API. Ensure LeaveTypesSection fetches from GET /api/settings/leave-types and CRUD operations call the correct POST/PUT/DELETE endpoints, LeavePoliciesSection fetches from GET /api/settings/leave-policies and save calls PUT /api/settings/leave-policies, NotificationPrefsSection fetches/saves via GET/PUT /api/settings/notifications, and SaveActionsSection handleSave triggers the correct API calls and reflects server response in toast. Verify admin-only access guard is enforced.
As a Tech Lead, verify the end-to-end integration between the LeaveRequest frontend and the Leave Requests backend API. Ensure LeaveRequestForm step 3 submission POSTs to /api/leave-requests with correct payload (leave_type, start_date, end_date, reason), LeaveRequestSubmit handles success/error states from the API response, and the submitted request appears in the employee's MyLeaves list and manager's LeaveRequests list after submission. Verify date range validation aligns between frontend InteractiveCalendar and backend.

Submit, review, and approve leave requests in one intuitive workspace. Track balances, spot conflicts on a shared calendar, and keep everyone in sync — from employees to managers to administrators.
Paper forms, scattered approvals, and guesswork scheduling pile up into real lost time. leave-approve replaces all of it with one clear, shared flow.
Leave requests bounce between email threads, spreadsheets, and chat apps. Every hand-off adds delay and a fresh chance for requests to slip through the cracks.
Managers cannot see who is off, when, or why at a glance. Overlapping absences and coverage gaps are discovered far too late to plan around them.
Admins rekey balances, chase approvals, and stitch together reports by hand each week — hours of repetitive work that drains time from real people work.
Hover any date to peek at who's away, drag across days to block out a range, and click to open the full leave request. This is the heart of leave-approve.
Drag across dates to select a range · Hover for details · Click to open a request
From the first request to the final approval, leave-approve keeps employees, managers and administrators aligned — transparently and in real time.
Submit time off in seconds — pick a leave type, set your start and end dates, and track every request from a single dashboard.
Review every team request in one queue. Approve or reject with a click and keep your team moving — no more email back-and-forth.
Configure leave types and policies for your whole organization, then generate usage reports on demand.
The moment a decision is made, everyone knows. Instant alerts keep employees and managers perfectly in sync.
From submitting time off to approving requests and shaping policy, leave-approve adapts to how each person works.
leave-approve guides every leave request along a single transparent path — so employees, managers and admins always know exactly where things stand.
An employee picks their leave type, start and end dates, then sends the request in seconds.
The manager sees the request alongside team coverage and pending balances at a glance.
With full context, the manager approves or rejects the request in a single confident click.
The employee is instantly notified of the decision so nothing gets lost in inboxes.
Everyone tracks live leave status and history from one transparent, shared timeline.
Join teams who've replaced messy spreadsheets and email threads with leave-approve. Submit, review, and approve time-off requests in one clear, transparent workspace — for employees, managers, and admins alike.
No comments yet. Be the first!