import { Check, Loader2 } from 'lucide-react'; import { useEffect, useState } from 'react'; import { getUser } from '../../lib/jwt'; import { useMutation, useQuery } from '@tanstack/react-query'; import { Modal } from '../Modal'; import { billingDetailsOptions, USER_SUBSCRIPTION_PLAN_PRICES, type AllowedSubscriptionInterval, } from '../../queries/billing'; import { cn } from '../../lib/classname'; import { queryClient } from '../../stores/query-client'; import { httpPost } from '../../lib/query-http'; import { useToast } from '../../hooks/use-toast'; import { UpdatePlanConfirmation } from './UpdatePlanConfirmation'; type CreateSubscriptionCheckoutSessionBody = { priceId: string; success?: string; cancel?: string; }; type CreateSubscriptionCheckoutSessionResponse = { checkoutUrl: string; }; type UpgradeAccountModalProps = { onClose: () => void; success?: string; cancel?: string; }; export function UpgradeAccountModal(props: UpgradeAccountModalProps) { const { onClose, success, cancel } = props; const [selectedPlan, setSelectedPlan] = useState('month'); const [isUpdatingPlan, setIsUpdatingPlan] = useState(false); const user = getUser(); const { data: userBillingDetails, isLoading, error: billingError, } = useQuery(billingDetailsOptions(), queryClient); const toast = useToast(); const { mutate: createCheckoutSession, isPending: isCreatingCheckoutSession, } = useMutation( { mutationFn: (body: CreateSubscriptionCheckoutSessionBody) => { return httpPost( '/v1-create-subscription-checkout-session', body, ); }, onSuccess: (data) => { window.location.href = data.checkoutUrl; }, onError: (error) => { console.error(error); toast.error(error?.message || 'Failed to create checkout session'); }, }, queryClient, ); const selectedPlanDetails = USER_SUBSCRIPTION_PLAN_PRICES.find( (plan) => plan.interval === selectedPlan, ); const currentPlanPriceId = userBillingDetails?.priceId; const currentPlan = USER_SUBSCRIPTION_PLAN_PRICES.find( (plan) => plan.priceId === currentPlanPriceId, ); useEffect(() => { if (!currentPlan) { return; } setSelectedPlan(currentPlan.interval); }, [currentPlan]); if (!user) { return null; } const loader = isLoading ? (
) : null; const error = billingError; const errorContent = error ? (

{error?.message || 'An error occurred while loading the billing details.'}

) : null; const calculateYearlyPrice = (monthlyPrice: number) => { return (monthlyPrice * 12).toFixed(2); }; if (isUpdatingPlan && selectedPlanDetails) { return ( setIsUpdatingPlan(false)} onCancel={() => setIsUpdatingPlan(false)} /> ); } return (
e.stopPropagation()}> {errorContent} {loader} {!isLoading && !error && (

Unlock premium features and by-pass the limits.

{USER_SUBSCRIPTION_PLAN_PRICES.map((plan) => { const isCurrentPlanSelected = currentPlan?.priceId === plan.priceId; const isYearly = plan.interval === 'year'; return (

{isYearly ? 'Yearly Payment' : 'Monthly Payment'}

{isYearly && ( (2 months free) )}
{isYearly && ( Most Popular )}
{isYearly && (

$ {calculateYearlyPrice( USER_SUBSCRIPTION_PLAN_PRICES[0].amount, )}

)}

${plan.amount}{' '} / {isYearly ? 'year' : 'month'}

); })}
)}
); }