Skip to content

fix(landing): TASK-20600 desktop hero Download now opens the scan-to-download QR - #3024

Merged
kushagrasarathe merged 2 commits into
mainfrom
hotfix/TASK-20600-hero-desktop-qr
Sep 7, 2026
Merged

kushagrasarathe merged 2 commits into
mainfrom
hotfix/TASK-20600-hero-desktop-qr

Conversation

@kushagrasarathe

@kushagrasarathe kushagrasarathe commented Sep 7, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Hotfix for the pwa-sunset landing hero on desktop. During the migration window the desktop hero showed only the two store web links — the one desktop download surface that skipped the scan-to-download QR rule every other surface follows (home banner, setup, guest CTAs), leaving a laptop visitor with a store web page as a dead end. The hero now shows one "Download now" primary that opens the existing ScanToDownloadModal — smart QR encoding /app, with the App Store / Google Play pair inside the modal. The hero's own store-button pair is gone (Kush's call: one CTA on the hero, the store links live in the modal).

No new components: composes the existing ScanToDownloadModal / DownloadQR used by home and the guest flow. The modal chunk is dynamic()-imported and only fetched on click, so the landing critical path gains nothing.

Task

Contributes to TASK-20600 — store links on landing + setup (this closes the gap between the task's intended desktop behavior — scan-to-download QR — and what shipped in #2591).

Risks / breaking changes

  • Flag OFF (all users today): zero change. Every changed line lives inside the migrationOn && isDesktop branch; flag-off renders the untouched heroConfig.primaryCta path. The only flag-off deltas are an unused useState and a dynamic() module reference that never loads.
  • Flag ON, mobile: unchanged (store deep-link primary as before).
  • Flag ON, desktop: the hero's store-link pair is replaced by the single "Download now" → QR modal path; the store links remain reachable inside the modal.
  • No cross-repo impact, no data-flow change (the migration_qr_shown event with surface: landing_hero already existed in the analytics schema).
  • Hotfix to main → creates main→dev back-merge debt.

QA

  1. Local dev (posthog off): localStorage.setItem('pwa-sunset', 'true') + reload, desktop viewport → hero shows "Download now" + store pair; clicking opens the QR modal (QR encodes <origin>/app).
  2. Remove the key + reload → hero identical to prod today (flag-off pinned: typecheck ✅, 346 test suites ✅, build ✅).
  3. Prod-like: posthog.featureFlags.overrideFeatureFlags({ flags: { 'pwa-sunset': true } }).

Screenshots

Captured on the branch, local dev, desktop 1440×900. Assets live on the pr-assets-3024 orphan branch — delete it after merge.

Flag ON — hero (new) Flag ON — Download now → QR modal (new) Flag OFF — hero (unchanged control)

Mobile (flag on and off) renders no changed code path — untouched.

During the pwa-sunset window the desktop hero showed only two store web
links — the one desktop download surface without the QR path every other
surface (home, setup, guest CTAs) follows, and a store web page is a dead
end for someone sitting at a laptop. Add the Download now primary that
opens ScanToDownloadModal, keep the store pair. Flag-off renders are
untouched: every changed line lives inside the migrationOn && isDesktop
branch.
@vercel

vercel Bot commented Sep 7, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
peanut-wallet Ready Ready Preview Sep 7, 2026 3:12pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Sep 7, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: 801e2f4f-dfc7-4e25-8968-199a245c8948

📥 Commits

Reviewing files that changed from the base of the PR and between 623291d and 6c4267b.

📒 Files selected for processing (1)
  • src/components/LandingPage/LandingPageClient.tsx

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The desktop landing hero now includes a “Download now” button. The button opens a lazily loaded QR scan modal. Existing store badges and supporting text remain visible.

Changes

Landing hero QR download

Layer / File(s) Summary
Modal loading and state
src/components/LandingPage/LandingPageClient.tsx
The landing hero imports Button directly, dynamically imports ScanToDownloadModal, and tracks modal visibility with qrModalOpen.
Desktop CTA and modal flow
src/components/LandingPage/LandingPageClient.tsx
The desktop hero renders the QR download button with the store badges. The modal renders conditionally with visible, onClose, and the landing-hero migration surface.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 6c426

Desktop visitors gain a Download now button that opens the QR download modal while retaining App Store and Google Play links. The change is ready to merge with no identified material risk.

Sequence Diagram(s)

sequenceDiagram
  participant DesktopVisitor
  participant LandingPageClient
  participant ScanToDownloadModal
  DesktopVisitor->>LandingPageClient: Select Download now
  LandingPageClient->>ScanToDownloadModal: Render visible modal
  ScanToDownloadModal-->>DesktopVisitor: Display QR download options
  DesktopVisitor->>ScanToDownloadModal: Close modal
  ScanToDownloadModal->>LandingPageClient: Call onClose
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the desktop hero change, the "Download now" CTA, the QR download flow, and TASK-20600.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hotfix/TASK-20600-hero-desktop-qr

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@notion-workspace

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Sep 7, 2026 •

Copy link
Copy Markdown
Contributor

Code-analysis diff

Painscore total: 7762.68 → 7762.63 (-0.05)
Findings: 0 net (+9 new, -9 resolved)

🆕 New findings (9)

  • critical complexity — src/components/LandingPage/LandingPageClient.tsx — CC 55, MI 57.46, SLOC 219
  • medium high-mdd — src/components/LandingPage/LandingPageClient.tsx:55 — LandingPageClient: MDD 65.9 (uses across many lines from declarations)
  • medium high-dlt — src/components/LandingPage/LandingPageClient.tsx:55 — LandingPageClient: DLT 31 (calls 31 distinct functions — high context load)
  • medium method-complexity — src/components/LandingPage/LandingPageClient.tsx:158 — CC 17 SLOC 39
  • medium react-direct-dom — src/components/LandingPage/LandingPageClient.tsx:160 — direct DOM: document.getElementById
  • low high-mdd — src/components/LandingPage/LandingPageClient.tsx:157 — : MDD 18.6 (uses across many lines from declarations)
  • low high-dlt — src/components/LandingPage/LandingPageClient.tsx:157 — : DLT 15 (calls 15 distinct functions — high context load)
  • low high-mdd — src/components/LandingPage/LandingPageClient.tsx:243 — : MDD 13.0 (uses across many lines from declarations)
  • low missing-return-type — src/components/LandingPage/LandingPageClient.tsx:55 — LandingPageClient: exported fn missing return type annotation

✅ Resolved (9)

  • src/components/LandingPage/LandingPageClient.tsx — CC 51, MI 56.24, SLOC 205
  • src/components/LandingPage/LandingPageClient.tsx:52 — LandingPageClient: MDD 62.3 (uses across many lines from declarations)
  • src/components/LandingPage/LandingPageClient.tsx:52 — LandingPageClient: DLT 30 (calls 30 distinct functions — high context load)
  • src/components/LandingPage/LandingPageClient.tsx:153 — CC 17 SLOC 39
  • src/components/LandingPage/LandingPageClient.tsx:155 — direct DOM: document.getElementById
  • src/components/LandingPage/LandingPageClient.tsx:152 — : MDD 18.6 (uses across many lines from declarations)
  • src/components/LandingPage/LandingPageClient.tsx:152 — : DLT 15 (calls 15 distinct functions — high context load)
  • src/components/LandingPage/LandingPageClient.tsx:238 — : MDD 13.0 (uses across many lines from declarations)
  • src/components/LandingPage/LandingPageClient.tsx:52 — LandingPageClient: exported fn missing return type annotation

@github-actions

github-actions Bot commented Sep 7, 2026 •

Copy link
Copy Markdown
Contributor

🧪 UI test report — ✅ all green

Suites

  • ✅ unit: 4265 ran, 0 failed, 0 skipped, 57.9s

📊 Coverage (unit)

metric %
statements 71.4%
branches 56.3%
functions 62.4%
lines 72.4%
⏱ 10 slowest test cases
time test
2.8s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › never places two stickers in heavy overlap (broad seed sweep)
1.0s src/hooks/query/__tests__/user.test.tsx › does NOT clear a token that rotated mid-request (stale 401 racing a fresh login)
0.9s src/utils/__tests__/crisp.test.ts › resets the native session on logout once support has been opened
0.5s src/app/receipt/[entryId]/pdf/__tests__/receipt-pdf-render.test.ts › produces a real, non-trivial PDF document
0.4s src/utils/__tests__/sentry.utils.test.ts › defaults to the client budget under a browser global
0.4s src/utils/__tests__/crisp.test.ts › settles, and hands back a usable plugin, against a real-shaped plugin proxy
0.4s src/utils/__tests__/crisp.test.ts › configures once across repeated support opens
0.4s src/utils/__tests__/crisp.test.ts › retries configuration on the next open after a failure
0.3s src/components/Card/__tests__/CardTermsScreen.test.tsx › points at the English documents for en
0.3s src/app/(mobile-ui)/withdraw/__tests__/withdraw-states.test.tsx › Bank withdrawal keeps the $1 minimum for sub-$1 amounts
📍 Inline annotations are in the **Unit test report** check above. Coverage artifact: `coverage-unit`. Generated by `.github/workflows/tests.yml`.

@kushagrasarathe

Copy link
Copy Markdown
Contributor Author

/chip review

@chip-peanut-bot chip-peanut-bot Bot 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.

Chip review — no blocking findings — this is not an approval

Clean review: the desktop migration CTA opens the existing scan-to-download modal without changing the flag-off or mobile paths.

Checked clean

  • Exact head, supplied base, and merge base match; the diff changes only LandingPageClient.tsx.
  • Flag-on desktop behavior: Download now mounts the existing ScanToDownloadModal, close paths unmount it, and the QR-shown event uses landing_hero.
  • Responsive and feature-flag branches: the new control is limited to migrationOn plus DeviceType.WEB; flag-off and phone CTA behavior are unchanged.
  • QR destination and loading: the existing DownloadQR encodes the serving origin plus /app, and the dynamically imported modal is rendered only after the click.
  • Security and trust boundaries: this UI-only change adds no auth, authorization, secret, amount, or outbound-data surface.
  • Exact-head CI passed aggregate ci-success, typecheck, unit, e2e, eslint, format, human-authors, review, CodeQL, and action analysis; Deploy Preview was still in progress when checked.

Security review: did not run — this change has no security, privacy or money surface, so it was not asked. This review is one reviewer short.

Third opinion by claude-opus: 0 finding(s), marked with the model name. It answers only product truth, missing tests and the cross-repo contract, so treat its findings as advice.

Exact head: 6c4267bc2677 · Context: repo · Took 6m

…the modal

Kush's review: three CTAs on the hero is noise; the modal already carries
the store links under the QR.

@chip-peanut-bot chip-peanut-bot Bot 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.

Chip review — no blocking findings — this is not an approval

No actionable defects found in the desktop landing-hero QR modal change.

Checked clean

  • Verified the supplied head and merge base exactly match the detached worktree and PR metadata.
  • Checked migration-flag and device branches: flag-off and mobile behavior remain unchanged, while desktop flag-on opens the existing scan-to-download modal.
  • Checked Hero custom CTA composition, button behavior, modal close lifecycle, smart /app QR construction, store badges, and landing_hero analytics attribution.
  • Checked exact-head CI: unit, e2e, typecheck, eslint, format, CodeQL, and workflow analysis checks were successful; deployment and aggregate reporting were still in progress.
  • Ran git diff --check with no whitespace errors.

Security review: did not run — this change has no security, privacy or money surface, so it was not asked. This review is one reviewer short.

Third opinion by claude-opus: 0 finding(s), marked with the model name. It answers only product truth, missing tests and the cross-repo contract, so treat its findings as advice.

Exact head: d0d04e5d8f35 · Context: repo · Took 6m

@0xkkonrad 0xkkonrad 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.

rubberstamping this as i am not qualified to do reviews

This branch was successfully deployed

1 active and 1 inactive deployments
Preview — d0d04e5d Deployed Sep 7, 2026 by vercel[bot]
content-publish — d0d04e5d Deployed Sep 7, 2026 by kushagrasarathe via approve-and-merge #3194
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.

2 participants