'use client'; import { useState, useCallback } from 'react'; import { PartnerEvent } from '@/types/partner'; import { approvePartnerEvent, rejectPartnerEvent } from '@/lib/actions/partner-governance'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Textarea } from '@/components/ui/textarea'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogFooter, } from '@/components/ui/dialog'; import { Calendar, MapPin, Ticket, CheckCircle2, XCircle, Clock, Eye, DollarSign, } from 'lucide-react'; import { toast } from 'sonner'; import { cn } from '@/lib/utils'; interface EventApprovalQueueProps { partnerId: string; events: PartnerEvent[]; onEventUpdated?: () => void; } const EVENT_STATUS_STYLES: Record = { PENDING_REVIEW: 'bg-warning/10 text-warning border-warning/20', LIVE: 'bg-success/10 text-success border-success/20', DRAFT: 'bg-muted text-muted-foreground border-border', COMPLETED: 'bg-primary/10 text-primary border-primary/20', CANCELLED: 'bg-destructive/10 text-destructive border-destructive/20', REJECTED: 'bg-destructive/10 text-destructive border-destructive/20', }; export function EventApprovalQueue({ partnerId, events, onEventUpdated }: EventApprovalQueueProps) { const [eventList, setEventList] = useState(events); const [reviewingEvent, setReviewingEvent] = useState(null); const [rejectionReason, setRejectionReason] = useState(''); const [processing, setProcessing] = useState(false); const pendingEvents = eventList.filter(e => e.status === 'PENDING_REVIEW'); const otherEvents = eventList.filter(e => e.status !== 'PENDING_REVIEW'); const handleApprove = useCallback(async (eventId: string) => { setProcessing(true); try { const result = await approvePartnerEvent(eventId); if (result.success) { toast.success(result.message); setEventList(prev => prev.map(e => e.id === eventId ? { ...e, status: 'LIVE' as const } : e) ); setReviewingEvent(null); onEventUpdated?.(); } else { toast.error(result.message); } } catch { toast.error('Failed to approve event.'); } finally { setProcessing(false); } }, [onEventUpdated]); const handleReject = useCallback(async (eventId: string) => { if (!rejectionReason.trim()) { toast.error('Please provide a reason for rejection.'); return; } setProcessing(true); try { const result = await rejectPartnerEvent(eventId, rejectionReason); if (result.success) { toast.success(result.message); setEventList(prev => prev.map(e => e.id === eventId ? { ...e, status: 'REJECTED' as const, rejectionReason } : e) ); setReviewingEvent(null); setRejectionReason(''); onEventUpdated?.(); } else { toast.error(result.message); } } catch { toast.error('Failed to reject event.'); } finally { setProcessing(false); } }, [rejectionReason, onEventUpdated]); const EventCard = ({ event, showActions }: { event: PartnerEvent; showActions: boolean }) => (

{event.title}

{new Date(event.date).toLocaleDateString()} {event.venue}
{event.status.replace('_', ' ')}
{event.ticketsSold}/{event.totalTickets} sold {event.ticketPrice > 0 && ( ₹{event.ticketPrice} )} {event.category && ( {event.category} )}
{showActions && event.status === 'PENDING_REVIEW' && (
)} {event.status === 'REJECTED' && event.rejectionReason && (

Rejected: {event.rejectionReason}

)}
); return (
{/* Pending Section */}

Pending Approval

{pendingEvents.length > 0 && ( {pendingEvents.length} pending )}
{pendingEvents.length > 0 ? (
{pendingEvents.map(event => ( ))}
) : (
No events pending review
)}
{/* Other Events */} {otherEvents.length > 0 && (

All Events

{otherEvents.map(event => ( ))}
)} {/* Review Dialog */} { if (!open) { setReviewingEvent(null); setRejectionReason(''); } }}> Review Event Review and approve or decline this event submission. {reviewingEvent && (

{reviewingEvent.title}

{new Date(reviewingEvent.date).toLocaleDateString()} {reviewingEvent.time && ` at ${reviewingEvent.time}`}
{reviewingEvent.venue}
{reviewingEvent.totalTickets} tickets
₹{reviewingEvent.ticketPrice} each
{reviewingEvent.category && ( {reviewingEvent.category} )}