From 20d12f46d9521a00edd632a2edcc190fd8be080d Mon Sep 17 00:00:00 2001 From: DEls Date: Wed, 26 Aug 2026 23:03:41 +0200 Subject: [PATCH] feat(slip-preview): render PDFs in an iframe instead of download-only --- src/components/slip-preview.tsx | 70 +++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/components/slip-preview.tsx diff --git a/src/components/slip-preview.tsx b/src/components/slip-preview.tsx new file mode 100644 index 0000000..49e769e --- /dev/null +++ b/src/components/slip-preview.tsx @@ -0,0 +1,70 @@ +"use client"; + +import { Download, FileImage } from "lucide-react"; +import { PB_BASE_URL } from "@/lib/pb"; + +/** + * Renders a delivery-note slip image or PDF download link. + * + * `filename` is the PB file-store path PocketBase stores on the + * `delivery_notes.slip_image` field — shaped `recordId/collectionId/stored`. + * PB exposes the bytes at + * {PB_BASE_URL}/api/files/// + * so we split + reassemble + URL-encode to fetch from the browser. + * + * Shared between the PO detail view (existing) and the "Awaiting PO + * assignment" modal (new). Keep the URL builder consistent with + * api/delivery-notes/[id]/slip/route.ts which uses the same pattern + * server-side. + */ +export function SlipPreview({ filename }: { filename: string }) { + if (!filename) { + return ( +
+ + No slip uploaded for this delivery note. +
+ ); + } + const parts = filename.split("/"); + const recordId = parts[0]; + const collectionId = parts[1]; + const stored = parts.slice(2).join("/"); + const url = `${PB_BASE_URL}/api/files/${collectionId}/${recordId}/${encodeURIComponent(stored)}`; + const isPdf = filename.toLowerCase().endsWith(".pdf"); + return ( +
+ {isPdf ? ( + <> +