first commit
This commit is contained in:
117
README.md
Normal file
117
README.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# KROW Workforce — redesign demo
|
||||
|
||||
A complete redesign prototype of the KROW Workforce product with Owliver, the
|
||||
workforce-intelligence panel, built in.
|
||||
|
||||
Everything is local. There is no backend, API, database, authentication or
|
||||
outbound network call — all figures come from a single typed mock-data module.
|
||||
|
||||
## Running it
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev # http://localhost:5173
|
||||
npm run build # production build
|
||||
npm run typecheck # tsc --noEmit
|
||||
npm run lint # oxlint
|
||||
```
|
||||
|
||||
## Stack
|
||||
|
||||
Vite · React 19 · TypeScript · Tailwind CSS v4 · shadcn/ui-style components on
|
||||
Radix · Lucide · Recharts · TanStack Table v9 · React Router.
|
||||
|
||||
## Layout
|
||||
|
||||
One CSS grid (`.app-shell` in `src/index.css`):
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────┐
|
||||
│ sidebar │ GLOBAL HEADER (64px) │
|
||||
│ (full ├────────────────────┬─────────────┤
|
||||
│ height) │ MAIN CONTENT │ OWLIVER │
|
||||
└───────────┴────────────────────┴─────────────┘
|
||||
```
|
||||
|
||||
The header spans main + Owliver only; the sidebar owns the full viewport
|
||||
height and all navigation. Owliver sits in its own rail on row 2, so it can
|
||||
never overlap or be clipped by the header.
|
||||
|
||||
**Breakpoints** — desktop ≥1280: all three columns. Tablet 768–1279: icon rail
|
||||
plus main, Owliver becomes an overlay. Mobile <768: sidebar becomes a drawer
|
||||
(with the complete navigation, nothing removed), Owliver a bottom sheet.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
src/
|
||||
config/navigation.ts information architecture (mirrors the vendor workspace)
|
||||
data/ types, mockData, selectors, store
|
||||
owliver/ block types, response engine, block renderers
|
||||
components/shell/ AppShell, Sidebar, TopHeader
|
||||
components/owliver/ panel + composer
|
||||
components/shared/ MetricCard, DataTable, Page, Toolbar, StatusBadge
|
||||
components/ui/ Radix-based primitives
|
||||
pages/ the fourteen product pages
|
||||
```
|
||||
|
||||
`src/data/mockData.ts` is the single source of truth and `selectors.ts` derives
|
||||
every computed figure, so a number on a KPI card and the same number quoted by
|
||||
Owliver cannot disagree.
|
||||
|
||||
## Home
|
||||
|
||||
Home is an AI workspace rather than a dashboard. The hierarchy is greeting →
|
||||
central Owliver card → quick actions → compact metrics → Today.
|
||||
|
||||
Performance content (utilisation, trends, attendance, performance health)
|
||||
deliberately does **not** appear on Home — it lives on the Performance page,
|
||||
which remains complete.
|
||||
|
||||
## Owliver
|
||||
|
||||
**One Owliver per page, never two.** Home shows the central card and no right
|
||||
rail; every other page shows the right rail and no central card. On Home the
|
||||
grid drops to two columns, so main reflows into the space rather than leaving an
|
||||
empty rail behind — and the rail stays hidden on Home even if it was left open
|
||||
elsewhere.
|
||||
|
||||
That means the central card owns the whole interaction on Home: it holds the
|
||||
conversation, the composer and the suggestions, and an answer appears inside
|
||||
that thread. Replies are typed block lists rendered as real components — text,
|
||||
metric cards, alerts, tables, charts, a staff-allocation flow diagram,
|
||||
recommendations, expandable details and working action buttons.
|
||||
|
||||
Home's thread starts empty (an invitation to ask). Every other page opens with a
|
||||
greeting, its own brief and one seeded exchange, so the You / Owliver
|
||||
distinction is legible straight away.
|
||||
|
||||
State lives in `OwliverProvider`, above the panel, which gives two properties
|
||||
the panel could not provide on its own:
|
||||
|
||||
- **History survives closing.** Collapsing the rail, or the tablet/mobile sheet
|
||||
unmounting, no longer discards the conversation.
|
||||
- **Each page keeps its own thread.** Navigating switches context instead of
|
||||
leaving Home's answers on the Payroll page; returning to a page restores what
|
||||
was asked there.
|
||||
|
||||
Responses are deterministic and delayed 500–900 ms behind a typing indicator.
|
||||
**Resolve Understaffed Shifts** mutates the shared data, so the greeting, the
|
||||
metrics and the sidebar badges all update behind the panel.
|
||||
|
||||
## Shell controls
|
||||
|
||||
The sidebar collapses to a 72px icon rail (labels become tooltips; active state
|
||||
and badges are preserved) and Owliver closes so main reclaims its column. Both
|
||||
are driven by `data-sidebar` / `data-owliver` attributes on the grid container,
|
||||
so the layout reflows rather than overlaying.
|
||||
|
||||
## Notes for future work
|
||||
|
||||
Two bugs worth remembering, both fixed here:
|
||||
|
||||
- Passing a fresh `state` / `initialState` object to TanStack Table v9's
|
||||
`useTable` on every render makes its store notify → re-render → notify.
|
||||
Both are memoised in `DataTable.tsx`.
|
||||
- Loading the whole app in one chunk blocked first paint long enough to look
|
||||
like a hang on heavier routes. Pages are lazy-loaded in `App.tsx`.
|
||||
Reference in New Issue
Block a user