import Header from "@/components/Header"; import FilterBar from "@/components/FilterBar"; import ConferenceCard from "@/components/ConferenceCard"; import conferencesData from "@/data/conferences.yml"; import { Conference } from "@/types/conference"; import { useState, useMemo, useEffect } from "react"; import { Switch } from "@/components/ui/switch" import { parseISO, isValid, isPast } from "date-fns"; import { extractCountry } from "@/utils/countryExtractor"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; import { X, ChevronRight, Filter, Globe } from "lucide-react"; import { getAllCountries } from "@/utils/countryExtractor"; import { getDeadlineInLocalTime } from "@/utils/dateUtils"; import { sortConferencesByDeadline } from "@/utils/conferenceUtils"; const Index = () => { const [selectedTags, setSelectedTags] = useState>(new Set()); const [selectedCountries, setSelectedCountries] = useState>(new Set()); const [searchQuery, setSearchQuery] = useState(""); const [showPastConferences, setShowPastConferences] = useState(false); // Category buttons configuration const categoryButtons = [ { id: "machine-learning", label: "Machine Learning" }, { id: "lifelong-learning", label: "Lifelong Learning" }, { id: "robotics", label: "Robotics" }, { id: "computer-vision", label: "Computer Vision" }, { id: "web-search", label: "Web Search" }, { id: "data-mining", label: "Data Mining" }, { id: "natural-language-processing", label: "Natural Language Processing" }, { id: "signal-processing", label: "Signal Processing" }, { id: "human-computer-interaction", label: "Human Computer Interaction" }, { id: "computer-graphics", label: "Computer Graphics" }, { id: "mathematics", label: "Mathematics" }, { id: "reinforcement-learning", label: "Reinforcement Learning" }, ]; const filteredConferences = useMemo(() => { if (!Array.isArray(conferencesData)) { console.error("Conferences data is not an array:", conferencesData); return []; } return conferencesData .filter((conf: Conference) => { // Filter by deadline (past/future) const deadlineDate = conf.deadline && conf.deadline !== 'TBD' ? parseISO(conf.deadline) : null; const isUpcoming = !deadlineDate || !isValid(deadlineDate) || !isPast(deadlineDate); if (!showPastConferences && !isUpcoming) return false; // Filter by tags const matchesTags = selectedTags.size === 0 || (Array.isArray(conf.tags) && conf.tags.some(tag => selectedTags.has(tag))); // Filter by countries const matchesCountry = selectedCountries.size === 0 || (conf.country && selectedCountries.has(conf.country)); // Filter by search query const matchesSearch = searchQuery === "" || conf.title.toLowerCase().includes(searchQuery.toLowerCase()) || (conf.full_name && conf.full_name.toLowerCase().includes(searchQuery.toLowerCase())); return matchesTags && matchesCountry && matchesSearch; }) .sort((a: Conference, b: Conference) => { const aDeadline = getDeadlineInLocalTime(a.deadline, a.timezone); const bDeadline = getDeadlineInLocalTime(b.deadline, b.timezone); if (aDeadline && bDeadline) { return aDeadline.getTime() - bDeadline.getTime(); } // Handle cases where one or both deadlines are invalid if (!aDeadline && !bDeadline) return 0; if (!aDeadline) return 1; if (!bDeadline) return -1; return 0; }); }, [selectedTags, selectedCountries, searchQuery, showPastConferences]); // Update handleTagsChange to handle multiple tags const handleTagsChange = (newTags: Set) => { setSelectedTags(newTags); const searchParams = new URLSearchParams(window.location.search); if (newTags.size > 0) { searchParams.set('tags', Array.from(newTags).join(',')); } else { searchParams.delete('tags'); } window.history.replaceState({}, '', `${window.location.pathname}?${searchParams}`); }; const handleCountriesChange = (newCountries: Set) => { setSelectedCountries(newCountries); const searchParams = new URLSearchParams(window.location.search); if (newCountries.size > 0) { searchParams.set('countries', Array.from(newCountries).join(',')); } else { searchParams.delete('countries'); } window.history.replaceState({}, '', `${window.location.pathname}?${searchParams}`); }; // Toggle a single tag const toggleTag = (tag: string) => { const newTags = new Set(selectedTags); if (newTags.has(tag)) { newTags.delete(tag); } else { newTags.add(tag); } handleTagsChange(newTags); }; // Load filters from URL on initial render useEffect(() => { const searchParams = new URLSearchParams(window.location.search); const tagsParam = searchParams.get('tags'); const countriesParam = searchParams.get('countries'); if (tagsParam) { const tags = tagsParam.split(','); setSelectedTags(new Set(tags)); } if (countriesParam) { const countries = countriesParam.split(','); setSelectedCountries(new Set(countries)); } }, []); if (!Array.isArray(conferencesData)) { return
Loading conferences...
; } return (
{/* Category filter buttons */}
{categoryButtons.map(category => ( ))}
{/* Controls row with past conferences toggle and country filter */}

Country

{getAllCountries(conferencesData as Conference[]).map(country => (
{ const newCountries = new Set(selectedCountries); if (newCountries.has(country)) { newCountries.delete(country); } else { newCountries.add(country); } handleCountriesChange(newCountries); }} />
))}
{/* Display selected countries */} {Array.from(selectedCountries).map(country => ( ))} {/* Clear all filters button */} {(selectedTags.size > 0 || selectedCountries.size > 0) && ( )}
{filteredConferences.length === 0 && (

There are no upcoming conferences for the selected categories - enable "Show past conferences" to see previous ones

)}
{filteredConferences.map((conference: Conference) => ( ))}
); }; export default Index;