@coursebuilder/commerce-next
Version:
Commerce Functionality for Course Builder with Next.js
44 lines (43 loc) • 6.12 kB
JavaScript
'use client';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import Image from 'next/image';
import Link from 'next/link';
import { redirect } from 'next/navigation';
import { signIn } from 'next-auth/react';
import Balancer from 'react-wrap-balancer';
import { Button } from '@coursebuilder/ui';
import { Icon } from '../components';
function formatPrice(amount, currency) {
if (!amount)
return 'N/A';
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: currency.toUpperCase(),
}).format(amount / 100);
}
function formatSubscriptionInterval(interval) {
return interval === 'month' ? 'Monthly' : 'Yearly';
}
export function SubscriptionWelcomePage({ subscription, stripeSubscription, isGithubConnected, isDiscordConnected = false, providers = {}, billingPortalUrl, }) {
if (!subscription) {
redirect('/');
}
const product = subscription?.product;
const subscriptionDetails = {
status: stripeSubscription.status,
quantity: stripeSubscription.items.data[0]?.quantity || 1,
interval: stripeSubscription.items.data[0]?.price.recurring?.interval || 'month',
currentPeriodEnd: stripeSubscription.current_period_end,
cancelAtPeriodEnd: stripeSubscription.cancel_at_period_end,
price: {
unitAmount: stripeSubscription.items.data[0]?.price.unit_amount,
currency: stripeSubscription.items.data[0]?.price.currency || 'usd',
},
};
return (_jsx("main", { className: "mx-auto flex w-full flex-grow flex-col items-center justify-center py-16", children: _jsxs("div", { className: "flex w-full max-w-screen-md flex-col gap-3", children: [_jsx("header", { children: _jsxs("div", { className: "flex flex-col items-center gap-10 pb-8 sm:flex-row", children: [product?.fields?.image && (_jsx("div", { className: "flex flex-shrink-0 items-center justify-center", children: _jsx(Image, { src: product.fields.image.url, alt: product.name, width: 250, height: 250 }) })), _jsxs("div", { className: "flex w-full flex-col items-center text-center sm:items-start sm:text-left", children: [_jsxs("h1", { className: "font-text w-full text-3xl font-bold sm:text-3xl lg:text-4xl", children: [_jsx("div", { className: "text-primary pb-2 text-sm font-normal uppercase", children: "Welcome to your subscription" }), _jsx(Balancer, { children: product?.name || 'Subscription' })] }), _jsxs("div", { className: "flex flex-wrap justify-center gap-3 pt-8 sm:justify-start", children: [providers.discord && !isDiscordConnected && (_jsxs("button", { onClick: () => signIn('discord'), className: "flex w-full items-center justify-center gap-2 rounded bg-gray-800 px-5 py-1 text-sm text-white transition hover:brightness-110 sm:w-auto", children: [_jsx(Icon, { name: "Discord", size: "20" }), "Join Discord"] })), providers.github && !isGithubConnected && (_jsxs("button", { onClick: () => signIn('github'), className: "flex w-full items-center justify-center gap-2 rounded bg-gray-800 px-5 py-3 text-lg font-semibold text-white shadow-xl shadow-black/10 transition hover:brightness-110 sm:w-auto", children: [_jsx(Icon, { name: "Github", size: "20" }), "Connect GitHub"] }))] })] })] }) }), _jsxs("div", { className: "flex flex-col gap-10", children: [_jsxs("div", { className: "border-b pb-5", children: [_jsx("h2", { className: "text-primary pb-4 text-sm uppercase", children: "Subscription Details" }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsxs("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: [_jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "text-muted-foreground text-sm", children: "Status" }), _jsx("span", { className: "capitalize", children: subscriptionDetails.status })] }), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "text-muted-foreground text-sm", children: "Billing" }), _jsxs("span", { children: [formatSubscriptionInterval(subscriptionDetails.interval), " -", ' ', formatPrice((subscriptionDetails.price.unitAmount ?? 0) *
subscriptionDetails.quantity, subscriptionDetails.price.currency)] })] }), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "text-muted-foreground text-sm", children: "Next Payment" }), _jsx("span", { children: new Date(subscriptionDetails.currentPeriodEnd * 1000).toLocaleDateString() })] }), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "text-muted-foreground text-sm", children: "Seats" }), _jsx("span", { children: subscriptionDetails.quantity })] })] }), subscriptionDetails.cancelAtPeriodEnd && (_jsx("div", { className: "mt-2 rounded-md bg-yellow-50 p-3 text-sm text-yellow-800", children: "This subscription will cancel at the end of the current period" })), _jsx("div", { className: "mt-4 flex gap-2", children: _jsx(Button, { asChild: true, variant: "outline", children: _jsx(Link, { href: billingPortalUrl, children: "Manage Billing" }) }) })] })] }), _jsxs("div", { children: [_jsx("h2", { className: "text-primary pb-4 text-sm uppercase", children: "Share" }), _jsx(Share, { productName: product?.name || 'this subscription' })] })] })] }) }));
}
const Share = ({ productName, }) => {
const tweet = `https://twitter.com/intent/tweet/?text=${productName} ${process.env.NEXT_PUBLIC_URL}`;
return (_jsxs("div", { className: "flex flex-col justify-between gap-5 rounded border px-5 py-6 sm:flex-row sm:items-center", children: [_jsxs("p", { children: ["Tell your friends about ", process.env.NEXT_PUBLIC_SITE_TITLE, ",", ' ', _jsx("br", { className: "hidden sm:block" }), "it would help me to get a word out.", ' ', _jsx("span", { role: "img", "aria-label": "smiling face", children: "\uD83D\uDE0A" })] }), _jsx(Button, { asChild: true, variant: "outline", className: "flex items-center gap-2", children: _jsxs("a", { href: tweet, rel: "noopener noreferrer", target: "_blank", children: [_jsx(Icon, { name: "Twitter" }), " Share with your friends!"] }) })] }));
};