import type { Metadata } from "next"; import Link from "next/link"; import { FileText, AudioLines, ImageIcon, Repeat, Infinity as InfinityIcon } from "lucide-react"; import { requireAuth } from "@/lib/auth/guards"; import { getEffectivePlan } from "@/lib/billing/subscription"; import { getUsageSummary } from "@/lib/usage/meter"; import { PageHeader } from "@/components/app/page-header"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Progress } from "@/components/ui/progress"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { UNLIMITED, type UsageMetric } from "@/lib/billing/plans"; export const metadata: Metadata = { title: "Usage" }; const METRICS: { key: UsageMetric; label: string; icon: React.ComponentType<{ className?: string }> }[] = [ { key: "script", label: "Scripts", icon: FileText }, { key: "audio", label: "Audio generations", icon: AudioLines }, { key: "art", label: "Cover art", icon: ImageIcon }, { key: "repurpose", label: "Repurposed content", icon: Repeat }, ]; function nextResetLabel(): string { const now = new Date(); const next = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 1)); return next.toLocaleDateString(undefined, { month: "long", day: "numeric" }); } export default async function UsagePage() { const session = await requireAuth(); const { plan, key, subjectId } = await getEffectivePlan( session.user.id, session.session.activeOrganizationId ); const usage = await getUsageSummary(subjectId); return ( <> Upgrade plan ) : undefined } />
Current plan {plan.name}
{METRICS.map((m) => { const used = usage[m.key]; const limit = plan.limits[m.key]; const unlimited = limit === UNLIMITED; const pct = unlimited ? 0 : Math.min(100, Math.round((used / Math.max(1, limit)) * 100)); const atLimit = !unlimited && used >= limit; return ( {m.label} {atLimit && Limit reached}
{used} {unlimited ? ( <> Unlimited ) : ( <>of {limit} )}
{!unlimited && ( )}
); })}
); }