"use client";
import { useState } from "react";
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 "@/core/logger";
import { openSsoLink } from "@/features/billing/utils/sso";
import { useInvoice, useCreateInvoiceSsoLink } from "@/features/billing/hooks";
import {
InvoiceItems,
InvoiceTotals,
InvoiceSummaryBar,
} from "@/features/billing/components/InvoiceDetail";
function InvoiceDetailSkeleton() {
return (
} title="Invoice">
{Array.from({ length: 5 }).map((_, i) => (
))}
);
}
export function InvoiceDetailContainer() {
const params = useParams();
const [loadingDownload, setLoadingDownload] = useState(false);
const [loadingPayment, setLoadingPayment] = useState(false);
const rawInvoiceParam = params["id"];
const invoiceIdParam = Array.isArray(rawInvoiceParam) ? rawInvoiceParam[0] : rawInvoiceParam;
const createSsoLinkMutation = useCreateInvoiceSsoLink();
const { data: invoice, error } = useInvoice(invoiceIdParam ?? "");
const isLoading = !invoice && !error;
const handleCreateSsoLink = (target: "view" | "download" | "pay" = "view") => {
void (async () => {
if (!invoice) return;
const isDownload = target === "download";
if (isDownload) setLoadingDownload(true);
else setLoadingPayment(true);
try {
const ssoLink = await createSsoLinkMutation.mutateAsync({ invoiceId: invoice.id, target });
openSsoLink(ssoLink.url, { newTab: !isDownload });
} catch (err) {
logger.error("Failed to create SSO link", err);
} finally {
if (isDownload) setLoadingDownload(false);
else setLoadingPayment(false);
}
})();
};
if (isLoading) return ;
if (error || !invoice) {
return (
}
title="Invoice"
backLink={{ label: "Back to Billing", href: "/account/billing" }}
>
);
}
return (
}
title={`Invoice #${invoice.id}`}
backLink={{ label: "Back to Billing", href: "/account/billing" }}
>
handleCreateSsoLink("download")}
onPay={() => handleCreateSsoLink("pay")}
/>
{invoice.status === "Paid" && (
Payment received
Paid on {invoice.paidDate || invoice.issuedAt}
)}
);
}
export default InvoiceDetailContainer;