import { canSee } from "@/lib/session"; import { getPortalSession } from "@/lib/get-session"; import { loadTenantForShell } from "@/lib/portal-data"; import { Panel } from "@/components/portal/Panel"; import { NotAllowed } from "@/components/portal/NotAllowed"; import { CreditCard, AlertTriangle } from "lucide-react"; const EUR = new Intl.NumberFormat("de-DE", { style: "currency", currency: "EUR" }); export default async function BillingPage({ params, }: { params: Promise<{ slug: string }>; }) { const { slug } = await params; const session = await getPortalSession(); if (!canSee(session, "billing")) return ; const t = await loadTenantForShell(slug); if (!t) return null; const monthlyVAT = Math.round(t.monthly * 0.19); const monthlyGross = t.monthly + monthlyVAT; const seatsPct = t.seats.total > 0 ? (t.seats.used / t.seats.total) * 100 : 0; const evidenceStorageUsed = t.metrics.evidence; const evidenceStorageMax = 1000; const evidencePct = (evidenceStorageUsed / evidenceStorageMax) * 100; const frozen = t.status === "frozen"; return (
Billing
Plan, usage, payment method and invoice history
PLAN
{t.plan}
{t.planCode}
MONTHLY
{EUR.format(t.monthly)}
+ 19% VAT = {EUR.format(monthlyGross)}
SEATS {t.seats.used} / {t.seats.total}
EVIDENCE STORAGE {evidenceStorageUsed} / {evidenceStorageMax} GB
90 ? "warn" : ""}`}>
{frozen ? (
Payment failed
) : (
SEPA Direct Debit
DE89 •••• •••• 7421 · {t.contact}
)}
Renews on
{t.renewal}
Billing email
{t.contactEmail}
Currency
EUR
VAT applied
19% (DE)
{t.invoices.length} entries} pad={false}> {t.invoices.map((inv) => ( ))}
Invoice Period Issued Seats Net VAT Total Status
{inv.id} {inv.period} {inv.issued} {inv.seats} {EUR.format(inv.net)} {EUR.format(inv.vat)} {EUR.format(inv.total)} {inv.status === "due" ? "Due" : "Paid"}
); }