import { useState, useMemo } from 'react'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Textarea } from '@/components/ui/textarea'; import { Label } from '@/components/ui/label'; import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'; import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; import { useCurrentUser } from '@/hooks/useCurrentUser'; import { useAuthor } from '@/hooks/useAuthor'; import { useWallet } from '@/hooks/useWallet'; import { useCrewZap, splitAmount, type CrewZapResult } from '@/hooks/useCrewZap'; import { useToast } from '@/hooks/useToast'; import { genUserName } from '@/lib/genUserName'; import { useTranslation } from '@/contexts/language'; import { Zap, Check, Copy, Loader2, X, Users, AlertCircle } from 'lucide-react'; const PRESETS = [210, 500, 1000, 2100, 5000]; interface ZapCrewDialogProps { crewName: string; /** Recipient pubkeys — typically founder + confirmed members. */ recipients: string[]; children: React.ReactNode; } function RecipientRow({ result }: { result: CrewZapResult }) { const { t } = useTranslation(); const author = useAuthor(result.pubkey); const meta = author.data?.metadata; const name = meta?.name ?? genUserName(result.pubkey); const { toast } = useToast(); const copyInvoice = async () => { if (!result.invoice) return; await navigator.clipboard.writeText(result.invoice); toast({ title: t('walletUi.zapCrew.invoiceCopied'), description: t('walletUi.zapCrew.invoiceCopiedDesc') }); }; return (
{name.slice(0, 2).toUpperCase()}

{name}

{result.amount.toLocaleString()} sats

); } function StatusPill({ result, onCopy }: { result: CrewZapResult; onCopy: () => void }) { const { t } = useTranslation(); switch (result.status) { case 'success': return {t('walletUi.zapCrew.sent')}; case 'resolving': case 'paying': return {result.status === 'paying' ? t('walletUi.zapCrew.paying') : t('walletUi.zapCrew.resolving')}; case 'skipped': return {t('walletUi.zapCrew.skipped')}; case 'failed': return result.invoice ? ( ) : ( {t('walletUi.zapCrew.failed')} ); default: return {t('walletUi.zapCrew.waiting')}; } } export function ZapCrewDialog({ crewName, recipients, children }: ZapCrewDialogProps) { const { t } = useTranslation(); const [open, setOpen] = useState(false); const { user } = useCurrentUser(); const { preferredMethod } = useWallet(); const { zapCrew, results, isRunning, reset } = useCrewZap(); const [amount, setAmount] = useState(1000); const [comment, setComment] = useState(''); // Don't include the current user as a recipient (no zapping yourself). const payable = useMemo( () => recipients.filter((pk) => pk !== user?.pubkey), [recipients, user?.pubkey] ); const numAmount = typeof amount === 'string' ? parseInt(amount, 10) || 0 : amount; const perHead = payable.length > 0 ? splitAmount(numAmount, payable.length) : []; const started = results.length > 0; const doneCount = results.filter((r) => r.status === 'success').length; const allDone = started && !isRunning; const handleZap = () => { if (numAmount <= 0 || payable.length === 0) return; zapCrew(payable, numAmount, comment || t('walletUi.zapCrew.defaultComment', { crew: crewName })); }; const handleOpenChange = (o: boolean) => { setOpen(o); if (!o) { reset(); setAmount(1000); setComment(''); } }; if (!user) return <>{children}; return (
{children}
{t('walletUi.zapCrew.title')} {t('walletUi.zapCrew.desc', { count: payable.length })} {payable.length === 0 ? (
{t('walletUi.zapCrew.noMembers')}
) : !started ? (
v && setAmount(parseInt(v, 10))} className="grid grid-cols-5 gap-1 mt-2" > {PRESETS.map((p) => ( {p >= 1000 ? `${p / 1000}k` : p} ))} setAmount(e.target.value)} placeholder={t('walletUi.zapCrew.customTotal')} className="mt-2 bg-gray-800 border-gray-700" />
{numAmount > 0 && (

≈ {perHead[0]?.toLocaleString()} {t('walletUi.zapCrew.each')} {perHead.length > 1 && perHead[0] !== perHead[perHead.length - 1] && ` ${t('walletUi.zapCrew.rounded')}`}

)}