fix: the invoice and receipt documents in the booking

This commit is contained in:
Nathnael
2026-07-22 08:00:38 +00:00
parent 905bf75bce
commit 16dc143e66
2 changed files with 112 additions and 61 deletions

View File

@@ -211,10 +211,6 @@ export function BookingPaymentPanel({
queryKey: ["booking-invoices", booking.id], queryKey: ["booking-invoices", booking.id],
queryFn: () => invoicesService.listForSource("booking", booking.id), queryFn: () => invoicesService.listForSource("booking", booking.id),
}); });
// The invoice worth a prominent "Download" — the first issued one, else any.
const primary =
invoices.find((inv) => inv.status !== "DRAFT") ?? invoices[0];
const primaryPaid = primary ? Number(primary.paidAmount) > 0 : false;
const downloadInvoice = async (inv: PortalInvoice) => { const downloadInvoice = async (inv: PortalInvoice) => {
try { try {
@@ -380,50 +376,67 @@ export function BookingPaymentPanel({
</Box> </Box>
<Group gap={8} wrap="nowrap"> <Group gap={8} wrap="nowrap">
<InvoiceStatusBadge status={inv.status} /> <InvoiceStatusBadge status={inv.status} />
<ActionIcon {invoices.length > 1 && (
variant="subtle" <>
color="gray" <ActionIcon
aria-label="Download invoice" variant="subtle"
onClick={() => downloadInvoice(inv)} color="gray"
> aria-label="Download invoice"
<Download size={16} /> onClick={() => downloadInvoice(inv)}
</ActionIcon> >
<Download size={16} />
</ActionIcon>
{Number(inv.paidAmount) > 0 && (
<ActionIcon
variant="subtle"
color="gray"
aria-label="Download receipt"
onClick={() => downloadReceipt(inv)}
>
<Receipt size={16} />
</ActionIcon>
)}
</>
)}
</Group> </Group>
</Group> </Group>
))} ))}
</Stack> </Stack>
</>
)}
{primary && ( {/* Single invoice: a prominent download instead of a lone row icon. */}
<Button {invoices.length === 1 && (
fullWidth <>
mt={16} <Button
variant="default" fullWidth
radius={10} mt={16}
leftSection={<FileText size={17} color="#475569" />} variant="default"
onClick={() => downloadInvoice(primary)} radius={10}
styles={{ leftSection={<FileText size={17} color="#475569" />}
root: { height: 46 }, onClick={() => downloadInvoice(invoices[0])}
label: { fontSize: 13.5, fontWeight: 700, color: "#10202F" }, styles={{
}} root: { height: 46 },
> label: { fontSize: 13.5, fontWeight: 700, color: "#10202F" },
Download invoice }}
</Button> >
)} Download invoice
{primary && primaryPaid && ( </Button>
<Button {Number(invoices[0].paidAmount) > 0 && (
fullWidth <Button
mt={8} fullWidth
variant="subtle" mt={8}
color="gray" variant="subtle"
radius={10} color="gray"
leftSection={<Receipt size={17} />} radius={10}
onClick={() => downloadReceipt(primary)} leftSection={<Receipt size={17} />}
styles={{ root: { height: 42 }, label: { fontSize: 13, fontWeight: 700 } }} onClick={() => downloadReceipt(invoices[0])}
> styles={{ root: { height: 42 }, label: { fontSize: 13, fontWeight: 700 } }}
Download receipt >
</Button> Download receipt
</Button>
)}
</>
)}
</>
)} )}
</SectionCard> </SectionCard>
); );

View File

@@ -1,6 +1,6 @@
import { ActionIcon, Box, Button, Group, Stack, Text } from "@mantine/core"; import { ActionIcon, Box, Button, Group, Stack, Text } from "@mantine/core";
import { useMutation, useQuery } from "@tanstack/react-query"; import { useMutation, useQuery } from "@tanstack/react-query";
import { CreditCard, Download, Receipt } from "lucide-react"; import { CreditCard, Download, FileText, Receipt } from "lucide-react";
import { useState } from "react"; import { useState } from "react";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
@@ -184,23 +184,27 @@ export function WarehousePaymentsSection({ bookingId }: { bookingId: string }) {
Pay Pay
</Button> </Button>
)} )}
<ActionIcon {invoices.length > 1 && (
variant="subtle" <>
color="gray" <ActionIcon
aria-label="Download invoice" variant="subtle"
onClick={() => download(inv)} color="gray"
> aria-label="Download invoice"
<Download size={16} /> onClick={() => download(inv)}
</ActionIcon> >
{Number(inv.paidAmount) > 0 && ( <Download size={16} />
<ActionIcon </ActionIcon>
variant="subtle" {Number(inv.paidAmount) > 0 && (
color="gray" <ActionIcon
aria-label="Download receipt" variant="subtle"
onClick={() => downloadReceipt(inv)} color="gray"
> aria-label="Download receipt"
<Receipt size={16} /> onClick={() => downloadReceipt(inv)}
</ActionIcon> >
<Receipt size={16} />
</ActionIcon>
)}
</>
)} )}
</Group> </Group>
</Group> </Group>
@@ -208,6 +212,40 @@ export function WarehousePaymentsSection({ bookingId }: { bookingId: string }) {
})} })}
</Stack> </Stack>
{/* Single invoice: a prominent download instead of a lone row icon. */}
{invoices.length === 1 && (
<>
<Button
fullWidth
mt="md"
variant="default"
radius={10}
leftSection={<FileText size={17} color="#475569" />}
onClick={() => download(invoices[0])}
styles={{
root: { height: 46 },
label: { fontSize: 13.5, fontWeight: 700, color: "#10202F" },
}}
>
Download invoice
</Button>
{Number(invoices[0].paidAmount) > 0 && (
<Button
fullWidth
mt={8}
variant="subtle"
color="gray"
radius={10}
leftSection={<Receipt size={17} />}
onClick={() => downloadReceipt(invoices[0])}
styles={{ root: { height: 42 }, label: { fontSize: 13, fontWeight: 700 } }}
>
Download receipt
</Button>
)}
</>
)}
<PaymentMethodModal <PaymentMethodModal
opened={payInvoice !== null} opened={payInvoice !== null}
onClose={closePayModal} onClose={closePayModal}