"use client"; import { useRef, useState } from "react"; import Link from "next/link"; import useSWR from "swr"; import { Image as ImageIcon, Download, Wand2, MessageSquare, Sparkles, X } from "lucide-react"; import { api, fetcher, fmtUsd, relTime } from "@/lib/client/fetcher"; import { useModels } from "@/lib/client/use-models"; import { Button, Empty, Spinner, cn, toast, Badge } from "../ui"; interface GenImage { id: string; filename: string; meta: { prompt?: string; model?: string; revisedPrompt?: string; size?: string; quality?: string; editedFrom?: string }; conversation_id: string | null; created_at: string } const SIZES = ["1024x1024", "1536x1024", "1024x1536"]; const QUALITIES = [["low", "basse"], ["medium", "moyenne"], ["high", "haute"]]; export function ImageStudio() { const { models } = useModels(true); const imageModels = models.filter(m => m.kind === "image" && m.available); const { data, mutate } = useSWR<{ images: GenImage[] }>("/api/images", fetcher); const [prompt, setPrompt] = useState(""); const [model, setModel] = useState(""); const [size, setSize] = useState(SIZES[0]); const [quality, setQuality] = useState("medium"); const [edit, setEdit] = useState(null); const [busy, setBusy] = useState(false); const [result, setResult] = useState<{ attachmentId: string; model: string; costUsd?: number | null } | null>(null); const ta = useRef(null); const chosen = model || (imageModels.find(m => m.id === "gpt-image-1.5")?.id ?? imageModels[0]?.id ?? ""); async function generate() { setBusy(true); setResult(null); try { const r = await api<{ attachmentId: string; model: string; costUsd?: number | null; error?: string }>("/api/images", { method: "POST", json: { prompt: prompt.trim(), model: chosen || undefined, size, quality, editAttachmentId: edit?.id } }); if (r.error) throw new Error(r.error); setResult(r); setEdit(null); void mutate(); toast(edit ? "Image modifiée" : "Image générée", "ok"); } catch (e) { toast((e as Error).message, "error"); } finally { setBusy(false); } } function startEdit(img: GenImage) { setEdit(img); setPrompt(""); ta.current?.focus(); window.scrollTo({ top: 0, behavior: "smooth" }); } return (

Images

Génération et retouche avec les modèles image OpenAI vérifiés. Chaque image est conservée dans l'historique ci-dessous.

{edit &&
Retouche de l'image sélectionnée{edit.meta.prompt}
}