import { useState } from 'react'; import type { MessageDescriptor } from '@lingui/core'; import { msg } from '@lingui/core/macro'; import { useLingui } from '@lingui/react'; import { Trans } from '@lingui/react/macro'; import { AnimatePresence, motion } from 'framer-motion'; import type { PriceIntervals } from '@documenso/ee/server-only/stripe/get-prices-by-interval'; import { useIsMounted } from '@documenso/lib/client-only/hooks/use-is-mounted'; import { toHumanPrice } from '@documenso/lib/universal/stripe/to-human-price'; import { trpc } from '@documenso/trpc/react'; import { Button } from '@documenso/ui/primitives/button'; import { Card, CardContent, CardTitle } from '@documenso/ui/primitives/card'; import { Tabs, TabsList, TabsTrigger } from '@documenso/ui/primitives/tabs'; import { useToast } from '@documenso/ui/primitives/use-toast'; type Interval = keyof PriceIntervals; const INTERVALS: Interval[] = ['day', 'week', 'month', 'year']; // eslint-disable-next-line @typescript-eslint/consistent-type-assertions const isInterval = (value: unknown): value is Interval => INTERVALS.includes(value as Interval); const FRIENDLY_INTERVALS: Record = { day: msg`Daily`, week: msg`Weekly`, month: msg`Monthly`, year: msg`Yearly`, }; const MotionCard = motion(Card); export type BillingPlansProps = { prices: PriceIntervals; }; export const BillingPlans = ({ prices }: BillingPlansProps) => { const { _ } = useLingui(); const { toast } = useToast(); const isMounted = useIsMounted(); const [interval, setInterval] = useState('month'); const [checkoutSessionPriceId, setCheckoutSessionPriceId] = useState(null); const { mutateAsync: createCheckoutSession } = trpc.profile.createCheckoutSession.useMutation(); const onSubscribeClick = async (priceId: string) => { try { setCheckoutSessionPriceId(priceId); const url = await createCheckoutSession({ priceId }); if (!url) { throw new Error('Unable to create session'); } window.open(url); } catch (_err) { toast({ title: _(msg`Something went wrong`), description: _(msg`An error occurred while trying to create a checkout session.`), variant: 'destructive', }); } finally { setCheckoutSessionPriceId(null); } }; return (
isInterval(value) && setInterval(value)}> {INTERVALS.map( (interval) => prices[interval].length > 0 && ( {_(FRIENDLY_INTERVALS[interval])} ), )}
{prices[interval].map((price) => ( {price.product.name}
${toHumanPrice(price.unit_amount ?? 0)} {price.currency.toUpperCase()}{' '} per {interval}
{price.product.description}
{price.product.features && price.product.features.length > 0 && (
Includes:
    {price.product.features.map((feature, index) => (
  • {feature.name}
  • ))}
)}
))}
); };