import React, { useState } from 'react'; import { Head, router } from '@inertiajs/react'; import AdminLayout from '../../../Layouts/AdminLayout'; import { Heart, Plus, Trash2, Send, CheckCircle2, Check, X, Calendar, MapPin, Clock, Gift, Sparkles, Search, ChevronDown, ChevronUp, Building, User, XCircle, Eye, BellRing } from 'lucide-react'; const hoursList = [ '12:00', '12:30', '01:00', '01:30', '02:00', '02:30', '03:00', '03:30', '04:00', '04:30', '05:00', '05:30', '06:00', '06:30', '07:00', '07:30', '08:00', '08:30', '09:00', '09:30', '10:00', '10:30', '11:00', '11:30' ]; export default function Announcements({ initialAnnouncements }) { const [announcements, setAnnouncements] = useState(initialAnnouncements || []); const [isFormOpen, setIsFormOpen] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const [statusFilter, setStatusFilter] = useState('All'); const [expandedCards, setExpandedCards] = useState({}); // Time picker states const [startTimeHour, setStartTimeHour] = useState('09:00'); const [startTimeAmpm, setStartTimeAmpm] = useState('AM'); const [endTimeHour, setEndTimeHour] = useState('04:00'); const [endTimeAmpm, setEndTimeAmpm] = useState('PM'); const [isStartPickerOpen, setIsStartPickerOpen] = useState(false); const [isEndPickerOpen, setIsEndPickerOpen] = useState(false); const [newAnnouncement, setNewAnnouncement] = useState({ title: '', content: '', provided_items: '', event_date: '', event_time: '09:00 AM - 04:00 PM', location_details: '', location_pin: '' }); const [errors, setErrors] = useState({}); const [toastMessage, setToastMessage] = useState(null); const [rejectingAnnouncementId, setRejectingAnnouncementId] = useState(null); const [rejectionRemarks, setRejectionRemarks] = useState(''); const showToast = (message) => { setToastMessage(message); setTimeout(() => setToastMessage(null), 3000); }; const handleCreate = (e) => { e.preventDefault(); let newErrors = {}; if (!newAnnouncement.title.trim()) newErrors.title = 'Title is required'; if (!newAnnouncement.content.trim()) newErrors.content = 'Description is required'; if (!newAnnouncement.provided_items.trim()) newErrors.provided_items = 'Provided items is required'; if (!newAnnouncement.event_date.trim()) newErrors.event_date = 'Event date is required'; if (!newAnnouncement.event_time.trim()) newErrors.event_time = 'Event time is required'; if (!newAnnouncement.location_details.trim()) newErrors.location_details = 'Location details is required'; if (!newAnnouncement.location_pin.trim()) { newErrors.location_pin = 'Location pin URL is required'; } else if (!newAnnouncement.location_pin.startsWith('http://') && !newAnnouncement.location_pin.startsWith('https://')) { newErrors.location_pin = 'Must be a valid URL'; } if (Object.keys(newErrors).length > 0) { setErrors(newErrors); return; } router.post(route('admin.announcements.store'), { title: newAnnouncement.title, content: newAnnouncement.content, provided_items: newAnnouncement.provided_items, event_date: newAnnouncement.event_date, event_time: newAnnouncement.event_time, location_details: newAnnouncement.location_details, location_pin: newAnnouncement.location_pin }, { onSuccess: () => { setNewAnnouncement({ title: '', content: '', provided_items: '', event_date: '', event_time: '09:00 AM - 04:00 PM', location_details: '', location_pin: '' }); setStartTimeHour('09:00'); setStartTimeAmpm('AM'); setEndTimeHour('04:00'); setEndTimeAmpm('PM'); setErrors({}); setIsFormOpen(false); showToast('Charity Event created successfully'); setTimeout(() => window.location.reload(), 500); } }); }; const updateEventTime = (sh, sa, eh, ea) => { setNewAnnouncement(prev => ({ ...prev, event_time: `${sh} ${sa} - ${eh} ${ea}` })); }; const handleApprove = (id) => { router.post(route('admin.announcements.approve', id), {}, { onSuccess: () => { showToast('Charity Event approved successfully'); setTimeout(() => window.location.reload(), 500); } }); }; const handleReject = (id) => { setRejectingAnnouncementId(id); setRejectionRemarks(''); }; const handleRejectSubmit = (e) => { e.preventDefault(); if (!rejectionRemarks.trim()) return; router.post(route('admin.announcements.reject', rejectingAnnouncementId), { remarks: rejectionRemarks }, { onSuccess: () => { setRejectingAnnouncementId(null); setRejectionRemarks(''); showToast('Charity Event rejected successfully'); setTimeout(() => window.location.reload(), 500); } }); }; const handleDelete = (id) => { if (confirm('Are you sure you want to delete this charity event?')) { router.delete(route('admin.announcements.delete', id), { onSuccess: () => { showToast('Charity Event deleted'); setTimeout(() => window.location.reload(), 500); } }); } }; const toggleExpand = (id) => { setExpandedCards(prev => ({ ...prev, [id]: !prev[id] })); }; // Calculate dynamic statistics const totalDrives = announcements.length; const pendingCount = announcements.filter(a => a.status === 'pending').length; const approvedCount = announcements.filter(a => a.status === 'approved').length; const rejectedCount = announcements.filter(a => a.status === 'rejected').length; // Filter announcements const filteredAnnouncements = announcements.filter(ann => { const matchesSearch = ann.title.toLowerCase().includes(searchQuery.toLowerCase()) || ann.content.toLowerCase().includes(searchQuery.toLowerCase()) || (ann.posted_by && ann.posted_by.toLowerCase().includes(searchQuery.toLowerCase())) || (ann.organization && ann.organization.toLowerCase().includes(searchQuery.toLowerCase())) || (ann.charityDetails?.provided_items && ann.charityDetails.provided_items.toLowerCase().includes(searchQuery.toLowerCase())); const matchesStatus = statusFilter === 'All' || ann.status === statusFilter.toLowerCase(); return matchesSearch && matchesStatus; }); return ( {/* Toast Notification */} {toastMessage && (
{toastMessage}
)}
{/* Upper Header section */}

Charity Events & Drives

Manage, approve, or launch community charity initiatives.

{/* Dashboard Stats Overview (Compact) */}
Total Drives
{totalDrives}
Pending
{pendingCount}
Approved
{approvedCount}
Rejected
{rejectedCount}
{/* Search & Filtering Control Bar */}
{/* Search Field */}
setSearchQuery(e.target.value)} placeholder="Search events by title, description, or sponsor..." className="w-full pl-10 pr-4 py-2 text-sm bg-slate-50 border border-slate-200 rounded-lg outline-none focus:bg-white focus:border-[#0F6E56] focus:ring-2 focus:ring-[#0F6E56]/10 transition-all" /> {searchQuery && ( )}
{/* Filter Tabs */}
{['All', 'Pending', 'Approved', 'Rejected'].map((tab) => ( ))}
{/* Event Creation Modal */} {isFormOpen && (

Compose Charity Event

setNewAnnouncement({ ...newAnnouncement, title: e.target.value })} className={`w-full px-4 py-2.5 rounded-xl border ${errors.title ? 'border-red-500' : 'border-slate-300'} text-sm focus:ring-2 focus:ring-[#0F6E56]/20 focus:border-[#0F6E56] outline-none transition-all`} placeholder="e.g. Free Dental checkup by Emirates Charity" /> {errors.title &&

{errors.title}

}
setNewAnnouncement({ ...newAnnouncement, event_date: e.target.value })} className={`w-full h-11 px-3.5 rounded-xl border ${errors.event_date ? 'border-red-500' : 'border-slate-300'} text-xs focus:ring-2 focus:ring-[#0F6E56]/20 focus:border-[#0F6E56] outline-none transition-all`} /> {errors.event_date &&

{errors.event_date}

}
{isStartPickerOpen && (
setIsStartPickerOpen(false)} /> )}
{isStartPickerOpen && (
{hoursList.map(h => ( ))}
{['AM', 'PM'].map(ampm => ( ))}
)}
{isEndPickerOpen && (
setIsEndPickerOpen(false)} /> )}
{isEndPickerOpen && (
{hoursList.map(h => ( ))}
{['AM', 'PM'].map(ampm => ( ))}
)}
setNewAnnouncement({ ...newAnnouncement, provided_items: e.target.value })} className={`w-full px-4 py-2.5 rounded-xl border ${errors.provided_items ? 'border-red-500' : 'border-slate-300'} text-sm focus:ring-2 focus:ring-[#0F6E56]/20 focus:border-[#0F6E56] outline-none transition-all`} placeholder="e.g. Free Medical Checks & Food Supplies" /> {errors.provided_items &&

{errors.provided_items}

}
setNewAnnouncement({ ...newAnnouncement, location_details: e.target.value })} className={`w-full px-4 py-2.5 rounded-xl border ${errors.location_details ? 'border-red-500' : 'border-slate-300'} text-sm focus:ring-2 focus:ring-[#0F6E56]/20 focus:border-[#0F6E56] outline-none transition-all`} placeholder="e.g. Al Quoz Community Center, Dubai" /> {errors.location_details &&

{errors.location_details}

}
setNewAnnouncement({ ...newAnnouncement, location_pin: e.target.value })} className={`w-full px-4 py-2.5 rounded-xl border ${errors.location_pin ? 'border-red-500' : 'border-slate-300'} text-sm focus:ring-2 focus:ring-[#0F6E56]/20 focus:border-[#0F6E56] outline-none transition-all`} placeholder="e.g. https://maps.app.goo.gl/xyz" /> {errors.location_pin &&

{errors.location_pin}

}
{errors.content &&

{errors.content}

}
)} {/* Rejection remarks modal */} {rejectingAnnouncementId && (

Reject Charity Event

)} {/* Compact Grid of Events */} {filteredAnnouncements.length === 0 ? (

No charity events match your criteria.

) : (
{filteredAnnouncements.map((ann) => { const details = ann.charityDetails; const isExpanded = !!expandedCards[ann.id]; // Color accents based on status const statusColorClass = ann.status === 'approved' ? 'border-l-emerald-500' : ann.status === 'rejected' ? 'border-l-rose-500' : 'border-l-amber-500'; return (
{/* Top Card Area */}

{ann.title}

{ann.status}
{ann.organization} {ann.posted_by}
{/* Action Control Buttons */}
{ann.status === 'pending' && (
)}
{/* Collapsible Content */}

{ann.content}

{ann.content.length > 90 && ( )} {ann.status === 'rejected' && ann.remarks && (
Remarks: {ann.remarks}
)}
{/* Details metadata row (compact icons) */} {details && (
{details.provided_items}
{details.event_date}
{details.location_details}
)}
{/* Bottom Card Footer */}
Published: {ann.created_at} {details?.location_pin && ( View on Map )}
); })}
)}
); }