import React, { useState, useMemo } from 'react'; import { Button } from './ui/button'; import { Copy, ThumbsUp, ThumbsDown, ChevronDown, ChevronUp, Check, Bot } from 'lucide-react'; import { Badge } from './ui/badge'; import { Collapsible, CollapsibleContent, CollapsibleTrigger } from './ui/collapsible'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from './ui/dialog'; import { Textarea } from './ui/textarea'; import type { Message as MessageType, LearningMode } from '../App'; import { toast } from 'sonner'; interface MessageProps { message: MessageType; showSenderInfo?: boolean; // ✅ needed for logging feedback userId: string; isLoggedIn: boolean; learningMode: LearningMode; docType: string; // optional: pass the last user message so feedback can include question lastUserText?: string; } async function postJson(path: string, payload: any) { const res = await fetch(path, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), }); if (!res.ok) { const txt = await res.text().catch(() => ''); throw new Error(`HTTP ${res.status}: ${txt || res.statusText}`); } return res.json(); } export function Message({ message, showSenderInfo = false, userId, isLoggedIn, learningMode, docType, lastUserText = '', }: MessageProps) { const [feedback, setFeedback] = useState<'helpful' | 'not-helpful' | null>(null); const [copied, setCopied] = useState(false); const [referencesOpen, setReferencesOpen] = useState(false); const [showFeedbackDialog, setShowFeedbackDialog] = useState(false); const [feedbackType, setFeedbackType] = useState<'helpful' | 'not-helpful' | null>(null); const [feedbackText, setFeedbackText] = useState(''); const [submitting, setSubmitting] = useState(false); const isUser = message.role === 'user'; const refs = useMemo(() => (message.references || []).filter(Boolean), [message.references]); const handleCopy = async () => { await navigator.clipboard.writeText(message.content); setCopied(true); toast.success('Message copied to clipboard'); setTimeout(() => setCopied(false), 2000); }; const handleFeedbackDialogOpen = (type: 'helpful' | 'not-helpful') => { if (!isLoggedIn || !userId) { toast.error('Please log in first'); return; } setFeedbackType(type); setShowFeedbackDialog(true); }; const handleFeedbackDialogClose = () => { setShowFeedbackDialog(false); setFeedbackType(null); setFeedbackText(''); }; const handleFeedbackDialogSubmit = async () => { if (!feedbackType) return; if (!isLoggedIn || !userId) { toast.error('Please log in first'); return; } try { setSubmitting(true); await postJson('/api/feedback', { user_id: userId, rating: feedbackType === 'helpful' ? 'helpful' : 'not_helpful', assistant_message_id: message.id, assistant_text: message.content, user_text: lastUserText || '', comment: feedbackText.trim(), refs, learning_mode: learningMode, doc_type: docType, timestamp_ms: Date.now(), }); setFeedback(feedbackType); toast.success('Thanks for your feedback!'); handleFeedbackDialogClose(); } catch (e: any) { console.error(e); toast.error(`Feedback failed: ${e?.message || 'unknown error'}`); } finally { setSubmitting(false); } }; return (
{message.content}