From 5b9713f0ae15f14a0ce860650bde4e52bf7c8702 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 20 Jan 2026 15:56:05 +0000 Subject: [PATCH] feat: add zap button to goal renderers Show a 'Zap this Goal' button in both feed and detail views when the goal is still open (not past its closed_at deadline). --- .../nostr/kinds/GoalDetailRenderer.tsx | 19 ++++++++++++++++++- src/components/nostr/kinds/GoalRenderer.tsx | 19 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/components/nostr/kinds/GoalDetailRenderer.tsx b/src/components/nostr/kinds/GoalDetailRenderer.tsx index 6158c27..eb65152 100644 --- a/src/components/nostr/kinds/GoalDetailRenderer.tsx +++ b/src/components/nostr/kinds/GoalDetailRenderer.tsx @@ -1,5 +1,6 @@ import { useMemo } from "react"; import { NostrEvent } from "@/types/nostr"; +import { Zap } from "lucide-react"; import { useTimeline } from "@/hooks/useTimeline"; import { getGoalAmount, @@ -14,6 +15,7 @@ import { getZapAmount, getZapSender } from "applesauce-common/helpers/zap"; import { formatTimestamp } from "@/hooks/useLocale"; import { useGrimoire } from "@/core/state"; import { Progress } from "@/components/ui/progress"; +import { Button } from "@/components/ui/button"; import { UserName } from "../UserName"; import { Skeleton } from "@/components/ui/skeleton"; import { AGGREGATOR_RELAYS } from "@/services/loaders"; @@ -29,7 +31,7 @@ interface Contributor { * Shows full goal info with sorted contributor breakdown */ export function GoalDetailRenderer({ event }: { event: NostrEvent }) { - const { locale } = useGrimoire(); + const { locale, addWindow } = useGrimoire(); // Get goal metadata const targetAmount = getGoalAmount(event); @@ -109,6 +111,13 @@ export function GoalDetailRenderer({ event }: { event: NostrEvent }) { ? formatTimestamp(closedAt, "absolute", locale.locale) : null; + const handleZap = () => { + addWindow("zap", { + recipientPubkey: event.pubkey, + eventPointer: { id: event.id }, + }); + }; + return (
{/* Header */} @@ -153,6 +162,14 @@ export function GoalDetailRenderer({ event }: { event: NostrEvent }) {
)} + {/* Zap Button */} + {!closed && ( + + )} + {/* Beneficiaries */} {beneficiaries.length > 0 && (
diff --git a/src/components/nostr/kinds/GoalRenderer.tsx b/src/components/nostr/kinds/GoalRenderer.tsx index 0f4a44d..b9f69fb 100644 --- a/src/components/nostr/kinds/GoalRenderer.tsx +++ b/src/components/nostr/kinds/GoalRenderer.tsx @@ -4,6 +4,7 @@ import { BaseEventContainer, ClickableEventTitle, } from "./BaseEventRenderer"; +import { Zap } from "lucide-react"; import { useTimeline } from "@/hooks/useTimeline"; import { getGoalAmount, @@ -17,6 +18,7 @@ import { getZapAmount } from "applesauce-common/helpers/zap"; import { formatTimestamp } from "@/hooks/useLocale"; import { useGrimoire } from "@/core/state"; import { Progress } from "@/components/ui/progress"; +import { Button } from "@/components/ui/button"; import { AGGREGATOR_RELAYS } from "@/services/loaders"; /** @@ -24,7 +26,7 @@ import { AGGREGATOR_RELAYS } from "@/services/loaders"; * Shows goal title, description, and funding progress */ export function GoalRenderer({ event }: BaseEventProps) { - const { locale } = useGrimoire(); + const { locale, addWindow } = useGrimoire(); // Get goal metadata const targetAmount = getGoalAmount(event); @@ -77,6 +79,13 @@ export function GoalRenderer({ event }: BaseEventProps) { ? formatTimestamp(closedAt, "absolute", locale.locale) : null; + const handleZap = () => { + addWindow("zap", { + recipientPubkey: event.pubkey, + eventPointer: { id: event.id }, + }); + }; + return (
@@ -130,6 +139,14 @@ export function GoalRenderer({ event }: BaseEventProps) { )}
)} + + {/* Zap Button */} + {!closed && ( + + )}
);