From 07e3561053323d5432e0f465dab65aaf0b2cc24d Mon Sep 17 00:00:00 2001 From: Annakaee Date: Mon, 27 Jul 2026 23:50:42 +0100 Subject: [PATCH] feat(frontend): add WhatsApp share button for claim links (closes #150) --- docs/EXPERIMENTS.md | 26 +++++++ .../send-form/steps/confirm-step.tsx | 27 +++++-- frontend/components/share-prompt.test.tsx | 20 ++++++ frontend/components/share-prompt.tsx | 72 ++++++++++++------- 4 files changed, 113 insertions(+), 32 deletions(-) create mode 100644 docs/EXPERIMENTS.md create mode 100644 frontend/components/share-prompt.test.tsx diff --git a/docs/EXPERIMENTS.md b/docs/EXPERIMENTS.md new file mode 100644 index 0000000..23a1f71 --- /dev/null +++ b/docs/EXPERIMENTS.md @@ -0,0 +1,26 @@ +# Bridgelet Frontend Experiments + +This document records experimental features built for the Bridgelet reference UI. + +--- + +## Experiment 1: WhatsApp Share Button for Claim Links (Issue #150) +- **Goal**: Enable direct messaging sharing of payment claim URLs via WhatsApp (`wa.me`). +- **Target Markets**: Primary communication channel for African and LatAm disbursement flows. +- **Implementation**: `frontend/components/share-prompt.tsx` and `ConfirmStep` render deep links: + ```text + https://wa.me/?text=Send%20and%20claim%20crypto%20payments%3A%20 + ``` + +--- + +## Experiment 2: Multi-Chain Support UI Stubs (Issue #152) +- **Goal**: Provide UI placeholders for future EVM & Soroban multi-chain payment flows while maintaining active Stellar functionality. +- **Implementation**: `ChainSelector` (`frontend/components/chain-selector.tsx`) displays Stellar (active) alongside disabled options for Ethereum, Polygon, and Soroban with `[Coming Soon]` badges. + +--- + +## Experiment 3: Web NFC Tap to Share (Issue #154) +- **Goal**: Allow event organizers and community leaders to write claim URLs directly onto NFC cards/tags via mobile devices. +- **Browser Compatibility**: Utilizes the Web NFC API (`NDEFReader`). Supported natively on Android Chrome. +- **Implementation**: `NfcShareButton` (`frontend/components/nfc-share-button.tsx`) detects browser support, requests NFC write permissions, and writes URL records to nearby tags upon user interaction. diff --git a/frontend/components/send-form/steps/confirm-step.tsx b/frontend/components/send-form/steps/confirm-step.tsx index a51f56d..a3d3bee 100644 --- a/frontend/components/send-form/steps/confirm-step.tsx +++ b/frontend/components/send-form/steps/confirm-step.tsx @@ -28,17 +28,32 @@ export function ConfirmStep({ state, onBack }: ConfirmStepProps) { } if (submitted) { + const claimLink = typeof window !== 'undefined' ? `${window.location.origin}/claim` : 'https://bridgelet.org/claim'; + const whatsappUrl = `https://wa.me/?text=${encodeURIComponent(`Here is your payment claim link via Bridgelet: ${claimLink}`)}`; + return (
-

Payment sent!

-

- A claim link has been sent to {state.recipientEmail}. They have 24 - hours to claim their funds. -

+
+

Payment sent!

+

+ A claim link has been generated for {state.recipientEmail}. They have 24 + hours to claim their funds. +

+
+
+ + Share via WhatsApp + +
); } diff --git a/frontend/components/share-prompt.test.tsx b/frontend/components/share-prompt.test.tsx new file mode 100644 index 0000000..e44a304 --- /dev/null +++ b/frontend/components/share-prompt.test.tsx @@ -0,0 +1,20 @@ +import { render, screen } from '@testing-library/react'; +import { SharePrompt } from './share-prompt'; + +describe('SharePrompt', () => { + it('renders WhatsApp share link with wa.me deep link format', () => { + const testUrl = 'https://bridgelet.org/claim?token=123'; + render(); + + const whatsappLink = screen.getByRole('link', { name: /share on whatsapp/i }); + expect(whatsappLink).toBeInTheDocument(); + expect(whatsappLink).toHaveAttribute( + 'href', + expect.stringContaining('https://wa.me/?text=') + ); + expect(whatsappLink).toHaveAttribute( + 'href', + expect.stringContaining(encodeURIComponent(testUrl)) + ); + }); +}); diff --git a/frontend/components/share-prompt.tsx b/frontend/components/share-prompt.tsx index 59f1472..a979bb0 100644 --- a/frontend/components/share-prompt.tsx +++ b/frontend/components/share-prompt.tsx @@ -1,6 +1,7 @@ 'use client'; import { useState } from 'react'; +import { NfcShareButton } from './nfc-share-button'; type SharePromptProps = { appUrl: string; @@ -19,16 +20,22 @@ export function SharePrompt({ appUrl }: SharePromptProps) { } } + const shareText = encodeURIComponent(`Send and claim crypto payments seamlessly with Bridgelet: ${appUrl}`); + const whatsappUrl = `https://wa.me/?text=${shareText}`; + return ( -
-

- Do you send payments to your team or community? -

-

- Bridgelet lets anyone send funds to recipients who have no crypto wallet — they claim - directly from a link. Share it with employers, payroll managers, or community leaders. -

-
+
+
+

+ Do you send payments to your team or community? +

+

+ Bridgelet lets anyone send funds to recipients who have no crypto wallet — they claim + directly from a link. Share it with employers, payroll managers, or community leaders. +

+
+ +
{appUrl} @@ -40,23 +47,36 @@ export function SharePrompt({ appUrl }: SharePromptProps) { {copied ? 'Copied!' : 'Copy link'}
- );