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 { Zap, Check, Copy, Loader2, X, Users, AlertCircle } from 'lucide-react';
import { cn } from '@/lib/utils';
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 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: 'Invoice copied', description: 'Paste it into any Lightning wallet' });
};
return (
{name.slice(0, 2).toUpperCase()}
{name}
{result.amount.toLocaleString()} sats
);
}
function StatusPill({ result, onCopy }: { result: CrewZapResult; onCopy: () => void }) {
switch (result.status) {
case 'success':
return Sent;
case 'resolving':
case 'paying':
return {result.status === 'paying' ? 'Paying' : 'Resolving'};
case 'skipped':
return Skipped;
case 'failed':
return result.invoice ? (
) : (
Failed
);
default:
return Waiting;
}
}
export function ZapCrewDialog({ crewName, recipients, children }: ZapCrewDialogProps) {
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 || `Zapped the ${crewName} crew! π€`);
};
const handleOpenChange = (o: boolean) => {
setOpen(o);
if (!o) {
reset();
setAmount(1000);
setComment('');
}
};
if (!user) return <>{children}>;
return (
);
}