feat(02-05): ColorLegend, AppNav, ViewToolbar, SkeletonCalendar, EmptyState; retire EventProof

- ColorLegend: per-member color swatches (12px circle, label) + always-visible Family row
- AppNav: phone 48px top bar (avatar with aria-label/title) + tablet/desktop 240px sidebar with ColorLegend
- ViewToolbar: Today/prev/next + Day/Week/Month/Agenda view switcher; 44px min-height; active state uses surface tint not accent
- SkeletonCalendar: shimmer month (6x7 grid) and agenda (4 date-group blocks) variants; aria-busy=true
- EmptyState: CalendarDays icon + 'Nothing here' heading + body copy per UI-SPEC
- CalendarShell: full phone/desktop layout with AppNav + ViewToolbar + ColorLegend chrome
- CalendarShell: state branches — loading→SkeletonCalendar, empty→EmptyState, error→'Couldn't load events' + Retry button (refetchQueries)
- EventProof.tsx deleted; legacy types removed from client.ts
- CalendarShell.test.tsx: updated to waitFor ScheduleXCalendar after data loads
- All 36 tests pass, tsc clean, vite build clean (490kB)
This commit is contained in:
Lucas Berger
2026-06-05 10:58:06 -04:00
parent 3eebfbff42
commit 216ddcedf4
9 changed files with 840 additions and 230 deletions
+2 -40
View File
@@ -95,43 +95,5 @@ export async function fetchEvents(
return res.json() as Promise<OccurrencesResponse>
}
// ── Legacy types + function for EventProof (Phase 1 broker-proof component) ──
// EventProof.tsx uses these; the component is removed in Plan 05.
// Kept here to prevent build breakage until then.
/**
* @deprecated Phase 1 raw cache shape — use CalendarOccurrence for Phase 2.
* EventProof uses this type; it is removed in Plan 05.
*/
export interface CalendarEvent {
id: number
calendarId: number
uid: string
etag: string | null
rawVevent: string
dtstartUtc: string | null
dtstartDate: string | null
allDay: boolean
updatedAt: string | null
}
/**
* @deprecated Phase 1 raw response shape — use OccurrencesResponse for Phase 2.
*/
export interface EventsResponse {
events: CalendarEvent[]
}
/**
* @deprecated Phase 1 broker-proof fetch — unwindowed, returns raw cache rows.
* Used only by EventProof.tsx; removed in Plan 05.
*/
export async function fetchEventsLegacy(): Promise<EventsResponse> {
const res = await fetch('/api/events', {
credentials: 'include',
})
if (!res.ok) {
throw new Error(`GET /api/events failed: ${res.status}`)
}
return res.json() as Promise<EventsResponse>
}
// Phase 1 legacy types (CalendarEvent, EventsResponse, fetchEventsLegacy) removed in Plan 05
// when the Phase 1 broker-proof component was retired.