Untitled
unknown
plain_text
2 months ago
4.8 kB
3
Indexable
// app/api/comments/route.ts import { NextResponse } from "next/server"; // Interface for comment structure interface Comment { id: string; photoId: string; name: string; rating: number; text: string; createdAt: string; } // Interface for comment index interface CommentIndex { [photoId: string]: number; // photoId -> comment count } // Helper to get R2 paths const getR2Path = (clientId: string, path: string) => { return `${clientId}/comments/${path}`; }; // Helper to fetch JSON from R2 async function fetchJsonFromR2(key: string): Promise<any> { try { // Use R2 public URL if available const publicUrl = `${process.env.NEXT_PUBLIC_R2_PUBLIC_URL}/${key}`; const response = await fetch(publicUrl, { cache: 'no-store', headers: { 'Cache-Control': 'no-cache' } }); if (!response.ok) { if (response.status === 404) { return null; // File doesn't exist } throw new Error(`Failed to fetch from R2: ${response.status}`); } return await response.json(); } catch (error) { console.error(`Error fetching from R2: ${key}`, error); return null; } } // Helper to upload JSON to R2 async function uploadJsonToR2(key: string, data: any): Promise<boolean> { try { // Use the R2 proxy endpoint (create this endpoint next) const uploadUrl = `/api/r2-upload?key=${encodeURIComponent(key)}`; const response = await fetch(uploadUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data), }); if (!response.ok) { throw new Error(`Failed to upload to R2: ${response.status}`); } return true; } catch (error) { console.error(`Error uploading to R2: ${key}`, error); return false; } } export async function GET(request: Request) { try { const { searchParams } = new URL(request.url); const photoId = searchParams.get("photoId"); const clientId = searchParams.get("clientId"); const getIndex = searchParams.get("index") === "true"; if (!clientId) { return NextResponse.json( { error: "Client ID is required" }, { status: 400 } ); } // If requesting the index if (getIndex) { const indexPath = getR2Path(clientId, 'index.json'); const index = await fetchJsonFromR2(indexPath); return NextResponse.json(index || {}); } // If requesting comments for a specific photo if (!photoId) { return NextResponse.json( { error: "Photo ID is required" }, { status: 400 } ); } const commentsPath = getR2Path(clientId, `${photoId}.json`); const comments = await fetchJsonFromR2(commentsPath); return NextResponse.json(comments || []); } catch (error) { console.error("Error fetching comments:", error); return NextResponse.json( { error: "Failed to fetch comments" }, { status: 500 } ); } } export async function POST(request: Request) { try { const body = await request.json(); const { photoId, clientId, name, rating, text } = body; if (!photoId || !text || !clientId) { return NextResponse.json( { error: "Photo ID, Client ID, and text are required" }, { status: 400 } ); } // Create paths for R2 storage const commentsPath = getR2Path(clientId, `${photoId}.json`); const indexPath = getR2Path(clientId, 'index.json'); // Fetch existing comments or create empty array let comments: Comment[] = await fetchJsonFromR2(commentsPath) || []; // Create new comment const newComment: Comment = { id: Date.now().toString(), photoId, name: name || "Anonym", rating: rating || 0, text, createdAt: new Date().toISOString() }; // Add comment to beginning of array comments.unshift(newComment); // Upload comments to R2 const commentUploadSuccess = await uploadJsonToR2(commentsPath, comments); if (!commentUploadSuccess) { throw new Error("Failed to upload comments to R2"); } // Update index in R2 const index: CommentIndex = await fetchJsonFromR2(indexPath) || {}; index[photoId] = comments.length; const indexUploadSuccess = await uploadJsonToR2(indexPath, index); if (!indexUploadSuccess) { console.warn("Failed to update comment index in R2"); } return NextResponse.json(newComment); } catch (error) { console.error("Error creating comment:", error); return NextResponse.json( { error: "Failed to create comment" }, { status: 500 } ); } }
Editor is loading...
Leave a Comment