import { FormEvent, useEffect, useRef, useState } from 'react'; import { pollVideoJob, startVideoJob } from '../api'; import type { AsyncJob } from '../types'; const POLL_INTERVAL_MS = 5_000; export function VideoTab() { const [prompt, setPrompt] = useState('a fox running across a snowy field'); const [job, setJob] = useState(null); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); const pollTimer = useRef | null>(null); useEffect(() => () => { if (pollTimer.current) clearTimeout(pollTimer.current); }, []); function schedulePoll(jobId: string) { if (pollTimer.current) clearTimeout(pollTimer.current); pollTimer.current = setTimeout(async () => { try { const next = await pollVideoJob(jobId); setJob(next); if (next.status === 'queued' || next.status === 'processing') schedulePoll(jobId); } catch (err) { setError(err instanceof Error ? err.message : String(err)); } }, POLL_INTERVAL_MS); } async function onSubmit(event: FormEvent) { event.preventDefault(); if (!prompt.trim() || busy) return; setBusy(true); setError(null); setJob(null); try { const started = await startVideoJob(prompt); setJob(started); const id = started.jobId ?? started.id; if (id && (started.status === 'queued' || started.status === 'processing')) schedulePoll(id); } catch (err) { setError(err instanceof Error ? err.message : String(err)); } finally { setBusy(false); } } const videoUrl = (job?.output as { videoUrl?: string } | undefined)?.videoUrl; return (
setPrompt(e.target.value)} placeholder="Describe a short clip…" disabled={busy} data-testid="video-prompt" />
{error ?

{error}

: null} {job ? (
Job {(job.jobId ?? job.id ?? '').slice(0, 12)}…

Status: {job.status}

) : null} {videoUrl ?
); }