diff --git a/backend/src/main/java/com/rit/ems/controller/EventController.java b/backend/src/main/java/com/rit/ems/controller/EventController.java index 96e2bff..71485f4 100644 --- a/backend/src/main/java/com/rit/ems/controller/EventController.java +++ b/backend/src/main/java/com/rit/ems/controller/EventController.java @@ -34,6 +34,17 @@ public class EventController { List regs = registrationRepository.findAll(); for (Event event : events) { + if (event.getStartDate() != null) { + String sd = event.getStartDate().replace(" ", "T"); + if (!sd.endsWith("Z")) sd += "Z"; + event.setStartDate(sd); + } + if (event.getEndDate() != null) { + String ed = event.getEndDate().replace(" ", "T"); + if (!ed.endsWith("Z")) ed += "Z"; + event.setEndDate(ed); + } + int count = (int) regs.stream() .filter(r -> r.getEventId() != null && r.getEventId().equals(event.getId())) .count(); diff --git a/backend/src/main/java/com/rit/ems/controller/RegistrationController.java b/backend/src/main/java/com/rit/ems/controller/RegistrationController.java index 7db0257..dadfa84 100644 --- a/backend/src/main/java/com/rit/ems/controller/RegistrationController.java +++ b/backend/src/main/java/com/rit/ems/controller/RegistrationController.java @@ -28,16 +28,25 @@ public class RegistrationController { public List getRegistrations(@RequestParam(required = false) Long userId, @RequestParam(required = false) Long eventId, @RequestParam(required = false) String teamCode) { + List list; if (userId != null) { - return registrationRepository.findByUserId(userId); + list = registrationRepository.findByUserId(userId); + } else if (eventId != null) { + list = registrationRepository.findByEventId(eventId); + } else if (teamCode != null) { + list = registrationRepository.findByTeamCode(teamCode); + } else { + list = registrationRepository.findAll(); } - if (eventId != null) { - return registrationRepository.findByEventId(eventId); + + for (Registration reg : list) { + if (reg.getRegisteredAt() != null) { + String ra = reg.getRegisteredAt().replace(" ", "T"); + if (!ra.endsWith("Z")) ra += "Z"; + reg.setRegisteredAt(ra); + } } - if (teamCode != null) { - return registrationRepository.findByTeamCode(teamCode); - } - return registrationRepository.findAll(); + return list; } @PostMapping diff --git a/backend/src/main/java/com/rit/ems/controller/SpecialEventController.java b/backend/src/main/java/com/rit/ems/controller/SpecialEventController.java index bc9e2da..e3c40df 100644 --- a/backend/src/main/java/com/rit/ems/controller/SpecialEventController.java +++ b/backend/src/main/java/com/rit/ems/controller/SpecialEventController.java @@ -21,6 +21,23 @@ public class SpecialEventController { @GetMapping public List getAllSpecialEvents() { List list = specialEventRepository.findAll(); + for (SpecialEvent se : list) { + if (se.getStartDate() != null) { + String sd = se.getStartDate().replace(" ", "T"); + if (!sd.endsWith("Z")) sd += "Z"; + se.setStartDate(sd); + } + if (se.getEndDate() != null) { + String ed = se.getEndDate().replace(" ", "T"); + if (!ed.endsWith("Z")) ed += "Z"; + se.setEndDate(ed); + } + if (se.getCreatedAt() != null) { + String ca = se.getCreatedAt().replace(" ", "T"); + if (!ca.endsWith("Z")) ca += "Z"; + se.setCreatedAt(ca); + } + } list.sort((a, b) -> { String ca = a.getCreatedAt() != null ? a.getCreatedAt() : ""; String cb = b.getCreatedAt() != null ? b.getCreatedAt() : ""; diff --git a/frontend/src/components/dashboard/AllEvents.tsx b/frontend/src/components/dashboard/AllEvents.tsx index 4cbb57a..63e84b0 100644 --- a/frontend/src/components/dashboard/AllEvents.tsx +++ b/frontend/src/components/dashboard/AllEvents.tsx @@ -1,6 +1,6 @@ import { API_BASE_URL } from '../../lib/config'; import React, { useEffect, useState } from 'react'; -import { motion } from 'framer-motion'; +import { motion, AnimatePresence } from 'framer-motion'; import { Calendar, MapPin, @@ -8,22 +8,46 @@ import { Filter, Search, Trash2, - FileSpreadsheet + FileSpreadsheet, + FileText, + Users, + Ticket, + Wallet, + Heart, + XCircle, + AlertTriangle, + Split, + Layers, + CheckCircle } from 'lucide-react'; import { cn } from '../../lib/utils'; import { useAuth } from '../../context/AuthContext'; import { StatusTimeline, type Event } from './EventStatusTimeline'; import { Pagination } from './Pagination'; +interface ExtendedEvent extends Event { + description?: string; + sponsors?: string[]; + academicYears?: string[]; + dayConfigs?: any[]; + deptLimits?: Record; + deptSectionLimits?: Record; + budget?: number; + hasRegistrationFee?: boolean; + registrationFee?: number; + conflictMessage?: string; +} + interface AllEventsProps { onEditEvent?: (event: any) => void; } export const AllEvents: React.FC = ({ onEditEvent }) => { const { user } = useAuth(); - const [events, setEvents] = useState([]); + const [events, setEvents] = useState([]); const [isLoading, setIsLoading] = useState(true); const [searchTerm, setSearchTerm] = useState(''); + const [selectedEvent, setSelectedEvent] = useState(null); useEffect(() => { fetchEvents(); @@ -78,7 +102,6 @@ export const AllEvents: React.FC = ({ onEditEvent }) => { } }; - const [currentPage, setCurrentPage] = useState(1); const [itemsPerPage, setItemsPerPage] = useState(10); @@ -209,6 +232,12 @@ export const AllEvents: React.FC = ({ onEditEvent }) => {
+ {(user?.role === 'ADMIN' || (event.status === 'REQUESTED' && event.proposer?.email === user?.email)) && onEditEvent && (
+ + {/* Details Modal */} + + {selectedEvent && ( +
+ setSelectedEvent(null)} + className="absolute inset-0 bg-slate-900/40 backdrop-blur-sm" + /> + +
+
+
+ Event Details + + {selectedEvent.institution} + {selectedEvent.category === 'CLUB' && ( + <> + + Institutional Club Event + + )} +
+

{selectedEvent.title}

+
+ +
+ +
+ {/* Description Section */} + {selectedEvent.description && ( +
+
+ + Event Description +
+

+ {selectedEvent.description} +

+
+ )} + +
+
+
+
+ + Schedule +
+

+ {parseDate(selectedEvent.startDate) ? parseDate(selectedEvent.startDate)!.toLocaleString('en-IN') : 'N/A'} +

+
+
+
+ + Venue +
+

{selectedEvent.location}

+
+
+ +
+
+
+ + Proposed By +
+

{selectedEvent.proposer?.fullName || 'Faculty'}

+

{selectedEvent.department}

+
+ {selectedEvent.academicYears && selectedEvent.academicYears.length > 0 && ( +
+
+ + Target Audience +
+

{selectedEvent.academicYears.join(', ')} Batches

+
+ )} +
+
+ + {/* Sponsors Section */} + {selectedEvent.sponsors && selectedEvent.sponsors.length > 0 && ( +
+
+ + Event Sponsors +
+
+ {selectedEvent.sponsors.map((sponsor, idx) => ( + + {sponsor} + + ))} +
+
+ )} + + {/* Itinerary & Day Configs */} + {selectedEvent.dayConfigs && selectedEvent.dayConfigs.length > 0 && ( +
+
+ + Detailed Itinerary & Schedule +
+
+ {selectedEvent.dayConfigs.map((day: any, dIdx: number) => { + const dayDate = day.date ? new Date(day.date) : null; + return ( +
+
+ + Day {dIdx + 1}: {dayDate && !isNaN(dayDate.getTime()) ? dayDate.toLocaleDateString() : day.date || 'TBD'} + + + {day.batches?.length || 0} {(day.batches?.length || 0) === 1 ? 'Batch' : 'Batches'} + +
+
+ {day.batches?.map((batch: any, bIdx: number) => ( +
+
+ + Batch {batch.id || bIdx + 1} + + + + {batch.startTime || 'TBD'} - {batch.endTime || 'TBD'} + +
+ {batch.resourcePerson && batch.resourcePerson.name && ( +
+
+
+

Resource Person

+

{batch.resourcePerson.name}

+
+ + {batch.resourcePerson.type || 'INTERNAL'} + +
+
+ {batch.resourcePerson.dept && ( +
+ Dept: {batch.resourcePerson.dept} +
+ )} + {batch.resourcePerson.college_name && ( +
+ Inst: {batch.resourcePerson.college_name} +
+ )} + {batch.resourcePerson.phone && ( +
+ Phone: {batch.resourcePerson.phone} +
+ )} + {batch.resourcePerson.email && ( +
+ Email: {batch.resourcePerson.email} +
+ )} +
+
+ )} +
+ ))} +
+
+ ); + })} +
+
+ )} + + {/* Department limits and quotas */} + {selectedEvent.deptLimits && Object.keys(selectedEvent.deptLimits).length > 0 && ( +
+
+ + Department Limits & Quotas +
+
+ {Object.entries(selectedEvent.deptLimits).map(([dept, maxSeats]) => { + const sectionLimits = selectedEvent.deptSectionLimits?.[dept]; + const hasSectionLimits = sectionLimits && Object.keys(sectionLimits).length > 0; + return ( +
+
+ {dept} + + Quota: {maxSeats} Seats + +
+ {hasSectionLimits && ( +
+ {Object.entries(sectionLimits).map(([sec, limit]) => ( +
+ Sec {sec} + {limit} +
+ ))} +
+ )} +
+ ); + })} +
+
+ )} + +
+
+
+ + Estimated Budget +
+

₹{selectedEvent.budget?.toLocaleString() || '0'}

+
+
+
+ + Registration +
+

+ {selectedEvent.hasRegistrationFee ? `₹${selectedEvent.registrationFee}` : 'FREE'} +

+
+
+
+
+
+ )} +
); }; +