feat: auto-fill mockup dimensions and family from Google Sheets

- Extend Sheets read range from A1:Z to A1:AZ (52 columns)
- Parse longueur, largeur, marque, famille, sousFamille, prixRemise, specificFields
- Add /api/products/sheet-info endpoint to fetch product data by ref
- Auto-fill family and dimensions on product selection in all 3 mockup entry points
- Strengthen carrelage mockup prompt with strict tile-size consistency rules

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-26 13:35:39 +02:00
parent 4f617b15b2
commit ac58289bb7
7 changed files with 142 additions and 35 deletions
+5 -3
View File
@@ -57,16 +57,18 @@ export function MockupModal({ product, onClose }: Props) {
fetch('/api/mockup/templates').then(r => r.json()),
fetch('/api/sheets/tabs').then(r => r.json()),
fetch(`/api/mockup/product-meta/${product.shopifyId}`).then(r => r.json()),
]).then(([tplData, tabsData, metaData]) => {
product.ref ? fetch(`/api/products/sheet-info?ref=${encodeURIComponent(product.ref)}`).then(r => r.ok ? r.json() : null) : Promise.resolve(null),
]).then(([tplData, tabsData, metaData, sheetData]) => {
setTemplates(tplData as MockupTemplate[])
const tabs: string[] = (tabsData.tabs ?? []).filter((t: string) =>
!['COLLECTIONS', 'LIVRAISONS', 'ECOPART', 'RECAP'].some(x => t.toUpperCase().includes(x))
)
setFamilies(tabs)
setFamily(tabs[0] ?? '')
const sheetFamille = sheetData?.product?.famille
setFamily(sheetFamille && tabs.includes(sheetFamille) ? sheetFamille : tabs[0] ?? '')
setMetafields(metaData.metafields ?? [])
}).finally(() => setLoadingMeta(false))
}, [product.shopifyId])
}, [product.shopifyId, product.ref])
const isCarrelage = family.toLowerCase().includes('carrelage')
+10 -3
View File
@@ -21,6 +21,7 @@ export function MockupModalFromImage({ item, onClose }: Props) {
const [templates, setTemplates] = useState<MockupTemplate[]>([])
const [families, setFamilies] = useState<string[]>([])
const [family, setFamily] = useState('')
const [dimensions, setDimensions] = useState('')
const [selectedTemplate, setSelectedTemplate] = useState<string | null>(null)
const [instruction, setInstruction] = useState('')
const [generating, setGenerating] = useState(false)
@@ -35,15 +36,20 @@ export function MockupModalFromImage({ item, onClose }: Props) {
Promise.all([
fetch('/api/mockup/templates').then(r => r.json()),
fetch('/api/sheets/tabs').then(r => r.json()),
]).then(([tplData, tabsData]) => {
item.ref ? fetch(`/api/products/sheet-info?ref=${encodeURIComponent(item.ref)}`).then(r => r.ok ? r.json() : null) : Promise.resolve(null),
]).then(([tplData, tabsData, sheetData]) => {
setTemplates(tplData as MockupTemplate[])
const tabs: string[] = (tabsData.tabs ?? []).filter((t: string) =>
!['COLLECTIONS', 'LIVRAISONS', 'ECOPART', 'RECAP'].some(x => t.toUpperCase().includes(x))
)
setFamilies(tabs)
setFamily(tabs[0] ?? '')
const sheetFamille = sheetData?.product?.famille
setFamily(sheetFamille && tabs.includes(sheetFamille) ? sheetFamille : tabs[0] ?? '')
const { longueur, largeur } = sheetData?.product ?? {}
if (longueur && largeur) setDimensions(`${longueur}x${largeur}cm`)
else if (longueur) setDimensions(`${longueur}cm`)
})
}, [])
}, [item.ref])
const filteredTemplates = templates.filter(t =>
t.family === family || t.family === 'Tous'
@@ -82,6 +88,7 @@ export function MockupModalFromImage({ item, onClose }: Props) {
productImageBase64,
productName: item.shopifyProductTitle ?? item.ref,
family: family || 'Tous',
dimensions: dimensions || undefined,
instruction: instruction || undefined,
}),
})