Frontend: - Replace Next.js with Vite + React + TypeScript - Add new component architecture (app-shell, sidebar, dashboard modules) - Implement product modules: FRAME, safety protocols, walkthrough checkin, campus/staff attendance, personality quiz, sign language, classroom timer - Add shadcn/ui component library with Tailwind CSS - Remove legacy generated components, stores, and pages Backend: - Add product migrations: frame_entries, user_progress, safety_quiz_results, walkthrough_checkins, communication_events, personality_quiz_results, campus_attendance_config/summaries, staff_attendance_records, content_catalog - Add corresponding models, services, and routes - Implement cookie-based auth with refresh token rotation - Add content catalog seeder with product content - Migrate to ESLint flat config - Switch from yarn to npm Infrastructure: - Update .gitignore for new tooling - Add project documentation (CLAUDE.md, docs/) - Remove deprecated config files and yarn.lock Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
73 lines
3.5 KiB
Markdown
73 lines
3.5 KiB
Markdown
# UI Kit
|
|
|
|
## Purpose
|
|
|
|
The frontend uses the local UI kit in `frontend/src/components/ui/` as the shared view-layer foundation. Product components should compose these primitives instead of duplicating low-level button, input, table, and status markup.
|
|
|
|
## Current Foundation
|
|
|
|
- `button.tsx` with variants in `button-variants.ts`; it also owns shared loading and leading-icon button behavior.
|
|
- `input.tsx`, `textarea.tsx`, `native-select.tsx`, `select.tsx`, `checkbox.tsx`, `radio-group.tsx`, and `form.tsx` for form controls.
|
|
- `table.tsx` for structured tables.
|
|
- `card.tsx`, `alert.tsx`, `badge.tsx`, `tabs.tsx`, `dialog.tsx`, `tooltip.tsx`, and other shadcn-style primitives.
|
|
- `state-panel.tsx` with variants in `state-panel-variants.ts` for loading, error, and empty states.
|
|
- `module-header.tsx` for repeated module title, icon, and description headers.
|
|
|
|
## StatePanel Usage
|
|
|
|
Use `StatePanel` when a feature needs a standard loading, error, or empty block.
|
|
|
|
```tsx
|
|
<StatePanel tone="violet" size="lg" alignment="center" loading>
|
|
Loading assessment content...
|
|
</StatePanel>
|
|
```
|
|
|
|
```tsx
|
|
<StatePanel tone="red" role="alert">
|
|
Assessment content could not be loaded from the backend.
|
|
</StatePanel>
|
|
```
|
|
|
|
Feature-specific wrapper components may stay in their module folder when they carry product copy or workflow-specific props. Those wrappers should delegate the repeated shell to `StatePanel`.
|
|
|
|
## Button Usage
|
|
|
|
Use `Button` for new clickable commands. Prefer `leadingIcon`, `loading`, and `loadingLabel` instead of duplicating inline spinner branches.
|
|
|
|
```tsx
|
|
<Button loading={saving} loadingLabel="Saving..." leadingIcon={<Save size={14} />}>
|
|
Save
|
|
</Button>
|
|
```
|
|
|
|
Feature components may pass product-specific `className` values while the shared component owns disabled and busy behavior.
|
|
|
|
## Table Usage
|
|
|
|
Use `Table`, `TableHeader`, `TableBody`, `TableRow`, `TableHead`, and `TableCell` for structured table markup. Preserve feature-specific density and colors with `className`; do not duplicate native `<table>` shells in new code.
|
|
|
|
## Form Controls
|
|
|
|
Use `Input` for text-like controls and `NativeSelect` for simple browser-native select fields. Use the Radix `Select` primitive only when the product requires custom dropdown behavior.
|
|
|
|
## Module Headers
|
|
|
|
Use `ModuleHeader` for repeated module-level title blocks with a square icon and short description. Feature headers may still render additional callouts or actions around it.
|
|
|
|
## Rules
|
|
|
|
- Keep UI variants and class maps in dedicated non-component files.
|
|
- Use `StatePanel` for repeated loading, error, and empty panels instead of copying Tailwind containers.
|
|
- Use existing `Button`, `Input`, `Textarea`, `Select`, and `Table` primitives for new view code.
|
|
- Use `NativeSelect` for simple select fields where native browser behavior is sufficient.
|
|
- Use `ModuleHeader` for repeated page/module headings instead of duplicating title/icon markup.
|
|
- Do not add another external UI kit unless the existing primitives cannot support a concrete product requirement.
|
|
- Do not move business rules into UI primitives. UI kit components should stay presentation-focused.
|
|
|
|
## Remaining Consolidation Candidates
|
|
|
|
- Repeated statistic cards can be promoted to a shared metric component after at least two active modules need the same prop shape.
|
|
- New structured table views should use `table.tsx`; existing feature tables can switch to it when product work touches those modules.
|
|
- Module-specific wrapper components should stay local until the same component contract is repeated across active modules.
|