import React, { useState, useEffect, useMemo } from 'react'; import { Calendar, momentLocalizer } from 'react-big-calendar'; import moment from 'moment'; import 'react-big-calendar/lib/css/react-big-calendar.css'; import './MemberCalendar.css'; import api from '../../utils/api'; import Navbar from '../../components/Navbar'; import MemberFooter from '../../components/MemberFooter'; import { Card } from '../../components/ui/card'; import { Button } from '../../components/ui/button'; import { Badge } from '../../components/ui/badge'; import AddToCalendarButton from '../../components/AddToCalendarButton'; import { toast } from 'sonner'; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from '../../components/ui/dialog'; import { Calendar as CalendarIcon, MapPin, Users, Clock, X, Check, HelpCircle } from 'lucide-react'; const localizer = momentLocalizer(moment); export default function MemberCalendar() { const [events, setEvents] = useState([]); const [loading, setLoading] = useState(true); const [selectedEvent, setSelectedEvent] = useState(null); const [isDialogOpen, setIsDialogOpen] = useState(false); const [rsvpLoading, setRsvpLoading] = useState(false); const [currentDate, setCurrentDate] = useState(new Date()); const [currentView, setCurrentView] = useState('month'); useEffect(() => { fetchEvents(); }, []); const fetchEvents = async () => { try { const response = await api.get('/events'); setEvents(response.data); } catch (error) { toast.error('Failed to load events'); } finally { setLoading(false); } }; // Transform events for react-big-calendar const calendarEvents = useMemo(() => { return events.map(event => ({ id: event.id, title: event.title, start: new Date(event.start_at), end: new Date(event.end_at), resource: event, })); }, [events]); const handleSelectEvent = (event) => { setSelectedEvent(event.resource); setIsDialogOpen(true); }; const handleNavigate = (newDate) => { setCurrentDate(newDate); }; const handleViewChange = (newView) => { setCurrentView(newView); }; const handleRSVP = async (status) => { if (!selectedEvent) return; setRsvpLoading(true); try { await api.post(`/events/${selectedEvent.id}/rsvp`, { rsvp_status: status }); toast.success(`RSVP updated to: ${status}`); await fetchEvents(); const updatedEvent = events.find(e => e.id === selectedEvent.id); if (updatedEvent) { setSelectedEvent({ ...updatedEvent, user_rsvp_status: status }); } } catch (error) { toast.error('Failed to update RSVP'); } finally { setRsvpLoading(false); } }; const eventStyleGetter = (event) => { const rsvpStatus = event.resource?.user_rsvp_status; let backgroundColor = '#DDD8EB'; let borderColor = '#664fa3'; if (rsvpStatus === 'yes') { backgroundColor = '#81B29A'; borderColor = '#66927e'; } else if (rsvpStatus === 'no') { backgroundColor = '#9ca3af'; borderColor = '#6b7280'; } else if (rsvpStatus === 'maybe') { backgroundColor = '#fb923c'; borderColor = '#ea580c'; } return { style: { backgroundColor, borderColor, borderWidth: '2px', borderStyle: 'solid', borderRadius: '6px', color: 'white', fontWeight: '500', fontSize: '0.875rem', padding: '2px 6px', } }; }; if (loading) { return (

Loading calendar...

); } return (

Event Calendar

View and manage your event RSVPs. Click on any event to see details and update your RSVP.

Going
Maybe
Not Going
No RSVP
{selectedEvent && ( <>
{selectedEvent.user_rsvp_status && ( {selectedEvent.user_rsvp_status === 'yes' && 'Going'} {selectedEvent.user_rsvp_status === 'no' && 'Not Going'} {selectedEvent.user_rsvp_status === 'maybe' && 'Maybe'} )}
{selectedEvent.title}
{new Date(selectedEvent.start_at).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}
{new Date(selectedEvent.start_at).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })} - {new Date(selectedEvent.end_at).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
{selectedEvent.location}
{selectedEvent.rsvp_count || 0} {selectedEvent.rsvp_count === 1 ? 'person' : 'people'} attending {selectedEvent.capacity && ` (Capacity: ${selectedEvent.capacity})`}
{selectedEvent.description && (

About This Event

{selectedEvent.description}

)}

Your RSVP

Add to Your Calendar

)}
); }