"use client"; import { useEffect, useState } from "react"; interface SiteImage { key: string; url: string; label: string; updated_at: string | null; } export default function AdminImages() { const [images, setImages] = useState([]); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(null); const [editUrls, setEditUrls] = useState>({}); const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null); useEffect(() => { fetch("/api/admin/site-images") .then((r) => r.json()) .then((data) => { setImages(data.images || []); const urls: Record = {}; for (const img of data.images || []) { urls[img.key] = img.url; } setEditUrls(urls); }) .finally(() => setLoading(false)); }, []); const handleSave = async (key: string) => { setSaving(key); setMessage(null); try { const res = await fetch("/api/admin/site-images", { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ key, url: editUrls[key] }), }); const data = await res.json(); if (res.ok) { setMessage({ type: "success", text: `Image "${key}" mise à jour !` }); setImages((prev) => prev.map((img) => img.key === key ? { ...img, url: editUrls[key], updated_at: new Date().toISOString() } : img ) ); } else { setMessage({ type: "error", text: data.error || "Erreur" }); } } catch { setMessage({ type: "error", text: "Erreur réseau" }); } setSaving(null); }; if (loading) { return (

Images du site

Chargement...

); } return (

Images du site

Changez les URLs des images affichées sur le site. Collez un lien Noelshack, Unsplash, ou tout autre hébergeur d'images.

{message && (
{message.text}
)} {/* Info SQL */}

Si la sauvegarde échoue, créez la table dans Supabase (SQL Editor) :

{`CREATE TABLE site_images (
  key TEXT PRIMARY KEY,
  url TEXT NOT NULL,
  label TEXT,
  updated_at TIMESTAMPTZ DEFAULT NOW()
);`}
        
{images.map((img) => (
{/* Preview */}
{/* eslint-disable-next-line @next/next/no-img-element */} {img.label} { (e.target as HTMLImageElement).src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23666' viewBox='0 0 24 24'%3E%3Cpath d='M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z'/%3E%3C/svg%3E"; }} />
{/* Form */}

{img.label}

{img.key}
{img.updated_at && (

Modifié le{" "} {new Date(img.updated_at).toLocaleDateString("fr-FR", { day: "numeric", month: "short", year: "numeric", hour: "2-digit", minute: "2-digit", })}

)}
setEditUrls((prev) => ({ ...prev, [img.key]: e.target.value }))} placeholder="https://..." className="flex-1 px-4 py-2.5 bg-black/30 border border-dark-border rounded-xl text-white text-sm placeholder:text-white/20 focus:border-orange focus:ring-1 focus:ring-orange outline-none" />
))}
); }