Skip to content

feat: share badge from the detail modal (per-badge share copy) - #2609

Merged
abalinda merged 2 commits into
devfrom
feat/badge-share-modal-refresh
Aug 5, 2026
Merged

feat: share badge from the detail modal (per-badge share copy)#2609
abalinda merged 2 commits into
devfrom
feat/badge-share-modal-refresh

Conversation

@0xkkonrad

@0xkkonrad 0xkkonrad commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

This supersedes #2382, rebuilt directly on the current dev tip after the original branch became 775 commits stale and conflicted with the current badge/i18n work.

  • Replaces the badge detail modal's dismiss CTA with the localized Share Achievement action while retaining the top-right close control.
  • Shares the holder's public profile from all three entry points: Your Badges, the unlock drawer, and the earned-badge toast.
  • Keeps badge metadata and bespoke English share copy in the canonical BADGES catalog. The current 45-code catalog has 42 bespoke lines; CERTIFIED_YAPPER, TOKEN_NATION_SP_2026, and FESTA_JUNINA_2026 intentionally use the localized generic fallback.
  • Preserves the existing translated generic share copy outside English rather than shipping unreviewed translations.
  • Includes current catalog additions such as MANICERO and corrects OFFRAMP_USER copy for the current migration flow.
  • Prevents the shared ShareButton from reporting success or closing its parent when clipboard copy fails and native sharing is unavailable, including the legacy execCommand('copy') === false path.

Risks / breaking changes

  • Frontend-only: no API, schema, or money-state changes.
  • Bespoke lines are English-only by design; other locales retain their translated generic message.
  • The shared ShareButton now treats a failed desktop copy with no native-share support as an error instead of a false success.

QA

  • Current with dev: 2 commits ahead, 0 behind; GitHub reports the PR mergeable and clean.
  • Commit signatures: valid and GitHub-verified.
  • Repository-wide Prettier check — pass.
  • corepack pnpm typecheck — pass.
  • Full Jest run — 192/192 suites; 2,508 passed, 3 skipped, 0 failed (2,511 total).
  • GitHub CI — format, ESLint, typecheck, unit, e2e, analysis, report, Deploy Preview, and Vercel all pass.
  • git diff --check — pass.

Manual verification checklist

  1. Profile → Your Badges → open a badge → Share Achievement.
  2. Confirm English uses the badge-specific line and the holder's public profile URL.
  3. Confirm a non-English locale and an intentionally unmapped badge use the existing localized generic copy.
  4. Confirm clipboard failure without native sharing leaves the modal open and displays the failure toast.

Screenshots: NONE — the deployed /badges route is auth-protected, and its web build cannot activate the native-only demo user fixture. A safe Playwright attempt therefore remained behind the auth/loading redirect before the first badge rendered. Local preview compilation was also killed by the shared host's earlyoom daemon. The rendered modal, generated copy, successful close behavior, and failure-stays-open behavior are covered by component tests; the deployed Vercel build itself is green.

Rebuild the stale badge-sharing change on the current dev tree, keep bespoke English badge copy in the canonical badge catalog, preserve localized fallbacks, and keep failed desktop shares open.
@vercel

vercel Bot commented Aug 5, 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 Aug 5, 2026 11:07am

Request Review

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Badge sharing now supports badge-specific English copy, localized fallback text, profile URLs, and badge codes across detail views. ShareButton reports copy failures and cleans up fallback DOM elements.

Changes

Badge sharing flow

Layer / File(s) Summary
Badge share content
src/components/Badges/badge.utils.ts, src/components/Badges/__tests__/badge.utils.test.ts
Badge metadata now includes share lines. getBadgeShareText selects localized fallback or badge-specific English text and appends the profile URL.
Share failure handling
src/components/Global/ShareButton/index.tsx, src/components/Global/ShareButton/__tests__/ShareButton.test.tsx
Clipboard fallback elements are removed in finally. Failed copy operations trigger error handling instead of success callbacks.
Badge modal sharing
src/components/Badges/BadgeDetailModal.tsx, src/components/Badges/BadgeEarnToast.tsx, src/components/Badges/BadgeStatusDrawer.tsx, src/components/Badges/index.tsx, src/components/Badges/__tests__/*
Badge codes now flow into the detail modal. The modal builds localized share text and uses ShareButton to close after successful sharing.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: hugo0, innolope-dev

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. 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 accurately describes the primary badge-sharing change in the detail modal, including per-badge share copy.
✨ 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 feat/badge-share-modal-refresh

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.

@0xkkonrad

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Code-analysis diff

Painscore total: 7008.7 → 7011.92 (+3.22)
Findings: +2 net (+17 new, -15 resolved)

🆕 New findings (17)

  • high hotspot — src/components/Badges/badge.utils.ts — 38 commits, +438/-116 lines since 6 months ago
  • high complexity — src/components/Badges/badge.utils.ts — CC 15, MI 45.02, SLOC 204
  • medium high-mdd — src/components/Badges/BadgeStatusDrawer.tsx:26 — BadgeStatusDrawer: MDD 41.9 (uses across many lines from declarations)
  • medium high-mdd — src/components/Badges/BadgeEarnToast.tsx:34 — BadgeEarnToast: MDD 32.5 (uses across many lines from declarations)
  • medium complexity — src/components/Global/ShareButton/index.tsx — CC 28, MI 50.12, SLOC 83
  • medium high-mdd — src/components/Global/ShareButton/index.tsx:29 — ShareButton: MDD 27.9 (uses across many lines from declarations)
  • medium high-mdd — src/components/Badges/index.tsx:20 — Badges: MDD 26.5 (uses across many lines from declarations)
  • medium method-complexity — src/components/Global/ShareButton/index.tsx:73 — CC 19 SLOC 47
  • medium complexity — src/components/Badges/BadgeEarnToast.tsx — CC 16, MI 58.81, SLOC 80
  • medium complexity — src/components/Badges/BadgeStatusDrawer.tsx — CC 10, MI 60.4, SLOC 52
  • medium complexity — src/components/Badges/BadgeDetailModal.tsx — CC 4, MI 65, SLOC 24
  • medium react-direct-dom — src/components/Global/ShareButton/index.tsx:55 — direct DOM: document.createElement
  • low high-mdd — src/components/Badges/BadgeEarnToast.tsx:45 — : MDD 17.8 (uses across many lines from declarations)
  • low high-dlt — src/components/Badges/BadgeStatusDrawer.tsx:26 — BadgeStatusDrawer: DLT 15 (calls 15 distinct functions — high context load)
  • low high-mdd — src/components/Global/ShareButton/index.tsx:73 — : MDD 13.4 (uses across many lines from declarations)
  • low high-mdd — src/components/Global/ShareButton/index.tsx:46 — copyTextToClipboardWithFallback: MDD 10.8 (uses across many lines from declarations)
  • low missing-return-type — src/components/Badges/BadgeDetailModal.tsx:23 — BadgeDetailModal: exported fn missing return type annotation

✅ Resolved (15)

  • src/components/Badges/badge.utils.ts — 37 commits, +375/-116 lines since 6 months ago
  • src/components/Badges/badge.utils.ts — CC 10, MI 46.25, SLOC 157
  • src/components/Badges/BadgeStatusDrawer.tsx:26 — BadgeStatusDrawer: MDD 37.4 (uses across many lines from declarations)
  • src/components/Badges/BadgeEarnToast.tsx:34 — BadgeEarnToast: MDD 32.2 (uses across many lines from declarations)
  • src/components/Badges/index.tsx:20 — Badges: MDD 25.6 (uses across many lines from declarations)
  • src/components/Global/ShareButton/index.tsx — CC 26, MI 51.25, SLOC 76
  • src/components/Global/ShareButton/index.tsx:29 — ShareButton: MDD 23.6 (uses across many lines from declarations)
  • src/components/Global/ShareButton/index.tsx:71 — CC 17 SLOC 41
  • src/components/Badges/BadgeEarnToast.tsx — CC 16, MI 59.06, SLOC 79
  • src/components/Badges/BadgeStatusDrawer.tsx — CC 10, MI 61.62, SLOC 47
  • src/components/Global/ShareButton/index.tsx:53 — direct DOM: document.createElement
  • src/components/Badges/BadgeEarnToast.tsx:45 — : MDD 17.3 (uses across many lines from declarations)
  • src/components/Badges/BadgeDetailModal.tsx:19 — BadgeDetailModal: MDD 13.0 (uses across many lines from declarations)
  • src/components/Global/ShareButton/index.tsx:71 — : MDD 11.1 (uses across many lines from declarations)
  • src/components/Badges/BadgeDetailModal.tsx:19 — BadgeDetailModal: exported fn missing return type annotation

📈 Painscore deltas (top movers)

File Before After Δ
src/components/Global/ShareButton/index.tsx 13.2 14.2 +0.9
src/components/Badges/badge.utils.ts 11.4 12.1 +0.7
src/components/Badges/BadgeStatusDrawer.tsx 8.9 9.6 +0.6
src/components/Badges/BadgeDetailModal.tsx 6.5 7.2 +0.6

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

🧪 UI test report — ✅ all green

Suites

  • unit: 2511 ran, 0 failed, 0 skipped, 39.9s

📊 Coverage (unit)

metric %
statements 62.7%
branches 46.0%
functions 51.8%
lines 63.3%
⏱ 10 slowest test cases
time test
3.7s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › never places two stickers in heavy overlap (broad seed sweep)
1.0s src/utils/__tests__/demo-api.test.ts › isDemoMode() is false when not running under Capacitor
0.4s src/app/actions/__tests__/api-headers.test.ts › should include Content-Type in validateInviteCode
0.4s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › every sticker stays within canvas at any count
0.3s src/utils/__tests__/sentry.utils.test.ts › defaults to the client budget under a browser global
0.3s src/app/actions/__tests__/api-headers-extended.test.ts › should not include apiKey in validateInviteCode body
0.3s src/app/(mobile-ui)/withdraw/__tests__/withdraw-states.test.tsx › Bank withdrawal keeps the $1 minimum for sub-$1 amounts
0.3s src/utils/__tests__/sentry.utils.test.ts › still lets a per-call timeoutMs win over the default
0.3s src/utils/__tests__/auth-token.test.ts › does not let a stale stored value overwrite a token set during hydration
0.3s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › keeps stickers off the username pill (final pass respects the keep-out)
📍 Inline annotations are in the **Unit test report** check above. Coverage artifact: `coverage-unit`. Generated by `.github/workflows/tests.yml`.

Treat execCommand returning false as a failed copy, clean up the temporary textarea in all paths, and keep callers open when no share mechanism succeeds.
@0xkkonrad

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@abalinda
abalinda merged commit 9d17a5e into dev Aug 5, 2026
20 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.

2 participants