"use client"; import { Box, VStack, Heading, Text, Card, HStack, Badge, Spinner, Flex, Link, Button, Alert, IconButton, Tooltip, Wrap, } from "@chakra-ui/react"; import { useParams, useRouter } from "next/navigation"; import { useEffect, useState } from "react"; import { FaSync, FaClock, FaUsers, FaEnvelope } from "react-icons/fa"; import { LuArrowLeft } from "react-icons/lu"; import useApi from "../../../../lib/useApi"; import { CalendarEventResponse } from "../../../../api"; export default function RoomCalendarPage() { const params = useParams(); const router = useRouter(); const roomName = params.roomName as string; const api = useApi(); const [events, setEvents] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [syncing, setSyncing] = useState(false); const fetchEvents = async () => { if (!api) return; try { setLoading(true); setError(null); const response = await api.v1RoomsListMeetings({ roomName }); setEvents(response); } catch (err: any) { setError(err.body?.detail || "Failed to load calendar events"); } finally { setLoading(false); } }; const handleSync = async () => { if (!api) return; try { setSyncing(true); await api.v1RoomsSyncIcs({ roomName }); await fetchEvents(); // Refresh events after sync } catch (err: any) { setError(err.body?.detail || "Failed to sync calendar"); } finally { setSyncing(false); } }; useEffect(() => { fetchEvents(); }, [api, roomName]); const formatEventTime = (start: string, end: string) => { const startDate = new Date(start); const endDate = new Date(end); const options: Intl.DateTimeFormatOptions = { hour: "2-digit", minute: "2-digit", }; const dateOptions: Intl.DateTimeFormatOptions = { weekday: "long", year: "numeric", month: "long", day: "numeric", }; const isSameDay = startDate.toDateString() === endDate.toDateString(); if (isSameDay) { return `${startDate.toLocaleDateString(undefined, dateOptions)} • ${startDate.toLocaleTimeString(undefined, options)} - ${endDate.toLocaleTimeString(undefined, options)}`; } else { return `${startDate.toLocaleDateString(undefined, dateOptions)} ${startDate.toLocaleTimeString(undefined, options)} - ${endDate.toLocaleDateString(undefined, dateOptions)} ${endDate.toLocaleTimeString(undefined, options)}`; } }; const isEventActive = (start: string, end: string) => { const now = new Date(); const startDate = new Date(start); const endDate = new Date(end); return now >= startDate && now <= endDate; }; const isEventUpcoming = (start: string) => { const now = new Date(); const startDate = new Date(start); const hourFromNow = new Date(now.getTime() + 60 * 60 * 1000); return startDate > now && startDate <= hourFromNow; }; const getAttendeeDisplay = (attendee: any) => { // Use name if available, otherwise use email const displayName = attendee.name || attendee.email || "Unknown"; // Extract just the name part if it's in "Name " format const cleanName = displayName.replace(/<.*>/, "").trim(); return cleanName; }; const getAttendeeEmail = (attendee: any) => { return attendee.email || ""; }; const renderAttendees = (attendees: any[]) => { if (!attendees || attendees.length === 0) return null; return ( Attendees: {attendees.map((attendee, index) => { const email = getAttendeeEmail(attendee); const display = getAttendeeDisplay(attendee); if (email && email !== display) { return ( {email} } > {display} ); } else { return ( {display} ); } })} ); }; const sortedEvents = [...events].sort( (a, b) => new Date(a.start_time).getTime() - new Date(b.start_time).getTime(), ); // Separate events by status const now = new Date(); const activeEvents = sortedEvents.filter((e) => isEventActive(e.start_time, e.end_time), ); const upcomingEvents = sortedEvents.filter( (e) => new Date(e.start_time) > now, ); const pastEvents = sortedEvents .filter((e) => new Date(e.end_time) < now) .reverse(); return ( router.push("/rooms")} > Calendar for {roomName} {error && ( {error} )} {loading ? ( ) : events.length === 0 ? ( No calendar events found. Make sure your calendar is configured and synced. ) : ( {/* Active Events */} {activeEvents.length > 0 && ( Active Now {activeEvents.map((event) => ( {event.title || "Untitled Event"} Active {formatEventTime( event.start_time, event.end_time, )} {event.description && ( {event.description} )} {renderAttendees(event.attendees)} ))} )} {/* Upcoming Events */} {upcomingEvents.length > 0 && ( Upcoming Events {upcomingEvents.map((event) => ( {event.title || "Untitled Event"} {isEventUpcoming(event.start_time) && ( Starting Soon )} {formatEventTime( event.start_time, event.end_time, )} {event.description && ( {event.description} )} {renderAttendees(event.attendees)} ))} )} {/* Past Events */} {pastEvents.length > 0 && ( Past Events {pastEvents.slice(0, 5).map((event) => ( {event.title || "Untitled Event"} {formatEventTime( event.start_time, event.end_time, )} {renderAttendees(event.attendees)} ))} {pastEvents.length > 5 && ( And {pastEvents.length - 5} more past events... )} )} )} ); }