import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Skeleton } from '@/components/ui/skeleton'; import { ZapButton } from '@/components/ZapButton'; import { useCrewGoal } from '@/hooks/useCrewGoal'; import { cn } from '@/lib/utils'; import { Target, Zap, Users, CheckCircle2 } from 'lucide-react'; /** * Crew treasury — a transparent, zap-funded NIP-75 goal. Contributions are * ordinary zaps to the goal event that settle to the founder's own Lightning * wallet; SkateSpots never custodies funds. Progress is tallied from public * zap receipts, so anyone can audit it. */ export function CrewTreasuryCard({ goalId }: { goalId?: string }) { const { data: goal, isLoading } = useCrewGoal(goalId); if (!goalId) return null; if (isLoading) { return ( ); } if (!goal) return null; const pct = Math.min(100, goal.percent); const reached = goal.percent >= 100; const now = Math.floor(Date.now() / 1000); const closed = goal.closedAt ? goal.closedAt < now : false; const daysLeft = goal.closedAt ? Math.ceil((goal.closedAt - now) / 86400) : null; return ( Crew Treasury {goal.summary && {goal.summary}} {goal.description && ( {goal.description} )} {/* Progress bar */} {goal.raisedSats.toLocaleString()} sats of {goal.targetSats.toLocaleString()} goal {reached ? ( Goal reached! ) : ( {goal.percent}% funded )} {goal.contributions} contribution{goal.contributions === 1 ? '' : 's'} {daysLeft !== null && daysLeft > 0 && ` · ${daysLeft}d left`} {closed && ' · closed'} {/* Contribute — zaps the goal event; settles to the founder's wallet. */} {!closed && ( Non-custodial · zaps go straight to the crew's Lightning wallet )} ); }
{goal.summary}
{goal.description}
Non-custodial · zaps go straight to the crew's Lightning wallet