"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { useTranslations } from "next-intl"; import { Card } from "@/components/ui/card"; interface OrgEntry { zitadelOrgId: string; companyName: string | null; country: string | null; hasSavedCard: boolean; cardLabel: string | null; payByInvoice: boolean; autoChargeEnabled: boolean; } interface Props { orgs: OrgEntry[]; } /** * Inline toggles for pay_by_invoice and auto_charge_enabled per * org. Each toggle round-trips to /api/admin/billing/orgs/[orgId] * /payment-mode and then router.refresh() so the server-fetched * state stays canonical (avoids drift between optimistic UI and * the DB). * * Phase 9b-2. */ export function OrgPaymentModeList({ orgs }: Props) { const t = useTranslations("adminBilling"); const router = useRouter(); const [busy, setBusy] = useState(null); const [error, setError] = useState(""); const toggle = async ( orgId: string, patch: { payByInvoice?: boolean; autoChargeEnabled?: boolean } ) => { setError(""); setBusy(orgId); try { const res = await fetch( `/api/admin/billing/orgs/${encodeURIComponent(orgId)}/payment-mode`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(patch), } ); const j = await res.json().catch(() => ({})); if (!res.ok) throw new Error(j.error || `HTTP ${res.status}`); router.refresh(); } catch (e: any) { setError(e.message); } finally { setBusy(null); } }; if (orgs.length === 0) { return (
{t("orgsEmpty")}
); } return ( {error && (
{error}
)} {orgs.map((o) => ( ))}
{t("orgsColCustomer")} {t("orgsColCard")} {t("orgsColPayByInvoice")} {t("orgsColAutoCharge")}
{o.companyName ?? ( {o.zitadelOrgId} )}
{o.country && (
{o.country}
)}
{o.hasSavedCard ? ( {o.cardLabel} ) : ( {t("orgsNoSavedCard")} )}
); }