import { useEffect, useState } from 'react' import { api } from '../api' import { useJob, ProgressBox, ErrorBox } from '../hooks' import PromptPanel from '../components/PromptPanel' export default function ScriptStep({ reelData, refreshReel, reelId, projectId, setStep }) { const reel = reelData?.reel const script = reelData?.script const base = `/api/projects/${projectId}/reels/${reelId}` const [local, setLocal] = useState(script) const [dirty, setDirty] = useState(false) const [topic, setTopic] = useState(reel?.topic || '') const [targetSec, setTargetSec] = useState(0) // 0 = auto (default 30–45s) const [prompt, setPrompt] = useState(null) const [scenePrompts, setScenePrompts] = useState({}) // {sceneNo: prompt override} const [error, setError] = useState('') const genJob = useJob() const sceneJob = useJob() useEffect(() => { setLocal(reelData?.script); setDirty(false) }, [reelData?.script]) useEffect(() => { setTopic(reel?.topic || '') }, [reel?.topic]) if (!reelId) { return (

Script

Select or create a reel first (left sidebar), or pick a topic on the Topics step.

) } const mutate = (fn) => { const next = structuredClone(local); fn(next); setLocal(next); setDirty(true) } const save = async () => { try { await api.patch(`${base}/script`, local) await refreshReel() setError('') } catch (e) { setError(e.message) } } const generate = async () => { if (!topic.trim()) { setError('Enter a topic for this reel first.'); return } try { await genJob.start(`${base}/script/generate`, { topic: topic.trim(), prompt, target_sec: targetSec || null }) await refreshReel() } catch { /* shown */ } } const regenerateScene = async (sceneNo) => { try { await sceneJob.start(`${base}/script/regenerate-scene`, { scene: sceneNo, prompt: scenePrompts[sceneNo] ?? null }) await refreshReel() } catch { /* shown */ } } const goMedia = async () => { if (dirty) await save(); setStep(4) } // --- No script yet: topic + generate (with editable prompt) --- if (!local) { return (

Script

Write the scene-structured script for this reel, in your references' style.

(await api.post(`${base}/script/prompt`, { topic: topic.trim() })).prompt} /> {genJob.running && }
) } // --- Script exists: editable scenes --- return (

Script

Topic: {local.topic || local.title} {local.clone_source && <> · cloned structure from source (fresh wording)}

{(genJob.running || sceneJob.running) && }
Hook — pick one of 3 (spoken in the first 2 seconds)
{local.hook_options.map((h, i) => ( ))}
{local.scenes.map((scene, i) => (
Scene {scene.scene} {scene.duration_sec}s