import { ShowBase, useShowContext, useTranslate, useListContext, useDataProvider, useNotify, useRedirect, } from "ra-core"; import { useQuery } from "@tanstack/react-query"; import { useEffect } from "react"; import { ReferenceField } from "@/components/ds/admin/reference-field"; import { ReferenceManyField } from "@/components/ds/admin/reference-many-field"; import { TextField } from "@/components/ds/admin/text-field"; import { DateField } from "@/components/ds/admin/date-field"; import { FunctionField } from "@/components/ds/admin/function-field"; import { Card, CardContent, CardHeader, CardTitle, } from "@/components/ds/ui/card"; import { Separator } from "@/components/ds/ui/separator"; import { CompanyLogo } from "../companies/CompanyLogo"; import { NoteCreate } from "../notes/NoteCreate"; import { NotesIterator } from "../notes/NotesIterator"; import type { Invoice, InvoiceItem } from "../types"; import { InvoiceAside } from "./InvoiceAside"; import { InvoiceStatusBadge } from "./InvoiceStatusBadge"; export const InvoiceShow = () => ( ); const InvoiceShowContent = () => { const { record, isPending, error } = useShowContext(); const translate = useTranslate(); const dataProvider = useDataProvider(); const notify = useNotify(); const redirect = useRedirect(); // Handle error (invoice not found) useEffect(() => { if (error) { notify("Invoice not found or has been deleted", { type: "error" }); redirect("/invoices"); } }, [error, notify, redirect]); // Fetch business profile for sender branding const { data: businessProfile } = useQuery({ queryKey: ["business_profile"], queryFn: async () => { try { const { data } = await dataProvider.getOne("business_profile", { id: 1, }); return data; } catch { return null; } }, }); if (isPending || !record) return null; return (
{businessProfile?.logo?.src ? ( {businessProfile.name} ) : ( record.company_id && ( ) )}
{translate("resources.invoices.name", { smart_count: 1 })}{" "} #{record.invoice_number}
{record.reference && (

{translate("resources.invoices.fields.reference")}:{" "} {record.reference}

)}
{/* Sender Info (Address/Tax ID) */} {businessProfile && (

{businessProfile.name}

{businessProfile.address && (

{businessProfile.address}

)} {businessProfile.tax_id && (

{translate("resources.business_profile.fields.tax_id")}:{" "} {businessProfile.tax_id}

)}
)}
{/* Invoice Details */}

{translate("resources.invoices.section.details")}

{translate("resources.invoices.fields.issue_date")}:
{translate("resources.invoices.fields.due_date")}:
{record.paid_at && (
{translate("resources.invoices.fields.paid_at")}:
)}

{translate("resources.invoices.section.billing")}

{record.company_id && (
{translate("resources.invoices.fields.company_id")}:
)} {record.contact_id && (
{translate("resources.invoices.fields.contact_id")}:
`${r.first_name} ${r.last_name}` } />
)} {record.deal_id && (
{translate("resources.invoices.fields.deal_id")}:
)}
{/* Line Items */}

{translate("resources.invoices.section.items")}

{/* Totals */}
{translate("resources.invoices.fields.subtotal")}: {record.currency} {record.subtotal.toFixed(2)}
{record.discount > 0 && (
{translate("resources.invoices.fields.discount")}: {record.discount_type === "percentage" ? `-${record.discount}%` : `-${record.currency} ${record.discount.toFixed(2)}`}
)}
{translate("resources.invoices.fields.tax_total")}: {record.currency} {record.tax_total.toFixed(2)}
{translate("resources.invoices.fields.total")}: {record.currency} {record.total.toFixed(2)}
{record.amount_paid > 0 && ( <>
{translate("resources.invoices.fields.amount_paid")}: {record.currency} {record.amount_paid.toFixed(2)}
{translate("resources.invoices.fields.balance_due")}: {record.currency}{" "} {(record.total - record.amount_paid).toFixed(2)}
)}
{/* Notes, Terms & Conditions */}
{record.notes && (

{translate("resources.invoices.fields.notes")}:

{record.notes}

)} {record.payment_terms && (

{translate("resources.invoices.fields.payment_terms")}:

{record.payment_terms}

)} {record.terms_and_conditions && (

{translate( "resources.invoices.fields.terms_and_conditions", )} :

{record.terms_and_conditions}

)} {businessProfile?.bank_details && (

{translate( "resources.business_profile.fields.bank_details", )} :

{businessProfile.bank_details}

)}
{/* Activity Notes (Hidden from print) */}

{translate("resources.invoices.section.activity")}

{translate("resources.invoices.section.activity_description")}

} >
); }; const InvoiceItemsTable = ({ currency }: { currency: string }) => { const translate = useTranslate(); const { data } = useListContext(); if (!data || data.length === 0) { return (

{translate("resources.invoices.empty_items")}

); } return (
{data.map((item, index) => ( ))}
{translate("resources.invoices.item.name")} {translate("resources.invoices.item.quantity")} {translate("resources.invoices.item.unit_price")} {translate("resources.invoices.item.tax")} {translate("resources.invoices.item.total")}

{item.description}

{item.item_description && (

{item.item_description}

)} {item.item_type !== "service" && (

{translate( `resources.invoices.item_type.${item.item_type}`, )}

)}
{item.quantity} {currency} {item.unit_price.toFixed(2)} {item.tax_rate > 0 ? (

{item.tax_rate}%

{item.tax_name && (

{item.tax_name}

)}
) : ( "-" )}
{currency} {item.line_total_with_tax.toFixed(2)}
); };