import { useState, useEffect } from 'react' interface ModelInfo { name: string max_duration: number default_duration: number description: string } interface Props { onGenerate: () => void } export default function Generator({ onGenerate }: Props) { const [prompt, setPrompt] = useState('') const [model, setModel] = useState('lyria-3-clip-preview') const [duration, setDuration] = useState(30) const [isLoading, setIsLoading] = useState(false) const [error, setError] = useState('') const [models, setModels] = useState>({}) useEffect(() => { fetch('/api/models') .then(res => res.json()) .then(data => { setModels(data.models || {}) setModel(data.default || 'lyria-3-clip-preview') const defaultInfo = data.models?.[data.default] setDuration(defaultInfo?.default_duration || 30) }) .catch(() => {}) // Use hardcoded defaults on failure }, []) const handleModelChange = (newModel: string) => { setModel(newModel) const info = models[newModel] if (info) { setDuration(info.default_duration) } } const currentModelInfo = models[model] const maxDuration = currentModelInfo?.max_duration || 30 const minDuration = 5 const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() if (!prompt.trim()) return setIsLoading(true) setError('') try { const res = await fetch('/api/generate', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: prompt.trim(), model, duration }) }) if (!res.ok) { try { const errorData = await res.json() throw new Error(errorData.error || errorData.detail || 'Generation failed') } catch (parseErr) { if (parseErr instanceof Error && parseErr.message !== 'Generation failed') throw parseErr throw new Error('Generation failed') } } const data = await res.json() if (data.error) { throw new Error(data.error) } setPrompt('') onGenerate() } catch (err) { setError(err instanceof Error ? err.message : 'Something went wrong') } finally { setIsLoading(false) } } return (

Generate