"use client"; import { useState } from "react"; import { toast } from "sonner"; import { Check } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { cn } from "@/lib/utils"; type Tier = "free" | "pro" | "family"; type PlanCard = { tier: Tier; name: string; monthlyPrice: string; yearlyPrice: string | null; features: string[]; purchasable: boolean; }; export function BillingPlanCards({ currentTier, plans }: { currentTier: Tier; plans: PlanCard[] }) { const [checkingOut, setCheckingOut] = useState(null); async function checkout(tier: "pro" | "family") { setCheckingOut(tier); try { const res = await fetch("/api/v1/billing/checkout", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ tier, interval: "month" }), }); if (!res.ok) { const data = await res.json().catch(() => ({})); throw new Error((data as { error?: string }).error ?? "Checkout failed"); } const { url } = (await res.json()) as { url: string }; window.location.assign(url); } catch (err) { toast.error(err instanceof Error ? err.message : "Checkout failed"); setCheckingOut(null); } } return (
{plans.map((plan) => { const isCurrent = plan.tier === currentTier; return (
{plan.name} {isCurrent && Current plan}

{plan.monthlyPrice}

    {plan.features.map((f) => (
  • {f}
  • ))}
{!isCurrent && plan.purchasable && plan.tier !== "free" && ( )} {!isCurrent && !plan.purchasable && plan.tier !== "free" && (

Not available yet — pricing not configured.

)}
); })}
); }