'use client'; import { useMemo, useState } from 'react'; import { motion } from 'framer-motion'; import ReactMarkdown from 'react-markdown'; import { User, Bot, Copy, Check, ExternalLink, ThumbsUp, ThumbsDown, Share2, Sparkles } from 'lucide-react'; import * as Tooltip from '@radix-ui/react-tooltip'; import type { Message, Citation as CitationType } from '@/lib/types'; interface ChatMessageProps { message: Message; } export function ChatMessage({ message }: ChatMessageProps) { const [copied, setCopied] = useState(false); const [feedback, setFeedback] = useState<'up' | 'down' | null>(null); const isUser = message.role === 'user'; const handleCopy = async () => { await navigator.clipboard.writeText(message.content); setCopied(true); setTimeout(() => setCopied(false), 2000); }; return ( {isUser ? (

{message.content}

) : (
{/* Assistant Header */}
GooSeek
{/* Citations - Show at top like Perplexity */} {message.citations && message.citations.length > 0 && (
{message.citations.slice(0, 6).map((citation) => ( ))} {message.citations.length > 6 && ( )}
)} {/* Message Content */}
(

{children}

), a: ({ href, children }) => ( {children} ), code: ({ className, children }) => { const isInline = !className; if (isInline) { return ( {children} ); } return {children}; }, pre: ({ children }) => (
                    {children}
                  
), ul: ({ children }) => (
    {children}
), ol: ({ children }) => (
    {children}
), li: ({ children }) => (
  • {children}
  • ), h1: ({ children }) => (

    {children}

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

    {children}

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

    {children}

    ), blockquote: ({ children }) => (
    {children}
    ), strong: ({ children }) => ( {children} ), }} > {message.content}
    {/* Streaming Cursor */} {message.isStreaming && ( )}
    {/* Actions */} {!message.isStreaming && (
    {}} />
    setFeedback('up')} active={feedback === 'up'} /> setFeedback('down')} active={feedback === 'down'} />
    )}
    )} ); } interface ActionButtonProps { icon: React.ElementType; label: string; onClick: () => void; active?: boolean; } function ActionButton({ icon: Icon, label, onClick, active }: ActionButtonProps) { return ( {label} ); } function CitationBadge({ citation }: { citation: CitationType }) { return ( {citation.index} {citation.favicon && ( { (e.target as HTMLImageElement).style.display = 'none'; }} /> )} {citation.domain}

    {citation.title}

    {citation.snippet && (

    {citation.snippet}

    )}

    {citation.url}

    ); }