182 lines
5.0 KiB
TypeScript
Raw Normal View History

2023-11-02 10:50:49 -04:00
import { useState } from "react";
2023-10-25 12:56:51 -04:00
import { Button } from "@/components/ui/button";
2023-11-02 10:50:49 -04:00
import { HiOutlineLightningBolt } from "react-icons/hi";
2023-11-04 12:12:55 -04:00
import { RiRepeatFill } from "react-icons/ri";
2023-11-02 10:50:49 -04:00
2023-10-25 12:56:51 -04:00
import RSVPModal from "@/components/Modals/RSVP";
2023-11-02 10:50:49 -04:00
import ConfirmModal from "@/components/Modals/Confirm";
2023-11-03 14:34:54 -04:00
import { NDKKind, type NDKEvent } from "@nostr-dev-kit/ndk";
2023-11-02 10:50:49 -04:00
import { getTagAllValues, getTagValues } from "@/lib/nostr/utils";
import { formatDate } from "@/lib/utils/dates";
import { useModal } from "@/app/_providers/modal/provider";
import { btcToSats, formatNumber } from "@/lib/utils";
import useCurrentUser from "@/lib/hooks/useCurrentUser";
import { useNDK } from "@/app/_providers/ndk";
import { toast } from "sonner";
import { sendZap, checkPayment } from "@/lib/actions/zap";
2023-11-03 14:34:54 -04:00
import { useEvent } from "@/lib/hooks/useEvents";
2023-10-25 12:56:51 -04:00
type RSVPButtonProps = {
2023-11-02 10:50:49 -04:00
event: NDKEvent;
2023-10-25 12:56:51 -04:00
};
2023-11-02 10:50:49 -04:00
export default function RSVPButton({ event }: RSVPButtonProps) {
2023-10-25 12:56:51 -04:00
const modal = useModal();
2023-11-02 10:50:49 -04:00
const { currentUser } = useCurrentUser();
const { ndk } = useNDK();
const eventReference = event.tagId();
2024-04-27 13:28:53 -04:00
const name = getTagValues("title", event.tags);
2023-11-02 10:50:49 -04:00
const tickets = getTagValues("tickets", event.tags);
const price = getTagAllValues("price", event.tags);
const priceInBTC = parseFloat(getTagValues("price", event.tags) ?? "0");
const [ticketPending, setTicketPending] = useState(false);
const [checkingPayment, setCheckingPayment] = useState(false);
const [hasValidPayment, setHasValidPayment] = useState(false);
2023-11-03 14:34:54 -04:00
const { event: rsvpEvent } = useEvent({
filter: {
kinds: [31925 as NDKKind],
authors: [currentUser?.pubkey as string],
["#a"]: [eventReference],
},
enabled: !!currentUser,
});
2023-11-02 10:50:49 -04:00
async function handleBuyTicket() {
setTicketPending(true);
try {
if (!currentUser || !ndk?.signer) return;
const result = await sendZap(
ndk!,
btcToSats(priceInBTC),
event.rawEvent(),
`Ticket payment: ${name}`,
);
toast.success("Payment Sent!");
void handleCheckPayment();
} catch (err) {
console.log("error sending zap", err);
} finally {
setTicketPending(false);
}
}
2023-10-25 12:56:51 -04:00
2023-11-02 10:50:49 -04:00
async function handleCheckPayment() {
if (!event || !currentUser || !ndk) return;
setCheckingPayment(true);
try {
const result = await checkPayment(
ndk,
event.tagId(),
currentUser.pubkey,
event.rawEvent(),
);
console.log("Payment result", result);
if (result) {
setHasValidPayment(true);
}
} catch (err) {
console.log("error sending zap", err);
} finally {
setCheckingPayment(false);
}
}
2023-11-03 14:34:54 -04:00
2023-11-02 10:50:49 -04:00
if (!tickets) {
2023-11-03 14:34:54 -04:00
if (rsvpEvent) {
const rsvpResponse = getTagValues("l", rsvpEvent.tags);
return (
2023-11-04 12:17:12 -04:00
<div className="flex items-center gap-2">
2023-11-04 12:12:55 -04:00
<Button disabled>
{rsvpResponse === "accepted"
? "Going"
: rsvpResponse === "tentative"
? "Tentative"
: "Not Going"}
</Button>
<Button
onClick={() =>
modal?.show(<RSVPModal eventReference={eventReference} />)
}
2023-11-04 12:17:12 -04:00
variant={"outline"}
2023-11-04 12:12:55 -04:00
size="icon"
>
2023-11-04 12:17:12 -04:00
<RiRepeatFill className="h-4 w-4 text-muted-foreground" />
2023-11-04 12:12:55 -04:00
</Button>
</div>
2023-11-03 14:34:54 -04:00
);
} else {
return (
<Button
onClick={() =>
modal?.show(<RSVPModal eventReference={eventReference} />)
}
>
RSVP
</Button>
);
}
2023-11-02 10:50:49 -04:00
}
if (price) {
return (
<Button
onClick={() =>
modal?.show(
<ConfirmModal
title={`Buy Ticket for ${name}`}
onConfirm={handleBuyTicket}
ctaBody={
<>
<span>Zap for Ticket</span>
<HiOutlineLightningBolt className="h-4 w-4" />
</>
}
>
<p className="text-muted-forground">
2023-11-20 08:04:47 -05:00
{`Pay ${priceInBTC.toFixed()} BTC (${formatNumber(
2023-11-02 10:50:49 -04:00
btcToSats(priceInBTC),
)} sats) for one ticket for ${name}`}
</p>
</ConfirmModal>,
)
}
>
Buy Ticket
</Button>
);
}
2023-10-25 12:56:51 -04:00
return (
<Button
2023-11-02 10:50:49 -04:00
onClick={() =>
modal?.show(
<ConfirmModal
title={`Get Ticket for ${name}`}
onConfirm={handleBuyTicket}
ctaBody={
<>
<span>Zap to Subscribe</span>
<HiOutlineLightningBolt className="h-4 w-4" />
</>
}
>
<p className="text-muted-forground">
{`Pay ${priceInBTC} BTC (${formatNumber(
btcToSats(priceInBTC),
)} sats) for year long access until ${formatDate(
new Date(new Date().setFullYear(new Date().getFullYear() + 1)),
"MMM Do, YYYY",
)}`}
</p>
</ConfirmModal>,
)
}
2023-10-25 12:56:51 -04:00
>
2023-11-02 10:50:49 -04:00
Get Ticket
2023-10-25 12:56:51 -04:00
</Button>
);
}