Added time logic and edited several buttons in hod panel
This commit is contained in:
@@ -34,6 +34,17 @@ public class EventController {
|
|||||||
List<Registration> regs = registrationRepository.findAll();
|
List<Registration> regs = registrationRepository.findAll();
|
||||||
|
|
||||||
for (Event event : events) {
|
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()
|
int count = (int) regs.stream()
|
||||||
.filter(r -> r.getEventId() != null && r.getEventId().equals(event.getId()))
|
.filter(r -> r.getEventId() != null && r.getEventId().equals(event.getId()))
|
||||||
.count();
|
.count();
|
||||||
|
|||||||
@@ -28,16 +28,25 @@ public class RegistrationController {
|
|||||||
public List<Registration> getRegistrations(@RequestParam(required = false) Long userId,
|
public List<Registration> getRegistrations(@RequestParam(required = false) Long userId,
|
||||||
@RequestParam(required = false) Long eventId,
|
@RequestParam(required = false) Long eventId,
|
||||||
@RequestParam(required = false) String teamCode) {
|
@RequestParam(required = false) String teamCode) {
|
||||||
|
List<Registration> list;
|
||||||
if (userId != null) {
|
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 list;
|
||||||
return registrationRepository.findByTeamCode(teamCode);
|
|
||||||
}
|
|
||||||
return registrationRepository.findAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
|
|||||||
@@ -21,6 +21,23 @@ public class SpecialEventController {
|
|||||||
@GetMapping
|
@GetMapping
|
||||||
public List<SpecialEvent> getAllSpecialEvents() {
|
public List<SpecialEvent> getAllSpecialEvents() {
|
||||||
List<SpecialEvent> list = specialEventRepository.findAll();
|
List<SpecialEvent> 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) -> {
|
list.sort((a, b) -> {
|
||||||
String ca = a.getCreatedAt() != null ? a.getCreatedAt() : "";
|
String ca = a.getCreatedAt() != null ? a.getCreatedAt() : "";
|
||||||
String cb = b.getCreatedAt() != null ? b.getCreatedAt() : "";
|
String cb = b.getCreatedAt() != null ? b.getCreatedAt() : "";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { API_BASE_URL } from '../../lib/config';
|
import { API_BASE_URL } from '../../lib/config';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { motion } from 'framer-motion';
|
import { motion, AnimatePresence } from 'framer-motion';
|
||||||
import {
|
import {
|
||||||
Calendar,
|
Calendar,
|
||||||
MapPin,
|
MapPin,
|
||||||
@@ -8,22 +8,46 @@ import {
|
|||||||
Filter,
|
Filter,
|
||||||
Search,
|
Search,
|
||||||
Trash2,
|
Trash2,
|
||||||
FileSpreadsheet
|
FileSpreadsheet,
|
||||||
|
FileText,
|
||||||
|
Users,
|
||||||
|
Ticket,
|
||||||
|
Wallet,
|
||||||
|
Heart,
|
||||||
|
XCircle,
|
||||||
|
AlertTriangle,
|
||||||
|
Split,
|
||||||
|
Layers,
|
||||||
|
CheckCircle
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { cn } from '../../lib/utils';
|
import { cn } from '../../lib/utils';
|
||||||
import { useAuth } from '../../context/AuthContext';
|
import { useAuth } from '../../context/AuthContext';
|
||||||
import { StatusTimeline, type Event } from './EventStatusTimeline';
|
import { StatusTimeline, type Event } from './EventStatusTimeline';
|
||||||
import { Pagination } from './Pagination';
|
import { Pagination } from './Pagination';
|
||||||
|
|
||||||
|
interface ExtendedEvent extends Event {
|
||||||
|
description?: string;
|
||||||
|
sponsors?: string[];
|
||||||
|
academicYears?: string[];
|
||||||
|
dayConfigs?: any[];
|
||||||
|
deptLimits?: Record<string, any>;
|
||||||
|
deptSectionLimits?: Record<string, any>;
|
||||||
|
budget?: number;
|
||||||
|
hasRegistrationFee?: boolean;
|
||||||
|
registrationFee?: number;
|
||||||
|
conflictMessage?: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface AllEventsProps {
|
interface AllEventsProps {
|
||||||
onEditEvent?: (event: any) => void;
|
onEditEvent?: (event: any) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AllEvents: React.FC<AllEventsProps> = ({ onEditEvent }) => {
|
export const AllEvents: React.FC<AllEventsProps> = ({ onEditEvent }) => {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const [events, setEvents] = useState<Event[]>([]);
|
const [events, setEvents] = useState<ExtendedEvent[]>([]);
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [searchTerm, setSearchTerm] = useState('');
|
const [searchTerm, setSearchTerm] = useState('');
|
||||||
|
const [selectedEvent, setSelectedEvent] = useState<ExtendedEvent | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchEvents();
|
fetchEvents();
|
||||||
@@ -78,7 +102,6 @@ export const AllEvents: React.FC<AllEventsProps> = ({ onEditEvent }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [itemsPerPage, setItemsPerPage] = useState(10);
|
const [itemsPerPage, setItemsPerPage] = useState(10);
|
||||||
|
|
||||||
@@ -209,6 +232,12 @@ export const AllEvents: React.FC<AllEventsProps> = ({ onEditEvent }) => {
|
|||||||
</td>
|
</td>
|
||||||
<td className="px-8 py-6 text-right">
|
<td className="px-8 py-6 text-right">
|
||||||
<div className="flex items-center justify-end gap-2">
|
<div className="flex items-center justify-end gap-2">
|
||||||
|
<button
|
||||||
|
onClick={() => setSelectedEvent(event)}
|
||||||
|
className="px-4 py-2 bg-slate-50 text-brand-indigo hover:bg-brand-indigo hover:text-white rounded-xl text-[9px] font-black uppercase tracking-widest transition-all border border-brand-indigo/10"
|
||||||
|
>
|
||||||
|
View
|
||||||
|
</button>
|
||||||
{(user?.role === 'ADMIN' || (event.status === 'REQUESTED' && event.proposer?.email === user?.email)) && onEditEvent && (
|
{(user?.role === 'ADMIN' || (event.status === 'REQUESTED' && event.proposer?.email === user?.email)) && onEditEvent && (
|
||||||
<button
|
<button
|
||||||
onClick={() => onEditEvent(event)}
|
onClick={() => onEditEvent(event)}
|
||||||
@@ -248,6 +277,262 @@ export const AllEvents: React.FC<AllEventsProps> = ({ onEditEvent }) => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Details Modal */}
|
||||||
|
<AnimatePresence>
|
||||||
|
{selectedEvent && (
|
||||||
|
<div className="fixed inset-0 z-[100] flex items-center justify-center p-4">
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
exit={{ opacity: 0 }}
|
||||||
|
onClick={() => setSelectedEvent(null)}
|
||||||
|
className="absolute inset-0 bg-slate-900/40 backdrop-blur-sm"
|
||||||
|
/>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, scale: 0.9, y: 20 }}
|
||||||
|
animate={{ opacity: 1, scale: 1, y: 0 }}
|
||||||
|
exit={{ opacity: 0, scale: 0.9, y: 20 }}
|
||||||
|
className="relative w-full max-w-2xl bg-white rounded-[2.5rem] premium-shadow overflow-hidden max-h-[90vh] overflow-y-auto"
|
||||||
|
>
|
||||||
|
<div className={cn(
|
||||||
|
"p-8 text-white flex justify-between items-start",
|
||||||
|
selectedEvent.status === 'CANCELLED' ? "bg-red-600" : "bg-brand-navy"
|
||||||
|
)}>
|
||||||
|
<div>
|
||||||
|
<div className="flex items-center gap-2 mb-2">
|
||||||
|
<span className="text-[10px] font-black uppercase tracking-[0.2em] text-white/60">Event Details</span>
|
||||||
|
<span className="w-1 h-1 bg-white/30 rounded-full" />
|
||||||
|
<span className="text-[10px] font-black uppercase tracking-[0.2em] text-white/60">{selectedEvent.institution}</span>
|
||||||
|
{selectedEvent.category === 'CLUB' && (
|
||||||
|
<>
|
||||||
|
<span className="w-1 h-1 bg-white/30 rounded-full" />
|
||||||
|
<span className="text-[10px] font-black uppercase tracking-[0.2em] text-emerald-400">Institutional Club Event</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<h3 className="text-2xl font-black tracking-tight">{selectedEvent.title}</h3>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={() => setSelectedEvent(null)}
|
||||||
|
className="p-2 hover:bg-white/10 rounded-xl transition-all"
|
||||||
|
>
|
||||||
|
<XCircle className="w-6 h-6" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="p-8 space-y-8">
|
||||||
|
{/* Description Section */}
|
||||||
|
{selectedEvent.description && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-text-muted">
|
||||||
|
<FileText className="w-3.5 h-3.5" />
|
||||||
|
Event Description
|
||||||
|
</div>
|
||||||
|
<p className="text-sm font-medium text-text-dark leading-relaxed bg-slate-50 p-4 rounded-2xl border border-slate-100">
|
||||||
|
{selectedEvent.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="grid grid-cols-2 gap-8">
|
||||||
|
<div className="space-y-6">
|
||||||
|
<div className="space-y-1">
|
||||||
|
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-text-muted">
|
||||||
|
<Calendar className="w-3.5 h-3.5" />
|
||||||
|
Schedule
|
||||||
|
</div>
|
||||||
|
<p className="text-sm font-bold text-text-dark">
|
||||||
|
{parseDate(selectedEvent.startDate) ? parseDate(selectedEvent.startDate)!.toLocaleString('en-IN') : 'N/A'}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-1">
|
||||||
|
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-text-muted">
|
||||||
|
<MapPin className="w-3.5 h-3.5" />
|
||||||
|
Venue
|
||||||
|
</div>
|
||||||
|
<p className="text-sm font-bold text-text-dark">{selectedEvent.location}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-6">
|
||||||
|
<div className="space-y-1">
|
||||||
|
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-text-muted">
|
||||||
|
<Users className="w-3.5 h-3.5" />
|
||||||
|
Proposed By
|
||||||
|
</div>
|
||||||
|
<p className="text-sm font-bold text-text-dark">{selectedEvent.proposer?.fullName || 'Faculty'}</p>
|
||||||
|
<p className="text-[10px] font-black text-brand-indigo uppercase">{selectedEvent.department}</p>
|
||||||
|
</div>
|
||||||
|
{selectedEvent.academicYears && selectedEvent.academicYears.length > 0 && (
|
||||||
|
<div className="space-y-1">
|
||||||
|
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-text-muted">
|
||||||
|
<Users className="w-3.5 h-3.5" />
|
||||||
|
Target Audience
|
||||||
|
</div>
|
||||||
|
<p className="text-sm font-bold text-text-dark">{selectedEvent.academicYears.join(', ')} Batches</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Sponsors Section */}
|
||||||
|
{selectedEvent.sponsors && selectedEvent.sponsors.length > 0 && (
|
||||||
|
<div className="space-y-3">
|
||||||
|
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-text-muted">
|
||||||
|
<Heart className="w-3.5 h-3.5 text-brand-indigo" />
|
||||||
|
Event Sponsors
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{selectedEvent.sponsors.map((sponsor, idx) => (
|
||||||
|
<span key={idx} className="px-3 py-1 bg-brand-glow text-brand-indigo rounded-lg text-[10px] font-black uppercase tracking-widest border border-brand-indigo/10">
|
||||||
|
{sponsor}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Itinerary & Day Configs */}
|
||||||
|
{selectedEvent.dayConfigs && selectedEvent.dayConfigs.length > 0 && (
|
||||||
|
<div className="space-y-3">
|
||||||
|
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-text-muted">
|
||||||
|
<Calendar className="w-3.5 h-3.5 text-brand-indigo" />
|
||||||
|
Detailed Itinerary & Schedule
|
||||||
|
</div>
|
||||||
|
<div className="space-y-4">
|
||||||
|
{selectedEvent.dayConfigs.map((day: any, dIdx: number) => {
|
||||||
|
const dayDate = day.date ? new Date(day.date) : null;
|
||||||
|
return (
|
||||||
|
<div key={dIdx} className="p-4 rounded-2xl bg-slate-50 border border-slate-100 space-y-3">
|
||||||
|
<div className="flex justify-between items-center border-b border-slate-200 pb-1.5">
|
||||||
|
<span className="text-[11px] font-black text-brand-navy uppercase tracking-wider">
|
||||||
|
Day {dIdx + 1}: {dayDate && !isNaN(dayDate.getTime()) ? dayDate.toLocaleDateString() : day.date || 'TBD'}
|
||||||
|
</span>
|
||||||
|
<span className="px-2 py-0.5 bg-brand-glow text-brand-indigo text-[8px] font-black uppercase tracking-widest rounded">
|
||||||
|
{day.batches?.length || 0} {(day.batches?.length || 0) === 1 ? 'Batch' : 'Batches'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-3 divide-y divide-slate-200/50">
|
||||||
|
{day.batches?.map((batch: any, bIdx: number) => (
|
||||||
|
<div key={bIdx} className="pt-3 first:pt-0 space-y-2">
|
||||||
|
<div className="flex justify-between items-center">
|
||||||
|
<span className="text-[9px] font-black text-slate-400 uppercase tracking-widest">
|
||||||
|
Batch {batch.id || bIdx + 1}
|
||||||
|
</span>
|
||||||
|
<span className="text-[10px] font-bold text-brand-indigo bg-white px-2 py-0.5 rounded-lg border border-slate-200 shadow-sm flex items-center gap-1">
|
||||||
|
<Clock className="w-3.5 h-3.5" />
|
||||||
|
{batch.startTime || 'TBD'} - {batch.endTime || 'TBD'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{batch.resourcePerson && batch.resourcePerson.name && (
|
||||||
|
<div className="p-3 bg-white rounded-xl border border-slate-100 space-y-1.5">
|
||||||
|
<div className="flex justify-between items-start">
|
||||||
|
<div>
|
||||||
|
<p className="text-[8px] font-black text-slate-400 uppercase tracking-widest">Resource Person</p>
|
||||||
|
<p className="text-xs font-bold text-text-dark">{batch.resourcePerson.name}</p>
|
||||||
|
</div>
|
||||||
|
<span className={cn(
|
||||||
|
"px-2 py-0.5 rounded text-[8px] font-black uppercase tracking-wider",
|
||||||
|
batch.resourcePerson.type === 'EXTERNAL' ? "bg-amber-50 text-amber-600 border border-amber-100" : "bg-brand-glow text-brand-indigo border border-brand-indigo/10"
|
||||||
|
)}>
|
||||||
|
{batch.resourcePerson.type || 'INTERNAL'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-1.5 text-[9px] text-text-muted font-semibold">
|
||||||
|
{batch.resourcePerson.dept && (
|
||||||
|
<div>
|
||||||
|
<span className="font-bold text-slate-400 uppercase tracking-wider">Dept:</span> {batch.resourcePerson.dept}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{batch.resourcePerson.college_name && (
|
||||||
|
<div className="col-span-2">
|
||||||
|
<span className="font-bold text-slate-400 uppercase tracking-wider">Inst:</span> {batch.resourcePerson.college_name}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{batch.resourcePerson.phone && (
|
||||||
|
<div>
|
||||||
|
<span className="font-bold text-slate-400 tracking-wider uppercase">Phone:</span> {batch.resourcePerson.phone}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{batch.resourcePerson.email && (
|
||||||
|
<div>
|
||||||
|
<span className="font-bold text-slate-400 tracking-wider uppercase">Email:</span> {batch.resourcePerson.email}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Department limits and quotas */}
|
||||||
|
{selectedEvent.deptLimits && Object.keys(selectedEvent.deptLimits).length > 0 && (
|
||||||
|
<div className="space-y-3">
|
||||||
|
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-text-muted">
|
||||||
|
<Users className="w-3.5 h-3.5 text-brand-indigo" />
|
||||||
|
Department Limits & Quotas
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
|
{Object.entries(selectedEvent.deptLimits).map(([dept, maxSeats]) => {
|
||||||
|
const sectionLimits = selectedEvent.deptSectionLimits?.[dept];
|
||||||
|
const hasSectionLimits = sectionLimits && Object.keys(sectionLimits).length > 0;
|
||||||
|
return (
|
||||||
|
<div key={dept} className="bg-slate-50 border border-slate-100 rounded-2xl p-4 space-y-3">
|
||||||
|
<div className="flex justify-between items-center">
|
||||||
|
<span className="text-xs font-black text-brand-navy uppercase tracking-wider">{dept}</span>
|
||||||
|
<span className="px-2 py-0.5 bg-brand-indigo text-white text-[9px] font-black uppercase rounded-md">
|
||||||
|
Quota: {maxSeats} Seats
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{hasSectionLimits && (
|
||||||
|
<div className="pt-2 border-t border-slate-200/60 grid grid-cols-3 gap-2">
|
||||||
|
{Object.entries(sectionLimits).map(([sec, limit]) => (
|
||||||
|
<div key={sec} className="bg-white px-2 py-1 rounded-xl border border-slate-100 text-center">
|
||||||
|
<span className="block text-[8px] font-black text-slate-400 uppercase mb-0.5">Sec {sec}</span>
|
||||||
|
<span className="text-[10px] font-black text-brand-navy">{limit}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="grid grid-cols-2 gap-8 pt-4 border-t border-slate-50">
|
||||||
|
<div className="p-4 bg-slate-50 rounded-2xl">
|
||||||
|
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-text-muted mb-1">
|
||||||
|
<Wallet className="w-3.5 h-3.5 text-brand-indigo" />
|
||||||
|
Estimated Budget
|
||||||
|
</div>
|
||||||
|
<p className="text-lg font-black text-text-dark">₹{selectedEvent.budget?.toLocaleString() || '0'}</p>
|
||||||
|
</div>
|
||||||
|
<div className="p-4 bg-slate-50 rounded-2xl">
|
||||||
|
<div className="flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-text-muted mb-1">
|
||||||
|
<Ticket className="w-3.5 h-3.5 text-brand-indigo" />
|
||||||
|
Registration
|
||||||
|
</div>
|
||||||
|
<p className="text-lg font-black text-text-dark">
|
||||||
|
{selectedEvent.hasRegistrationFee ? `₹${selectedEvent.registrationFee}` : 'FREE'}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user