import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { CalendarDays, Globe, Tag, Clock, AlarmClock, CalendarPlus } from "lucide-react"; import { Conference } from "@/types/conference"; import { formatDistanceToNow, parseISO, isValid, format } from "date-fns"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; interface ConferenceDialogProps { conference: Conference; open: boolean; onOpenChange: (open: boolean) => void; } const ConferenceDialog = ({ conference, open, onOpenChange }: ConferenceDialogProps) => { const deadlineDate = conference.deadline && conference.deadline !== 'TBD' ? parseISO(conference.deadline) : null; const daysLeft = deadlineDate && isValid(deadlineDate) ? formatDistanceToNow(deadlineDate, { addSuffix: true }) : 'TBD'; const getCountdownColor = () => { if (!deadlineDate || !isValid(deadlineDate)) return "text-neutral-600"; const daysRemaining = Math.ceil((deadlineDate.getTime() - new Date().getTime()) / (1000 * 60 * 60 * 24)); if (daysRemaining <= 7) return "text-red-600"; if (daysRemaining <= 30) return "text-orange-600"; return "text-green-600"; }; const createCalendarEvent = (type: 'google' | 'apple') => { const startDate = conference.start ? parseISO(conference.start) : parseISO(conference.date.split('-')[0].trim()); const endDate = conference.end ? parseISO(conference.end) : parseISO(conference.date.split('-')[1]?.trim() || conference.date); const formatDateForGoogle = (date: Date) => format(date, "yyyyMMdd'T'HHmmss'Z'"); const formatDateForApple = (date: Date) => format(date, "yyyyMMdd'T'HHmmss"); const title = encodeURIComponent(conference.title); const location = encodeURIComponent(conference.place); const description = encodeURIComponent( `Conference: ${conference.full_name || conference.title}\n` + `Location: ${conference.place}\n` + `Deadline: ${conference.deadline}\n` + (conference.abstract_deadline ? `Abstract Deadline: ${conference.abstract_deadline}\n` : '') + (conference.link ? `Website: ${conference.link}` : '') ); if (type === 'google') { const url = `https://calendar.google.com/calendar/render?action=TEMPLATE` + `&text=${title}` + `&dates=${formatDateForGoogle(startDate)}/${formatDateForGoogle(endDate)}` + `&details=${description}` + `&location=${location}` + `&sprop=website:${encodeURIComponent(conference.link || '')}`; window.open(url, '_blank'); } else { const url = `data:text/calendar;charset=utf8,BEGIN:VCALENDAR VERSION:2.0 BEGIN:VEVENT URL:${conference.link || ''} DTSTART:${formatDateForApple(startDate)} DTEND:${formatDateForApple(endDate)} SUMMARY:${title} DESCRIPTION:${description} LOCATION:${location} END:VEVENT END:VCALENDAR`; const link = document.createElement('a'); link.href = url; link.download = `${conference.title.toLowerCase().replace(/\s+/g, '-')}.ics`; document.body.appendChild(link); link.click(); document.body.removeChild(link); } }; return (
{conference.title} {conference.full_name && (

{conference.full_name}

)}
createCalendarEvent('google')}> Add to Google Calendar createCalendarEvent('apple')}> Add to Apple Calendar
{conference.date}
{conference.place}
Deadline: {conference.deadline === 'TBD' ? 'TBD' : conference.deadline} {conference.timezone && ( Timezone: {conference.timezone} )}
{daysLeft}
{conference.abstract_deadline && (
Abstract Deadline: {conference.abstract_deadline}
)} {Array.isArray(conference.tags) && conference.tags.length > 0 && (
{conference.tags.map((tag) => ( {tag} ))}
)} {conference.note && (
)} {conference.link && (
Visit Conference Website →
)}
); }; export default ConferenceDialog;