"use client"; import { useState } from "react"; import Link from "next/link"; import { useParams } from "next/navigation"; import { LoadingCard, Skeleton } from "@/components/atoms/loading-skeleton"; import { ErrorState } from "@/components/atoms/error-state"; import { CheckCircleIcon, DocumentTextIcon } from "@heroicons/react/24/outline"; import { PageLayout } from "@/components/templates/PageLayout"; import { logger } from "@customer-portal/logging"; import { apiClient, getDataOrThrow } from "@/lib/api"; import { openSsoLink } from "@/features/billing/utils/sso"; import { useInvoice, useCreateInvoiceSsoLink } from "@/features/billing/hooks"; import type { InvoiceSsoLink } from "@customer-portal/domain/billing"; import { InvoiceItems, InvoiceTotals, InvoiceSummaryBar, } from "@/features/billing/components/InvoiceDetail"; export function InvoiceDetailContainer() { const params = useParams(); const [loadingDownload, setLoadingDownload] = useState(false); const [loadingPayment, setLoadingPayment] = useState(false); const [loadingPaymentMethods, setLoadingPaymentMethods] = useState(false); const rawInvoiceParam = params.id; const invoiceIdParam = Array.isArray(rawInvoiceParam) ? rawInvoiceParam[0] : rawInvoiceParam; const invoiceId = Number.parseInt(invoiceIdParam ?? "", 10); const createSsoLinkMutation = useCreateInvoiceSsoLink(); const { data: invoice, isLoading, error } = useInvoice(invoiceIdParam ?? ""); const handleCreateSsoLink = (target: "view" | "download" | "pay" = "view") => { void (async () => { if (!invoice) return; if (target === "download") setLoadingDownload(true); else setLoadingPayment(true); try { const ssoLink = await createSsoLinkMutation.mutateAsync({ invoiceId: invoice.id, target }); if (target === "download") openSsoLink(ssoLink.url, { newTab: false }); else openSsoLink(ssoLink.url, { newTab: true }); } catch (err) { logger.error(err, "Failed to create SSO link"); } finally { if (target === "download") setLoadingDownload(false); else setLoadingPayment(false); } })(); }; const handleManagePaymentMethods = () => { void (async () => { setLoadingPaymentMethods(true); try { const response = await apiClient.POST("/auth/sso-link", { body: { path: "index.php?rp=/account/paymentmethods" }, }); const sso = getDataOrThrow( response, "Failed to create payment methods SSO link" ); openSsoLink(sso.url, { newTab: true }); } catch (err) { logger.error(err, "Failed to create payment methods SSO link"); } finally { setLoadingPaymentMethods(false); } })(); }; if (isLoading) { return ( } title="Invoice" description="Invoice details and actions" >
{Array.from({ length: 5 }).map((_, i) => (
))}
); } if (error || !invoice) { return ( } title="Invoice" description="Invoice details and actions" >
← Back to invoices
); } return (
{/* Navigation */}
Back to Invoices
{/* Main Invoice Card */}
handleCreateSsoLink("download")} onPay={() => handleCreateSsoLink("pay")} /> {/* Success Banner for Paid Invoices */} {invoice.status === "Paid" && (

Payment Received

Paid on {invoice.paidDate || invoice.issuedAt}

)} {/* Content */}
{/* Invoice Items */} {/* Invoice Summary - Full Width */}
); } export default InvoiceDetailContainer;