'use client'; import { Progress, Badge, Chip, Spinner } from "@heroui/react"; import { Button } from "@/components/ui/button"; import { Label } from "@/app/lib/components/label"; import { Customer, UsageResponse } from "@/app/lib/types/billing_types"; import { z } from "zod"; import { tokens } from "@/app/styles/design-tokens"; import { SectionHeading } from "@/components/ui/section-heading"; import { HorizontalDivider } from "@/components/ui/horizontal-divider"; import clsx from 'clsx'; import { getCustomerPortalUrl } from "../actions/billing.actions"; import { useState } from "react"; import { ArrowUpCircle } from "lucide-react"; import { BillingUpgradeModal } from "@/components/common/billing-upgrade-modal"; const planDetails = { free: { name: "Free Plan", color: "default" }, starter: { name: "Starter Plan", color: "primary" }, pro: { name: "Pro Plan", color: "secondary" } }; interface BillingPageProps { customer: z.infer; usage: z.infer; } function getDisplayStatus(status: string | undefined) { if (status === "active") { return "Active"; } else if (status === "past_due") { return "Past Due!"; } else { return "Inactive"; } } export function BillingPage({ customer, usage }: BillingPageProps) { const plan = customer.subscriptionPlan || "free"; const displayStatus = getDisplayStatus(customer.subscriptionStatus); const planInfo = planDetails[plan]; const [loading, setLoading] = useState(false); const [upgradeModalOpen, setUpgradeModalOpen] = useState(false); const [upgradeError, setUpgradeError] = useState(""); // show friendly values for credits const sanctionedCredits = Math.floor(usage.sanctionedCredits / (10 ** 6)); const availableCredits = Math.floor(usage.availableCredits / (10 ** 6)); const usedCredits = Math.ceil((usage.sanctionedCredits - usage.availableCredits) / (10 ** 6)); // Prepare usage metrics data const usageData = Object.entries(usage.usage) .map(([type, credits]) => ({ type, credits, totalUsedCredits: usage.sanctionedCredits - usage.availableCredits })) .sort((a, b) => b.credits - a.credits); async function handleManageSubscription() { setLoading(true); const returnUrl = new URL('/billing/callback', window.location.origin); returnUrl.searchParams.set('redirect', window.location.href); const url = await getCustomerPortalUrl(returnUrl.toString()); window.location.href = url; } return (

Billing

{/* Subscription Status Panel */}
Current Plan

{planInfo.name}

{displayStatus}
{(plan === "free" || plan === "starter") && ( )} {!loading && { e.preventDefault(); try { await handleManageSubscription(); } catch (err) { setUpgradeError("Failed to open subscription portal"); } }} > Manage Subscription } {loading && }
{/* Credits Overview Panel */}
Credits Overview
{/* Warning for negative credits */} {usage.availableCredits < 0 && (

⚠️ You have exceeded your credit limit. Please upgrade your plan or contact support to avoid service interruptions.

)} {/* Warning for high credit usage (>80%) */} {usage.availableCredits >= 0 && ((usage.sanctionedCredits - usage.availableCredits) / usage.sanctionedCredits) > 0.8 && (

⚠️ You have used more than 80% of your credits. Consider upgrading your plan to avoid interruptions.

)} {/* Credits Progress Bar */}
{/* Usage Metrics Panel */}
Usage split
{usageData.length === 0 ? (

No usage data yet

) : ( usageData.map(({ type, credits, totalUsedCredits }) => { const percentage = totalUsedCredits > 0 ? (credits / totalUsedCredits) * 100 : 0; return (
{Math.round(percentage)}%
); }) )}
setUpgradeModalOpen(false)} errorMessage={upgradeError} />
); }