import { useState } from "react"; import { Calendar } from "@/components/ui/calendar"; import { Conference } from "@/types/conference"; import { parseISO, format, parse, startOfMonth } from "date-fns"; interface ConferenceCalendarProps { conferences: Conference[]; } const ConferenceCalendar = ({ conferences }: ConferenceCalendarProps) => { const [selectedDate, setSelectedDate] = useState(undefined); const [currentMonth, setCurrentMonth] = useState(new Date()); // Handle month change const handleMonthChange = (month: Date) => { setCurrentMonth(month); setSelectedDate(undefined); // Clear selected date when changing months }; // Convert conference dates to calendar events const conferenceEvents = conferences.map(conf => { let startDate: Date | null = null; try { // First try to use the start field if it exists if (conf.start) { startDate = parseISO(conf.start); } // If no start field or it failed, try to parse the date field else if (conf.date) { // Handle various date formats const dateStr = conf.date.split('–')[0].split('-')[0].trim(); // Get first date in range // Try different date formats try { // Try "MMM d, yyyy" format (e.g., "Feb 28, 2025") startDate = parse(dateStr, 'MMM d, yyyy', new Date()); } catch { try { // Try "MMMM d, yyyy" format (e.g., "February 28, 2025") startDate = parse(dateStr, 'MMMM d, yyyy', new Date()); } catch { // If all else fails, try ISO format startDate = parseISO(dateStr); } } } // Only return event if we successfully parsed a date if (startDate && isValidDate(startDate)) { return { date: startDate, title: conf.title, conference: conf }; } return null; } catch (error) { console.warn(`Failed to parse date for conference ${conf.title}:`, error); return null; } }).filter(event => event !== null); // Remove any null events // Helper function to check if date is valid function isValidDate(date: Date) { return date instanceof Date && !isNaN(date.getTime()); } // Get events for the selected date const getEventsForDate = (date: Date) => { if (!date || !isValidDate(date)) return []; return conferenceEvents.filter(event => event && event.date && format(event.date, 'yyyy-MM-dd') === format(date, 'yyyy-MM-dd') ); }; // Get events for the current month const getEventsForMonth = (date: Date) => { return conferenceEvents.filter(event => event && event.date && format(event.date, 'yyyy-MM') === format(date, 'yyyy-MM') ); }; // Create footer content const footer = (

Events in {format(currentMonth, 'MMMM yyyy')}:

{getEventsForMonth(currentMonth).length > 0 ? (
    {getEventsForMonth(currentMonth).map((event, index) => (
  • {event.title} ({format(event.date, 'MMM d')}) - {event.conference.place}
  • ))}
) : (

No events this month

)} {selectedDate && (

Events on {format(selectedDate, 'MMMM d, yyyy')}:

{getEventsForDate(selectedDate).length > 0 ? (
    {getEventsForDate(selectedDate).map((event, index) => (
  • {event.title} - {event.conference.place}
  • ))}
) : (

No events on this date

)}
)}
); return (
getEventsForDate(date).length > 0 }} modifiersStyles={{ event: { fontWeight: 'bold', textDecoration: 'underline' } }} />
); }; export default ConferenceCalendar;