improving subscribing ux

This commit is contained in:
zmeyer44 2023-10-21 09:23:08 -04:00
parent 0cb461d123
commit b817287525
2 changed files with 60 additions and 12 deletions

View File

@ -20,9 +20,8 @@ import { useModal } from "@/app/_providers/modal/provider";
import { type NDKEvent } from "@nostr-dev-kit/ndk"; import { type NDKEvent } from "@nostr-dev-kit/ndk";
import { btcToSats, formatNumber } from "@/lib/utils"; import { btcToSats, formatNumber } from "@/lib/utils";
import { formatDate } from "@/lib/utils/dates"; import { formatDate } from "@/lib/utils/dates";
const EditListModal = dynamic(() => import("@/components/Modals/EditList"), { import { follow } from "@/lib/actions/create";
ssr: false, import { log } from "@/lib/utils";
});
const CreateEventModal = dynamic(() => import("@/components/Modals/NewEvent"), { const CreateEventModal = dynamic(() => import("@/components/Modals/NewEvent"), {
ssr: false, ssr: false,
}); });
@ -37,6 +36,7 @@ export default function Header({ event }: { event: NDKEvent }) {
const [checkingPayment, setCheckingPayment] = useState(false); const [checkingPayment, setCheckingPayment] = useState(false);
const [hasValidPayment, setHasValidPayment] = useState(false); const [hasValidPayment, setHasValidPayment] = useState(false);
const [syncingUsers, setSyncingUsers] = useState(false); const [syncingUsers, setSyncingUsers] = useState(false);
const [subscribing, setSubscribing] = useState(false);
const pubkey = event.pubkey; const pubkey = event.pubkey;
const { profile } = useProfile(pubkey); const { profile } = useProfile(pubkey);
@ -53,14 +53,14 @@ export default function Header({ event }: { event: NDKEvent }) {
const description = getTagValues("description", event.tags); const description = getTagValues("description", event.tags);
const rawEvent = event.rawEvent(); const rawEvent = event.rawEvent();
const subscriptionsEnabled = !!getTagValues("subscriptions", rawEvent.tags);
const priceInBTC = parseFloat(getTagValues("price", rawEvent.tags) ?? "0"); const priceInBTC = parseFloat(getTagValues("price", rawEvent.tags) ?? "0");
const isMember = const isMember =
currentUser && currentUser &&
getTagsValues("p", rawEvent.tags).includes(currentUser.pubkey); getTagsValues("p", rawEvent.tags).includes(currentUser.pubkey);
const delegate = getTagValues("delegate", event.tags);
useEffect(() => { useEffect(() => {
if (!currentUser || !subscriptionsEnabled) return; if (!currentUser) return;
if (!isMember && !checkingPayment && !hasValidPayment) { if (!isMember && !checkingPayment && !hasValidPayment) {
void handleCheckPayment(); void handleCheckPayment();
} }
@ -100,8 +100,15 @@ export default function Header({ event }: { event: NDKEvent }) {
setSyncingUsers(false); setSyncingUsers(false);
} }
} }
async function handleSendZap() { async function handleSubscribe() {
log("func", "handleSubscribe");
setSubscribing(true);
try { try {
if (!currentUser || !ndk?.signer) return;
if (delegate) {
await follow(ndk, currentUser, delegate);
log("info", "followed");
}
const result = await sendZap( const result = await sendZap(
ndk!, ndk!,
btcToSats(priceInBTC), btcToSats(priceInBTC),
@ -113,6 +120,7 @@ export default function Header({ event }: { event: NDKEvent }) {
} catch (err) { } catch (err) {
console.log("error sending zap", err); console.log("error sending zap", err);
} finally { } finally {
setSubscribing(false);
} }
} }
if (!event) { if (!event) {
@ -171,17 +179,17 @@ export default function Header({ event }: { event: NDKEvent }) {
</Button> */} </Button> */}
</> </>
)} )}
{subscriptionsEnabled && {!isMember &&
!isMember &&
(hasValidPayment ? ( (hasValidPayment ? (
<Button variant={"outline"}>Pending Sync</Button> <Button variant={"outline"}>Pending Sync</Button>
) : ( ) : (
<Button <Button
loading={subscribing}
onClick={() => onClick={() =>
modal?.show( modal?.show(
<ConfirmModal <ConfirmModal
title={`Subscribe to ${title}`} title={`Subscribe to ${title}`}
onConfirm={handleSendZap} onConfirm={handleSubscribe}
ctaBody={ ctaBody={
<> <>
<span>Zap to Subscribe</span> <span>Zap to Subscribe</span>

View File

@ -1,6 +1,7 @@
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import Image from "next/image"; import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
import dynamic from "next/dynamic";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { import {
Card, Card,
@ -19,9 +20,19 @@ import { sendZap, checkPayment } from "@/lib/actions/zap";
import { btcToSats, formatNumber } from "@/lib/utils"; import { btcToSats, formatNumber } from "@/lib/utils";
import { BANNER } from "@/constants"; import { BANNER } from "@/constants";
import { follow } from "@/lib/actions/create"; import { follow } from "@/lib/actions/create";
import { HiOutlineLightningBolt } from "react-icons/hi";
import { formatDate } from "@/lib/utils/dates";
import { useModal } from "@/app/_providers/modal/provider";
const ConfirmModal = dynamic(() => import("@/components/Modals/Confirm"), {
ssr: false,
});
export default function SubscriptionCard({ event }: { event: NDKEvent }) { export default function SubscriptionCard({ event }: { event: NDKEvent }) {
const { currentUser } = useCurrentUser(); const { currentUser } = useCurrentUser();
const { ndk } = useNDK(); const { ndk } = useNDK();
const modal = useModal();
const [subscribing, setSubscribing] = useState(false);
const [checkingPayment, setCheckingPayment] = useState(false); const [checkingPayment, setCheckingPayment] = useState(false);
const [hasValidPayment, setHasValidPayment] = useState(false); const [hasValidPayment, setHasValidPayment] = useState(false);
const { tags } = event; const { tags } = event;
@ -36,6 +47,7 @@ export default function SubscriptionCard({ event }: { event: NDKEvent }) {
async function handleSubscribe() { async function handleSubscribe() {
log("func", "handleSubscribe"); log("func", "handleSubscribe");
setSubscribing(true);
try { try {
if (!currentUser || !ndk?.signer) return; if (!currentUser || !ndk?.signer) return;
if (delegate) { if (delegate) {
@ -53,6 +65,7 @@ export default function SubscriptionCard({ event }: { event: NDKEvent }) {
} catch (err) { } catch (err) {
console.log("error sending zap", err); console.log("error sending zap", err);
} finally { } finally {
setSubscribing(false);
} }
} }
@ -112,12 +125,39 @@ export default function SubscriptionCard({ event }: { event: NDKEvent }) {
) : ( ) : (
<> <>
<Button <Button
loading={checkingPayment} loading={subscribing}
onClick={handleSubscribe} onClick={() =>
modal?.show(
<ConfirmModal
title={`Subscribe to ${title}`}
onConfirm={handleSubscribe}
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>,
)
}
className="w-full" className="w-full"
> >
Join now Subscribe
</Button> </Button>
<Link href={`/sub/${event.encode()}`} className="w-full"> <Link href={`/sub/${event.encode()}`} className="w-full">
<Button variant={"secondary"} className="w-full"> <Button variant={"secondary"} className="w-full">
Details Details