diff --git a/src/app/api/children/[id]/route.ts b/src/app/api/children/[id]/route.ts index 68a5ca5..eaf0de8 100644 --- a/src/app/api/children/[id]/route.ts +++ b/src/app/api/children/[id]/route.ts @@ -63,7 +63,7 @@ export async function POST( { expiresIn: 3600 } ); - return NextResponse.json({ uploadUrl, publicUrl: `${baseUrl}/${r2Key}` }); + return NextResponse.json({ uploadUrl, key: r2Key, publicUrl: `${baseUrl}/${r2Key}` }); } // PATCH — update child profile fields (imageUrl, and extensible for name/etc later) diff --git a/src/app/page.tsx b/src/app/page.tsx index 55284dd..7400d3d 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -188,17 +188,23 @@ export default function HomePage() { if (!file || !childId) return; setUploadingPhoto(true); try { - // 1. Get presigned R2 URL - const presignRes = await fetch(`/api/children/${childId}`, { + // 1. Get R2 key + public URL from server + const initRes = await fetch(`/api/children/${childId}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ contentType: file.type, filename: file.name }), }); - if (!presignRes.ok) throw new Error("Failed to get upload URL"); - const { uploadUrl, publicUrl } = await presignRes.json(); + if (!initRes.ok) throw new Error("Failed to get upload URL"); + const { key, publicUrl } = await initRes.json(); - // 2. Upload directly to R2 - await fetch(uploadUrl, { method: "PUT", body: file, headers: { "Content-Type": file.type } }); + // 2. Upload via server proxy — avoids CORS on direct R2 PUT + const putParams = new URLSearchParams({ key, contentType: file.type }); + const putRes = await fetch(`/api/upload?${putParams}`, { + method: "PUT", + body: file, + headers: { "Content-Type": file.type }, + }); + if (!putRes.ok) throw new Error("Upload failed"); // 3. Save URL to DB await fetch(`/api/children/${childId}`, { @@ -211,6 +217,7 @@ export default function HomePage() { updateChildImage(childId, publicUrl); } catch (err) { console.error("Photo upload failed:", err); + alert("Photo upload failed. Please try again."); } setUploadingPhoto(false); if (photoInputRef.current) photoInputRef.current.value = "";