import React, { useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { MessageSquare, EyeOff, Trash2, CheckCircle, User } from 'lucide-react'; import { parseISO } from 'date-fns'; import { toast } from 'react-toastify'; import { Card, Loading, Button } from '../common'; import { AdminAuthenticatedImage } from './AdminAuthenticatedImage'; import { feedbackService, type FeedbackResponse, type PhotoFeedback } from '../../services/feedback.service'; import { useLocalizedDate } from '../../hooks/useLocalizedDate'; interface FeedbackModerationPanelProps { eventId: number; className?: string; compact?: boolean; maxItems?: number; } export const FeedbackModerationPanel: React.FC = ({ eventId, className = '', compact = false, maxItems = 5 }) => { const { t } = useTranslation(); const { format } = useLocalizedDate(); const queryClient = useQueryClient(); const [showAll, setShowAll] = useState(false); // Fetch pending feedback const { data: feedbackData, isLoading } = useQuery({ queryKey: ['event-feedback-moderation', eventId], queryFn: () => feedbackService.getEventFeedback(eventId.toString(), { type: 'comment', status: 'pending', limit: showAll ? 100 : maxItems }), refetchInterval: 30000 // Refresh every 30 seconds }); // Moderation mutation const moderateMutation = useMutation({ mutationFn: ({ feedbackId, action }: { feedbackId: string; action: 'approve' | 'hide' | 'reject' }) => feedbackService.moderateFeedback(feedbackId, action), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['event-feedback-moderation', eventId] }); toast.success(t('feedback.moderationSuccess')); } }); // Delete mutation const deleteMutation = useMutation({ mutationFn: (feedbackId: string) => feedbackService.deleteFeedback(feedbackId), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['event-feedback-moderation', eventId] }); toast.success(t('feedback.deleted')); } }); if (isLoading) { return (
); } const pendingComments: PhotoFeedback[] = feedbackData?.feedback || []; const hasPending = pendingComments.length > 0; return (

{t('feedback.pendingModeration', 'Pending Moderation')}

{hasPending && ( {pendingComments.length} {t('feedback.pending', 'pending')} )}
{!hasPending ? (

{t('feedback.noPendingComments', 'No comments pending moderation')}

) : (
{pendingComments.slice(0, showAll ? undefined : maxItems).map((item) => (
{item.guest_name || t('feedback.anonymous', 'Anonymous')} {format( typeof item.created_at === 'string' ? parseISO(item.created_at) : new Date(item.created_at), 'MMM d, h:mm a' )}

{item.comment_text || item.comment}

{item.photo_id && (

{t('feedback.onPhoto', 'On photo')}: {item.filename || item.photo_filename || `#${item.photo_id}`}

)}
{/* Actions */}
))} {pendingComments.length > maxItems && !showAll && ( )}
)} {/* Quick link to full feedback page */}
{t('feedback.viewAllFeedback', 'View all feedback & settings')}
); }; FeedbackModerationPanel.displayName = 'FeedbackModerationPanel';