import { useState, useMemo } from "react"; import { useParams } from "react-router-dom"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Loader2, Sparkles, ChevronRight, CheckCircle2, BookOpen } from "lucide-react"; import { useGenerateOutline, useGenerateChapterContent, usePublishWorkbench } from "@/hooks/queries"; import { useToast } from "@/hooks/use-toast"; import type { WorkbenchGeneratedOutline, WorkbenchGeneratedChapter } from "@/types/courseware"; function sanitizeHtml(dirty: string): string { const div = document.createElement("div"); div.textContent = ""; const parser = new DOMParser(); const doc = parser.parseFromString(dirty, "text/html"); const scripts = doc.querySelectorAll("script, iframe, object, embed, link[rel=import]"); scripts.forEach((el) => el.remove()); doc.querySelectorAll("*").forEach((el) => { for (const attr of Array.from(el.attributes)) { if (attr.name.startsWith("on") || attr.value.trim().toLowerCase().startsWith("javascript:")) { el.removeAttribute(attr.name); } } }); return doc.body.innerHTML; } type Complexity = "beginner" | "intermediate" | "advanced"; export default function AiWorkbench() { const { courseId } = useParams<{ courseId: string }>(); const cid = Number(courseId); const { toast } = useToast(); const [step, setStep] = useState(1); const [topic, setTopic] = useState(""); const [objectives, setObjectives] = useState(""); const [complexity, setComplexity] = useState("intermediate"); const [outline, setOutline] = useState(null); const [generatedContent, setGeneratedContent] = useState(null); const generateOutline = useGenerateOutline(); const generateContent = useGenerateChapterContent(); const publishWorkbench = usePublishWorkbench(); const handleGenerateOutline = () => { generateOutline.mutate( { course_id: cid, topic, objectives, complexity }, { onSuccess: (data) => { setOutline(data); setStep(2); }, onError: () => toast({ title: "Error", description: "Failed to generate outline", variant: "destructive" }), }, ); }; const handleGenerateContent = () => { generateContent.mutate( { course_id: cid, topic, objectives, complexity }, { onSuccess: (data) => { setGeneratedContent(data); setStep(3); }, onError: () => toast({ title: "Error", description: "Failed to generate content", variant: "destructive" }), }, ); }; const handlePublish = () => { publishWorkbench.mutate( { course_id: cid, topic, objectives, complexity, outline, content: generatedContent }, { onSuccess: () => { toast({ title: "Published Successfully" }); setStep(4); }, onError: () => toast({ title: "Error", description: "Failed to publish", variant: "destructive" }), }, ); }; const steps = [ { num: 1, label: "Requirements" }, { num: 2, label: "Review Outline" }, { num: 3, label: "Generated Content" }, { num: 4, label: "Published" }, ]; return (

AI Workbench

Generate course content using AI assistance.

{steps.map((s, i) => (
= s.num ? "bg-primary/10 text-primary font-medium" : "text-muted-foreground"}`}> {step > s.num ? : {s.num}} {s.label}
{i < steps.length - 1 && }
))}
{step === 1 && ( Input Requirements Describe what content you want the AI to generate.
setTopic(e.target.value)} />