From 2f39a7241adf35dbb649b182261bc1d5cefc379e Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Mon, 20 Apr 2026 22:29:19 +0200 Subject: [PATCH] fix: persist crop preview in ImageUpload via initialCrop prop Crop values were stored in DB but never passed back to ImageUpload on reload, causing images to revert to object-contain. Now both admin and user item pages pass persisted crop data so the cropped view displays correctly. Co-Authored-By: Claude Opus 4.6 --- src/client/components/ImageUpload.tsx | 4 +++- src/client/routes/admin/items/$itemId.tsx | 9 +++++++++ src/client/routes/items/$itemId.tsx | 9 +++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/client/components/ImageUpload.tsx b/src/client/components/ImageUpload.tsx index dc32397..32be5d9 100644 --- a/src/client/components/ImageUpload.tsx +++ b/src/client/components/ImageUpload.tsx @@ -8,6 +8,7 @@ interface ImageUploadProps { value: string | null; imageUrl?: string | null; dominantColor?: string | null; + initialCrop?: { zoom: number; x: number; y: number } | null; onChange: (filename: string | null, dominantColor?: string | null) => void; onCropChange?: (crop: { zoom: number; x: number; y: number }) => void; } @@ -19,6 +20,7 @@ export function ImageUpload({ value: _value, imageUrl, dominantColor, + initialCrop, onChange, onCropChange, }: ImageUploadProps) { @@ -31,7 +33,7 @@ export function ImageUpload({ zoom: number; x: number; y: number; - } | null>(null); + } | null>(initialCrop ?? null); const inputRef = useRef(null); async function handleFileChange(e: React.ChangeEvent) { diff --git a/src/client/routes/admin/items/$itemId.tsx b/src/client/routes/admin/items/$itemId.tsx index 1476ee9..b42d586 100644 --- a/src/client/routes/admin/items/$itemId.tsx +++ b/src/client/routes/admin/items/$itemId.tsx @@ -291,6 +291,15 @@ function AdminItemEditPage() { value={form.imageFilename} imageUrl={form.imageUrl || null} dominantColor={form.dominantColor || null} + initialCrop={ + form.cropZoom != null + ? { + zoom: form.cropZoom, + x: form.cropX ?? 0, + y: form.cropY ?? 0, + } + : null + } onChange={(filename, dominantColor) => { setForm((prev) => ({ ...prev, diff --git a/src/client/routes/items/$itemId.tsx b/src/client/routes/items/$itemId.tsx index f412bde..16f1d1a 100644 --- a/src/client/routes/items/$itemId.tsx +++ b/src/client/routes/items/$itemId.tsx @@ -346,6 +346,15 @@ function ItemDetail() { value={form.imageFilename} imageUrl={imageUrl} dominantColor={item.dominantColor} + initialCrop={ + item.cropZoom != null + ? { + zoom: item.cropZoom, + x: item.cropX ?? 0, + y: item.cropY ?? 0, + } + : null + } onChange={(filename, dominantColor) => { setForm((f) => ({ ...f, imageFilename: filename })); if (dominantColor) {