import "./goal.css"; import { useMemo } from "react"; import * as Progress from "@radix-ui/react-progress"; import Confetti from "react-confetti"; import { FormattedMessage } from "react-intl"; import { type NostrEvent, NostrLink } from "@snort/system"; import { useUserProfile } from "@snort/system-react"; import { findTag } from "@/utils"; import { formatSats } from "@/number"; import usePreviousValue from "@/hooks/usePreviousValue"; import { SendZapsDialog } from "./send-zap"; import { getName } from "./profile"; import { Icon } from "./icon"; import { useZaps } from "@/hooks/zaps"; export function Goal({ ev }: { ev: NostrEvent }) { const profile = useUserProfile(ev.pubkey); const zapTarget = profile?.lud16 ?? profile?.lud06; const link = NostrLink.fromEvent(ev); const zaps = useZaps(link, true); const goalAmount = useMemo(() => { const amount = findTag(ev, "amount"); return amount ? Number(amount) / 1000 : null; }, [ev]); if (!goalAmount) { return null; } const soFar = useMemo(() => { return zaps .filter(z => z.receiver === ev.pubkey && z.targetEvents.some(a => a.matchesEvent(ev))) .reduce((acc, z) => acc + z.amount, 0); }, [zaps]); const progress = Math.max(0, Math.min(100, (soFar / goalAmount) * 100)); const isFinished = progress >= 100; const previousValue = usePreviousValue(isFinished); const goalContent = (
{ev.content.length > 0 &&

{ev.content}

}
{!isFinished && {formatSats(soFar)}}
{isFinished && previousValue === false && }
); return zapTarget ? ( ) : ( goalContent ); }