Skip to content

feat(web): standardize async states across community and proposal screens - #284

Merged
Caneryy merged 3 commits into
stolla-labs:mainfrom
emirykl:grantfox/issue-251-standardize-async-states-across-community-and-pr
Aug 30, 2026
Merged

feat(web): standardize async states across community and proposal screens#284
Caneryy merged 3 commits into
stolla-labs:mainfrom
emirykl:grantfox/issue-251-standardize-async-states-across-community-and-pr

Conversation

@emirykl

@emirykl emirykl commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Stacked on #283. This branch contains #283's commit as its first commit because the frontend test baseline on main is currently broken (7 tsc errors, 29 failing tests), so this change cannot be verified green on its own. Please review/merge #283 first — GitHub will then reduce this PR's diff to the single commit below. The reviewable commit here is feat(web): standardize async states across community and proposal screens.

Summary

Adds four small shared primitives and applies them across the community and proposal screens so async states read consistently.

  • New primitives under src/components/ui/, built with the existing design tokens:
    • AsyncState — in-flight reads; role="status", aria-live="polite", aria-busy="true".
    • EmptyState — a completed, successful read with no matching records; role="status".
    • ErrorState — retryable failures; role="alert" with a Retry button wired to the existing retry callback.
    • FreshnessNotice — stale or partially-failed reads; role="status", deliberately not an alert.
  • Applied to communities/, communities/[id]/, communities/[id]/proposals/, communities/[id]/proposals/[proposalId]/, proposals/, CommunityCard, CommunityProposalsView, and CommunityProposalDetailView.
  • Data-fetching logic, error mapping, and retry callbacks are unchanged — only the local state blocks are replaced.
  • Partial proposal failures now surface through FreshnessNotice alongside the successfully loaded items instead of replacing them.
  • CommunitiesPage.test.tsx's empty-state assertion is updated to target the semantic status region rather than the text node's own attribute.

Linked issue

Closes #251

Test plan

Ran from the repository root on a clean npm ci install:

  • npm run typecheckclean (main currently has 7 errors; test(web): consolidate Stellar test support and repair the test baseline #283 fixes those).
  • npm test65 test files, 443 tests passing, including the new src/components/ui/AsyncStates.test.tsx covering the four primitives' roles, live-region politeness, and retry callback.
  • npm run build — completes successfully.
  • npm run lint — down from 5 problems (3 errors, 2 warnings) on main to 3 (1 error, 2 warnings). This PR fixes both pre-existing react-hooks/set-state-in-effect errors in the proposal pages it touches. The one remaining error (hooks/useTransactionLifecycle.ts:76, react-hooks/refs) and both warnings are pre-existing in files this PR does not touch.

Accessibility behaviour was verified through the new tests: loading announces as busy without interrupting, empty results announce as a status, errors announce as an alert and invoke the retry callback, and partial data is qualified without being presented as an error.

Checklist

  • I have run npm run lint and fixed any warnings introduced by my changes (pre-existing warnings are acceptable).
  • I have run npm run build and it completes successfully.
  • My changes do not introduce new environment variables, secrets, or generated files.
  • UI changes include screenshots at mobile and desktop widths. — see note below.
  • Contract changes include or update unit tests and npm run test:contracts passes. — n/a, no contract changes.

On screenshots: this touches UI, but the change is a markup/wording consolidation of loading, empty, error, and stale blocks rather than a visual redesign, and the primitives reuse the existing tokens. Happy to attach before/after captures at mobile and desktop widths if you would like them before merging.

emirykl and others added 2 commits August 26, 2026 23:03
…eens

Add shared AsyncState, EmptyState, ErrorState, and FreshnessNotice
primitives and apply them to the community list/detail, proposal
list/detail, and proposal index screens so loading, empty, stale,
retryable error, and success states use consistent markup and wording.

Data-fetching logic, error mapping, and retry callbacks are unchanged;
only the presentation of each state is replaced. Partial proposal
failures now surface through FreshnessNotice instead of replacing the
successfully loaded items.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0187tinPTSTLHxYcEa62BreS
@vercel

vercel Bot commented Aug 26, 2026

Copy link
Copy Markdown

@emirykl is attempting to deploy a commit to the caneryy's projects Team on Vercel.

A member of the Team first needs to authorize it.

@emirykl

emirykl commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

CI note: the frontend job cannot run to completion on any PR in this repo right now — package-lock.json on main has 9 duplicate keys, two of them misaligned onto the wrong package names, which makes npm ci fail with EBADPLATFORM on the linux-x64 runner. Full diagnosis in #283 (comment). It is pre-existing on main and unrelated to this change.

Verified locally on a clean npm ci install at this PR's head: npm run typecheck clean, npm test 65 files / 443 tests passing, npm run build succeeds.

Merge origin/main into issue-251 branch and reconcile async-state
changes with merged community registry and wizard retirement work.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Caneryy
Caneryy merged commit e1d0ecf into stolla-labs:main Aug 30, 2026
0 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Standardize async states across community and proposal screens

2 participants