Add reference size fields to product admin editor
- Add referenceWidthCm and referenceHeightCm to ProductDTO - Update toProductDTO to include reference size fields - Add reference size inputs to admin product edit page - Update updateProduct action to handle reference sizes - Rulers on personalization page use product reference size Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 4.5
parent
740d2bbd29
commit
0e14fc7981
@@ -285,6 +285,41 @@ export default async function EditProductPage({ params }: { params: { id: string
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<label htmlFor="referenceWidthCm" className="tag-label mb-2 block">
|
||||||
|
Reference width (cm)
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="referenceWidthCm"
|
||||||
|
name="referenceWidthCm"
|
||||||
|
type="number"
|
||||||
|
step="0.1"
|
||||||
|
min="0"
|
||||||
|
placeholder="e.g. 40"
|
||||||
|
defaultValue={product.referenceWidthCm ?? ''}
|
||||||
|
className="w-full border border-line bg-paper px-3 py-2 text-sm"
|
||||||
|
/>
|
||||||
|
<p className="mt-1 text-xs text-muted">Width of garment/object for ruler reference (optional)</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="referenceHeightCm" className="tag-label mb-2 block">
|
||||||
|
Reference height (cm)
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="referenceHeightCm"
|
||||||
|
name="referenceHeightCm"
|
||||||
|
type="number"
|
||||||
|
step="0.1"
|
||||||
|
min="0"
|
||||||
|
placeholder="e.g. 60"
|
||||||
|
defaultValue={product.referenceHeightCm ?? ''}
|
||||||
|
className="w-full border border-line bg-paper px-3 py-2 text-sm"
|
||||||
|
/>
|
||||||
|
<p className="mt-1 text-xs text-muted">Height of garment/object for ruler reference (optional)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="tag-label mb-2 block">Colors</label>
|
<label className="tag-label mb-2 block">Colors</label>
|
||||||
<ColorPicker
|
<ColorPicker
|
||||||
|
|||||||
@@ -168,6 +168,10 @@ export async function updateProduct(formData: FormData) {
|
|||||||
const showOnPersonalised = String(formData.get('showOnPersonalised') ?? '') === '1';
|
const showOnPersonalised = String(formData.get('showOnPersonalised') ?? '') === '1';
|
||||||
const showOnProducts = String(formData.get('showOnProducts') ?? '') === '1';
|
const showOnProducts = String(formData.get('showOnProducts') ?? '') === '1';
|
||||||
const collectionIds = formData.getAll('collections').map((v) => String(v));
|
const collectionIds = formData.getAll('collections').map((v) => String(v));
|
||||||
|
const referenceWidthCmInput = String(formData.get('referenceWidthCm') ?? '').trim();
|
||||||
|
const referenceHeightCmInput = String(formData.get('referenceHeightCm') ?? '').trim();
|
||||||
|
const referenceWidthCm = referenceWidthCmInput ? Number(referenceWidthCmInput) : null;
|
||||||
|
const referenceHeightCm = referenceHeightCmInput ? Number(referenceHeightCmInput) : null;
|
||||||
|
|
||||||
if (!id) throw new Error('Missing product id.');
|
if (!id) throw new Error('Missing product id.');
|
||||||
if (!name || !category || !priceDollars) {
|
if (!name || !category || !priceDollars) {
|
||||||
@@ -228,6 +232,8 @@ export async function updateProduct(formData: FormData) {
|
|||||||
photoRecolorable: boolean;
|
photoRecolorable: boolean;
|
||||||
showOnPersonalised: boolean;
|
showOnPersonalised: boolean;
|
||||||
showOnProducts: boolean;
|
showOnProducts: boolean;
|
||||||
|
referenceWidthCm: number | null;
|
||||||
|
referenceHeightCm: number | null;
|
||||||
imageUrl?: string;
|
imageUrl?: string;
|
||||||
imageUrlBack?: string;
|
imageUrlBack?: string;
|
||||||
printArea?: string;
|
printArea?: string;
|
||||||
@@ -247,6 +253,8 @@ export async function updateProduct(formData: FormData) {
|
|||||||
photoRecolorable,
|
photoRecolorable,
|
||||||
showOnPersonalised,
|
showOnPersonalised,
|
||||||
showOnProducts,
|
showOnProducts,
|
||||||
|
referenceWidthCm,
|
||||||
|
referenceHeightCm,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Only touch the front photo/print area if a new photo was actually uploaded —
|
// Only touch the front photo/print area if a new photo was actually uploaded —
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ export function toProductDTO(p: PrismaProduct, activePromotions: ActivePromotion
|
|||||||
printAreaBack: p.printAreaBack ? JSON.parse(p.printAreaBack) : null,
|
printAreaBack: p.printAreaBack ? JSON.parse(p.printAreaBack) : null,
|
||||||
printAreaWidthMm: p.printAreaWidthMm,
|
printAreaWidthMm: p.printAreaWidthMm,
|
||||||
printAreaHeightMm: p.printAreaHeightMm,
|
printAreaHeightMm: p.printAreaHeightMm,
|
||||||
|
referenceWidthCm: p.referenceWidthCm,
|
||||||
|
referenceHeightCm: p.referenceHeightCm,
|
||||||
imageUrl: p.imageUrl,
|
imageUrl: p.imageUrl,
|
||||||
imageUrlBack: p.imageUrlBack,
|
imageUrlBack: p.imageUrlBack,
|
||||||
photoRecolorable: p.photoRecolorable,
|
photoRecolorable: p.photoRecolorable,
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ export type ProductDTO = {
|
|||||||
printAreaBack: PrintArea | null;
|
printAreaBack: PrintArea | null;
|
||||||
printAreaWidthMm: number;
|
printAreaWidthMm: number;
|
||||||
printAreaHeightMm: number;
|
printAreaHeightMm: number;
|
||||||
|
referenceWidthCm: number | null;
|
||||||
|
referenceHeightCm: number | null;
|
||||||
imageUrl: string | null;
|
imageUrl: string | null;
|
||||||
imageUrlBack: string | null;
|
imageUrlBack: string | null;
|
||||||
photoRecolorable: boolean;
|
photoRecolorable: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user