65 lines
3.4 KiB
Markdown
65 lines
3.4 KiB
Markdown
Create the Tessera frontend files in web/src/. The Next.js + shadcn/ui scaffold already exists. Only create TypeScript/TSX files — no bash commands needed.
|
|
|
|
## Files to create (read existing scaffold files first to understand imports)
|
|
|
|
### 1. web/src/lib/types.ts
|
|
Copy the types from the web spec (docs/web-spec.md lines 89-110). Add import for Lucide icons where needed. Create TypeScript interfaces for: Ticket, Queue, Transaction, Scrip, Template, Lifecycle, LifecycleDefinition, CustomField, CustomFieldValue, PreviewResult, PreparedScrip, UpdateResult, ScripResult.
|
|
|
|
### 2. web/src/lib/api.ts
|
|
Fetch wrapper using the types. Base URL is '/api' (proxied by next.config.ts to backend).
|
|
Every function returns Promise<{ data: T | null; error: string | null }>.
|
|
Import types from './types'.
|
|
Implement all 15 functions from docs/web-spec.md lines 69-84.
|
|
Use try/catch with fetch. Parse JSON responses. Handle non-200 status codes.
|
|
Use backend URL path mapping: /api/tickets, /api/queues, /api/scrips, /api/custom-fields, /api/lifecycles.
|
|
|
|
### 3. web/src/app/layout.tsx
|
|
Add dark mode. Import Inter from next/font/google. Set className="dark" on html element.
|
|
Import and use existing components: no shadcn components needed for layout.
|
|
Nav bar with gradient and blur. Content area with min-height.
|
|
|
|
### 4. web/src/app/page.tsx (ticket list)
|
|
Full ticket list page with:
|
|
- State: tickets array, queues array, filters (queue_id, status), loading, error
|
|
- Fetch tickets + queues on mount with useEffect
|
|
- Filter bar: Select for queue (shadcn Select), Select for status, Filter button
|
|
- Table using shadcn Table component
|
|
- Badge for status (shadcn Badge) with colors: new=default, open=blue, in_progress=yellow, resolved=green, closed=gray
|
|
- Click row → useRouter router.push(`/tickets/${id}`)
|
|
- Empty state: "No tickets yet"
|
|
- "New Ticket" button → shadcn Dialog with form (subject input, queue select)
|
|
- Form uses useState for values, calls createTicket on submit
|
|
- Loading: "Loading tickets..." text
|
|
- Error: red text with error message
|
|
|
|
### 5. web/src/app/tickets/[id]/page.tsx
|
|
Ticket detail page with:
|
|
- State: ticket, transactions, loading, error, selectedStatus, previewResult
|
|
- Back link using Link from next/link
|
|
- Ticket info: Card with subject, status badge, queue, dates, owner
|
|
- Status change: Select dropdown, "Preview" button (calls previewTicket, shows in Dialog), "Apply" button (calls updateTicket)
|
|
- Transaction timeline: Card with list of transactions. Each shows type badge (colored), field change, timestamp using date-fns formatDistanceToNow
|
|
- Custom fields: Card showing CF name:value pairs (from ticket.custom_fields)
|
|
|
|
### 6. web/src/app/admin/page.tsx
|
|
Admin page with shadcn Tabs: Queues, Lifecycles, Scrips, Custom Fields.
|
|
Each tab: list table + "Add" button → Dialog with form.
|
|
Uses existing API functions from lib/api.ts.
|
|
|
|
## Rules
|
|
- Use shadcn/ui components by importing from '@/components/ui/...' (e.g. '@/components/ui/button')
|
|
- Use lucide-react for icons (import from 'lucide-react')
|
|
- All state management with React useState/useEffect
|
|
- No external state libraries
|
|
- Proper TypeScript types everywhere
|
|
- Handle loading and error states
|
|
- Dark theme is automatic via the dark class on html
|
|
- Use Tailwind classes for spacing and layout
|
|
- Minimal styling needed — shadcn handles it
|
|
|
|
## Verification
|
|
After creating all files:
|
|
1. Run `cd /home/gjermund/projects/tessera/web && nix-shell -p bun --run "bun run build"` to verify no compile errors
|
|
2. Fix any type errors
|
|
3. Commit after each file
|