fastpocket/Frontend/components/PriceCard.tsx

129 lines
4.3 KiB
TypeScript

"use client";
import { Price, Product, SourceModal } from "@/types";
import { createCheckoutSession, isAuthenticated } from "@/app/actions";
import { toast } from "react-toastify";
import { useRouter } from "next/navigation";
import {CheckmarkCircle24Filled } from "@fluentui/react-icons"
export default function PriceCard({
product,
isAnnual,
loading,
}: {
product?: Product;
isAnnual?: boolean;
loading?: boolean;
}) {
const router = useRouter();
const openSignUpModalOnPriceClick = (price: Price, type: string) => {
const signUpModal = document.getElementById("sign-up-modal");
if (!signUpModal) return;
signUpModal.click();
};
const generateCheckoutPage = async (price: Price, type: string) => {
try {
const checkoutSessionResponse = await createCheckoutSession(
price.price_id,
type
);
console.log(checkoutSessionResponse);
router.push(checkoutSessionResponse.url);
} catch (error) {
if (error instanceof Error) {
toast.error(error.message, {
position: "bottom-left",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "colored",
});
}
}
};
const submitForm = async (product: Product) => {
const userIsAuthenticated = await isAuthenticated();
console.log("userIsAuthenticated", userIsAuthenticated);
const price = isAnnual ? product.yearlyPrice : product.monthlyPrice;
console.log("price", price);
console.log("product.type", product.type);
localStorage.setItem("price", JSON.stringify(price));
localStorage.setItem("type", product.type);
if (userIsAuthenticated) {
await generateCheckoutPage(price, product.type);
} else {
openSignUpModalOnPriceClick(price, product.type);
}
};
return (
<div
className={`relative w-64 sm:w-80 bg-base-200 rounded-lg p-6 shadow-lg border border-primary/40 ${
loading ? "animate-pulse h-[20rem]" : ""
}`}
>
<div className="flex flex-col h-full">
<div className="mb-12 relative">
{!loading && (
<p className="absolute top-[-10px] left-[50%] -translate-x-1/2 font-architects-daughter text-sm text-primary text-center">
$30 off for the first 5 customers{" "}
<span className="text-secondary">(3 left)</span>
</p>
)}
<h1 className="text-center text-3xl font-inter font-bold pt-12 text-base-content ">
{product?.name}
</h1>
<h2 className="text-center pt-4 text-base-content ">
{product?.description}
</h2>
</div>
<div className="pb-12">
<ul className="flex flex-col gap-y-3 mx-12">
{product?.metadata?.benefits?.map((x, i) => (
<li key={i} className="flex items-center gap-x-4 flex-nowrap">
<CheckmarkCircle24Filled />
<p className="w-40 text-base-content overflow-clip text-ellipsis">
{x}
</p>
</li>
))}
</ul>
</div>
<div className="flex flex-col mx-auto mt-auto">
{!loading && (
<div className="flex flex-row mx-auto gap-x-2 justify-center items-center mb-2">
<h1 className="text-base-content text-4xl font-bold">
$
{isAnnual
? (product?.yearlyPrice?.unit_amount ?? 0) / 100
: (product?.monthlyPrice?.unit_amount ?? 0) / 100}
</h1>
{product?.type != "one_time" ? (
<p className="w-16 leading-5 text-sm text-base-content ">
per user per {isAnnual ? "year" : "month"}
</p>
) : (
<p className="w-16 leading-5 text-sm text-base-content ">
One Time
</p>
)}
</div>
)}
{product && (
<button
onClick={() => submitForm(product)}
className="btn btn-primary rounded-full bg-gradient-to-r from-primary to-secondary outline-none border-none capitalize"
>
Let&apos;s go!
</button>
)}
</div>
</div>
</div>
);
}