import { useState, useRef, useCallback } from "react"; const API_URL = "https://api.anthropic.com/v1/messages"; const STYLES = [ { id: "luxury", label: "🏙️ Luxury Modern", desc: "Blau-grau, LED, Marmor" }, { id: "nordic", label: "🪵 Nordic Minimal", desc: "Hell, Holz, clean" }, { id: "industrial", label: "🏭 Industrial", desc: "Beton, Stahl, roh" }, { id: "warm", label: "🕯️ Warm Cozy", desc: "Erdtöne, weich" }, { id: "futuristic", label: "🚀 Futuristic", desc: "Dunkel, Neon, High-Tech" }, ]; const OUTPUTS = [ { id: "chatgpt", label: "ChatGPT / DALL·E 3" }, { id: "midjourney", label: "Midjourney v6.1" }, { id: "firefly", label: "Adobe Firefly" }, { id: "stablediffusion", label: "Stable Diffusion" }, { id: "gemini", label: "Gemini" }, { id: "all", label: "🔄 Alle" }, ]; const FORMAT_LABELS = { chatgpt: "ChatGPT / DALL·E 3", midjourney: "Midjourney v6.1", firefly: "Adobe Firefly", stablediffusion: "Stable Diffusion XL", gemini: "Google Gemini", }; const FORMAT_COLORS = { chatgpt: "#10a37f", midjourney: "#7c5cfc", firefly: "#ff4444", stablediffusion: "#f5a623", gemini: "#4285f4", }; // Where each AI can be opened with prefilled text const AI_URLS = { chatgpt: (prompt) => `https://chatgpt.com/?q=${encodeURIComponent(prompt)}`, gemini: (prompt) => `https://gemini.google.com/app?q=${encodeURIComponent(prompt)}`, firefly: (_) => `https://firefly.adobe.com/generate/images`, midjourney: (_) => `https://www.midjourney.com/imagine`, stablediffusion: (_) => `https://stablediffusionweb.com/`, }; const AI_OPEN_NOTES = { chatgpt: "Prompt wird vorausgefüllt — Grundriss noch anhängen", gemini: "Prompt wird vorausgefüllt — Grundriss noch anhängen", firefly: "Firefly öffnen — Prompt kopieren & Grundriss hochladen", midjourney: "Midjourney öffnen — Prompt ins /imagine Feld einfügen", stablediffusion: "Stable Diffusion öffnen — Prompt einfügen", }; const STYLE_PROMPTS = { luxury: "elegant blue-grey color palette, cinematic ambient lighting, softly glowing LED accents, high-end modern furniture, marble and glass surfaces", nordic: "bright airy Scandinavian palette, natural wood textures, minimalist clean lines, warm white lighting, linen and oak materials", industrial: "exposed concrete walls, raw steel elements, Edison bulb lighting, dark matte finishes, urban loft atmosphere", warm: "warm earth tones, terracotta and cream palette, soft candlelike lighting, plush textiles, hygge atmosphere", futuristic: "dark high-tech interior, neon accent lighting, glossy surfaces, smart home elements, cyberpunk-inspired palette", }; export default function FloorplanPromptGen() { const [image, setImage] = useState(null); const [selectedStyle, setSelectedStyle] = useState("luxury"); const [selectedOutput, setSelectedOutput] = useState("chatgpt"); const [loading, setLoading] = useState(false); const [results, setResults] = useState(null); const [error, setError] = useState(null); const [dragging, setDragging] = useState(false); const [copied, setCopied] = useState(null); const fileInputRef = useRef(); const handleFile = useCallback(async (file) => { if (!file || !file.type.startsWith("image/")) return; const dataUrl = await new Promise(res => { const r = new FileReader(); r.onload = () => res(r.result); r.readAsDataURL(file); }); setImage({ file, dataUrl, base64: dataUrl.split(",")[1], mediaType: file.type }); setResults(null); setError(null); }, []); const onDrop = (e) => { e.preventDefault(); setDragging(false); if (e.dataTransfer.files[0]) handleFile(e.dataTransfer.files[0]); }; const generate = async () => { if (!image) return; setLoading(true); setError(null); setResults(null); const targets = selectedOutput === "all" ? ["chatgpt", "gemini", "midjourney", "firefly", "stablediffusion"] : [selectedOutput]; const styleDesc = STYLE_PROMPTS[selectedStyle]; const styleName = STYLES.find(s => s.id === selectedStyle)?.label || selectedStyle; const system = `Du bist ein Experte für 3D-Architektur-Visualisierung und Prompt-Engineering. Analysiere Grundrisse und generiere präzise Bildgenerierungs-Prompts. Antworte NUR mit einem JSON-Objekt, ohne Markdown-Backticks oder anderen Text.`; const user = `Analysiere diesen Grundriss und erstelle optimierte Prompts für ein ultra-detailliertes 3D-Architektur-Floorplan-Rendering. Gewählter Stil: ${styleName} Stil-Eigenschaften: ${styleDesc} Erkenne aus dem Grundriss alle Räume, Größen und besondere Merkmale. Generiere folgendes JSON: { "rooms_detected": ["Liste der erkannten Räume mit m²"], "layout_notes": "kurze Beschreibung des Layouts", "prompts": { ${targets.map(t => `"${t}": "vollständiger Prompt für ${FORMAT_LABELS[t]}"`).join(",\n ")} } } Prompt-Anforderungen: - Enthält "ultra-detailed 3D architectural floor plan rendering" - Isometrische Draufsicht von oben - Alle erkannten Räume mit korrekter Möblierung erwähnen - Stil: ${styleDesc} - Fotorealistisch, hochdetailliert Format-spezifisch: - chatgpt: Natürliche Sprache, sehr detailliert, alle Räume aufgelistet - gemini: Natürliche Sprache, strukturiert, präzise - midjourney: Englisch, Tags-Stil, endet mit --ar 9:16 --v 6.1 --stylize 300 - firefly: Englisch, Satzform, Firefly-optimiert - stablediffusion: Englisch, (tag:1.2) Gewichtung, nach ### negative prompt`; try { const resp = await fetch(API_URL, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ model: "claude-sonnet-4-20250514", max_tokens: 4000, system, messages: [{ role: "user", content: [ { type: "image", source: { type: "base64", media_type: image.mediaType, data: image.base64 } }, { type: "text", text: user } ] }] }) }); if (!resp.ok) throw new Error(`API Fehler ${resp.status}`); const data = await resp.json(); const text = data.content.map(i => i.text || "").join(""); const clean = text.replace(/```json|```/g, "").trim(); const parsed = JSON.parse(clean); setResults({ ...parsed, targets }); } catch (e) { setError(e.message); } finally { setLoading(false); } }; const copy = (text, id) => { navigator.clipboard.writeText(text).then(() => { setCopied(id); setTimeout(() => setCopied(null), 2000); }); }; const openInAI = (target, prompt) => { const urlFn = AI_URLS[target]; if (urlFn) window.open(urlFn(prompt), "_blank"); }; return (
Grundriss hochladen → Stil wählen → direkt in deiner KI öffnen