Files
conference-room-booking-system/frontend/src/components/BookingList.tsx
2025-10-08 20:13:21 -04:00

106 lines
3.1 KiB
TypeScript

// Utility/helper imports
import { logger } from "../utils/logger";
// External imports
import React from "react";
// MUI imports
import { List, ListItemButton, Typography } from "@mui/material";
import "../styles/BookingList.css";
// Internal helper imports
import {
formatBookingTime,
sortBookingsByStartTime,
} from "../helpers/bookingList";
// Type-only imports
import type { BookingListProps } from "../interfaces";
// Context hook imports
import { useUsers } from "../context/UserContext";
/**
* BookingList component
* Displays a list of bookings for a room or user, including times and invitees.
* Handles empty state and sorts bookings chronologically.
* @component
* @param {BookingListProps} props - Component props
* @returns {JSX.Element} Booking list UI
*/
const BookingList: React.FC<BookingListProps> = ({ bookings, onSelect }) => {
// Context hook for users (must be called at top level)
const { users } = useUsers();
React.useEffect(() => {
// [BookingList] Mounted log removed
return () => {
// [BookingList] Unmounted log removed
};
}, []);
React.useEffect(() => {
logger.debug("[BookingList] bookings updated", bookings);
}, [bookings]);
if (!bookings || bookings.length === 0) {
return (
<List className="booking-list">
<ListItemButton className="bookinglist-empty" disabled>
<Typography className="bookinglist-item-title">
No bookings found.
</Typography>
</ListItemButton>
</List>
);
}
const sortedBookings = sortBookingsByStartTime(bookings);
/**
* Maps invitee email to user name for display.
* Only shows invitee names (not emails).
* @param {string} email - Invitee email
* @returns {string} Display name
*/
const getInviteeDisplay = (email: string) => {
const user = users.find(
(u: import("../interfaces").User) => u.email === email
);
return user ? user.name : email;
};
return (
<List className="booking-list">
{sortedBookings.map((booking) => {
let inviteeNames: string[] = [];
if (Array.isArray(booking.invitees)) {
inviteeNames = booking.invitees.map(getInviteeDisplay);
}
const roomId = booking.room_id ? Number(booking.room_id) : 0;
const roomColorIdx = ((roomId - 1) % 20) + 1;
const roomColorClass = `room-color-${roomColorIdx}`;
return (
<ListItemButton
key={booking.id}
onClick={() => onSelect && onSelect(booking)}
className={`booking-list-item ${roomColorClass}`}
>
<span className="booking-list-time">
{booking.start_time && booking.end_time
? `${formatBookingTime(
booking.start_time
)} - ${formatBookingTime(booking.end_time)}`
: "Time not set"}
</span>
<span className="booking-list-invitees">
{inviteeNames.length > 0
? `Invitees: ${inviteeNames.join(", ")}`
: "No invitees"}
</span>
</ListItemButton>
);
})}
</List>
);
};
export default BookingList;