Initial commit

This commit is contained in:
Sebastian
2025-11-26 19:00:04 +00:00
commit 0ba05b6483
27 changed files with 2517 additions and 0 deletions

View File

@@ -0,0 +1,118 @@
'use client';
import { aspectRatioSizes, videoDurations } from '@/lib/google-ai';
interface VideoConfigProps {
model: string;
aspectRatio: string;
onAspectRatioChange: (ratio: string) => void;
duration: number;
onDurationChange: (duration: number) => void;
negativePrompt: string;
onNegativePromptChange: (prompt: string) => void;
safetyLevel: 'block_none' | 'block_some' | 'block_most';
onSafetyLevelChange: (level: 'block_none' | 'block_some' | 'block_most') => void;
}
export function VideoConfig({
aspectRatio,
onAspectRatioChange,
duration,
onDurationChange,
negativePrompt,
onNegativePromptChange,
safetyLevel,
onSafetyLevelChange,
}: VideoConfigProps) {
const availableRatios = Object.keys(aspectRatioSizes);
const size = aspectRatioSizes[aspectRatio];
return (
<div className="space-y-4">
<h3 className="text-sm font-medium text-foreground">Configuración de Video</h3>
{/* Aspect Ratio */}
<div className="space-y-2">
<label className="text-xs font-medium text-muted-foreground">
Aspect Ratio
</label>
<div className="grid grid-cols-5 gap-2">
{availableRatios.map((ratio) => (
<button
key={ratio}
onClick={() => onAspectRatioChange(ratio)}
className={`
px-3 py-2 text-xs rounded-lg font-medium transition-all
${aspectRatio === ratio
? 'bg-primary text-primary-foreground'
: 'bg-secondary hover:bg-accent'
}
`}
>
{ratio}
</button>
))}
</div>
{size && (
<p className="text-xs text-muted-foreground">
Dimensiones: {size.width}x{size.height}px
</p>
)}
</div>
{/* Duración */}
<div className="space-y-2">
<label className="text-xs font-medium text-muted-foreground">
Duración: {duration} segundos
</label>
<div className="flex gap-2">
{videoDurations.map((dur) => (
<button
key={dur.value}
onClick={() => onDurationChange(dur.value)}
className={`
flex-1 px-3 py-2 text-xs rounded-lg font-medium transition-all
${duration === dur.value
? 'bg-primary text-primary-foreground'
: 'bg-secondary hover:bg-accent'
}
`}
>
{dur.label}
</button>
))}
</div>
</div>
{/* Negative Prompt */}
<div className="space-y-2">
<label className="text-xs font-medium text-muted-foreground">
Negative Prompt (opcional)
</label>
<textarea
value={negativePrompt}
onChange={(e) => onNegativePromptChange(e.target.value)}
placeholder="Elementos que NO quieres en el video..."
className="w-full px-3 py-2 bg-secondary border border-border rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary resize-none"
rows={2}
/>
</div>
{/* Safety Level */}
<div className="space-y-2">
<label className="text-xs font-medium text-muted-foreground">
Nivel de Seguridad
</label>
<select
value={safetyLevel}
onChange={(e) => onSafetyLevelChange(e.target.value as any)}
className="w-full px-3 py-2 bg-secondary border border-border rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary"
>
<option value="block_none">Sin bloqueo</option>
<option value="block_some">Bloqueo moderado</option>
<option value="block_most">Bloqueo alto</option>
</select>
</div>
</div>
);
}