'use client'; import { useState } from 'react'; import { Box, IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Button, TextField, Typography, Tooltip, Snackbar, Alert, } from '@mui/material'; import { ThumbUp, ThumbDown, ThumbUpOutlined, ThumbDownOutlined } from '@mui/icons-material'; import { useTranslation } from '@/hooks/useTranslation'; import apiClient from '@/lib/api/client'; interface MessageFeedbackProps { messageId: string; conversationId: string | null; } export function MessageFeedback({ messageId, conversationId }: MessageFeedbackProps) { const { t } = useTranslation('ai'); const [feedbackType, setFeedbackType] = useState<'positive' | 'negative' | null>(null); const [dialogOpen, setDialogOpen] = useState(false); const [feedbackText, setFeedbackText] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); const [snackbarOpen, setSnackbarOpen] = useState(false); const handleFeedback = async (type: 'positive' | 'negative') => { // If already submitted this type, ignore if (feedbackType === type) return; setFeedbackType(type); // For negative feedback, open dialog for additional comments if (type === 'negative') { setDialogOpen(true); return; } // For positive feedback, submit immediately await submitFeedback(type, ''); }; const submitFeedback = async (type: 'positive' | 'negative', text: string) => { if (!conversationId) return; setIsSubmitting(true); try { await apiClient.post('/api/v1/ai/feedback', { conversationId, messageId, feedbackType: type, feedbackText: text || undefined, }); console.log(`✅ Feedback submitted: ${type}`); // Show success snackbar setSnackbarOpen(true); // Close dialog if open if (dialogOpen) { setDialogOpen(false); setFeedbackText(''); } } catch (error) { console.error('Failed to submit feedback:', error); // Reset feedback type on error setFeedbackType(null); } finally { setIsSubmitting(false); } }; const handleDialogSubmit = async () => { if (feedbackType) { await submitFeedback(feedbackType, feedbackText); } }; const handleDialogClose = () => { setDialogOpen(false); setFeedbackText(''); // Reset feedback type if closing without submitting if (!feedbackType || feedbackType === 'negative') { setFeedbackType(null); } }; return ( <> handleFeedback('positive')} disabled={isSubmitting} sx={{ color: feedbackType === 'positive' ? 'success.main' : 'text.secondary', '&:hover': { color: 'success.main' }, }} > {feedbackType === 'positive' ? ( ) : ( )} handleFeedback('negative')} disabled={isSubmitting} sx={{ color: feedbackType === 'negative' ? 'error.main' : 'text.secondary', '&:hover': { color: 'error.main' }, }} > {feedbackType === 'negative' ? ( ) : ( )} {/* Feedback Dialog for negative feedback */} {t('feedback.dialogTitle') || 'Help us improve'} {t('feedback.dialogMessage') || 'What could have been better about this response?'} setFeedbackText(e.target.value)} variant="outlined" /> {/* Success Snackbar */} setSnackbarOpen(false)} anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} > setSnackbarOpen(false)} severity="success" sx={{ width: '100%' }} > {t('feedback.thankYou') || 'Thank you for your feedback!'} ); }