improving subscribing ux
This commit is contained in:
parent
0cb461d123
commit
b817287525
@ -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>
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user