diff --git a/src/routes/admin/approval/[id].tsx b/src/routes/admin/approval/[id].tsx index d72fc03..e55f5b5 100644 --- a/src/routes/admin/approval/[id].tsx +++ b/src/routes/admin/approval/[id].tsx @@ -3,6 +3,24 @@ import { createMemo, createResource, createSignal, For, Show, createEffect } fro const API = ''; +// Documents submitted for verification are stored as permanent Backblaze URLs. +// Never render one of those directly (img src / a href) — always exchange it for +// a short-lived signed URL through this endpoint first, on demand. +async function presignDocUrl(url: string): Promise { + try { + const res = await fetch(`${API}/api/admin/verifications/presign`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ url }), + }); + if (!res.ok) return url; + const data = await res.json(); + return data?.url ?? url; + } catch { + return url; + } +} + // ── Types ────────────────────────────────────────────────────────── type RoleType = @@ -475,23 +493,11 @@ function SubmissionViewer(props: { rows: Array<{ key: string; value: string }> }
setLightbox({ src: field.value, label })} + onClick={async () => setLightbox({ src: await presignDocUrl(field.value), label })} > - {label} { - (e.target as HTMLImageElement).style.display = 'none'; - ((e.target as HTMLImageElement).nextElementSibling as HTMLElement)!.style.display = 'flex'; - }} - /> -
+
🖼 - Preview unavailable -
-
- 🔍 Click to enlarge + Click to view
@@ -499,7 +505,7 @@ function SubmissionViewer(props: { rows: Array<{ key: string; value: string }> }
setPdfViewer({ src: field.value, label })} + onClick={async () => setPdfViewer({ src: await presignDocUrl(field.value), label })} > 📄 PDF Document @@ -511,11 +517,17 @@ function SubmissionViewer(props: { rows: Array<{ key: string; value: string }> } @@ -529,7 +541,7 @@ function SubmissionViewer(props: { rows: Array<{ key: string; value: string }> } @@ -538,15 +550,21 @@ function SubmissionViewer(props: { rows: Array<{ key: string; value: string }> } - +