diff --git a/web/src/pages/ProductForm.jsx b/web/src/pages/ProductForm.jsx index def5e1a..4a7748b 100644 --- a/web/src/pages/ProductForm.jsx +++ b/web/src/pages/ProductForm.jsx @@ -107,6 +107,9 @@ export default function ProductForm() { const [bildVersion, setBildVersion] = useState(0); // Ob gerade ein Bild vorliegt – steuert, ob „Entfernen" angeboten wird. const [hatBild, setHatBild] = useState(false); + // Beim Neuanlegen gibt es noch keine Produkt-ID zum Hochladen: Foto zwischen- + // speichern und nach dem Anlegen hochladen. { file, url } | null. + const [pendingPhoto, setPendingPhoto] = useState(null); const selectedUnit = units.find((u) => String(u.id) === String(form.unit_id)) || null; const unitFactor = selectedUnit ? selectedUnit.factor : 1; @@ -198,10 +201,18 @@ export default function ProductForm() { async function onPickPhoto(e) { const file = e.target.files?.[0]; e.target.value = ""; // erlaubt, dieselbe Datei erneut zu wählen - if (!file || isNew) return; + if (!file) return; setError(null); try { const foto = await verkleinereBild(file); + if (isNew) { + // Noch keine ID – Foto vormerken und erst nach dem Anlegen hochladen. + setPendingPhoto((alt) => { + if (alt?.url) URL.revokeObjectURL(alt.url); + return { file: foto, url: URL.createObjectURL(foto) }; + }); + return; + } await api.uploadProductImage(id, foto); setBildVersion((v) => v + 1); toast("Foto gespeichert."); @@ -210,6 +221,13 @@ export default function ProductForm() { } } + function removePendingPhoto() { + setPendingPhoto((alt) => { + if (alt?.url) URL.revokeObjectURL(alt.url); + return null; + }); + } + async function removePhoto() { const ok = await confirm({ title: "Foto entfernen?", confirmLabel: "Entfernen", danger: true, @@ -507,6 +525,16 @@ export default function ProductForm() { try { if (isNew) { const created = await api.createProduct(buildPayload()); + // Vorgemerktes Foto jetzt hochladen – ein Fehler dabei darf das Anlegen + // nicht zunichte machen, der Artikel existiert bereits. + if (pendingPhoto) { + try { + await api.uploadProductImage(created.id, pendingPhoto.file); + } catch (err) { + toast(`Artikel angelegt, aber Foto fehlgeschlagen: ${err.message}`, "warn"); + } + removePendingPhoto(); + } navigate(`/products/${created.id}`); } else { await api.updateProduct(id, buildPayload()); @@ -601,9 +629,13 @@ export default function ProductForm() { set("brand", e.target.value)} disabled={readOnly} /> - {!isNew && ( + {(!isNew || isAdmin) && (