| | import { useState } from 'react';
|
| | import { motion, AnimatePresence } from 'motion/react';
|
| | import { ThumbsUp, ThumbsDown, X, MessageSquare } from 'lucide-react';
|
| | import { Button } from './ui/button';
|
| | import { Textarea } from './ui/textarea';
|
| |
|
| | interface FeedbackPopupProps {
|
| | isOpen: boolean;
|
| | onClose: () => void;
|
| | messageId: string;
|
| | isUnivAiPlusMode?: boolean;
|
| | }
|
| |
|
| | export function FeedbackPopup({ isOpen, onClose, messageId, isUnivAiPlusMode }: FeedbackPopupProps) {
|
| | const [feedbackType, setFeedbackType] = useState<'positive' | 'negative' | null>(null);
|
| | const [comment, setComment] = useState('');
|
| | const [isSubmitted, setIsSubmitted] = useState(false);
|
| |
|
| | const handleSubmit = () => {
|
| |
|
| | console.log('Feedback submitted:', { messageId, feedbackType, comment });
|
| | setIsSubmitted(true);
|
| | setTimeout(() => {
|
| | setIsSubmitted(false);
|
| | setFeedbackType(null);
|
| | setComment('');
|
| | onClose();
|
| | }, 1500);
|
| | };
|
| |
|
| | const handleClose = () => {
|
| | setFeedbackType(null);
|
| | setComment('');
|
| | setIsSubmitted(false);
|
| | onClose();
|
| | };
|
| |
|
| | return (
|
| | <AnimatePresence>
|
| | {isOpen && (
|
| | <>
|
| | {/* Backdrop */}
|
| | <motion.div
|
| | initial={{ opacity: 0 }}
|
| | animate={{ opacity: 1 }}
|
| | exit={{ opacity: 0 }}
|
| | className="fixed inset-0 bg-black/50 backdrop-blur-sm z-50"
|
| | onClick={handleClose}
|
| | />
|
| |
|
| | {/* Popup */}
|
| | <motion.div
|
| | initial={{ opacity: 0, scale: 0.95, y: 20 }}
|
| | animate={{ opacity: 1, scale: 1, y: 0 }}
|
| | exit={{ opacity: 0, scale: 0.95, y: 20 }}
|
| | className={`fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-50 w-96 rounded-2xl border backdrop-blur-sm shadow-2xl transition-all duration-300 ${
|
| | isUnivAiPlusMode
|
| | ? 'bg-gradient-to-br from-white/95 to-purple-50/95 border-purple-200/50 shadow-purple-500/20'
|
| | : 'bg-gradient-to-br from-white/95 to-red-50/95 border-red-200/50 shadow-red-500/20'
|
| | }`}
|
| | >
|
| | {/* Header */}
|
| | <div className="flex items-center justify-between p-6 border-b border-current/10">
|
| | <div className="flex items-center gap-3">
|
| | <div className={`w-10 h-10 rounded-full flex items-center justify-center transition-all duration-300 ${
|
| | isUnivAiPlusMode
|
| | ? 'bg-gradient-to-r from-purple-500 to-pink-500 shadow-purple-500/30'
|
| | : 'bg-gradient-to-r from-red-500 to-orange-500 shadow-red-500/30'
|
| | }`}>
|
| | <MessageSquare className="text-white" size={20} />
|
| | </div>
|
| | <div>
|
| | <h3 className={`transition-all duration-300 ${
|
| | isUnivAiPlusMode
|
| | ? 'text-purple-900 dark:text-purple-100'
|
| | : 'text-red-900 dark:text-red-100'
|
| | }`}>
|
| | Share Feedback
|
| | </h3>
|
| | <p className={`text-sm transition-all duration-300 ${
|
| | isUnivAiPlusMode
|
| | ? 'text-purple-700/80 dark:text-purple-300/80'
|
| | : 'text-red-700/80 dark:text-red-300/80'
|
| | }`}>
|
| | Help us improve our responses
|
| | </p>
|
| | </div>
|
| | </div>
|
| | <Button
|
| | variant="ghost"
|
| | size="sm"
|
| | onClick={handleClose}
|
| | className={`transition-all duration-300 ${
|
| | isUnivAiPlusMode
|
| | ? 'hover:bg-purple-100 text-purple-600 dark:hover:bg-purple-900/30 dark:text-purple-400'
|
| | : 'hover:bg-red-100 text-red-600 dark:hover:bg-red-900/30 dark:text-red-400'
|
| | }`}
|
| | >
|
| | <X size={18} />
|
| | </Button>
|
| | </div>
|
| |
|
| | {/* Content */}
|
| | <div className="p-6">
|
| | {!isSubmitted ? (
|
| | <>
|
| | {/* Rating */}
|
| | <div className="mb-4">
|
| | <p className={`text-sm mb-3 transition-all duration-300 ${
|
| | isUnivAiPlusMode
|
| | ? 'text-purple-700/80 dark:text-purple-300/80'
|
| | : 'text-red-700/80 dark:text-red-300/80'
|
| | }`}>
|
| | How was this response?
|
| | </p>
|
| | <div className="flex gap-3">
|
| | <Button
|
| | variant={feedbackType === 'positive' ? 'default' : 'outline'}
|
| | size="sm"
|
| | onClick={() => setFeedbackType('positive')}
|
| | className={`flex items-center gap-2 transition-all duration-300 ${
|
| | feedbackType === 'positive'
|
| | ? isUnivAiPlusMode
|
| | ? 'bg-gradient-to-r from-purple-500 to-pink-500 text-white shadow-purple-500/30'
|
| | : 'bg-gradient-to-r from-red-500 to-orange-500 text-white shadow-red-500/30'
|
| | : isUnivAiPlusMode
|
| | ? 'border-purple-200 text-purple-700 hover:bg-purple-50 dark:border-purple-600 dark:text-purple-300 dark:hover:bg-purple-900/30'
|
| | : 'border-red-200 text-red-700 hover:bg-red-50 dark:border-red-600 dark:text-red-300 dark:hover:bg-red-900/30'
|
| | }`}
|
| | >
|
| | <ThumbsUp size={16} />
|
| | Helpful
|
| | </Button>
|
| | <Button
|
| | variant={feedbackType === 'negative' ? 'default' : 'outline'}
|
| | size="sm"
|
| | onClick={() => setFeedbackType('negative')}
|
| | className={`flex items-center gap-2 transition-all duration-300 ${
|
| | feedbackType === 'negative'
|
| | ? isUnivAiPlusMode
|
| | ? 'bg-gradient-to-r from-purple-500 to-pink-500 text-white shadow-purple-500/30'
|
| | : 'bg-gradient-to-r from-red-500 to-orange-500 text-white shadow-red-500/30'
|
| | : isUnivAiPlusMode
|
| | ? 'border-purple-200 text-purple-700 hover:bg-purple-50 dark:border-purple-600 dark:text-purple-300 dark:hover:bg-purple-900/30'
|
| | : 'border-red-200 text-red-700 hover:bg-red-50 dark:border-red-600 dark:text-red-300 dark:hover:bg-red-900/30'
|
| | }`}
|
| | >
|
| | <ThumbsDown size={16} />
|
| | Not helpful
|
| | </Button>
|
| | </div>
|
| | </div>
|
| |
|
| | {/* Comment */}
|
| | <div className="mb-4">
|
| | <p className={`text-sm mb-2 transition-all duration-300 ${
|
| | isUnivAiPlusMode
|
| | ? 'text-purple-700/80 dark:text-purple-300/80'
|
| | : 'text-red-700/80 dark:text-red-300/80'
|
| | }`}>
|
| | Additional comments (optional)
|
| | </p>
|
| | <Textarea
|
| | value={comment}
|
| | onChange={(e) => setComment(e.target.value)}
|
| | placeholder="Tell us more about your experience..."
|
| | className={`transition-all duration-300 ${
|
| | isUnivAiPlusMode
|
| | ? 'border-purple-200 focus:border-purple-400 dark:border-purple-600'
|
| | : 'border-red-200 focus:border-red-400 dark:border-red-600'
|
| | }`}
|
| | rows={3}
|
| | />
|
| | </div>
|
| |
|
| | {/* Actions */}
|
| | <div className="flex gap-3 justify-end">
|
| | <Button
|
| | variant="outline"
|
| | size="sm"
|
| | onClick={handleClose}
|
| | className={`transition-all duration-300 ${
|
| | isUnivAiPlusMode
|
| | ? 'border-purple-200 text-purple-700 hover:bg-purple-50 dark:border-purple-600 dark:text-purple-300 dark:hover:bg-purple-900/30'
|
| | : 'border-red-200 text-red-700 hover:bg-red-50 dark:border-red-600 dark:text-red-300 dark:hover:bg-red-900/30'
|
| | }`}
|
| | >
|
| | Cancel
|
| | </Button>
|
| | <Button
|
| | size="sm"
|
| | onClick={handleSubmit}
|
| | disabled={!feedbackType}
|
| | className={`transition-all duration-300 ${
|
| | isUnivAiPlusMode
|
| | ? 'bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600 text-white shadow-purple-500/30'
|
| | : 'bg-gradient-to-r from-red-500 to-orange-500 hover:from-red-600 hover:to-orange-600 text-white shadow-red-500/30'
|
| | }`}
|
| | >
|
| | Submit Feedback
|
| | </Button>
|
| | </div>
|
| | </>
|
| | ) : (
|
| | /* Success state */
|
| | <motion.div
|
| | initial={{ opacity: 0, y: 10 }}
|
| | animate={{ opacity: 1, y: 0 }}
|
| | className="text-center py-4"
|
| | >
|
| | <div className={`w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4 transition-all duration-300 ${
|
| | isUnivAiPlusMode
|
| | ? 'bg-gradient-to-r from-purple-400 to-pink-500 shadow-purple-500/30'
|
| | : 'bg-gradient-to-r from-green-400 to-green-500 shadow-green-500/30'
|
| | }`}>
|
| | <ThumbsUp className="text-white" size={24} />
|
| | </div>
|
| | <h4 className={`mb-2 transition-all duration-300 ${
|
| | isUnivAiPlusMode
|
| | ? 'text-purple-900 dark:text-purple-100'
|
| | : 'text-red-900 dark:text-red-100'
|
| | }`}>
|
| | Thank you!
|
| | </h4>
|
| | <p className={`text-sm transition-all duration-300 ${
|
| | isUnivAiPlusMode
|
| | ? 'text-purple-700/80 dark:text-purple-300/80'
|
| | : 'text-red-700/80 dark:text-red-300/80'
|
| | }`}>
|
| | Your feedback helps us improve
|
| | </p>
|
| | </motion.div>
|
| | )}
|
| | </div>
|
| | </motion.div>
|
| | </>
|
| | )}
|
| | </AnimatePresence>
|
| | );
|
| | } |