fix conflict

This commit is contained in:
yaschalew
2026-07-02 09:28:02 +03:00
183 changed files with 10335 additions and 5286 deletions

View File

@@ -50,6 +50,7 @@ import {
useBookingDetail,
useBookingMutations,
} from "@/hooks/bookings/useBookings";
import { useScrollToHash } from "@/hooks/useScrollToHash";
import toast from "react-hot-toast";
// Signature / generated-contract files are surfaced on the contract page, not
@@ -65,6 +66,8 @@ export default function BookingRequestDetailPage() {
const { id } = useParams<{ id: string }>();
const navigate = useNavigate();
const [searchParams, setSearchParams] = useSearchParams();
// Deep-link from a warehouse fee invoice → this booking's warehouse section.
useScrollToHash();
const {
data: booking,
isLoading,
@@ -281,10 +284,12 @@ export default function BookingRequestDetailPage() {
<Stack gap="lg">
<BookingCompanyCard booking={booking} />
<BookingPricingSummary booking={booking} />
<WarehouseInfoCard
bookingId={booking.id}
bookingReference={booking.reference}
/>
<Box id="warehouse-payments">
<WarehouseInfoCard
bookingId={booking.id}
bookingReference={booking.reference}
/>
</Box>
<BookingActionsToolbar
booking={booking}
mutations={mutations}

View File

@@ -1,5 +1,6 @@
import { Button, Card } from '@mantine/core';
import { PackageSearch } from 'lucide-react';
import { useState } from 'react';
import { Button, Card, Group, Modal, Stack } from '@mantine/core';
import { PackageSearch, Truck } from 'lucide-react';
import { useNavigate } from 'react-router-dom';
import { PageContainer, PageHeader } from '@/components/page';
@@ -7,6 +8,7 @@ import { WarehouseFlowWorkbench } from '@/components/warehouses';
export default function ExportWarehouseFlowPage() {
const navigate = useNavigate();
const [receiveOpen, setReceiveOpen] = useState(false);
return (
<PageContainer>
@@ -14,15 +16,41 @@ export default function ExportWarehouseFlowPage() {
title="Export Operations"
subtitle="Manage export receive, terminal inventory, loading readiness, loaded items, and dispatch flow."
action={
<Button variant="light" leftSection={<PackageSearch size={16} />} onClick={() => navigate('/dashboard/import-warehouse')}>
Import Operations
</Button>
<Group gap="xs">
<Button
fw={700}
leftSection={<Truck size={16} />}
onClick={() => setReceiveOpen(true)}
>
Receive for Loading
</Button>
<Button variant="light" leftSection={<PackageSearch size={16} />} onClick={() => navigate('/dashboard/import-warehouse')}>
Import Operations
</Button>
</Group>
}
/>
<Card>
<WarehouseFlowWorkbench direction="EXPORT" />
</Card>
<Modal
opened={receiveOpen}
onClose={() => setReceiveOpen(false)}
title="Receive for loading"
centered
size="80rem"
>
<Stack gap="md">
<WarehouseFlowWorkbench enabled={receiveOpen} direction="EXPORT" />
<Group justify="flex-end">
<Button variant="default" onClick={() => setReceiveOpen(false)}>
Close
</Button>
</Group>
</Stack>
</Modal>
</PageContainer>
);
}

View File

@@ -15,7 +15,8 @@ import {
Text,
TextInput,
} from '@mantine/core';
import { Ban, CreditCard, DoorOpen, Download, Eye, Receipt, Search } from 'lucide-react';
import { Ban, CreditCard, DoorOpen, Download, ExternalLink, Eye, Receipt, Search } from 'lucide-react';
import { useNavigate } from 'react-router-dom';
import { DataTable, type ColumnDef } from '@edr/ui-common';
import { PageContainer, PageHeader } from '@/components/page';
@@ -31,7 +32,7 @@ import {
type WarehouseInvoiceStatus,
} from '@/types/warehouse';
import { openPdfBlob } from '@/components/warehouses/pdf';
import { buildWarehouseExitPaperPdf, buildWarehouseInvoicePdf } from '@/components/warehouses/warehousePdf';
import { buildWarehouseExitPaperPdf } from '@/components/warehouses/warehousePdf';
import { extractErrorMessage } from '@/components/warehouses/options';
const STATUS_COLOR: Record<WarehouseInvoiceStatus, string> = {
@@ -155,6 +156,7 @@ export default function WarehouseInvoicesPage() {
function InvoiceDetailModal({ id, onClose }: { id: string | null; onClose: () => void }) {
const { toast } = useToast();
const navigate = useNavigate();
const { data: inv, isLoading } = useQuery(
api.warehouses.invoice.queryOptions({
input: { id: id ?? '' },
@@ -172,13 +174,33 @@ function InvoiceDetailModal({ id, onClose }: { id: string | null; onClose: () =>
const canGateClear = inv?.status === 'PAID' && Boolean(inv.inventoryId);
const downloadInvoicePdf = async (invoice: WarehouseFeeInvoice) => {
const blob = buildWarehouseInvoicePdf(invoice, 'INVOICE');
openPdfBlob(blob, `warehouse-invoice-${invoice.invoiceNumber}.pdf`);
const pdfWindow = window.open('', '_blank');
try {
const { data } = await warehouseService.downloadInvoiceDocument(invoice.id);
openPdfBlob(data, `warehouse-invoice-${invoice.invoiceNumber}.pdf`, pdfWindow);
} catch (error) {
pdfWindow?.close();
toast({
variant: 'destructive',
title: 'Download failed',
description: extractErrorMessage(error),
});
}
};
const downloadReceiptPdf = async (invoice: WarehouseFeeInvoice) => {
const blob = buildWarehouseInvoicePdf(invoice, 'RECEIPT');
openPdfBlob(blob, `warehouse-receipt-${invoice.invoiceNumber}.pdf`);
const pdfWindow = window.open('', '_blank');
try {
const { data } = await warehouseService.downloadInvoiceReceipt(invoice.id);
openPdfBlob(data, `warehouse-receipt-${invoice.invoiceNumber}.pdf`, pdfWindow);
} catch (error) {
pdfWindow?.close();
toast({
variant: 'destructive',
title: 'Download failed',
description: extractErrorMessage(error),
});
}
};
const getExitPaperContext = async (invoice: WarehouseFeeInvoice) => {
@@ -366,6 +388,20 @@ function InvoiceDetailModal({ id, onClose }: { id: string | null; onClose: () =>
)}
<Group justify="flex-end" mt="sm">
{inv.bookingId && (
<Button
variant="subtle"
color="gray"
leftSection={<ExternalLink size={16} />}
onClick={() =>
navigate(
`/dashboard/booking-requests/${inv.bookingId}#warehouse-payments`,
)
}
>
View booking
</Button>
)}
<Button
variant="light"
color="gray"