🔗 Live Demo · Getting Started · Architecture
An enterprise-grade, fully responsive admin dashboard for workforce operations and project management. Administrators get a real-time operational overview, an interactive task management board, a searchable employee directory, and a personalizable workspace — all backed by local/mock data that persists in the browser.
Built as a production-quality SPA with React + TypeScript + Vite, Tailwind CSS, React Router, Context API, and Recharts.
▶ Try it live: https://technikky.github.io/workforce-ops-dashboard/
- Metrics grid — live cards for Total Employees, Active Projects, Overdue Tasks, and Completion Rate. All values are derived from state, not hard-coded.
- Data visualization — an interactive Productivity Trends area chart (completed vs. created tasks) and a Project Completion bar chart, both fully theme-aware with custom tooltips.
- Recent Activity stream — a live feed of task moves, completions, new-hire events, and system notifications. New actions (creating/moving/deleting tasks) push real entries to the top of the feed.
- Kanban board with four columns (Backlog → In Progress → Review → Done).
- Priority levels (High / Medium / Low) with color-coded badges.
- Search by title, description, or project + filter by status and priority.
- One-click "Move to next stage" and delete on each task card.
- Task creation modal with full client-side validation (required title with min length, required project, required due date) and live error feedback.
- Overdue tasks are automatically flagged.
- Responsive card grid and an alternative data-table view (toggle).
- Avatar, name, role, department, location, and status for each employee.
- Search by name/role/email + filter by department and status.
- Theme switcher (Light / Dark) wired through global state, with a no-flash inline boot script so the persisted theme is applied before first paint.
- State persistence — tasks, activity feed, and theme are all saved to
localStorageand restored on reload. A "Reset to sample data" action restores the original seed. - Empty states, keyboard-dismissible modal (Esc + backdrop), focus-visible rings, themed scrollbars, and subtle entrance animations throughout.
| Concern | Choice |
|---|---|
| Framework | React 18 (function components + Hooks) |
| Language | TypeScript |
| Build tool | Vite 5 |
| Styling | Tailwind CSS 3 (class-based dark mode) |
| Routing | React Router 6 |
| State management | React Context API (ThemeContext, DataContext) |
| Data visualization | Recharts |
| Icons | lucide-react |
Why Context API? The state surface (tasks, employees, activity, theme) is well-bounded and read by clearly separated feature areas. Two focused providers give clean separation of concerns without the boilerplate of Redux, while still being trivially swappable for a real API layer later.
Prerequisites: Node.js 18+ (developed on Node 22) and npm.
# 1. Install dependencies
npm install
# 2. Start the dev server (http://localhost:5173)
npm run dev
# 3. Build for production
npm run build
# 4. Preview the production build locally
npm run previewsrc/
├── main.tsx # App entry — mounts Router + Providers
├── App.tsx # Route table (Dashboard / Tasks / Employees / Settings)
├── index.css # Tailwind layers + base + reusable component classes
│
├── types/ # Central domain types + shared enums (single source of truth)
│
├── data/
│ └── mockData.ts # Seed employees, tasks, activities, chart data
│
├── context/
│ ├── ThemeContext.tsx # Light/dark theme, persisted + system-aware
│ └── DataContext.tsx # Tasks/employees/activity state, actions, derived metrics
│
├── hooks/
│ └── useLocalStorage.ts # Typed useState that transparently persists to localStorage
│
├── lib/
│ └── format.ts # cn(), timeAgo(), formatDate(), daysUntil()
│
├── components/
│ ├── ui/ # Reusable primitives: Button, Card, Badge, Modal,
│ │ # Input, Select, Avatar, SearchInput, EmptyState
│ ├── layout/ # Sidebar, Topbar, Layout shell
│ ├── dashboard/ # MetricCard, charts, ChartTooltip, ActivityStream
│ ├── tasks/ # TaskCard, TaskColumn, TaskModal
│ └── employees/ # EmployeeCard
│
└── pages/ # Dashboard, Tasks, Employees, Settings, NotFound
- Single source of truth. Selectable values (departments, statuses, priorities)
live in
types/and drive both the UI and the seed data, so filters and forms can never drift out of sync. - Derived, not duplicated, state. Dashboard metrics (overdue count, completion
rate, active projects) are computed with
useMemofrom the task list rather than stored separately. - Separation of concerns.
ThemeContextowns appearance;DataContextowns domain data and exposes a small, intention-revealing action API (addTask,moveTask,deleteTask,resetData). SwappingmockDatafor real API calls touches onlyDataContext. - Reusable, accessible primitives. The
ui/folder holds small, composable, fully typed components witharia-*attributes, focus management, and dark-mode variants baked in.
DataProviderseeds frommockDataon first run, then hydrates fromlocalStorageon every subsequent load.- Components read state and actions via the
useData()/useTheme()hooks. - Every mutation updates state and persists to
localStorage(viauseLocalStorage), and user-driven task actions also append to the activity feed.
Runtime
react,react-dom— UI runtimereact-router-dom— client-side routingrecharts— area & bar chartslucide-react— icon set
Tooling
vite,@vitejs/plugin-react— dev server & buildtypescript,@types/*— type safetytailwindcss,postcss,autoprefixer— styling pipeline
- Mobile-first layout: collapsible sidebar with hamburger + backdrop on small screens, fluid grids that adapt from 1 → 4 columns across breakpoints.
- Keyboard support: modal closes on
Esc, focus-visible rings on all interactive elements, semantic table/feed/dialog roles. color-schemeandprefers-color-schemerespected; no flash of incorrect theme.
- This is a frontend-only application. All data is mock/local and persists in
the browser's
localStorage— there is no backend or network dependency. - To start from a clean slate, use Settings → Reset to sample data, or clear
the
wf.*keys in your browser's localStorage.