mirror of
https://github.com/xlorepdarkhelm/numinar-coding-project.git
synced 2026-09-08 18:53:11 -04:00
Organizing imports in the frontend.
Signed-off-by: Cliff Hill <xlorep@darkhelm.org>
This commit is contained in:
@@ -6,9 +6,9 @@
|
||||
* Author: Cliff Hill
|
||||
* Last updated: 2025-09-05
|
||||
*/
|
||||
import { logger } from "./utils/logger";
|
||||
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
|
||||
|
||||
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
|
||||
import { logger } from "./utils/logger";
|
||||
import LandingPage from "./pages/LandingPage";
|
||||
import BookingPage from "./pages/BookingPage";
|
||||
import ConfirmationPage from "./pages/ConfirmationPage";
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
* @param {BookingConfirmationProps} props - Component props
|
||||
* @returns {JSX.Element} Confirmation UI
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { Box, Button } from "@mui/material";
|
||||
|
||||
import type { BookingConfirmationProps } from "../schemas";
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,13 +6,15 @@
|
||||
* Author: Cliff Hill
|
||||
* Last updated: 2025-09-05
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import {
|
||||
formatLocalDateTimeInput,
|
||||
roundToStrictlyFutureQuarter,
|
||||
} from "../utils/date";
|
||||
getRoomBookings,
|
||||
createBooking,
|
||||
updateBooking,
|
||||
deleteBooking,
|
||||
} from "../apis/bookings";
|
||||
import { getEditBookingRoomId, formatBookingError } from "../helpers/booking";
|
||||
import {
|
||||
validateRoomId,
|
||||
@@ -23,11 +25,9 @@ import {
|
||||
validateRoomAvailability,
|
||||
} from "../helpers/validation";
|
||||
import {
|
||||
getRoomBookings,
|
||||
createBooking,
|
||||
updateBooking,
|
||||
deleteBooking,
|
||||
} from "../apis/bookings";
|
||||
formatLocalDateTimeInput,
|
||||
roundToStrictlyFutureQuarter,
|
||||
} from "../utils/date";
|
||||
import { connectRoomsAvailabilityStream } from "../apis/sse";
|
||||
import { getInvitees, addInvitee, removeInvitee } from "../apis/invitees";
|
||||
import { getAvailableUsers } from "../apis/users";
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
import React from "react";
|
||||
import { List, Typography, ListItemButton } from "@mui/material";
|
||||
// ...existing code...
|
||||
import {
|
||||
sortBookingsByStartTime,
|
||||
formatBookingTime,
|
||||
|
||||
@@ -10,16 +10,17 @@
|
||||
* CalendarView component.
|
||||
* Renders calendar with events, tooltips, and slot selection.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import FullCalendar from "@fullcalendar/react";
|
||||
import dayGridPlugin from "@fullcalendar/daygrid";
|
||||
import timeGridPlugin from "@fullcalendar/timegrid";
|
||||
import interactionPlugin from "@fullcalendar/interaction";
|
||||
import { EventInput } from "@fullcalendar/core";
|
||||
import timeGridPlugin from "@fullcalendar/timegrid";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import "../styles/CalendarView.css";
|
||||
import { EventInput } from "@fullcalendar/core";
|
||||
import { getEventDisplayText, getRoomClass } from "../helpers/calendar";
|
||||
import "../styles/CalendarView.css";
|
||||
|
||||
/**
|
||||
* Props for CalendarView.
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* Author: Cliff Hill
|
||||
* Last updated: 2025-09-05
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import {
|
||||
Dialog,
|
||||
@@ -16,7 +17,6 @@ import {
|
||||
Typography,
|
||||
Box,
|
||||
} from "@mui/material";
|
||||
|
||||
import type { RoomDetailsModalProps } from "../schemas";
|
||||
|
||||
const RoomDetailsModal: React.FC<RoomDetailsModalProps> = ({
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { FC } from "react";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
@@ -22,9 +23,8 @@ import {
|
||||
ListItemButton,
|
||||
} from "@mui/material";
|
||||
import MeetingRoomIcon from "@mui/icons-material/MeetingRoom";
|
||||
import { FC } from "react";
|
||||
import type { RoomListProps } from "../schemas";
|
||||
import { getRoomListItemStyles, getRoomSecondaryText } from "../helpers/room";
|
||||
import type { RoomListProps } from "../schemas";
|
||||
|
||||
/**
|
||||
* Renders a list of conference rooms with their details.
|
||||
|
||||
@@ -5,16 +5,17 @@
|
||||
* Author: Cliff Hill
|
||||
* Last updated: 2025-09-05
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import "./index.css";
|
||||
import App from "./App";
|
||||
import axios from "axios";
|
||||
import { ThemeProvider } from "@mui/material/styles";
|
||||
import CssBaseline from "@mui/material/CssBaseline";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import App from "./App";
|
||||
import theme from "./theme";
|
||||
import reportWebVitals from "./reportWebVitals";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import axios from "axios";
|
||||
import "./index.css";
|
||||
|
||||
// Global error handler to catch unhandled errors and prevent reloads
|
||||
window.onerror = function (message, source, lineno, colno, error) {
|
||||
|
||||
@@ -6,12 +6,9 @@
|
||||
* Author: Cliff Hill
|
||||
* Last updated: 2025-09-05
|
||||
*/
|
||||
|
||||
import React, { useMemo, useState, useEffect, useRef } from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getRooms } from "../apis/rooms";
|
||||
import { getUsers } from "../apis/users";
|
||||
import { getRoomBookings } from "../apis/bookings";
|
||||
import { connectRoomsAvailabilityStream } from "../apis/sse";
|
||||
import {
|
||||
Button,
|
||||
MenuItem,
|
||||
@@ -20,8 +17,12 @@ import {
|
||||
FormControl,
|
||||
Box,
|
||||
} from "@mui/material";
|
||||
import CalendarView from "../components/CalendarView";
|
||||
import { EventInput } from "@fullcalendar/core";
|
||||
import { getRooms } from "../apis/rooms";
|
||||
import { getUsers } from "../apis/users";
|
||||
import { getRoomBookings } from "../apis/bookings";
|
||||
import { connectRoomsAvailabilityStream } from "../apis/sse";
|
||||
import CalendarView from "../components/CalendarView";
|
||||
import BookingForm from "../components/BookingForm";
|
||||
import RoomDetailsModal from "../components/RoomDetailsModal";
|
||||
import { logger } from "../utils/logger";
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
* Author: Cliff Hill
|
||||
* Last updated: 2025-09-05
|
||||
*/
|
||||
|
||||
import React, { useState } from "react";
|
||||
import { Box } from "@mui/material";
|
||||
import BookingConfirmation from "../components/BookingConfirmation";
|
||||
import BookingForm from "../components/BookingForm";
|
||||
import { useNavigate, useLocation } from "react-router-dom";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getRooms } from "../apis/rooms";
|
||||
import { connectRoomsAvailabilityStream } from "../apis/sse";
|
||||
import BookingConfirmation from "../components/BookingConfirmation";
|
||||
import BookingForm from "../components/BookingForm";
|
||||
|
||||
// This page expects booking data to be passed via location.state
|
||||
const ConfirmationPage: React.FC = () => {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* Author: Cliff Hill
|
||||
* Last updated: 2025-09-05
|
||||
*/
|
||||
|
||||
import React, { FC, useEffect, useState } from "react";
|
||||
import {
|
||||
Typography,
|
||||
@@ -16,6 +17,7 @@ import {
|
||||
Card,
|
||||
CardContent,
|
||||
} from "@mui/material";
|
||||
import EventNoteIcon from "@mui/icons-material/EventNote";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getRooms } from "../apis/rooms";
|
||||
@@ -24,9 +26,8 @@ import RoomList from "../components/RoomList";
|
||||
import BookingList from "../components/BookingList";
|
||||
import type { ConferenceRoom } from "../schemas";
|
||||
import type { Booking } from "../schemas";
|
||||
import EventNoteIcon from "@mui/icons-material/EventNote";
|
||||
// import "./LandingPage.css";
|
||||
import { logger } from "../utils/logger";
|
||||
// import "./LandingPage.css";
|
||||
|
||||
/**
|
||||
* LandingPage component
|
||||
|
||||
226
frontend/src/styles/CalendarView.css
Normal file
226
frontend/src/styles/CalendarView.css
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* CalendarView.css
|
||||
* Styles for the calendar view component, including event colors and non-business hours.
|
||||
*
|
||||
* Author: Cliff Hill
|
||||
* Last updated: 2025-09-05
|
||||
*/
|
||||
/* Non-business hours styling for FullCalendar */
|
||||
.fc-timegrid-col-bg .fc-non-business,
|
||||
.fc-non-business {
|
||||
background: #888 !important;
|
||||
opacity: 0.5 !important;
|
||||
}
|
||||
|
||||
/* Room color classes for calendar events */
|
||||
.room-color-0 {
|
||||
background: #1976d2 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.room-color-1 {
|
||||
background: #388e3c !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.room-color-2 {
|
||||
background: #fbc02d !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.room-color-3 {
|
||||
background: #d32f2f !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.room-color-4 {
|
||||
background: #7b1fa2 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.room-color-5 {
|
||||
background: #0288d1 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.room-color-6 {
|
||||
background: #c2185b !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.room-color-7 {
|
||||
background: #ffa000 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
/* Truncate and ellipsis for event content and titles */
|
||||
.fc-event-title-ellipsis,
|
||||
.fc-event .fc-event-main > div,
|
||||
.fc-event-title,
|
||||
.fc-event-main,
|
||||
.fc-event .fc-event-main-frame,
|
||||
.fc-event .fc-event-title,
|
||||
.fc-event .fc-event-title-container,
|
||||
.fc-event .fc-event-time,
|
||||
.fc-event .fc-event-title,
|
||||
.fc-event .fc-event-title-container,
|
||||
.fc-event .fc-event-main {
|
||||
white-space: nowrap !important;
|
||||
overflow: hidden !important;
|
||||
text-overflow: ellipsis !important;
|
||||
max-width: 100% !important;
|
||||
display: block !important;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* Weekend all-day and time slots: unified non-business color, lighter border */
|
||||
.fc .fc-daygrid-day.fc-day-sat .fc-daygrid-day-frame,
|
||||
.fc .fc-daygrid-day.fc-day-sun .fc-daygrid-day-frame,
|
||||
.fc .fc-timegrid-col.fc-day-sat,
|
||||
.fc .fc-timegrid-col.fc-day-sun {
|
||||
background: #888 !important; /* unified non-business color */
|
||||
border-color: #bbb !important;
|
||||
}
|
||||
|
||||
.fc .fc-daygrid-day.fc-day-sat .fc-daygrid-day-number,
|
||||
.fc .fc-daygrid-day.fc-day-sun .fc-daygrid-day-number {
|
||||
color: #e0e0e0 !important;
|
||||
font-weight: 500 !important;
|
||||
opacity: 0.7 !important;
|
||||
}
|
||||
|
||||
/* Weekday non-business hours: same as weekend background */
|
||||
.fc .fc-non-business {
|
||||
background: #888 !important;
|
||||
opacity: 0.5 !important;
|
||||
}
|
||||
|
||||
/* Workday all-day and time slots: match all-day workday background */
|
||||
.fc .fc-daygrid-day .fc-daygrid-day-frame,
|
||||
.fc .fc-timegrid-col {
|
||||
background: #c0c0c0 !important;
|
||||
}
|
||||
|
||||
/* Lighter border for all-day row on weekends */
|
||||
.fc .fc-daygrid-day.fc-day-sat,
|
||||
.fc .fc-daygrid-day.fc-day-sun {
|
||||
border-color: #bbb !important;
|
||||
}
|
||||
|
||||
/* Out-of-month days: distinct but not too dark */
|
||||
.fc .fc-daygrid-day.fc-day-other .fc-daygrid-day-frame {
|
||||
background: #aaa !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
/* Calendar cell backgrounds use CSS variables */
|
||||
:root {
|
||||
--fc-page-bg-color: #a0a0a0;
|
||||
--fc-neutral-bg-color: #e3f2fd;
|
||||
--fc-today-bg-color: #e3f2fd;
|
||||
--fc-event-bg-color: #1976d2;
|
||||
--fc-border-color: #707070;
|
||||
}
|
||||
|
||||
.calendarContainer {
|
||||
padding: 2rem;
|
||||
background: #f8fafc !important;
|
||||
border-radius: 16px !important;
|
||||
box-shadow: 0 4px 24px rgba(30, 64, 175, 0.08) !important;
|
||||
/* Responsive container, no fixed height */
|
||||
}
|
||||
|
||||
.calendar-scroll-area {
|
||||
flex: 1 1 auto;
|
||||
overflow-y: auto;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.fc {
|
||||
font-family: "Inter", "Roboto", Arial, sans-serif !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.fc .fc-toolbar {
|
||||
background: #1976d2 !important;
|
||||
color: #fff !important;
|
||||
border-radius: 12px 12px 0 0 !important;
|
||||
padding: 0.5rem 1rem !important;
|
||||
}
|
||||
|
||||
.fc .fc-toolbar-title {
|
||||
font-size: 1.5rem !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
.fc .fc-button {
|
||||
background: #1976d2 !important;
|
||||
color: #fff !important;
|
||||
border: none !important;
|
||||
border-radius: 6px !important;
|
||||
padding: 0.3rem 0.8rem !important;
|
||||
margin: 0 0.2rem !important;
|
||||
font-weight: 500 !important;
|
||||
transition: background 0.2s !important;
|
||||
}
|
||||
|
||||
.fc .fc-button:hover,
|
||||
.fc .fc-button:focus {
|
||||
background: #1565c0 !important;
|
||||
}
|
||||
|
||||
.fc .fc-daygrid-day {
|
||||
box-shadow: 0 1px 4px rgba(30, 64, 175, 0.08) !important;
|
||||
transition: box-shadow 0.2s !important;
|
||||
}
|
||||
|
||||
.fc .fc-daygrid-day:hover {
|
||||
box-shadow: 0 4px 12px rgba(30, 64, 175, 0.16) !important;
|
||||
background: #e3f2fd !important;
|
||||
}
|
||||
|
||||
.fc .fc-daygrid-day-number {
|
||||
font-weight: 600 !important;
|
||||
color: #1976d2 !important;
|
||||
}
|
||||
|
||||
.fc .fc-event {
|
||||
background: #1976d2 !important;
|
||||
color: #fff !important;
|
||||
padding: 2px 6px !important;
|
||||
font-size: 0.95rem !important;
|
||||
box-shadow: 0 2px 8px rgba(30, 64, 175, 0.12) !important;
|
||||
}
|
||||
|
||||
.fc .fc-event:hover {
|
||||
background: #1565c0 !important;
|
||||
}
|
||||
|
||||
.fc .fc-day-today {
|
||||
background: #e3f2fd !important;
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
|
||||
.fc .fc-daygrid-day .fc-daygrid-day-frame {
|
||||
background: #c0c0c0 !important;
|
||||
box-shadow: 0 1px 4px rgba(30, 64, 175, 0.08) !important;
|
||||
transition: box-shadow 0.2s !important;
|
||||
}
|
||||
|
||||
.fc .fc-daygrid-day.fc-day-today .fc-daygrid-day-frame {
|
||||
background: #d0d0d0 !important;
|
||||
box-shadow: 0 4px 12px rgba(30, 64, 175, 0.16) !important;
|
||||
}
|
||||
|
||||
.fc .fc-daygrid-day.fc-day-other .fc-daygrid-day-frame {
|
||||
background: #aaa !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.fc .fc-daygrid-day.fc-day-other .fc-daygrid-day-number {
|
||||
color: #fff !important;
|
||||
opacity: 1 !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
.fc .fc-daygrid-day:hover .fc-daygrid-day-frame {
|
||||
background: #e3f2fd !important;
|
||||
box-shadow: 0 4px 12px rgba(30, 64, 175, 0.16) !important;
|
||||
}
|
||||
|
||||
.fc,
|
||||
.fc-toolbar.fc-header-toolbar {
|
||||
margin-bottom: 0px !important;
|
||||
}
|
||||
Reference in New Issue
Block a user