mirror of
https://github.com/xlorepdarkhelm/numinar-coding-project.git
synced 2026-09-06 20:38:26 -04:00
Getting the stream right for the frontend.
Signed-off-by: Cliff Hill <xlorep@darkhelm.org>
This commit is contained in:
@@ -78,14 +78,20 @@ const BookingList: FC<BookingListProps> = ({
|
||||
eventSourceRef.current.close();
|
||||
}
|
||||
// Subscribe to SSE for room availability/booking changes
|
||||
const url = `/rooms/${roomId}/bookings/stream?date=${date}`;
|
||||
const url = `http://localhost:8000/rooms/availability/stream`;
|
||||
const es = new window.EventSource(url);
|
||||
eventSourceRef.current = es;
|
||||
es.onmessage = (event) => {
|
||||
try {
|
||||
const data = JSON.parse(event.data);
|
||||
// Expecting the backend to send the full list of bookings for the room/date
|
||||
setLiveBookings(data.bookings || []);
|
||||
// Filter bookings for the current room and date
|
||||
let filtered = [];
|
||||
if (Array.isArray(data.bookings)) {
|
||||
filtered = data.bookings.filter(
|
||||
(b: any) => b.roomId === roomId && b.startTime.startsWith(date)
|
||||
);
|
||||
}
|
||||
setLiveBookings(filtered);
|
||||
} catch (e) {
|
||||
// Ignore parse errors
|
||||
}
|
||||
|
||||
@@ -118,7 +118,15 @@ const RoomList: FC<RoomListProps> = ({
|
||||
<ListItemButton
|
||||
key={room.id}
|
||||
selected={room.id === selectedRoomId}
|
||||
onClick={() => onSelectRoom(room.id)}
|
||||
onClick={(e) => {
|
||||
console.log("RoomList: ListItemButton click", room.id);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
onSelectRoom(room.id);
|
||||
setTimeout(() => {
|
||||
console.log("RoomList: after onSelectRoom", room.id);
|
||||
}, 0);
|
||||
}}
|
||||
aria-label={`Select room ${room.name}`}
|
||||
data-testid={`room-item-${room.id}`}
|
||||
sx={
|
||||
|
||||
@@ -9,6 +9,25 @@ import reportWebVitals from "./reportWebVitals";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import axios from "axios";
|
||||
|
||||
// Global error handler to catch unhandled errors and prevent reloads
|
||||
window.onerror = function (message, source, lineno, colno, error) {
|
||||
console.error("Global error handler:", {
|
||||
message,
|
||||
source,
|
||||
lineno,
|
||||
colno,
|
||||
error,
|
||||
});
|
||||
// Prevent default browser reload on error
|
||||
return true;
|
||||
};
|
||||
|
||||
window.onunhandledrejection = function (event) {
|
||||
console.error("Global unhandledrejection:", event.reason);
|
||||
// Prevent default browser reload on unhandled promise rejection
|
||||
return true;
|
||||
};
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
axios.defaults.baseURL =
|
||||
process.env.REACT_APP_API_URL || "http://localhost:8000";
|
||||
|
||||
@@ -27,6 +27,22 @@ import BookingList, { Booking } from "../components/BookingList";
|
||||
* @returns {JSX.Element} The landing page UI.
|
||||
*/
|
||||
const LandingPage: FC = () => {
|
||||
// Debug: log when LandingPage mounts
|
||||
useEffect(() => {
|
||||
console.log("LandingPage: mounted");
|
||||
return () => {
|
||||
console.log("LandingPage: unmounted");
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Debug: log before page unload
|
||||
useEffect(() => {
|
||||
const handler = (e: BeforeUnloadEvent) => {
|
||||
console.log("window.onbeforeunload: page is unloading");
|
||||
};
|
||||
window.addEventListener("beforeunload", handler);
|
||||
return () => window.removeEventListener("beforeunload", handler);
|
||||
}, []);
|
||||
const navigate = useNavigate();
|
||||
const today = new Date().toISOString().split("T")[0];
|
||||
|
||||
@@ -63,10 +79,19 @@ const LandingPage: FC = () => {
|
||||
} = useQuery({
|
||||
queryKey: ["bookings", today, selectedRoomId],
|
||||
enabled: !!selectedRoomId,
|
||||
queryFn: () =>
|
||||
axios
|
||||
queryFn: () => {
|
||||
console.log("LandingPage: fetching bookings for", selectedRoomId, today);
|
||||
return axios
|
||||
.get(`/bookings/room/${selectedRoomId}?date=${today}`)
|
||||
.then((res) => res.data as Booking[]),
|
||||
.then((res) => {
|
||||
console.log("LandingPage: bookings fetch result", res.data);
|
||||
return res.data as Booking[];
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("LandingPage: bookings fetch error", err);
|
||||
throw err;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// Display skeleton loaders during data fetching
|
||||
@@ -115,6 +140,7 @@ const LandingPage: FC = () => {
|
||||
|
||||
// Display error message with retry option
|
||||
if (roomsError || bookingsError) {
|
||||
console.error("LandingPage: error state", { roomsError, bookingsError });
|
||||
return (
|
||||
<div
|
||||
className="landing-root"
|
||||
|
||||
Reference in New Issue
Block a user