'use client'; import { motion } from 'motion/react'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import FileTypeIcon from './FileTypeIcon'; import Badge from './Badge'; import { ChatMessage } from '@/lib/kb-data'; interface SourceCardProps { name: string; type: string; } function SourceCard({ name, type }: SourceCardProps) { const isFileType = ['PDF', 'DOC', 'DOCX', 'EXCEL', 'XLS', 'XLSX', 'CSV'].includes( type.toUpperCase() ); const getBadgeColor = (): 'danger' | 'success' | 'info' | 'purple' | 'neutral' => { switch (type.toUpperCase()) { case 'PDF': return 'danger'; case 'EXCEL': case 'XLS': return 'success'; case 'DOCX': return 'info'; case 'Q&A': return 'purple'; default: return 'neutral'; } }; return (
{isFileType ? ( ) : ( * )} {name} {type}
); } interface MessageBubbleProps { message: ChatMessage; } function MarkdownContent({ text, compact = false }: { text: string; compact?: boolean }) { return ( (

{children}

), h2: ({ children }) => (

{children}

), h3: ({ children }) => (

{children}

), p: ({ children }) => (

{children}

), strong: ({ children }) => ( {children} ), em: ({ children }) => {children}, a: ({ href, children }) => ( {children} ), ul: ({ children }) => ( ), ol: ({ children }) => (
    {children}
), li: ({ children }) => (
  • {children}
  • ), blockquote: ({ children }) => (
    {children}
    ), code: ({ className, children, ...props }) => { const isBlock = className?.startsWith('language-'); if (isBlock) { return ( {children} ); } return ( {children} ); }, pre: ({ children }) => (
                {children}
              
    ), table: ({ children }) => (
    {children}
    ), th: ({ children }) => ( {children} ), td: ({ children }) => ( {children} ), hr: () =>
    , }} > {text}
    ); } export default function MessageBubble({ message }: MessageBubbleProps) { const isUser = message.sender === 'user'; if (isUser) { return (
    ); } return ( {message.sources && message.sources.length > 0 && (
    {message.sources.map((src, idx) => ( ))}
    )}
    ); }