/** * MessageFeedback Component * Allows users to rate and provide feedback on assistant messages */ import React, { useState } from 'react'; import { ThumbsUp, ThumbsDown, MessageSquare, X, Send, Loader2, Check, Flag, } from 'lucide-react'; interface MessageFeedbackProps { messageId: string; onFeedback?: (messageId: string, feedback: FeedbackData) => Promise; compact?: boolean; } export interface FeedbackData { rating: 'positive' | 'negative'; category?: string; comment?: string; } const FEEDBACK_CATEGORIES = [ { id: 'accurate', label: 'Accurate analysis' }, { id: 'helpful', label: 'Helpful response' }, { id: 'inaccurate', label: 'Inaccurate information' }, { id: 'unclear', label: 'Unclear explanation' }, { id: 'incomplete', label: 'Incomplete answer' }, { id: 'wrong_signal', label: 'Wrong trading signal' }, { id: 'other', label: 'Other' }, ]; const MessageFeedback: React.FC = ({ messageId, onFeedback, compact = false, }) => { const [rating, setRating] = useState<'positive' | 'negative' | null>(null); const [showForm, setShowForm] = useState(false); const [category, setCategory] = useState(''); const [comment, setComment] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); const [submitted, setSubmitted] = useState(false); const handleRating = async (value: 'positive' | 'negative') => { setRating(value); // For positive feedback, submit immediately without form if (value === 'positive') { await submitFeedback(value); } else { // For negative feedback, show the form for more details setShowForm(true); } }; const submitFeedback = async (feedbackRating: 'positive' | 'negative') => { if (!onFeedback) { setSubmitted(true); return; } setIsSubmitting(true); try { await onFeedback(messageId, { rating: feedbackRating, category: category || undefined, comment: comment || undefined, }); setSubmitted(true); setShowForm(false); } catch (error) { console.error('Failed to submit feedback:', error); } finally { setIsSubmitting(false); } }; const handleSubmit = async () => { if (rating) { await submitFeedback(rating); } }; const handleCancel = () => { setShowForm(false); setRating(null); setCategory(''); setComment(''); }; // Already submitted state if (submitted) { return (
Thanks for your feedback
); } // Compact mode - just icons if (compact && !showForm) { return (
); } return (
{/* Rating Buttons */} {!showForm && (
Was this helpful?
)} {/* Detailed Feedback Form (for negative feedback) */} {showForm && (
Tell us what went wrong
{/* Categories */}
{FEEDBACK_CATEGORIES.filter(c => rating === 'negative' ? !['accurate', 'helpful'].includes(c.id) : !['inaccurate', 'unclear', 'incomplete', 'wrong_signal'].includes(c.id) ).map((cat) => ( ))}
{/* Comment */}