From a1c6e022b8d282292cf7eca06c71221efdbab23f Mon Sep 17 00:00:00 2001 From: Andymick Date: Sat, 18 Jul 2026 10:36:51 +0100 Subject: [PATCH] Fix design spec measurements and add visual X/Y axis guides - Fixed conversion formula for accurate CM measurements - Add red dashed border around print area - Add blue X-axis line (horizontal, 0cm at left) - Add green Y-axis line (vertical, 0cm at top) - Add orange circles marking design element positions - Add reference legend explaining all visual guides - Element labels changed from E1, E2 for clarity --- src/app/api/orders/[id]/design-spec/route.ts | 191 +++++++++---------- 1 file changed, 91 insertions(+), 100 deletions(-) diff --git a/src/app/api/orders/[id]/design-spec/route.ts b/src/app/api/orders/[id]/design-spec/route.ts index 0344a40..092080c 100644 --- a/src/app/api/orders/[id]/design-spec/route.ts +++ b/src/app/api/orders/[id]/design-spec/route.ts @@ -42,10 +42,95 @@ export async function GET(req: Request, { params }: { params: { id: string } }) const printAreaWidthPx = DISPLAY * (printArea.wPct / 100); const printAreaHeightPx = DISPLAY * (printArea.hPct / 100); + + // Scale: how many pixels per millimeter const pxPerMm = printAreaWidthPx / printAreaWidthMm; - // Convert pixel positions to CM - const convertToCm = (px: number) => (px / pxPerMm / 10).toFixed(1); + // Convert pixel measurements to CM (divide by pxPerMm to get mm, then divide by 10 for cm) + const convertToCm = (px: number) => { + const mm = px / pxPerMm; + return (mm / 10).toFixed(1); + }; + + const printAreaStartX = DISPLAY * (printArea.xPct / 100); + const printAreaStartY = DISPLAY * (printArea.yPct / 100); + + const generateDesignSection = (designElements: any[], side: 'Front' | 'Back', placement: string | null, designPreview: string | null) => { + if (!designElements || designElements.length === 0) return ''; + + return ` +
+

${side} Design

+ + + + ${placement ? ` +
+

Design on product (reference only) — with measurement guides

+
+ ${side} design placement + + + + + + + + + + + + ${designElements.map((el, idx) => ` + + E${idx + 1} + `).join('')} + +
+
+

━━ Red dashed: Print area boundary

+

━ Blue: X-axis (0cm at left)

+

━ Green: Y-axis (0cm at top)

+

● Orange circles: Element positions with labels (E1, E2, etc.)

+
+
+ ` : ''} + + + + + + + + + + + + + ${designElements.map((el, idx) => ` + + + + + + + + `).join('')} + +
ElementTypePosition (CM)Size (CM)Details
E${idx + 1}${el.type === 'text' ? '📝 Text' : '🖼️ Image'}X: ${convertToCm(el.x)} | Y: ${convertToCm(el.y)}${el.type === 'image' ? `${convertToCm(el.width)} × ${convertToCm(el.height)}` : 'N/A'} + ${el.type === 'text' ? ` + Font: ${el.fontFamily}, ${Math.round(el.fontSize / pxPerMm * 10 / 10)}pt
+ Color: ${el.fill}
+ Text: "${el.text}"
+ Rotation: ${Math.round(el.rotation)}° + ` : ` + Rotation: ${Math.round(el.rotation)}° + `} +
+
+ `; + }; const html = ` @@ -134,109 +219,15 @@ export async function GET(req: Request, { params }: { params: { id: string } })

Order Date: ${new Date(order.createdAt).toLocaleDateString()}

- ${design.front && design.front.length > 0 ? ` -
-

Front Design

- - - - ${item.placementPreviewUrl ? ` -
-

Design on product (reference only)

- Front design placement -
- ` : ''} - - - - - - - - - - - - - ${(design.front as any[]).map((el, idx) => ` - - - - - - - - `).join('')} - -
ElementTypePosition (CM)Size (CM)Details
${idx + 1}${el.type === 'text' ? '📝 Text' : '🖼️ Image'}X: ${convertToCm(el.x)} | Y: ${convertToCm(el.y)}${el.type === 'image' ? `${convertToCm(el.width)} × ${convertToCm(el.height)}` : 'N/A'} - ${el.type === 'text' ? ` - Font: ${el.fontFamily}, ${Math.round(el.fontSize / pxPerMm * 10 / 10)}pt
- Color: ${el.fill}
- Text: "${el.text}"
- Rotation: ${Math.round(el.rotation)}° - ` : ` - Rotation: ${Math.round(el.rotation)}° - `} -
-
- ` : ''} - - ${design.back && design.back.length > 0 ? ` -
-

Back Design

- - - - ${item.placementPreviewUrlBack ? ` -
-

Design on product (reference only)

- Back design placement -
- ` : ''} - - - - - - - - - - - - - ${(design.back as any[]).map((el, idx) => ` - - - - - - - - `).join('')} - -
ElementTypePosition (CM)Size (CM)Details
${idx + 1}${el.type === 'text' ? '📝 Text' : '🖼️ Image'}X: ${convertToCm(el.x)} | Y: ${convertToCm(el.y)}${el.type === 'image' ? `${convertToCm(el.width)} × ${convertToCm(el.height)}` : 'N/A'} - ${el.type === 'text' ? ` - Font: ${el.fontFamily}, ${Math.round(el.fontSize / pxPerMm * 10 / 10)}pt
- Color: ${el.fill}
- Text: "${el.text}"
- Rotation: ${Math.round(el.rotation)}° - ` : ` - Rotation: ${Math.round(el.rotation)}° - `} -
-
- ` : ''} + ${generateDesignSection(design.front, 'Front', item.placementPreviewUrl, item.designPreviewUrl)} + ${generateDesignSection(design.back, 'Back', item.placementPreviewUrlBack, item.designPreviewUrlBack)}

Notes: