feat(frontend): optimistic UI for register/claim with rollback (#627)#663
Merged
joelpeace48-cell merged 1 commit intoJun 19, 2026
Conversation
) Register and claim now reflect the expected state the instant the user submits, then reconcile with chain truth on success or roll back on failure — so successful actions feel instant and failures recover cleanly. - useOptimisticAction hook (src/hooks): drives the idle → pending → success | error lifecycle. Applies an optimistic update, awaits the action, reconciles on success, and rolls back on failure. A synchronous in-flight latch guards against double-submit (a second click is ignored, never fires a second transaction). Rollback only runs if the optimistic update was actually applied. - errorMapping: add classifyError + mapError giving each failure a class (contract | wallet | network | rpc | validation | unknown) with distinct messaging — a network/RPC outage now reads differently from a contract revert, and contract reverts keep their precise per-code copy. - RegisterCampaign: status flips to "Registered" optimistically on submit; rolls back to the prior status on failure with a mapped error. - ClaimRewards: clears the input optimistically + shows a pending indicator; restores the amount on failure; reconciles the balance via onClaimSuccess. - TransactionStatus: new pending/success/error variant (backward compatible) so the pending state shows before a hash exists and errors render inline. Tests (src/hooks/useOptimisticAction.test.jsx, runs under the vitest include): optimistic-apply + reconcile, rollback on failure, no rollback when the optimistic step itself throws, double-submit guard, reset, and error classification (contract vs wallet vs network vs rpc messaging). A live register/claim E2E that forces a failure needs the docker-compose backend (the CI playwright run has none and skips the lifecycle suite), so rollback is covered here at the hook/integration level; the E2E can follow in that environment.
|
@anuoluwaponiorimi is attempting to deploy a commit to the joelpeace48-cell's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
b759dc1
into
FinesseStudioLab:main
11 of 12 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds optimistic UI to the register and claim flows (#627): the expected state is reflected the instant the user submits, then reconciled with chain truth on success or rolled back on failure with a clear, class-specific error. Successful actions feel instant; failed actions recover cleanly.
What changed
useOptimisticActionhook —src/hooks/useOptimisticAction.jsA small, reusable lifecycle engine:
idle → pending → success | error.runwhile one is in flight — a double-click can never fire two transactions.Error classification —
src/lib/errorMapping.jsclassifyError/mapErrorbucket every failure into a class —contract | wallet | network | rpc | validation | unknown— with distinct messaging:Components
RegisterCampaign.jsx: participant status flips to Registered optimistically on submit; rolls back to the prior status on failure; shows a pending card then a confirmed/error state.ClaimRewards.jsx: clears the input + shows a pending indicator immediately; restores the entered amount on failure; reconciles the on-chain balance viaonClaimSuccess.TransactionStatus.jsx: newvariantofpending | success | error(backward compatible — defaultsuccess), so a pending card can render before a hash exists and rolled-back errors render inline.Acceptance criteria
Testing
src/hooks/useOptimisticAction.test.jsx(under the vitestincludeglob, so it runs in CI):reset;Local: vitest (new suite) ✅,
eslint .✅ (0 errors),prettier --check✅,vite build✅.Note on E2E
The task list includes an E2E that forces a failure to assert rollback. The existing Playwright lifecycle suite (
tests/e2e/campaign-lifecycle.test.ts)test.skips itself when no backend is reachable, and the CI Playwright run has no backend — so a register/claim failure E2E needs the documented docker-compose environment. Rollback is therefore asserted here at the hook/integration level; the live E2E can follow in that environment.