Skip to content

chore(dev): /dev/migration UI showcase for app-migration surfaces - #2574

Closed
kushagrasarathe wants to merge 10 commits into
mainfrom
feat/migration-ui-mockups
Closed

chore(dev): /dev/migration UI showcase for app-migration surfaces#2574
kushagrasarathe wants to merge 10 commits into
mainfrom
feat/migration-ui-mockups

Conversation

@kushagrasarathe

Copy link
Copy Markdown
Contributor

Summary

Adds a dev-only preview page at /dev/migration that showcases every UI surface for the PWA → app-store migration, composed from the real app components (not lookalikes) so the states read like production.

Surfaces covered:

  • 01 Download prompt — single variant, deadline in copy; mobile shows the visitor's store CTA, desktop shows the QR inline.
  • 02 Access-ending screen — full-screen after cutover (mirrors ForceIOSPWAInstall).
  • 03 Guest link pages — claim / request / invite, built from PeanutActionDetailsCard + ActionListCard + the real "Continue with Peanut" button.
  • 04 Get-the-app banner — the real home CarouselCTA.
  • 05 Landing hero — the real <Hero> component, CTA swapped to "Download now".
  • 06 Review prompt / 07 Notifications promptActionModal pre-prompts.
  • 08 Scan-to-download — a QR with an App Store / Google Play toggle (a browser can't tell iOS from Android).

Device-aware throughout: one primary CTA per device (mobile → store button; desktop → QR).

Risk

None to production. Dev-only route — /dev is notFound() on prod (dev/layout.tsx), the whole page is behind that gate. No production code touched; only a new file under src/app/(mobile-ui)/dev/.

QA

./scripts/dev   # or: PORT=3055 pnpm dev in this worktree
open http://localhost:3055/dev/migration

Toggle iOS / Android / Desktop (top-right) to see the device-aware CTAs; open each modal; on Desktop the download CTAs show the dual-store QR.

Screenshots

Dev-only preview route — best viewed live at /dev/migration (steps above). Every surface is rendered from the real components; toggling the platform pill drives the CTA variants.

Design notes

  • No "native app" wording anywhere — users don't know the term; copy is "Peanut is becoming an app" / "download from the App Store or Google Play".
  • The dual-store QR toggle is deliberate; a single smart link (peanut.me/app redirecting by device) would remove the toggle — noted in a code comment as the lighter alternative, pending a product call.
  • Components are composed inline in the dev page for review — not yet extracted into production components; that happens when the migration decisions lock.

🤖 Generated with Claude Code

Preview page for every PWA->native migration component (download modal,
30-day block, guest CTA, open-in-app banner, app-store landing, setup
prefill, review nudge, push opt-in) composed from real Bruddle primitives
so the states are reviewable before wiring into the real flows.
modals now use ActionModal (pink icon circle + cta stack), block + landing
mirror the ForceIOSPWAInstall two-section install screen (secondary-3 hero +
peanut mascot + stars), guest CTA + setup prefill use AvatarWithBadge and the
live pay/claim amount typography — instead of the earlier bespoke markup.
…, full guest pages

- drop 'native app' wording everywhere (users don't know the term)
- add component index (what each is + where it's used)
- device-aware store CTA (platform toggle; user's store is primary/purple)
- 01 download modal: shorter CTAs, loud countdown pill
- 02 access-ending: PEANUTMAN_MOBILE mascot, clearer copy
- 03 guest link pages: full-page claim/request/invite with real 'Continue with Peanut'
- 04 banner: reuse home CarouselCTA
- 05 landing: whistling mascot hero, 'Download' CTA + rating (dropped 'Sign up')
- 06 setup-prefill screen removed (it's just existing signup with recovered context, not a new screen)
- 07 review + 08 push: better copy, fix CTA overflow + secondary shadow
bg-primary-1 + CloudsCss + PeanutWhistling + big uppercase heading, store
buttons row on web / stacked on phone, rating for trust. drops the phone-frame
card + 'Sign up' CTA.
on desktop, store links are dead, so download CTAs (download prompt, access-
ending screen, landing) show a 'Show QR to download' button that opens a QR
modal (mirrors InstallPWA DesktopInstructions). adds Desktop to the platform
toggle + a standalone QR example (08).
my hand-built hero was wrong (centered avatar+amount, custom rows). rebuild
with the actual page anatomy: centered header -> PeanutActionDetailsCard hero
(avatar + 'alice sent you' + amount) -> Continue with Peanut -> Divider ->
ActionListCard method rows. matches the live /claim + /request UI.
1. section 05 now renders the actual LandingPage/hero <Hero> (same as peanut.me),
   only the single CTA is device-based (App Store / Google Play / Download).
2. guest link page CTAs (Continue with Peanut + method rows) open the scan-to-
   download QR modal when platform is desktop.
… QR toggle

general:
- one primary CTA per device on mobile (visitor's store only, no dual buttons)
- desktop shows a scan-to-download QR with an App Store/Google Play toggle
  (can't detect the phone OS from a browser) — one QR at a time
component:
- 01 download prompt: single variant, deadline in copy, QR inline on desktop
  (no 'Show QR' click); mobile shows the single store CTA
- 05 landing: CTA 'Download now' for all; opens the QR modal on desktop
- 02 access-ending + 08 modal now use the shared dual-store DownloadQR
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
peanut-wallet Ready Ready Preview, Comment Jul 29, 2026 3:50pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 13a3a23d-d89a-4066-8ba3-2ab432a73ff0

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Code-analysis diff

Painscore total: 6306.66 → 6315.29 (+8.63)
Findings: +5 net (+5 new, -0 resolved)

🆕 New findings (5)

  • critical complexity — src/app/(mobile-ui)/dev/migration/page.tsx — CC 54, MI 69.32, SLOC 167
  • medium high-mdd — src/app/(mobile-ui)/dev/migration/page.tsx:182 — MigrationMockupsPage: MDD 122.0 (uses across many lines from declarations)
  • medium react-effect-derives-state — src/app/(mobile-ui)/dev/migration/page.tsx:197 — useEffect with empty deps + setState — derived state anti-pattern
  • low react-inline-arrows — src/app/(mobile-ui)/dev/migration/page.tsx:1 — 8 inline arrow handlers (extract or use useCallback)
  • low missing-return-type — src/app/(mobile-ui)/dev/migration/page.tsx:182 — MigrationMockupsPage: exported fn missing return type annotation

📈 Painscore deltas (top movers)

File Before After Δ
src/app/(mobile-ui)/dev/migration/page.tsx 0.0 8.6 +8.6

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

🧪 UI test report — ✅ all green

Suites

  • unit: 2235 ran, 0 failed, 0 skipped, 37.4s

📊 Coverage (unit)

metric %
statements 61.7%
branches 45.1%
functions 51.0%
lines 62.1%
⏱ 10 slowest test cases
time test
4.3s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › never places two stickers in heavy overlap (broad seed sweep)
1.2s src/utils/__tests__/demo-api.test.ts › isDemoMode() is false when not running under Capacitor
0.5s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › every sticker stays within canvas at any count
0.4s src/app/actions/__tests__/api-headers-extended.test.ts › should not include apiKey in validateInviteCode body
0.3s src/app/actions/__tests__/api-headers.test.ts › should include Content-Type in validateInviteCode
0.3s src/app/(mobile-ui)/withdraw/__tests__/withdraw-states.test.tsx › Bank withdrawal keeps the $1 minimum for sub-$1 amounts
0.2s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › keeps stickers off the username pill (final pass respects the keep-out)
0.2s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › Perk claim in progress shows disabled button + progress
0.2s src/utils/__tests__/demo-balance.test.ts › resetDemoBalance refills and restarts the TTL window
0.2s src/utils/__tests__/demo-balance.test.ts › starts at the full balance on a fresh install and stamps a timestamp
📍 Inline annotations are in the **Unit test report** check above. Coverage artifact: `coverage-unit`. Generated by `.github/workflows/tests.yml`.

content-driven height (no fixed h-[660px] cramping the desktop QR) + taller
padded hero + size-capped mascot with margin so its feet/shadow never clip.
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.

1 participant