Skip to content

feat: accessible multi-step escrow funding flow backed by a state machine - #44

Merged
meshackyaro merged 1 commit into
workman-labs:devfrom
Akanimoh12:feat/24-escrow-funding-wizard
Aug 18, 2026
Merged

feat: accessible multi-step escrow funding flow backed by a state machine#44
meshackyaro merged 1 commit into
workman-labs:devfrom
Akanimoh12:feat/24-escrow-funding-wizard

Conversation

@Akanimoh12

Copy link
Copy Markdown
Contributor

Summary

Implements the escrow funding wizard as an explicit finite state machine, with full keyboard navigation, screen-reader announcements, and resumable progress across reloads.

  • State machine (src/lib/escrowFunding.ts) — a pure transition(state, event) table over five states (review → connectWallet → confirm → funding → funded, plus a failed state reachable from funding). Every valid transition is enumerated once; invalid (state, event) pairs are simply absent rather than special-cased in the UI. This is deliberately not a useState step counter — the flow has real branching (wallet not connected, funding can fail and be retried, a step can only be reached once its predecessor completes) that a bare index can't express safely.
  • Accessibility
    • EscrowStepper is a roving-tabindex button group (arrow keys / Home / End move focus, one tab stop for the whole nav) with aria-current="step" on the active step.
    • An aria-live="polite" region announces every state transition in plain language ("Step 2 of 4: Connect your Stellar wallet.", "Escrow funded successfully…").
    • Focus moves to a heading at the top of each step on transition, so keyboard and screen-reader users land somewhere sensible after every step change.
    • Enter anywhere in the wizard body advances the primary action (Continue / Fund), without double-firing on focused buttons/links.
  • Resumable progress — step + context (never the wallet's private state) is persisted to localStorage per booking reference on every transition, mirroring the identity verification wizard's save-and-resume pattern. Transient (funding) and terminal (funded) states are never persisted, since there's nothing meaningful to resume into.
  • Funding call is a documented stubguildworkman-core's Soroban escrow contract isn't called from the backend yet (see the README's "Web3 / Stellar touches" section and the existing NOTE in BookingScreen.tsx). fundEscrow() simulates the round trip (latency + an occasional failure, to exercise the retry path) for the same reason submitIdentityVerification() does. Swapping in a real call later doesn't require changing the wizard component.
  • New route /escrow/[bookingRef] mounts the wizard standalone (mirrors /verify-identity's pattern). BookingScreen's existing one-shot "Pay into escrow" button is untouched — wiring the booking flow to this wizard is a natural follow-up, left out here to keep this PR scoped to the wizard itself.
  • 17 new unit tests for the transition table and save/resume persistence (src/lib/test/escrowFunding.test.ts), following the existing identityVerification.test.ts conventions.
  • No new dependencies — built entirely on the existing stack (React state, Tailwind primitives, useWallet(), react-icons).

Test plan

  • npx tsc --noEmit — no errors
  • npx eslint . — 0 errors (pre-existing react-hooks/set-state-in-effect warnings only, same pattern already used in BookingScreen.tsx)
  • npm test — 52/52 passing (17 new)
  • npm run build — production build succeeds, /escrow/[bookingRef] registered as a dynamic route
  • All checks run against Node 20 to match CI

Closes #24

…te machine

Models the escrow funding flow (review -> connect wallet -> confirm ->
fund -> funded/failed) as an explicit finite state machine in
lib/escrowFunding.ts, with full keyboard navigation on the step nav,
aria-live announcements + focus management for screen readers, and
resumable progress across reloads via localStorage, following the same
save-and-resume pattern as the identity verification wizard.

fundEscrow() simulates the round trip for the same reason
submitIdentityVerification() does: the Soroban escrow contract isn't
called from the backend yet.
@vercel

vercel Bot commented Aug 18, 2026

Copy link
Copy Markdown

@Akanimoh12 is attempting to deploy a commit to the Meshack Yaro's projects Team on Vercel.

A member of the Team first needs to authorize it.

@vercel

vercel Bot commented Aug 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
guildworkman-web Ready Ready Preview Aug 18, 2026 3:49pm

@meshackyaro meshackyaro left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a well-executed, thoughtfully scoped contribution that delivers a fully-accessible escrow funding wizard with clear intent, strong testing, and smart architectural choices. The PR is mergeable, low-risk, and demonstrates a deep understanding of the codebase patterns and accessibility standards. Well done @Akanimoh12!

@meshackyaro meshackyaro left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a well-executed, thoughtfully scoped contribution that delivers a fully-accessible escrow funding wizard with clear intent, strong testing, and smart architectural choices. The PR is mergeable, low-risk, and demonstrates a deep understanding of the codebase patterns and accessibility standards. Well done @Akanimoh12!

@meshackyaro
meshackyaro merged commit 2211338 into workman-labs:dev Aug 18, 2026
3 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.

Accessible Multi-Step Escrow Funding Flow Backed by a State Machine

2 participants