Files
krow_workforce_owliver/README.md
2026-09-16 20:11:27 +05:30

118 lines
4.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`.