import { NextRequest, NextResponse } from 'next/server' import { writeFile, mkdir } from 'fs/promises' import path from 'path' import { randomUUID } from 'crypto' import { getDb } from '@/lib/db' import { convertHeicToJpeg } from '@/lib/heic' export const runtime = 'nodejs' export const maxDuration = 60 const DATA_DIR = path.resolve(process.cwd(), process.env.DATA_DIR || 'data') const PHOTO_MIMES: Record = { 'image/jpeg': true, 'image/jpg': true, 'image/png': true, 'image/webp': true, 'image/gif': true, 'image/heic': true, 'image/heif': true, } const VIDEO_MIMES: Record = { 'video/mp4': true, 'video/quicktime': true, 'video/x-msvideo': true, 'video/webm': true, } // GET: List all pending/approved family uploads export async function GET() { const db = getDb() const uploads = db .prepare("SELECT * FROM media WHERE status IN ('pending', 'approved') ORDER BY created_at DESC") .all() return NextResponse.json(uploads) } export async function POST(req: NextRequest) { const formData = await req.formData() const file = formData.get('file') as File | null const name = formData.get('name') as string | null const email = formData.get('email') as string | null const relation = formData.get('relation') as string | null if (!file) { return NextResponse.json({ error: 'Datei erforderlich' }, { status: 400 }) } let mimeType = file.type?.toLowerCase() || '' const ext = path.extname(file.name).toLowerCase() if (!mimeType && (ext === '.heic' || ext === '.heif')) { mimeType = 'image/heic' } let type: 'photo' | 'video' let uploadDir: string if (PHOTO_MIMES[mimeType]) { type = 'photo' uploadDir = 'photos' } else if (VIDEO_MIMES[mimeType]) { type = 'video' uploadDir = 'videos' } else { return NextResponse.json( { error: 'Nur Fotos und Videos erlaubt' }, { status: 400 } ) } const buffer = Buffer.from(await file.arrayBuffer()) // Convert HEIC/HEIF to JPEG so all browsers can display it let finalBuffer: Buffer = buffer let finalExt = ext if (mimeType === 'image/heic' || mimeType === 'image/heif') { try { finalBuffer = await convertHeicToJpeg(buffer) finalExt = '.jpg' } catch { // Conversion failed — keep original } } const filename = `${uploadDir}/${randomUUID()}${finalExt || '.bin'}` const filePath = path.join(DATA_DIR, 'uploads', filename) await mkdir(path.dirname(filePath), { recursive: true }) await writeFile(filePath, finalBuffer) // Build caption with uploader info let caption = `Von ${(name || 'Anonym').trim()}` if (relation?.trim()) caption += ` (${relation.trim()})` const db = getDb() const result = db .prepare( "INSERT INTO media (filename, original_name, type, caption, status) VALUES (?, ?, ?, ?, 'pending')" ) .run(filename, file.name, type, caption) const media = db .prepare('SELECT * FROM media WHERE id = ?') .get(result.lastInsertRowid) return NextResponse.json(media, { status: 201 }) }