import React, { useState, useEffect, useRef } from 'react'; import ReactMarkdown from 'react-markdown'; import rehypeSanitize from 'rehype-sanitize'; import mermaid from 'mermaid'; import { X, Download, Loader, AlertCircle, FileText, File } from 'lucide-react'; mermaid.initialize({ startOnLoad: false, theme: 'dark', darkMode: true, themeVariables: { background: '#0f172a', primaryColor: '#1e3a5f', primaryTextColor: '#e2e8f0', primaryBorderColor: '#0ea5e9', lineColor: '#475569', secondaryColor: '#1a2e1a', tertiaryColor: '#2d1f14', edgeLabelBackground: '#1e293b', clusterBkg: '#1e293b', titleColor: '#e2e8f0', fontFamily: 'monospace' } }); let mermaidCounter = 0; function MermaidDiagram({ code }) { const ref = useRef(null); const [svgError, setSvgError] = useState(''); useEffect(() => { let cancelled = false; const id = `mermaid-kb-${++mermaidCounter}`; mermaid.render(id, code) .then(({ svg }) => { if (!cancelled && ref.current) { ref.current.innerHTML = svg; // Make SVG responsive const svgEl = ref.current.querySelector('svg'); if (svgEl) { svgEl.removeAttribute('width'); svgEl.removeAttribute('height'); svgEl.style.width = '100%'; svgEl.style.maxWidth = '100%'; } } }) .catch((err) => { if (!cancelled) setSvgError(err.message || 'Failed to render diagram'); }); return () => { cancelled = true; }; }, [code]); if (svgError) { return (
        Mermaid render error: {svgError}
      
); } return (
); } const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api'; export default function KnowledgeBaseViewer({ article, onClose }) { const [content, setContent] = useState(''); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); useEffect(() => { fetchArticleContent(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [article.id]); const fetchArticleContent = async () => { setLoading(true); setError(''); try { const response = await fetch(`${API_BASE}/knowledge-base/${article.id}/content`, { credentials: 'include' }); if (!response.ok) throw new Error('Failed to fetch article content'); const text = await response.text(); setContent(text); } catch (err) { console.error('Error fetching article content:', err); setError(err.message); } finally { setLoading(false); } }; const handleDownload = async () => { try { const response = await fetch(`${API_BASE}/knowledge-base/${article.id}/download`, { credentials: 'include' }); if (!response.ok) throw new Error('Download failed'); const blob = await response.blob(); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = article.file_name; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); document.body.removeChild(a); } catch (err) { console.error('Error downloading file:', err); setError('Failed to download file'); } }; const isMarkdown = article.file_name?.endsWith('.md'); const isText = article.file_name?.endsWith('.txt'); const isPDF = article.file_name?.endsWith('.pdf'); const isImage = /\.(jpg|jpeg|png|gif|bmp)$/i.test(article.file_name || ''); const getCategoryColor = (cat) => { const colors = { 'General': '#94A3B8', 'Policy': '#0EA5E9', 'Procedure': '#10B981', 'Guide': '#F59E0B', 'Reference': '#8B5CF6' }; return colors[cat] || '#94A3B8'; }; const formatDate = (dateString) => { return new Date(dateString).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); }; return (
{/* Header */}

{article.title}

{article.description && (

{article.description}

)}
{article.category} Created: {formatDate(article.created_at)} {article.created_by_username && ( By: {article.created_by_username} )}
{/* Content */}
{loading && (

Loading document...

)} {error && (

Failed to Load Document

{error}

)} {!loading && !error && ( <> {/* Markdown Rendering */} {isMarkdown && (
; } return ( {children} ); } }} > {content}
)} {/* Plain Text */} {isText && !isMarkdown && (
                {content}
              
)} {/* PDF */} {isPDF && (
)} {/* Images */} {isImage && (
{article.title}
)} {/* Other file types */} {!isMarkdown && !isText && !isPDF && !isImage && (

Preview not available for this file type.

)} )}
); }