Repository navigation
Description
[PLAN] Create a Next Task component
Type: Task
Parent: #246 ("[Feature] Create a Next Task component")
Plan v11. Replaces the earlier event-bus plan. #246 is unchanged. AI-executed PR: #248.
Scope
A reusable modal that opens after a successful action. First consumer: the claim flow in CitizenClaimWidget. Not in scope: analytics tooling, a content store or CMS, PR #191's native-redirect research. The component only exposes simple extension points: a content prop and onShown / onClicked / onDismissed callbacks.
Decisions (Laurence, Oct 21 to Nov 5)
- Controlled component, no event bus. The host (or the widget) passes
open,contentandonClose.useNextTaskTriggerand thewindowevent bus are removed. - CTA navigation: the host handles it, or we use
Anchor.resolveNavigationpassed: the CTA is aButtonand the host owns navigation (e.g. in-app GoodWallet routes). No external fallback.- Not passed: the CTA is
AnchorwithctaTarget, after an http(s)-only check. - Handler throws or rejects, or the URL is rejected: show the error and keep the drawer open so the user can retry or dismiss (Laurence, Nov 5). No silent failure. PR Feature: Next Task component (NextTaskModal) #248 still closes the drawer after a failure; fixed in issue [GoodBounty] Finalize Next Task component PR (#248) #276.
resolveNavigationtype:(ctaTarget: string) => void | Promise<void>.- No
react-nativeimport inNextTaskModal(TamaguiImage;Anchorhandles native links). Anchormode must carry the primary CTA prominence shown in the design reference (Laurence, Nov 5, replacing the Nov 4 "link is fine" decision). PR Feature: Next Task component (NextTaskModal) #248 still renders a plain link; fixed in the contributor issue [GoodBounty] Finalize Next Task component PR (#248) #276.- Dismiss reason: the shared
Drawerhas oneonClose, so the X button and an overlay press both report'overlay'. Accepted as a known limitation (Oliseh, Nov 4). - Copy is integrator-configurable through the same
contentJSON (Laurence, Nov 5, replacing the earlier "fixed copy" draft default): optionalheadline,supportingCopy,recommendedLabel,skipLabelandstatusLabel, falling back to the in-app defaults ("One good next step", etc.) when unset. PR Feature: Next Task component (NextTaskModal) #248 still hardcodes them; fixed in issue [GoodBounty] Finalize Next Task component PR (#248) #276.Draweris used as elsewhere in the repo. NextTaskModalandNextTaskCtaCardlive inpackages/ui. Tests live intests/design-system/smoke.spec.ts.
Behavior
- Single-chain claim: the modal opens after the success toast and
onClaimSuccess, outside the claimtry/catch, so a Next Task failure cannot report a successful claim as failed. - Multi-chain
claimAll: opens once, only if at least one claim succeeded, even ifrefresh()throws. - No
content: nothing renders. Ifcontentis removed while open, the modal closes without callingonDismissed. - Callbacks are wrapped so a throwing integrator callback cannot break the claim result or the modal.
- Custom element (
citizen-claim-widget):nextTaskContentandnextTaskResolveNavigationare properties;next-task-shown,next-task-clickedandnext-task-dismissedare events.
Acceptance criteria
AI-executed PR #248 (checked = done and evidenced in the PR):
-
NextTaskModal/NextTaskCtaCardbuilt once inpackages/ui. - Controlled by
open/content/onClose; event bus removed. - Nothing renders when
contentis missing. - Host handler mode (
Button) andAnchormode, with the http(s) check. - Handler throw, handler rejection and rejected URL each show an error toast.
- Dismiss closes with no navigation and fires
onDismissed. -
onShown/onClicked/onDismissedexist and failures are contained. - Claim flow wired for single-chain and multi-chain,
onClaimSuccess/onClaimErrorunchanged. - Custom element props and events added.
- Playwright specs and baselines (desktop and mobile) in
tests/design-system/. - No new
tscerrors (9 pre-existing, same asmain).
Left for the human contributor ([GoodBounty] issue #276):
- Match the design reference closely (primary CTA prominent in both modes).
- Responsive: usable on mobile, small screens, landscape and desktop, with realistic copy.
- Navigation failure keeps the drawer open (error shown, retry or dismiss).
- Integrator-configurable copy: headline, supporting line, badge, skip and status labels via
content, with defaults. - Test the real
CitizenClaimWidgetflow (drawer opens after a successful claim, CTA works, dismiss works), plus focused responsive and failure regression tests.
Out of scope: special Shadow DOM handling, a shared portal/Drawer redesign.
Not part of this plan or its PR: native device/simulator verification. GoodWidget and Storybook have no real-native test setup today, so this is documented separately as a nice-to-have (a testing environment for real native devices) and left to the QA process.
Deferred to a separate testing workstream and NOT marked as passed by this PR: broader test-quality/coverage criteria (extra Playwright states beyond the navigation-mode and error-toast cases, overlay dismiss, and the 9 pre-existing tsc errors, which stay at main's baseline).
Human-reviewer checklist
- The http(s)-only URL check is enough for
Anchormode, or a stricter rule (e.g. a domain allowlist) is wanted ifcontentever comes from a less-trusted source. -
resolveNavigation(void | Promise<void>, errors become a toast) matches what host integrators expect. - "No UI when
contentis missing" is acceptable as is. - The optional copy fields in
content(with defaults) are the right way for integrators to choose what to display. -
Anchorno longer registers in the theme manifest (needed soonPressworks on native); acceptable for a shared component. - Both modes show a primary CTA as in the design reference; dismiss reasons are limited as described above.
- PR Citizen-claim-widget: contract-sourced how-it-works copy (invite rewards) #191's native-redirect overlap is still tracked for Laurence and is not resolved by this plan.
- Storybook output matches the design reference in light and dark themes, at mobile width.
-
packages/uiis the right home vs. a dedicated package. - The claim wiring point in
CitizenClaimWidget.tsxis correct and does not double-fire across single-chain and multi-chain.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsIn Progress
Activity
[-][DRAFT][PLAN] Create a Next Task component[/-][+][PLAN] Create a Next Task component[/+]