'use client' import { useState, useEffect, useRef } from 'react' interface GalerieBild { id: string; storage_path: string; alt_text: string; reihenfolge: number; url: string } export function GalerieVerwaltung() { const [bilder, setBilder] = useState([]) const [uploading, setUploading] = useState(false) const [loading, setLoading] = useState(true) const fileRef = useRef(null) useEffect(() => { fetch('/api/admin/galerie').then(r => r.json()).then(({ bilder: b }) => { setBilder(b ?? []); setLoading(false) }) }, []) async function handleUpload(e: React.ChangeEvent) { const files = Array.from(e.target.files ?? []) if (!files.length) return setUploading(true) for (const file of files) { const fd = new FormData(); fd.append('file', file); fd.append('alt_text', file.name.replace(/\.[^.]+$/, '')) const res = await fetch('/api/admin/galerie', { method: 'POST', body: fd }) const { bild, error } = await res.json() if (bild) { const base = process.env.NEXT_PUBLIC_SUPABASE_URL ?? '' setBilder(prev => [...prev, { ...bild, url: `${base}/storage/v1/object/public/galerie-bilder/${bild.storage_path}` }]) } else { alert(error ?? 'Upload fehlgeschlagen') } } setUploading(false) if (fileRef.current) fileRef.current.value = '' } async function handleDelete(bild: GalerieBild) { if (!confirm(`"${bild.alt_text || bild.storage_path}" löschen?`)) return await fetch('/api/admin/galerie', { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: bild.id, storagePath: bild.storage_path }) }) setBilder(prev => prev.filter(b => b.id !== bild.id)) } async function move(index: number, dir: -1 | 1) { const newBilder = [...bilder] const target = index + dir if (target < 0 || target >= newBilder.length) return ;[newBilder[index], newBilder[target]] = [newBilder[target], newBilder[index]] const withOrder = newBilder.map((b, i) => ({ ...b, reihenfolge: i })) setBilder(withOrder) await fetch('/api/admin/galerie/sort', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ order: withOrder.map(b => ({ id: b.id, reihenfolge: b.reihenfolge })) }) }) } if (loading) return

Lade…

return (
{bilder.length} Bilder · Reihenfolge per ↑↓
{bilder.map((bild, i) => (
{/* eslint-disable-next-line @next/next/no-img-element */} {bild.alt_text}
{ await fetch('/api/admin/galerie', { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: bild.id, alt_text: e.target.value }) }) }} />
))}
) }