merging all

This commit is contained in:
zmeyer44 2023-11-02 10:50:49 -04:00
parent 6fbd12d59b
commit 1e57afb1ac
3 changed files with 146 additions and 17 deletions

View File

@ -27,7 +27,7 @@ import { btcToSats, formatNumber } from "@/lib/utils";
import { formatDate } from "@/lib/utils/dates"; import { formatDate } from "@/lib/utils/dates";
import SmallCalendarIcon from "@/components/EventIcons/DateIcon"; import SmallCalendarIcon from "@/components/EventIcons/DateIcon";
import LocationIcon from "@/components/EventIcons/LocationIcon"; import LocationIcon from "@/components/EventIcons/LocationIcon";
import BannerImage from "@/components/PageComponents/BannerImage";
const RSVPButton = dynamic(() => import("./RSVPButton"), { const RSVPButton = dynamic(() => import("./RSVPButton"), {
ssr: false, ssr: false,
}); });
@ -128,16 +128,7 @@ export default function Header({ event }: { event: NDKEvent }) {
<div className="relative overflow-hidden rounded-[1rem] border bg-muted p-[0.5rem] @container"> <div className="relative overflow-hidden rounded-[1rem] border bg-muted p-[0.5rem] @container">
<div className="overflow-hidden rounded-[0.5rem] p-0"> <div className="overflow-hidden rounded-[0.5rem] p-0">
<div className="relative w-full overflow-hidden bg-gradient-to-b from-primary pb-[50%] @5xl:rounded-[20px] md:pb-[40%]"> <div className="relative w-full overflow-hidden bg-gradient-to-b from-primary pb-[50%] @5xl:rounded-[20px] md:pb-[40%]">
{!!image && ( {!!image && <BannerImage image={image} />}
<Image
className="absolute inset-0 h-full w-full object-cover align-middle"
src={image}
width={400}
height={100}
alt="banner"
unoptimized
/>
)}
</div> </div>
</div> </div>
<div className="space-y-1 p-3 @sm:px-3.5 @sm:pb-2 @sm:pt-5"> <div className="space-y-1 p-3 @sm:px-3.5 @sm:pb-2 @sm:pt-5">
@ -154,7 +145,7 @@ export default function Header({ event }: { event: NDKEvent }) {
{!!currentUser && currentUser.pubkey === pubkey && ( {!!currentUser && currentUser.pubkey === pubkey && (
<EditEventButton event={event.rawEvent()} /> <EditEventButton event={event.rawEvent()} />
)} )}
{!isMember && <RSVPButton eventReference={eventReference} />} {!isMember && <RSVPButton event={event} />}
{/* {!isMember && {/* {!isMember &&
(hasValidPayment ? ( (hasValidPayment ? (
<Button variant={"outline"}>Pending Sync</Button> <Button variant={"outline"}>Pending Sync</Button>

View File

@ -1,19 +1,146 @@
import { useState } from "react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { useModal } from "@/app/_providers/modal/provider"; import { HiOutlineLightningBolt } from "react-icons/hi";
import RSVPModal from "@/components/Modals/RSVP"; import RSVPModal from "@/components/Modals/RSVP";
import ConfirmModal from "@/components/Modals/Confirm";
import { type NDKEvent } from "@nostr-dev-kit/ndk";
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";
type RSVPButtonProps = { type RSVPButtonProps = {
eventReference: string; event: NDKEvent;
}; };
export default function RSVPButton({ eventReference }: RSVPButtonProps) { export default function RSVPButton({ event }: RSVPButtonProps) {
const modal = useModal(); const modal = useModal();
const { currentUser } = useCurrentUser();
const { ndk } = useNDK();
const eventReference = event.encode();
const name = getTagValues("name", event.tags);
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);
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);
}
}
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);
}
}
if (!tickets) {
return (
<Button
onClick={() =>
modal?.show(<RSVPModal eventReference={eventReference} />)
}
>
RSVP
</Button>
);
}
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">
{`Pay ${priceInBTC} BTC (${formatNumber(
btcToSats(priceInBTC),
)} sats) for one ticket for ${name}`}
</p>
</ConfirmModal>,
)
}
>
Buy Ticket
</Button>
);
}
return ( return (
<Button <Button
onClick={() => modal?.show(<RSVPModal eventReference={eventReference} />)} 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>,
)
}
> >
RSVP Get Ticket
</Button> </Button>
); );
} }

View File

@ -130,3 +130,14 @@ input[type="time"]::-webkit-calendar-picker-indicator {
background: none; background: none;
display: none; display: none;
} }
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type="number"] {
-moz-appearance: textfield;
}