fix: photos lost on save, multi-upload only kept last file, thumbnails 400
recipe-form/API routes were never sending/persisting photos on create+update. PhotoUploader accumulated uploads via a stale closure over the photos prop, so only the last file of a multi-select survived. Once both were fixed, thumbnails still 400'd because Next's image optimizer blocks upstream hosts resolving to private/loopback IPs (localhost:9000 MinIO) — skip optimization for storage-hosted photos since they're already web-sized user uploads.
This commit is contained in:
@@ -29,6 +29,11 @@ export function PhotoUploader({
|
||||
async function handleFiles(files: FileList) {
|
||||
setUploading(true);
|
||||
try {
|
||||
// Accumulate locally instead of calling onChange(...photos, entry) per file —
|
||||
// `photos` is a stale closure over the prop from when handleFiles was called,
|
||||
// so multiple onChange calls in this loop would each overwrite the previous
|
||||
// one's addition instead of stacking (only the last uploaded file would stick).
|
||||
let next = photos;
|
||||
for (const file of Array.from(files)) {
|
||||
const res = await fetch("/api/v1/upload/presign", {
|
||||
method: "POST",
|
||||
@@ -38,8 +43,9 @@ export function PhotoUploader({
|
||||
if (!res.ok) continue;
|
||||
const { url, key } = await res.json() as { url: string; key: string };
|
||||
await fetch(url, { method: "PUT", body: file, headers: { "Content-Type": file.type } });
|
||||
const isFirst = photos.length === 0;
|
||||
onChange([...photos, { key, isCover: isFirst, preview: URL.createObjectURL(file) }]);
|
||||
const isFirst = next.length === 0;
|
||||
next = [...next, { key, isCover: isFirst, preview: URL.createObjectURL(file) }];
|
||||
onChange(next);
|
||||
}
|
||||
} finally {
|
||||
setUploading(false);
|
||||
@@ -65,6 +71,7 @@ export function PhotoUploader({
|
||||
<div key={photo.key} className="relative group h-24 w-24">
|
||||
<Image
|
||||
src={photo.preview || getPublicUrl(photo.key)}
|
||||
unoptimized
|
||||
alt="Recipe photo"
|
||||
fill
|
||||
className={`rounded-lg object-cover border-2 ${
|
||||
|
||||
Reference in New Issue
Block a user