"use client"; import { useState, useEffect, useRef } from "react"; import { Wand2, Loader2, Code2, Play } from "lucide-react"; import { cmsApi } from "@/lib/api"; import mermaid from "mermaid"; import DOMPurify from "isomorphic-dompurify"; interface MermaidBlockProps { id: string; title?: string; description?: string; mermaid_code?: string; editMode: boolean; courseId: string; lessonId: string; aiGenerationEnabled?: boolean; onChange: (updates: { title?: string; description?: string; mermaid_code?: string }) => void; } export default function MermaidBlock({ id, title, description, mermaid_code = "", editMode, lessonId, aiGenerationEnabled = true, onChange }: MermaidBlockProps) { const [isGenerating, setIsGenerating] = useState(false); const [promptHint, setPromptHint] = useState(""); const [renderError, setRenderError] = useState(null); const mermaidRef = useRef(null); useEffect(() => { mermaid.initialize({ startOnLoad: false, theme: "default", securityLevel: "loose", fontFamily: "inherit" }); }, []); const renderMermaid = async () => { if (!mermaidRef.current || !mermaid_code.trim()) return; try { setRenderError(null); mermaidRef.current.innerHTML = ""; const { svg } = await mermaid.render(`mermaid-${id}`, mermaid_code); if (mermaidRef.current) { // Sanitizar SVG antes de inyectar mermaidRef.current.innerHTML = DOMPurify.sanitize(svg); } } catch (error: any) { console.error("Mermaid parsing error:", error); setRenderError(error?.message || "Error al renderizar el diagrama."); } }; useEffect(() => { renderMermaid(); }, [mermaid_code, editMode]); const handleGenerateAI = async () => { if (!aiGenerationEnabled) { alert("La generación de diagramas Mermaid está desactivada para esta organización."); return; } setIsGenerating(true); try { const data = await cmsApi.generateMermaidDiagram(lessonId, { prompt_hint: promptHint || undefined }); onChange({ mermaid_code: data.mermaid_code }); } catch (error) { console.error("AI Mermaid Generation failed:", error); alert("No se pudo generar el diagrama con IA. Por favor, intenta de nuevo."); } finally { setIsGenerating(false); } }; if (!editMode) { return (

{title || "Diagrama Interactivo"}

{description || "Procesos y flujos visuales"}

{mermaid_code.trim() ? ( <> {renderError && (
{renderError}
)}
) : (

Diagrama no configurado.

)}
); } return (
onChange({ title: e.target.value })} placeholder="Ej. Arquitectura del Sistema..." className="w-full bg-slate-50 dark:bg-black/40 border border-slate-100 dark:border-white/10 rounded-2xl px-6 py-4 text-sm font-black uppercase tracking-tight text-slate-800 dark:text-white focus:ring-4 focus:ring-indigo-500/10 focus:border-indigo-500 transition-all outline-none" />
onChange({ description: e.target.value })} placeholder="Ej. Representación visual de los flujos de datos..." className="w-full bg-slate-50 dark:bg-black/40 border border-slate-100 dark:border-white/10 rounded-2xl px-6 py-4 text-sm font-bold text-slate-600 dark:text-gray-300 focus:ring-4 focus:ring-indigo-500/10 focus:border-indigo-500 transition-all outline-none" />

Generación con IA

{!aiGenerationEnabled && (
Mermaid está desactivado para esta organización. Puedes conservar o editar código existente manualmente.
)}