diff --git a/frontend/src/pages/ShoppingPage.tsx b/frontend/src/pages/ShoppingPage.tsx index a4071e3..cbd2542 100644 --- a/frontend/src/pages/ShoppingPage.tsx +++ b/frontend/src/pages/ShoppingPage.tsx @@ -4,7 +4,7 @@ import type { ShoppingListDetail, ShoppingList, Store, Product } from '../api/sh import { fetchLists, createList, fetchListDetail, deleteList, addItem, updateItem, deleteItem, finishShopping, fetchStores, generateMagicList, - searchProducts, + searchProducts, createProduct, } from '../api/shopping' import Modal from '../components/Modal' import ItemRow from '../components/shopping/ItemRow' @@ -44,6 +44,7 @@ export default function ShoppingPage() { const [selectedProduct, setSelectedProduct] = useState(null) const [newItemQty, setNewItemQty] = useState('') const [newItemUnit, setNewItemUnit] = useState('') + const [addToCatalogue, setAddToCatalogue] = useState(true) useWakeLock(currentList !== null) @@ -109,6 +110,7 @@ export default function ShoppingPage() { setSelectedProduct(null) setNewItemQty('') setNewItemUnit('') + setAddToCatalogue(true) setShowAddItemModal(false) } @@ -120,13 +122,25 @@ export default function ShoppingPage() { async function handleAddItem() { if (!currentList) return - const hasProduct = selectedProduct !== null - const customName = hasProduct ? undefined : itemSearch.trim() - if (!hasProduct && !customName) return + const customName = itemSearch.trim() + if (!selectedProduct && !customName) return try { + let productId = selectedProduct?.id + + // Article libre + case "Ajouter au catalogue" cochée → créer le produit d'abord + if (!selectedProduct && customName && addToCatalogue) { + const newProduct = await createProduct({ + name: customName, + default_unit: newItemUnit || undefined, + }) + productId = newProduct.id + // Met à jour la liste locale des produits pour les prochains ajouts + setProducts(prev => [...prev, newProduct].sort((a, b) => a.name.localeCompare(b.name, 'fr'))) + } + await addItem(currentList.id, { - product_id: selectedProduct?.id, - custom_name: customName, + product_id: productId, + custom_name: !productId ? customName : undefined, quantity: newItemQty || undefined, unit: newItemUnit || undefined, }) @@ -425,7 +439,7 @@ export default function ShoppingPage() { color: 'var(--ink-4)', fontFamily: 'var(--font-ui)', fontSize: 13, textAlign: 'center', padding: '12px 16px', margin: 0, ...noSelect, }}> - {itemSearch.trim() ? `"${itemSearch}" — sera ajouté comme article libre` : 'Catalogue vide'} + {itemSearch.trim() ? `"${itemSearch}" — article libre` : 'Catalogue vide'}

)} {filteredProducts.map((p, idx) => { @@ -460,6 +474,21 @@ export default function ShoppingPage() { })} + {/* Case "Ajouter au catalogue" — uniquement si article libre sans correspondance */} + {!selectedProduct && itemSearch.trim() && filteredProducts.length === 0 && ( + + )} + {/* Quantité + Unité */}