Description
State handling is inconsistent across the dashboard: app/(dashboard)/events/loading.tsx renders a real EventsTableSkeleton, while app/(dashboard)/disputes/loading.tsx and app/(dashboard)/verification/loading.tsx simply return null, and the only empty state is an inline EmptyState defined locally inside components/active-bets/ActiveBets.tsx. The dashboard page hand-rolls its own loading/empty/error switch. This issue extracts a shared, accessible state-component system and adopts it so every list route presents consistent loading, empty, and error UX.
Requirements and context
- Create
components/ui/empty-state.tsx, components/ui/error-state.tsx, and a small components/ui/loading-state.tsx (or extend the existing skeleton.tsx/loading-more-indicator.tsx) with typed props (icon, title, description, optional action).
- Replace the
return null bodies in disputes/loading.tsx and verification/loading.tsx with a skeleton, and refactor the inline EmptyState in ActiveBets.tsx plus the empty branch in events-table.tsx to use the shared component.
- Adopt
error-state.tsx where the events store sets error so failures render consistently.
- Non-functional: components must expose
role="status"/aria-live for loading and clear headings for empty/error; no visual regressions to existing skeletons.
- Keep the global
components/error-boundary.tsx as the catch-all; this issue is about expected (non-crash) states.
Acceptance criteria
Suggested execution
1. Fork the repo and create a branch — git checkout -b feature/state-component-system.
2. Implement changes — add components under components/ui/; update app/(dashboard)/disputes/loading.tsx, app/(dashboard)/verification/loading.tsx, components/active-bets/ActiveBets.tsx, components/events/events-table.tsx.
3. Write/extend tests — Jest + React Testing Library with pnpm; add tests under components/ui/__tests__/ following end-of-list.test.tsx and loading-more-indicator.test.tsx.
4. Test and commit —
pnpm install
pnpm test
pnpm test:coverage
pnpm lint
Example commit message
refactor(ui): add shared empty/error/loading state components and adopt across dashboard
Guidelines
- Aim for >=90% coverage on the new components.
- Document the components in the design-system page or docs and keep ARIA roles consistent; verify no skeleton regressions.
- Timeframe: 96 hours.
Description
State handling is inconsistent across the dashboard:
app/(dashboard)/events/loading.tsxrenders a realEventsTableSkeleton, whileapp/(dashboard)/disputes/loading.tsxandapp/(dashboard)/verification/loading.tsxsimplyreturn null, and the only empty state is an inlineEmptyStatedefined locally insidecomponents/active-bets/ActiveBets.tsx. The dashboard page hand-rolls its own loading/empty/error switch. This issue extracts a shared, accessible state-component system and adopts it so every list route presents consistent loading, empty, and error UX.Requirements and context
components/ui/empty-state.tsx,components/ui/error-state.tsx, and a smallcomponents/ui/loading-state.tsx(or extend the existingskeleton.tsx/loading-more-indicator.tsx) with typed props (icon, title, description, optional action).return nullbodies indisputes/loading.tsxandverification/loading.tsxwith a skeleton, and refactor the inlineEmptyStateinActiveBets.tsxplus the empty branch inevents-table.tsxto use the shared component.error-state.tsxwhere the events store setserrorso failures render consistently.role="status"/aria-livefor loading and clear headings for empty/error; no visual regressions to existing skeletons.components/error-boundary.tsxas the catch-all; this issue is about expected (non-crash) states.Acceptance criteria
components/ui/with typed props.disputes/loading.tsxandverification/loading.tsxrender a skeleton instead ofnull.ActiveBetsandEventsTableempty states use the sharedEmptyState.Suggested execution
1. Fork the repo and create a branch —
git checkout -b feature/state-component-system.2. Implement changes — add components under
components/ui/; updateapp/(dashboard)/disputes/loading.tsx,app/(dashboard)/verification/loading.tsx,components/active-bets/ActiveBets.tsx,components/events/events-table.tsx.3. Write/extend tests — Jest + React Testing Library with pnpm; add tests under
components/ui/__tests__/followingend-of-list.test.tsxandloading-more-indicator.test.tsx.4. Test and commit —
pnpm install pnpm test pnpm test:coverage pnpm lintExample commit message
Guidelines