From c81f434a0b820d2a70470ed57812aec11b087c2b Mon Sep 17 00:00:00 2001 From: Andymick Date: Mon, 20 Jul 2026 20:35:24 +0100 Subject: [PATCH] Fix: Preserve print area when editing products PhotoPrintAreaField now accepts and loads existing print area coordinates when editing products. Previously, the component always initialized to DEFAULT_BOX, causing the saved print area to be lost when editing. Changes: - Export Box type from PhotoPrintAreaField - Add existingPrintArea prop to PhotoPrintAreaField - Initialize box state with existing print area if provided - Convert print area from database format (0-1 decimals) to component format (0-100 percentages) - Update edit page to parse and pass existing print area values Result: Print area masks now persist when editing products and adding them to different catalogs (ready-made, plain, etc). Co-Authored-By: Claude Haiku 4.5 --- src/app/admin/products/[id]/edit/page.tsx | 22 +++++++++++++++++++--- src/components/PhotoPrintAreaField.tsx | 6 ++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/app/admin/products/[id]/edit/page.tsx b/src/app/admin/products/[id]/edit/page.tsx index f83fad9..ef35582 100644 --- a/src/app/admin/products/[id]/edit/page.tsx +++ b/src/app/admin/products/[id]/edit/page.tsx @@ -6,7 +6,7 @@ import { updateProduct } from '../../actions'; import AdminNav from '@/components/AdminNav'; import ColorPicker from '@/components/ColorPicker'; import SizePicker from '@/components/SizePicker'; -import PhotoPrintAreaField from '@/components/PhotoPrintAreaField'; +import PhotoPrintAreaField, { type Box } from '@/components/PhotoPrintAreaField'; import { MOCKUP_OPTIONS } from '@/lib/mockupDefaults'; export default async function EditProductPage({ params }: { params: { id: string } }) { @@ -21,6 +21,22 @@ export default async function EditProductPage({ params }: { params: { id: string const recipients = collections.filter((c) => c.group === 'RECIPIENT'); const selectedCollectionIds = new Set(row.collections.map((c) => c.id)); + // Parse print areas from database (stored as 0-1 decimals, component expects 0-100 percentages) + const printAreaData = row.printArea ? JSON.parse(row.printArea) : null; + const printAreaBack = row.printAreaBack ? JSON.parse(row.printAreaBack) : null; + const existingPrintArea = printAreaData ? { + xPct: printAreaData.xPct * 100, + yPct: printAreaData.yPct * 100, + wPct: printAreaData.wPct * 100, + hPct: printAreaData.hPct * 100, + } : undefined; + const existingPrintAreaBack = printAreaBack ? { + xPct: printAreaBack.xPct * 100, + yPct: printAreaBack.yPct * 100, + wPct: printAreaBack.wPct * 100, + hPct: printAreaBack.hPct * 100, + } : undefined; + return (
@@ -286,12 +302,12 @@ export default async function EditProductPage({ params }: { params: { id: string
- +
- +
diff --git a/src/components/PhotoPrintAreaField.tsx b/src/components/PhotoPrintAreaField.tsx index 7f4e11f..70497a8 100644 --- a/src/components/PhotoPrintAreaField.tsx +++ b/src/components/PhotoPrintAreaField.tsx @@ -2,7 +2,7 @@ import { useRef, useState } from 'react'; -type Box = { xPct: number; yPct: number; wPct: number; hPct: number }; // 0-100 +export type Box = { xPct: number; yPct: number; wPct: number; hPct: number }; // 0-100 const DEFAULT_BOX: Box = { xPct: 30, yPct: 25, wPct: 40, hPct: 35 }; const MIN_SIZE = 6; // percent @@ -10,12 +10,14 @@ const MIN_SIZE = 6; // percent export default function PhotoPrintAreaField({ variant = 'front', existingImageUrl, + existingPrintArea, }: { variant?: 'front' | 'back'; existingImageUrl?: string; + existingPrintArea?: Box; }) { const [previewUrl, setPreviewUrl] = useState(null); - const [box, setBox] = useState(DEFAULT_BOX); + const [box, setBox] = useState(existingPrintArea || DEFAULT_BOX); const [showPrintAreaEditor, setShowPrintAreaEditor] = useState(false); const [isRemoved, setIsRemoved] = useState(false); const containerRef = useRef(null);