Add "Don't have Bitcoin?" Cash App prompt to campaign pages

This commit is contained in:
Alex Gleason
2026-06-25 15:32:00 +03:00
parent 9bfc3498da
commit 059dff3686
2 changed files with 73 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
import { openUrl } from '@/lib/downloadFile';
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
interface NoBitcoinDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
}
/**
* For donors who don't already hold Bitcoin. Rather than a wall of
* instructions, this is a simple "get it here" surface — a single branded
* Cash App badge (styled like the App Store / Google Play badges) that
* deep-links to cash.app, where the donor can buy Bitcoin and send it on.
* Agora never custodies or converts funds; this just points at a mainstream
* on-ramp the donor controls.
*/
export function NoBitcoinDialog({ open, onOpenChange }: NoBitcoinDialogProps) {
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-sm rounded-2xl">
<DialogHeader>
<DialogTitle>No Bitcoin yet?</DialogTitle>
<DialogDescription>
Buy Bitcoin in Cash App, then send it to this campaign.
</DialogDescription>
</DialogHeader>
<button
type="button"
onClick={() => void openUrl('https://cash.app')}
aria-label="Get Cash App"
className="group flex w-full items-center gap-4 rounded-2xl bg-[#00D632] px-5 py-4 text-left text-white shadow-sm transition-transform hover:scale-[1.02] active:scale-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#00D632] focus-visible:ring-offset-2"
>
<span
aria-hidden
className="flex size-12 shrink-0 items-center justify-center rounded-2xl bg-white/20 text-3xl font-bold leading-none"
>
$
</span>
<span className="flex flex-col">
<span className="text-xs font-medium uppercase tracking-wide text-white/80">
Get it on
</span>
<span className="text-xl font-semibold leading-tight">Cash App</span>
</span>
</button>
</DialogContent>
</Dialog>
);
}
+17
View File
@@ -24,6 +24,7 @@ import {
} from '@/components/CampaignWalletDonatePanel';
import { HDSendBitcoinDialog } from '@/components/HDSendBitcoinDialog';
import { Lightbox } from '@/components/ImageGallery';
import { NoBitcoinDialog } from '@/components/NoBitcoinDialog';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton';
@@ -1080,6 +1081,7 @@ function DonateColumn({
const { user } = useCurrentUser();
const hdAccess = useHdWalletAccess();
const [sendOpen, setSendOpen] = useState(false);
const [noBitcoinOpen, setNoBitcoinOpen] = useState(false);
const isSilentPayment = !campaign.wallets.onchain;
// The in-app "Pay with Agora" button opens HDSendBitcoinDialog
@@ -1199,6 +1201,20 @@ function DonateColumn({
</Button>
</div>
}
{/* For donors who don't already hold Bitcoin: a low-emphasis text
link (no button chrome) that opens an instructional dialog
pointing at a mainstream on-ramp. Kept visually quiet so it
never competes with the primary on-chain CTA above. */}
<div className="text-center">
<button
type="button"
onClick={() => setNoBitcoinOpen(true)}
className="text-xs text-muted-foreground underline-offset-2 hover:text-foreground hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-sm transition-colors"
>
Don't have Bitcoin?
</button>
</div>
</CardContent>
{canPayInApp && campaign.wallets.onchain && (
<HDSendBitcoinDialog
@@ -1219,6 +1235,7 @@ function DonateColumn({
}
/>
)}
<NoBitcoinDialog open={noBitcoinOpen} onOpenChange={setNoBitcoinOpen} />
</Card>
);
}