import dayjs from "dayjs"; import Layout from "../components/Layout"; import ky from "ky/umd"; import { useEffect, useState } from "react"; import authServerSideProps from "../services/authServerSideProps"; import classnames from "classnames"; import prettyBytes from "pretty-bytes"; import config from "../config"; import useAccountsApi from "../services/useAccountsApi"; import { isFreeTier, isPaidTier } from "../services/tiers"; const apiPrefix = process.env.NODE_ENV === "development" ? "/api/stubs" : ""; const ActiveBadge = () => { return ( active ); }; export const getServerSideProps = authServerSideProps(async (context, api) => { const [user, stats, stripe] = await Promise.all([ api.get("user").json(), api.get("user/stats").json(), api.get("stripe/prices").json(), ]); const plans = [config.tiers.starter, ...stripe].sort((a, b) => a.tier - b.tier); return { props: { plans, user, stats } }; }); export default function Payments({ plans, user: initialUserData, stats: initialStatsData }) { const { data: user } = useAccountsApi(`${apiPrefix}/user`, { initialData: initialUserData }); const { data: stats } = useAccountsApi(`${apiPrefix}/user/stats`, { initialData: initialStatsData }); const [selectedPlan, setSelectedPlan] = useState(plans.find(({ tier }) => isFreeTier(tier))); const activePlan = plans.find(({ tier }) => (user ? user.tier === tier : isFreeTier(tier))); const handleSubscribe = async () => { try { const price = selectedPlan.stripe; const { sessionId } = await ky.post("/api/stripe/checkout", { json: { price } }).json(); const stripe = new Stripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY); await stripe.redirectToCheckout({ sessionId }); } catch (error) { console.log(error); // todo: handle error } }; useEffect(() => { if (activePlan && isPaidTier(activePlan.tier)) { setSelectedPlan(activePlan); } }, [activePlan, selectedPlan, setSelectedPlan]); return ( Current plan {activePlan?.name || "—"} Subscription status {isFreeTier(activePlan?.tier) ? "—" : user?.subscriptionStatus} {user?.subscriptionCancelAtPeriodEnd && ( Your plan will be cancelled on {dayjs(user.subscriptionCancelAt).format("D MMM YYYY")}. )} Storage used {prettyBytes(stats?.totalUploadsSize ?? 0)} Plan Pricing plans {plans.map((plan, index) => ( {isFreeTier(activePlan?.tier) && ( setSelectedPlan(plan)} /> )} {plan.name} {activePlan === plan && } {plan.price ? `$${plan.price} / mo` : "no cost"} {plan.description} ))} {user && isPaidTier(user.tier) ? ( Use Stripe Customer Portal to manage your active subscription, payment methods and view your billing history Stripe Customer Portal ) : ( Subscribe )} ); }
{plan.price ? `$${plan.price} / mo` : "no cost"}
{plan.description}