- Add @tanstack/react-query 5.101.0; wrap app with QueryClientProvider - Add AvailabilityStatus type and AvailabilityResponse to api/types.ts - Implement useAvailabilityStatus (staleTime 30s, stale-on-error preserved) - Add AvailabilityStatusBadge with green/amber/red states and stale indicator - Replace DashboardPage placeholder card with live availability widget - Add MSW availability handler; update test/utils with QueryClientProvider - 55/55 tests pass (FR-05) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
7.2 KiB
7.2 KiB
Code Generation Plan — Unit 4: Dashboard
Status: ✅ Complete
Unit Context
Unit: Unit 4 — Dashboard Type: Frontend (React/TypeScript) Depends on: Unit 3 (AppLayout, AuthContext) — complete Stories Covered: FR-05 (availability widget on dashboard)
Key Design Decisions (from functional design):
@tanstack/react-queryadded as new dependency;QueryClientProviderwraps the app inmain.tsxuseAvailabilityStatususesuseQuerywithstaleTime: 30_000ms- Error + stale data: show last known status with stale indicator + error banner with Retry
AvailabilityStatustype andAvailabilityResponseinterface added toapi/types.ts- MSW mock handler created for tests
Files to Modify:
frontend/package.json— add@tanstack/react-queryfrontend/src/main.tsx— wrap withQueryClientProviderfrontend/src/api/types.ts— addAvailabilityStatus,AvailabilityResponsefrontend/src/mocks/index.ts— register availability handlersfrontend/src/pages/DashboardPage.tsx— replace placeholder with availability widgetfrontend/src/i18n/locales/en/translation.json— addavailability.*keysfrontend/src/i18n/locales/nl/translation.json— addavailability.*keys
Files to Create:
frontend/src/api/useAvailability.tsfrontend/src/components/shared/AvailabilityStatusBadge.tsxfrontend/src/mocks/availability/handlers.tsfrontend/src/api/useAvailability.test.tsfrontend/src/components/shared/AvailabilityStatusBadge.test.tsxaidlc-docs/features/cms-frontend/construction/unit-4/code/code-generation-summary.md
Code Generation Steps
Step 1: Install @tanstack/react-query
- Run
pnpm add @tanstack/react-queryinfrontend/ - Verify
package.jsonupdated with@tanstack/react-query
Step 2: Add AvailabilityStatus and AvailabilityResponse to api/types.ts
- Append to
frontend/src/api/types.ts:export type AvailabilityStatus = 'Available' | 'Maintenance' | 'Unavailable'; export interface AvailabilityResponse { status: AvailabilityStatus; checkedAt: string; // ISO 8601 message: string; }
Step 3: Wrap app with QueryClientProvider in main.tsx
- Import
QueryClient,QueryClientProviderfrom@tanstack/react-query - Create
queryClientinstance withdefaultOptions: { queries: { retry: 1, refetchOnWindowFocus: true } } - Wrap
<AuthProvider>with<QueryClientProvider client={queryClient}>
Step 4: Create useAvailability.ts
- Create
frontend/src/api/useAvailability.ts - Implement
useAvailabilityStatus()usinguseQuery:queryKey: ['availability', 'status']queryFn:api.get<AvailabilityResponse>('/api/v1/Availability/status')staleTime: 30_000
- Return full TanStack Query result (
data,error,isLoading,isError,isFetching,refetch)
Step 5: Create AvailabilityStatusBadge.tsx
- Create
frontend/src/components/shared/AvailabilityStatusBadge.tsx - Props:
status: AvailabilityStatus,message?: string,stale?: boolean - Status → color/icon mapping:
Available→bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200+CheckCircleiconMaintenance→bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-200+AlertTriangleiconUnavailable→bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200+XCircleicon
- Show
messageas subtitle paragraph when non-empty (data-testid="availability-message") - When
stale={true}: amber dashed border +Clockicon +t('availability.staleLabel')label (data-testid="availability-stale-indicator") - Test IDs:
availability-badge(wrapper),availability-status-label
Step 6: Update DashboardPage.tsx
- Import
useAvailabilityStatus,AvailabilityStatusBadgeandCard*components - Replace generic placeholder
Cardwith the availability widget:- Card title:
t('availability.title') isLoading→ skeleton placeholder (data-testid="availability-skeleton")datapresent →<AvailabilityStatusBadge status={data.status} message={data.message} stale={isError} />isError && !data→ error-only state:t('availability.errorTitle')+ Retry buttonisError(any) → error banner below/above badge with Retry button (data-testid="availability-error",data-testid="availability-retry")
- Card title:
- Keep welcome header section unchanged
Step 7: Add i18n keys
- Add to
frontend/src/i18n/locales/en/translation.json:"availability": { "title": "System Status", "available": "Available", "maintenance": "Maintenance", "unavailable": "Unavailable", "errorTitle": "Could not load status", "staleLabel": "Last known status", "retry": "Retry" } - Add to
frontend/src/i18n/locales/nl/translation.json:"availability": { "title": "Systeemstatus", "available": "Beschikbaar", "maintenance": "Onderhoud", "unavailable": "Niet beschikbaar", "errorTitle": "Status kon niet worden geladen", "staleLabel": "Laatste bekende status", "retry": "Opnieuw proberen" }
Step 8: Create MSW availability handler
- Create
frontend/src/mocks/availability/handlers.ts:import { http, HttpResponse } from 'msw'; export const availabilityHandlers = [ http.get('*/Availability/status', () => HttpResponse.json({ status: 'Available', checkedAt: new Date().toISOString(), message: '', }) ), ]; - Modify
frontend/src/mocks/index.ts:- Import
availabilityHandlers - Spread into
handlersarray - Re-export
availabilityHandlers
- Import
Step 9: Tests — useAvailabilityStatus
- Create
frontend/src/api/useAvailability.test.ts - Test cases (using MSW +
renderHookwithQueryClientProviderwrapper):- Returns
isLoading=trueinitially - Returns
dataon successful fetch (using default MSW handler) - Returns
isError=true+ preserves staledataon refetch failure (override handler to return 500) refetch()triggers a new fetch
- Returns
Step 10: Tests — AvailabilityStatusBadge
- Create
frontend/src/components/shared/AvailabilityStatusBadge.test.tsx - Test cases:
Available→ green badge,t('availability.available')labelMaintenance→ amber badge,t('availability.maintenance')labelUnavailable→ red badge,t('availability.unavailable')labelmessageprop: renders subtitle when non-empty, hidden when emptystale={true}: renders stale indicatorstale={false}(default): no stale indicator
Step 11: Final verification
pnpm build— no TypeScript or Vite errorspnpm lint— no ESLint errorspnpm test— all tests pass (existing + new)- Dev server: verify availability widget renders on dashboard, skeleton visible on load, Retry button functional
Step 12: Write code generation summary
- Create
aidlc-docs/features/cms-frontend/construction/unit-4/code/code-generation-summary.md - List all created/modified files with paths
- Record test results
Step 13: Commit
- Commit with message referencing Unit 4 / FR-05