pdfs
This commit is contained in:
@@ -464,6 +464,19 @@ export const api = {
|
||||
token
|
||||
);
|
||||
},
|
||||
async getShipmentPackingSlipPdf(token: string, shipmentId: string) {
|
||||
const response = await fetch(`/api/v1/documents/shipping/shipments/${shipmentId}/packing-slip.pdf`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new ApiError("Unable to render packing slip PDF.", "PACKING_SLIP_FAILED");
|
||||
}
|
||||
|
||||
return response.blob();
|
||||
},
|
||||
async getCompanyProfilePreviewPdf(token: string) {
|
||||
const response = await fetch("/api/v1/documents/company-profile-preview.pdf", {
|
||||
headers: {
|
||||
|
||||
@@ -15,6 +15,7 @@ export function ShipmentDetailPage() {
|
||||
const [relatedShipments, setRelatedShipments] = useState<ShipmentSummaryDto[]>([]);
|
||||
const [status, setStatus] = useState("Loading shipment...");
|
||||
const [isUpdatingStatus, setIsUpdatingStatus] = useState(false);
|
||||
const [isRenderingPdf, setIsRenderingPdf] = useState(false);
|
||||
|
||||
const canManage = user?.permissions.includes(permissions.shippingWrite) ?? false;
|
||||
|
||||
@@ -55,6 +56,27 @@ export function ShipmentDetailPage() {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleOpenPackingSlip() {
|
||||
if (!token || !shipment) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsRenderingPdf(true);
|
||||
setStatus("Rendering packing slip PDF...");
|
||||
try {
|
||||
const blob = await api.getShipmentPackingSlipPdf(token, shipment.id);
|
||||
const objectUrl = URL.createObjectURL(blob);
|
||||
window.open(objectUrl, "_blank", "noopener,noreferrer");
|
||||
window.setTimeout(() => URL.revokeObjectURL(objectUrl), 60_000);
|
||||
setStatus("Packing slip PDF rendered.");
|
||||
} catch (error: unknown) {
|
||||
const message = error instanceof ApiError ? error.message : "Unable to render packing slip PDF.";
|
||||
setStatus(message);
|
||||
} finally {
|
||||
setIsRenderingPdf(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!shipment) {
|
||||
return <div className="rounded-[28px] border border-line/70 bg-surface/90 p-4 text-sm text-muted shadow-panel">{status}</div>;
|
||||
}
|
||||
@@ -72,6 +94,9 @@ export function ShipmentDetailPage() {
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<Link to="/shipping/shipments" className="inline-flex items-center justify-center rounded-2xl border border-line/70 px-2 py-2 text-sm font-semibold text-text">Back to shipments</Link>
|
||||
<Link to={`/sales/orders/${shipment.salesOrderId}`} className="inline-flex items-center justify-center rounded-2xl border border-line/70 px-2 py-2 text-sm font-semibold text-text">Open sales order</Link>
|
||||
<button type="button" onClick={handleOpenPackingSlip} disabled={isRenderingPdf} className="inline-flex items-center justify-center rounded-2xl border border-line/70 px-2 py-2 text-sm font-semibold text-text disabled:cursor-not-allowed disabled:opacity-60">
|
||||
{isRenderingPdf ? "Rendering PDF..." : "Open packing slip"}
|
||||
</button>
|
||||
{canManage ? (
|
||||
<Link to={`/shipping/shipments/${shipment.id}/edit`} className="inline-flex items-center justify-center rounded-2xl bg-brand px-2 py-2 text-sm font-semibold text-white">Edit shipment</Link>
|
||||
) : null}
|
||||
|
||||
Reference in New Issue
Block a user