Skip to content

Add referral link copy fallback - #130

Closed
absalonCRC wants to merge 1 commit into
profullstack:masterfrom
absalonCRC:fix-referral-copy-fallback
Closed

Add referral link copy fallback#130
absalonCRC wants to merge 1 commit into
profullstack:masterfrom
absalonCRC:fix-referral-copy-fallback

Conversation

@absalonCRC

@absalonCRC absalonCRC commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary

  • guard referral link copying when navigator.clipboard.writeText is unavailable or rejects
  • fall back to a temporary textarea copy path for blocked Clipboard API contexts
  • show a manual-copy error if both copy paths fail
  • add dashboard referral regression coverage for rejected clipboard writes and failed fallback copying

Fixes #129

Validation

  • pnpm test:run src/app/dashboard/referrals/page.test.tsx
  • pnpm type-check
  • pnpm exec eslint src/app/dashboard/referrals/page.tsx src/app/dashboard/referrals/page.test.tsx
  • git diff --check

Bounty / payment

Submitted for the active uGig affiliate-program testing task. SOL receive address: 27sdMYXofqoM9qR13bZhccRNYeEgYn5EoHXTSJn4QWKP.

Payment fallback: PayPal cultofrozen@gmail.com

@greptile-apps

greptile-apps Bot commented May 23, 2026

Copy link
Copy Markdown

Greptile Summary

This PR guards navigator.clipboard.writeText behind a capability check and catch block, falling back to the deprecated document.execCommand("copy") textarea approach, and surfacing a manual-copy error message when both paths fail. Two regression tests cover the rejection and full-failure paths.

  • Fallback logic (page.tsx): copyText correctly tries the Clipboard API first, silently catches failures, then attempts the textarea approach, throwing on execCommand returning false.
  • Error state placement (page.tsx): The error state is shared between the copy and send-invites flows; the only render site for the error is inside the Send Invites card, so clipboard errors appear in the wrong section and clicking Copy silently clears any existing send-invites error.
  • Test coverage (page.test.tsx): New tests mock both failure modes and assert the expected UI states; they pass regardless of error placement because getByText is DOM-position-agnostic.

Confidence Score: 3/5

The fallback copy logic itself is functionally sound, but the copy error message appears inside the Send Invites card rather than near the Copy button, and clicking Copy clears any unrelated send-invites error — both of which affect real user-facing behavior.

The core copyText helper works correctly for all three paths (Clipboard API success, Clipboard API rejection with execCommand fallback, full failure). The defect is in how the result is communicated back to the user: the shared error state renders only inside the Send Invites section, so a copy failure produces no visible feedback near the button that was clicked, and clicking Copy actively discards any pre-existing invite error. These are present, observable defects in the changed UI flow.

src/app/dashboard/referrals/page.tsx — the error state and its render site need to be scoped to their respective operations

Important Files Changed

Filename Overview
src/app/dashboard/referrals/page.tsx Adds copyText helper with Clipboard API + textarea execCommand fallback; wires copyLink with try/catch. Copy error message is rendered in the wrong UI section (Send Invites card) because error state is shared.
src/app/dashboard/referrals/page.test.tsx New test file covering rejected clipboard write and failed fallback; both scenarios are correctly mocked. Tests pass even though the error message is in the wrong DOM section because getByText finds it regardless of position.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User clicks Copy] --> B[setError null]
    B --> C[copyText called]
    C --> D{navigator.clipboard\n?.writeText exists?}
    D -- Yes --> E[navigator.clipboard.writeText]
    E -- Success --> F[return]
    E -- Throws --> G[catch: fall through]
    D -- No --> H[textarea fallback]
    G --> H
    H --> I[document.body.appendChild textarea]
    I --> J[textarea.select]
    J --> K[document.execCommand copy]
    K -- returns true --> L[remove textarea\nreturn]
    K -- returns false --> M[throw Error\nremove textarea]
    F --> N[setCopied true\nsetTimeout reset]
    L --> N
    M --> O[catch in copyLink]
    O --> P[setCopied false\nsetError shown in\nSend Invites card ⚠️]
Loading

Comments Outside Diff (1)

  1. src/app/dashboard/referrals/page.tsx, line 223-225 (link)

    P1 Copy error rendered in wrong section

    The error state is shared between the copy operation and the send-invites flow. When copyText throws, setError("Unable to copy referral link...") is called, but the only {error && ...} render block sits inside the Send Invites card (lines 223-225), not inside the Referral Link card. A user who clicks Copy and gets a failure will see no feedback near the Copy button; the red message silently appears far below in a different panel, which is easy to miss. Additionally, clicking Copy calls setError(null) at line 93, so any pre-existing send-invites error (e.g. "Please enter at least one email address") gets silently cleared the moment the user clicks Copy.

Reviews (1): Last reviewed commit: "Add referral link copy fallback" | Re-trigger Greptile

@ralyodio ralyodio closed this May 23, 2026
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.

bug: invite referral copy button fails when clipboard API is blocked

2 participants