Skip to content

fix(setup): replace desktop Install App modal with inline QR code#1751

Open
chip-peanut-bot[bot] wants to merge 103 commits intodevfrom
chip/desktop-setup-inline-qr
Open

fix(setup): replace desktop Install App modal with inline QR code#1751
chip-peanut-bot[bot] wants to merge 103 commits intodevfrom
chip/desktop-setup-inline-qr

Conversation

@chip-peanut-bot
Copy link
Contributor

Problem

On desktop, the setup flow shows a misleading "Install App" button. The QR-to-mobile flow is buried in a modal that auto-opens and gets dismissed — after which the user is left with a dead-end button.

Flagged by @kkonrad in #desktop thread.

Changes

  • Inline QR code on the main setup screen for desktop users (no more modal)
  • Updated copy: "Peanut works best on your phone" / "Scan the QR code to get started on mobile — it takes 30 seconds"
  • "Continue on desktop" as subtle underlined text link (not a primary button)
  • Removed unused Modal import, showModal state, and iOS modal auto-open timer (was dead code — iOS uses ForceIOSPWAInstall instead)
  • Skip button in top nav remains as-is

Benefits

  • 🎯 Pushes users toward mobile without a dismissable modal they'll ignore
  • 🧹 No confusing "Install App" on desktop
  • 📱 QR code is persistent and visible
  • 🔓 Desktop users not blocked — subtle continue + skip still work
  • ♻️ Zero new components — reuses DesktopInstructions, QRCodeWrapper, StepTitle

Screenshots

Mockup of the new desktop view:

desktop-mockup

(See Discord thread for mockup screenshot)

chip-peanut-bot bot and others added 30 commits March 9, 2026 12:17
…le-use

copy: clarify reference code is one-time use
copy: update landing page — YOUR MONEY. YOUR RULES.
- Change new user node color from blue to green to match legend
- Debounce topNodes slider (500ms) to prevent refetch on every tick
- Pass includeNewDays to backend so new users always appear regardless of topNodes filter
docs.peanut.me was redirecting to peanut.me (homepage) instead of
/en/help. Add host-based redirect to route docs subdomain traffic
to the help center.
…tent submodule

- SEOFooter: filter hardcoded link lists against actual COUNTRIES_SEO/
  COMPETITORS/EXCHANGES data so broken links never render
- deposit/compare/receive-money-from pages: remove React fallback
  rendering paths (all content now has MDX), require MDX or 404
- Delete dead code: ComparisonTable.tsx, ReceiveMoneyContent.tsx
- Update content submodule to include 32 new content files (8 country
  hubs, 8 send-to pages, 15 exchange deposit guides, 1 Chile entity)
Use displaySettingsRef to read current activityFilter.activityDays
so includeNewDays always reflects the latest value without adding
activityFilter to the useEffect dependency array.
fix: full-graph new users render green + debounce topNodes slider
Prevents FOUC where the page shell (hero + footer) renders
with a blank gap while HelpLanding client component hydrates.
The old JoinWaitlistPage gated the invite code input behind
isPermissionGranted, permanently trapping users who denied notifications.

New flow:
1. Email collection (required) — saved via updateUserById server action
2. Enable notifications (skippable) — soft prompt with "Not now" link
3. Jail screen — always shows invite code input regardless of notification state

Also adds a subtle notification banner on the jail screen for users who
skipped step 2.
…module

- generateMetadata() now checks for published MDX content before
  emitting canonical/hreflang tags (mirrors compare and deposit pages)
- Content submodule updated with CR fixes: diacritics, broken links,
  TBD placeholders
The previous commit replaced all docs.peanut.me links with /en/help
too aggressively — losing deep link paths and removing target="_blank"
from contextual links (tooltips, setup flows, modals, error views).

Navigation links (footer, sidebar) correctly stay as /en/help in same
tab. Contextual links now open in new tabs with proper article slugs:
- tooltips, limits → /en/help/transaction-limits
- passkey setup/test → /en/help/passkeys
- payment error → /en/help/request-money
- regulated rails → /en/help/transaction-limits
- early user modal → /en/help (new tab)
Footer.tsx is imported by client-routed pages (e.g. /exchange), so
importing @/data/seo (which depends on fs via @/lib/content) breaks
the webpack build. Revert to inlined data with all 8 countries that
now have published content. Updated comment explains the constraint.
Remove duplicated testing/formatting sections — that info now lives
in CONTRIBUTING.md. README stays focused on setup and project context.
Signed-off-by: Hugo Montenegro <hugo@peanut.to>
Add CONTRIBUTING.md as single source of truth for dev rules
Previous PR gitignored the symlinks, meaning devs had to create them
manually. Now CLAUDE.md, AGENTS.md, .cursorrules, .windsurfrules, and
.github/copilot-instructions.md are tracked symlinks pointing to
CONTRIBUTING.md.
- validateInviteCode: wrap in try/finally so isLoading always clears
- handleLogout: wrap in try/finally so isLoggingOut always clears
- Email input: add aria-label for accessibility
- Step 1: email collection (required, server action)
- Step 2: enable notifications (skippable)
- Step 3: jail screen with invite code input (always accessible)

Uses useQueryState from nuqs for step management, matching the
codebase convention for multi-step flows. Step survives refresh,
supports deep-linking, and reacts to auth state changes via useEffect.

Fixes bug where users got permanently stuck on "Enable notifications"
screen when denying permission.
chip-peanut-bot bot and others added 25 commits March 11, 2026 11:02
Changes per LP audit (Notion):
- Move stats fold (YourMoney) up after MercadoPago/PIX fold
- Hero: TAP.SEND → TAP.SCAN, cities → Buenos Aires/São Paulo/Mexico City, add "No local ID" line
- Waitlist subtext → "Join +10,000 happy users"
- Add "Works with" label above bank/partner logo marquee
- Add sticky mobile CTA bar (hides near existing CTAs)
- Curate Wall of Love to 11 shortlisted tweets per audit
…weets

Changes:
- Replace hero SVG image with HTML using knerd font (Title component)
- Hero subtitle: RECEIVE. PAY. ANYWHERE.
- Waitlist subtext: cool people (not happy users)
- MercadoPago fold: new copy per Notion audit
- Wall of Love: expanded from 11 to 17 curated tweets
- Replace SVG with new "GLOBAL CASH LOCAL FEEL" PNG from Konrad
- Subtitle: TAP. SCAN. ANYWHERE.
- Cities: Buenos Aires. São Paulo. Floripa.
- Add "No local id or bank required" tiny line
…(624:276)

The new PNG has a different aspect ratio. Wrapping in a container with
the original 624:276 ratio + object-fit:contain keeps the peanut mascot
overlap balanced across all breakpoints.
…bottom

- Renamed GET PEANUT → SIGN UP NOW
- Hide bar at page bottom to prevent scroll-back blocking
- Added pointer-events-none on container so touch events pass through
- Only show after scrolling past hero (300px)
- New PNG from Konrad matching original dimensions
- Subtitle: TAP. SCAN. ANYWHERE.
- Cities: Buenos Aires. São Paulo. Floripa.
- No local ID or bank required.
- PeanutMascot component measures h2 position and places itself
  so only 3% of its height (feet) overlaps the subtitle
- Subtitle: TAP. SCAN. ANYWHERE.
- Cities: Buenos Aires. São Paulo. Floripa.
- No local ID or bank required.
- Fix StickyMobileCTA flickering: add rAF throttle, change guard
  (lastVisible ref), and increase atBottom threshold from 20→100px
  for momentum scroll
- Use variant="purple" on sticky CTA button per design system
- Remove unused useState import from hero.tsx
- Fix PeanutMascot comment (3% → 6% to match code)
- Remove trailing space in RegulatedRails className
Show after hero, hide at page bottom. No more hiding near section CTAs —
that logic caused the flickering.
All 77 tweets preserved with visible: true/false. Only 17 visible ones
shown in carousel. Hidden tweets can be re-enabled by flipping the flag.
feat: landing page audit — reorder, copy, sticky CTA, curate tweets
On desktop, the setup flow showed a misleading 'Install App' button
with a modal containing the mobile QR code. This replaces it with:

- Inline QR code + 'Peanut works best on your phone' copy
- Subtle 'Continue on desktop' text link (not a primary button)
- Removes unused Modal import and showModal state

Pushes users toward mobile without blocking desktop access.
@vercel
Copy link

vercel bot commented Mar 16, 2026

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

Project Deployment Actions Updated (UTC)
peanut-wallet Ready Ready Preview, Comment Mar 16, 2026 10:34am

Request Review

DesktopInstructions was rendering its own title+description+icon below
the SetupWrapper title/description, causing a double header.

Fixes:
- Strip title/icon/description from DesktopInstructions (just QR now)
- Update pwa-install step copy in consts to work for both mobile+desktop
- Remove unused StepTitle, Icon, Modal imports
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