import { useState, useEffect } from 'react'; import { Rocket, Search, FileText, ArrowRight, ChevronLeft, Database, Plus, RefreshCw, Edit3 } from 'lucide-react'; // --- TYPES --- interface GTMProject { id: string; name: string; productCategory: string; } interface ContentProject { id: number; name: string; category: string; gtm_project_id: string; created_at: string; seo_strategy?: { seed_keywords?: string[] }; assets?: ContentAsset[]; } interface ContentAsset { id: number; section_key: string; content: string; status: string; } // --- SUB-COMPONENTS --- function SEOPlanner({ project, setLoading, onUpdate }: { project: ContentProject, setLoading: (b: boolean) => void, onUpdate: () => void }) { const [keywords, setKeywords] = useState(project.seo_strategy?.seed_keywords || []); const generateKeywords = async () => { setLoading(true); try { const res = await fetch('api/seo_brainstorming', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ projectId: project.id }) }); const data = await res.json(); if (data.error) { alert(`Error: ${data.error}`); } else { setKeywords(data.keywords || []); onUpdate(); } } catch (err) { console.error(err); alert("Network Error"); } setLoading(false); }; return (

SEO Strategy

Define the keywords that drive your content structure.

{keywords.length > 0 ? (
{keywords.map((kw, i) => (
{String(i+1).padStart(2, '0')} {kw}
))}
) : (

No keywords generated yet. Start here!

)}
); } function WebsiteBuilder({ project, setLoading, onUpdate }: { project: ContentProject, setLoading: (b: boolean) => void, onUpdate: () => void }) { const [sections, setSections] = useState(project.assets || []); const [editingContent, setEditingContent] = useState<{ [key: string]: string }>({}); useEffect(() => { // When project updates (e.g. via onUpdate->Parent Refresh), update local sections if (project.assets) { setSections(project.assets); const newEditing: { [key: string]: string } = {}; project.assets.forEach(s => { newEditing[s.section_key] = s.content; }); setEditingContent(newEditing); } }, [project.assets]); const generateSection = async (key: string) => { setLoading(true); try { const res = await fetch('api/generate_section', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ projectId: project.id, sectionKey: key, keywords: project.seo_strategy?.seed_keywords || [] }) }); const data = await res.json(); if (data.error) { alert(`Error: ${data.error}`); return; } onUpdate(); // Refresh parent to get fresh data from DB } catch (err) { console.error(err); alert("Network Error"); } setLoading(false); }; const handleEditChange = (key: string, val: string) => { setEditingContent(prev => ({ ...prev, [key]: val })); }; const saveEdit = async (key: string) => { const content = editingContent[key]; if (!content) return; setLoading(true); try { await fetch('api/generate_section', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ projectId: project.id, sectionKey: key, manualContent: content }) }); onUpdate(); // Refresh parent alert("Saved successfully!"); } catch (err) { console.error(err); alert("Network Error"); } setLoading(false); }; const copyToClipboard = (val: string) => { navigator.clipboard.writeText(val); alert('Copied to clipboard!'); }; return (

Website Copy Sections

Generate and refine high-converting blocks based on your strategy.

{[ { key: 'hero', label: 'Hero Section', desc: 'Headline, Subline & CTA' }, { key: 'problem', label: 'The Challenger Story', desc: 'Pain Points & Consequences' }, { key: 'value_prop', label: 'Hybrid Solution', desc: 'Symbiosis of Machine & Human' }, { key: 'features', label: 'Feature-to-Value', desc: 'Benefit-driven Tech Deep Dive' } ].map(s => { const hasContent = editingContent[s.key] !== undefined; return (

{s.label}

{s.desc}

{hasContent && ( )}
{hasContent ? (