'use client'; import { useState } from 'react'; import { InspectMode } from './InspectMode'; import { PromptReuseButton } from './PromptReuseButton'; import { CompletedTimerBadge } from './GenerationTimer'; import { CodeExamplesWidget } from './CodeExamplesWidget'; const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000'; interface EnhancementOptionsData { imageStyle?: string; aspectRatio?: string; mood?: string; lighting?: string; cameraAngle?: string; negativePrompts?: string[]; } interface GenerationResult { id: string; timestamp: Date; originalPrompt: string; enhancedPrompt?: string; leftImage: { url: string; width: number; height: number; error?: string; } | null; rightImage: { url: string; width: number; height: number; error?: string; } | null; durationMs?: number; leftData?: { request: object; response: object; geminiParams: object; }; rightData?: { request: object; response: object; geminiParams: object; }; enhancementOptions?: EnhancementOptionsData; } interface ResultCardProps { result: GenerationResult; apiKey: string; onZoom: (url: string) => void; onCopy: (text: string) => void; onDownload: (url: string, filename: string) => void; onReusePrompt: (prompt: string) => void; } type ViewMode = 'preview' | 'inspect'; export function ResultCard({ result, apiKey, onZoom, onCopy, onDownload, onReusePrompt, }: ResultCardProps) { const [viewMode, setViewMode] = useState('preview'); // Build enhancement options JSON for code examples const buildEnhancementOptionsJson = () => { if (!result.enhancementOptions) return ''; const opts: any = {}; if (result.enhancementOptions.imageStyle) opts.imageStyle = result.enhancementOptions.imageStyle; if (result.enhancementOptions.aspectRatio) opts.aspectRatio = result.enhancementOptions.aspectRatio; if (result.enhancementOptions.mood) opts.mood = result.enhancementOptions.mood; if (result.enhancementOptions.lighting) opts.lighting = result.enhancementOptions.lighting; if (result.enhancementOptions.cameraAngle) opts.cameraAngle = result.enhancementOptions.cameraAngle; if (result.enhancementOptions.negativePrompts) opts.negativePrompts = result.enhancementOptions.negativePrompts; if (Object.keys(opts).length === 0) return ''; return JSON.stringify(opts, null, 2) .split('\n') .map((line, i) => (i === 0 ? line : ` ${line}`)) .join('\n'); }; const enhancementOptionsJson = buildEnhancementOptionsJson(); const hasEnhancementOptions = !!result.enhancementOptions; const curlCode = hasEnhancementOptions ? `# Right image (with enhancement options) curl -X POST ${API_BASE_URL}/api/text-to-image \\ -H "Content-Type: application/json" \\ -H "X-API-Key: ${apiKey}" \\ -d '{ "prompt": "${result.originalPrompt.replace(/"/g, '\\"')}", "filename": "generated_image", "enhancementOptions": ${enhancementOptionsJson.replace(/\n/g, '\n ')} }'` : `curl -X POST ${API_BASE_URL}/api/text-to-image \\ -H "Content-Type: application/json" \\ -H "X-API-Key: ${apiKey}" \\ -d '{ "prompt": "${result.originalPrompt.replace(/"/g, '\\"')}", "filename": "generated_image" }'`; const fetchCode = hasEnhancementOptions ? `// Right image (with enhancement options) fetch('${API_BASE_URL}/api/text-to-image', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': '${apiKey}' }, body: JSON.stringify({ prompt: '${result.originalPrompt.replace(/'/g, "\\'")}', filename: 'generated_image', enhancementOptions: ${enhancementOptionsJson} }) }) .then(res => res.json()) .then(data => console.log(data));` : `fetch('${API_BASE_URL}/api/text-to-image', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': '${apiKey}' }, body: JSON.stringify({ prompt: '${result.originalPrompt.replace(/'/g, "\\'")}', filename: 'generated_image' }) }) .then(res => res.json()) .then(data => console.log(data));`; const restCode = hasEnhancementOptions ? `### Right Image - With Enhancement Options POST ${API_BASE_URL}/api/text-to-image Content-Type: application/json X-API-Key: ${apiKey} { "prompt": "${result.originalPrompt.replace(/"/g, '\\"')}", "filename": "generated_image", "enhancementOptions": ${enhancementOptionsJson} }` : `### Generate Image - Text to Image POST ${API_BASE_URL}/api/text-to-image Content-Type: application/json X-API-Key: ${apiKey} { "prompt": "${result.originalPrompt.replace(/"/g, '\\"')}", "filename": "generated_image" }`; const codeExamples = { curl: curlCode, fetch: fetchCode, rest: restCode, }; return (
{/* Header */}
{result.timestamp.toLocaleString()} {result.durationMs && }
{/* View Mode Toggle */}
{/* Content */} {viewMode === 'preview' ? ( <> {/* Image Comparison */}
{/* Left Image */} {/* Right Image */}
{/* API Code Examples */} ) : ( )}
); } // Image Preview Component function ImagePreview({ image, label, prompt, onZoom, onDownload, onReusePrompt, filename, hasEnhancementOptions = false, }: { image: GenerationResult['leftImage']; label: string; prompt: string; onZoom: (url: string) => void; onDownload: (url: string, filename: string) => void; onReusePrompt: (prompt: string) => void; filename: string; hasEnhancementOptions?: boolean; }) { const [promptExpanded, setPromptExpanded] = useState(false); const [urlCopied, setUrlCopied] = useState(false); const copyImageUrl = () => { if (image?.url) { navigator.clipboard.writeText(image.url); setUrlCopied(true); setTimeout(() => setUrlCopied(false), 2000); } }; return (
{label} {hasEnhancementOptions && ( + Options )}
{image?.error ? (
⚠️
{image.error}
) : ( image && ( <>
{label} onZoom(image.url)} />
{/* Image URL with Copy Button */}
{image.url}
) )} {/* Prompt with Truncation */}

{prompt}

{prompt.length > 150 && ( )}
); }