'use client'; import { useState } from 'react'; import { Sparkles, Loader2, ImageIcon, Video } from 'lucide-react'; import { ModelSelector } from '@/components/model-selector'; import { ImageConfig } from '@/components/image-config'; import { VideoConfig } from '@/components/video-config'; import { ImageCard } from '@/components/image-card'; import { VideoCard } from '@/components/video-card'; import { ReferenceImages } from '@/components/reference-images'; type ContentType = 'image' | 'video'; interface GeneratedImage { id: string; imageData: string; prompt: string; model: string; aspectRatio: string; timestamp: number; } interface GeneratedVideo { id: string; videoData: string; prompt: string; model: string; aspectRatio: string; duration: number; timestamp: number; } interface ReferenceImage { id: string; data: string; mimeType: string; preview: string; name: string; } export default function Home() { // Estado del tipo de contenido const [contentType, setContentType] = useState('image'); // Estado del modelo y configuración const [selectedModel, setSelectedModel] = useState('gemini-2.5-flash-image'); const [aspectRatio, setAspectRatio] = useState('1:1'); const [numberOfImages, setNumberOfImages] = useState(1); const [videoDuration, setVideoDuration] = useState(5); const [negativePrompt, setNegativePrompt] = useState(''); const [safetyLevel, setSafetyLevel] = useState<'block_none' | 'block_some' | 'block_most'>('block_some'); const [referenceImages, setReferenceImages] = useState([]); // Estado del chat const [prompt, setPrompt] = useState(''); const [isGenerating, setIsGenerating] = useState(false); const [generatedImages, setGeneratedImages] = useState([]); const [generatedVideos, setGeneratedVideos] = useState([]); const [error, setError] = useState(null); // Cambiar tipo de contenido y actualizar modelo por defecto const handleContentTypeChange = (type: ContentType) => { setContentType(type); if (type === 'image') { setSelectedModel('gemini-2.5-flash-image'); setAspectRatio('1:1'); } else { setSelectedModel('veo-3.0-generate-001'); setAspectRatio('16:9'); } }; const handleGenerateImage = async () => { if (!prompt.trim()) return; setIsGenerating(true); setError(null); try { const response = await fetch('/api/generate-image', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ model: selectedModel, prompt: prompt.trim(), aspectRatio, numberOfImages, negativePrompt: negativePrompt.trim() || undefined, safetyFilterLevel: safetyLevel, temperature: 1, referenceImages: referenceImages.length > 0 ? referenceImages.map(img => ({ data: img.data, mimeType: img.mimeType, })) : undefined, }), }); const data = await response.json(); if (!response.ok) { throw new Error(data.details || data.error || 'Error generando imagen'); } // Agregar imágenes generadas al historial const newImages: GeneratedImage[] = data.images.map((imageData: string, index: number) => ({ id: `${Date.now()}-${index}`, imageData, prompt: prompt.trim(), model: selectedModel, aspectRatio, timestamp: Date.now(), })); setGeneratedImages([...newImages, ...generatedImages]); setPrompt(''); // Limpiar prompt después de generar } catch (err: any) { setError(err.message); } finally { setIsGenerating(false); } }; const handleGenerateVideo = async () => { if (!prompt.trim()) return; setIsGenerating(true); setError(null); try { const response = await fetch('/api/generate-video', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ model: selectedModel, prompt: prompt.trim(), aspectRatio, duration: videoDuration, negativePrompt: negativePrompt.trim() || undefined, safetyFilterLevel: safetyLevel, temperature: 1, }), }); const data = await response.json(); if (!response.ok) { throw new Error(data.details || data.error || 'Error generando video'); } // Agregar video generado al historial const newVideo: GeneratedVideo = { id: `${Date.now()}`, videoData: data.videoData, prompt: prompt.trim(), model: selectedModel, aspectRatio, duration: videoDuration, timestamp: Date.now(), }; setGeneratedVideos([newVideo, ...generatedVideos]); setPrompt(''); // Limpiar prompt después de generar } catch (err: any) { setError(err.message); } finally { setIsGenerating(false); } }; const handleGenerate = () => { if (contentType === 'image') { handleGenerateImage(); } else { handleGenerateVideo(); } }; const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleGenerate(); } }; return (
{/* Header */}

AI Playground

Genera imágenes y videos con Google Generative AI

{/* Selector de tipo de contenido */}
{/* Panel de configuración */}
{contentType === 'image' ? ( ) : ( )}
{contentType === 'image' && (
)}
{/* Stats */}
{contentType === 'image' ? ( ) : (
{contentType === 'image' ? (

Imágenes generadas: {generatedImages.length}

) : (

Videos generados: {generatedVideos.length}

)}

Modelo actual: {selectedModel}

{/* Área principal */}
{/* Input de prompt */}