diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index ecc11de..f2538d6 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,10 +4,8 @@
-
-
-
-
+
+
@@ -129,7 +127,7 @@
1774643312599
-
+
@@ -299,7 +297,15 @@
1774717104130
-
+
+
+ 1774717642991
+
+
+
+ 1774717642991
+
+
@@ -329,6 +335,7 @@
-
+
+
\ No newline at end of file
diff --git a/apps/api/src/reservations/reservations.service.ts b/apps/api/src/reservations/reservations.service.ts
index c3f0309..2aef008 100644
--- a/apps/api/src/reservations/reservations.service.ts
+++ b/apps/api/src/reservations/reservations.service.ts
@@ -137,6 +137,13 @@ export class ReservationsService {
reservation.space.floorId,
reservation.spaceId,
false,
+ {
+ reservation: {
+ id: reservation.id,
+ startTime: reservation.startTime,
+ endTime: reservation.endTime,
+ }
+ }
);
console.log('Emitted space_status_changed for cancelled reservation', reservation.space.floorId, reservation.spaceId);
diff --git a/apps/web/src/lib/components/FloorplanViewer.svelte b/apps/web/src/lib/components/FloorplanViewer.svelte
index 1ec49bf..c8c8f6b 100644
--- a/apps/web/src/lib/components/FloorplanViewer.svelte
+++ b/apps/web/src/lib/components/FloorplanViewer.svelte
@@ -21,23 +21,35 @@
// Track if we have received any real-time updates to avoid overwriting them with stale initial status
let realtimeUpdates: Record = {};
+ let lastSelectedDateString = selectedDate.toDateString();
+
+ $: isToday = new Date(selectedDate.getTime()).setHours(0,0,0,0) === new Date().setHours(0,0,0,0);
$: {
- // Initialize space status from the current state (e.g. from API)
+ // Detect when the actual day changes to clear real-time updates
+ const currentDateString = selectedDate.toDateString();
+ if (currentDateString !== lastSelectedDateString) {
+ realtimeUpdates = {};
+ lastSelectedDateString = currentDateString;
+ }
+
+ // Reset spaceStatus and ensure we re-calculate from new spaces prop
+ let newStatus: Record = {};
+
spaces.forEach(s => {
- // Don't overwrite if we already have a real-time update for today
- if (isToday && realtimeUpdates[s.id]) {
- spaceStatus[s.id] = realtimeUpdates[s.id];
+ // Don't overwrite if we already have a real-time update for this view
+ if (realtimeUpdates[s.id]) {
+ newStatus[s.id] = realtimeUpdates[s.id];
return;
}
const activeReservation = s.reservations && s.reservations.length > 0 ? s.reservations[0] : null;
- spaceStatus[s.id] = {
+ newStatus[s.id] = {
isOccupied: !!activeReservation,
reservation: activeReservation
};
});
- spaceStatus = { ...spaceStatus };
+ spaceStatus = newStatus;
updateContainerSizeToFitAll();
}
@@ -58,15 +70,6 @@
if (b > maxB) maxB = b;
});
- // To be consistent with editor, we should probably use the same base.
- // However, in the viewer, we just want to show everything.
- // If spaces were saved with percentages relative to a larger container,
- // we need to know that container's aspect ratio.
-
- // Actually, the percentages ARE the aspect ratio.
- // If a space is at x=110%, it means it's outside the "original" 800px.
- // So we should just find the max percentage and scale the container.
-
let maxXP = 100;
let maxYP = 100;
spaces.forEach(s => {
@@ -84,8 +87,6 @@
containerHeight += 40;
}
- $: isToday = new Date(selectedDate.getTime()).setHours(0,0,0,0) === new Date().setHours(0,0,0,0);
-
onMount(() => {
const socketUrl = import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:3000';
socket = io(socketUrl, {
@@ -99,10 +100,30 @@
socket.on('space_status_changed', (data: { spaceId: string, isOccupied: boolean, reservation?: any }) => {
console.log('Space status changed received:', data);
- if (!isToday) {
- console.log('Ignoring real-time update: not today', {
- selectedDate: selectedDate.toDateString(),
- now: new Date().toDateString()
+
+ let isRelevant = false;
+ if (data.reservation) {
+ const start = new Date(data.reservation.startTime);
+ const end = new Date(data.reservation.endTime);
+ const viewStart = new Date(selectedDate.getTime());
+ viewStart.setHours(0, 0, 0, 0);
+ const viewEnd = new Date(selectedDate.getTime());
+ viewEnd.setHours(23, 59, 59, 999);
+
+ isRelevant = (start <= viewEnd && end >= viewStart);
+ } else {
+ // If we don't have reservation data (should not happen with updated API),
+ // fallback to isToday check.
+ isRelevant = isToday;
+ }
+
+ if (!isRelevant) {
+ console.log('Ignoring real-time update: not relevant to current view', {
+ selectedDate: selectedDate.toDateString(),
+ reservation: data.reservation ? {
+ start: new Date(data.reservation.startTime).toDateString(),
+ end: new Date(data.reservation.endTime).toDateString()
+ } : 'none'
});
return;
}
diff --git a/apps/web/src/lib/components/SpaceCard.svelte b/apps/web/src/lib/components/SpaceCard.svelte
index a8d2044..5d67a6d 100644
--- a/apps/web/src/lib/components/SpaceCard.svelte
+++ b/apps/web/src/lib/components/SpaceCard.svelte
@@ -14,11 +14,19 @@
// Track if we have received any real-time updates for this space
let realtimeOccupied: boolean | null = null;
+ let lastSelectedDateString = selectedDate.toDateString();
$: isToday = new Date(selectedDate.getTime()).setHours(0,0,0,0) === new Date().setHours(0,0,0,0);
$: if (initialStatus !== undefined) {
- if (isToday && realtimeOccupied !== null) {
+ // Detect when the actual day changes to clear real-time updates
+ const currentDateString = selectedDate.toDateString();
+ if (currentDateString !== lastSelectedDateString) {
+ realtimeOccupied = null;
+ lastSelectedDateString = currentDateString;
+ }
+
+ if (realtimeOccupied !== null) {
isOccupied = realtimeOccupied;
} else {
isOccupied = initialStatus;
@@ -37,8 +45,24 @@
socket.emit('join_floor', floorId);
});
- socket.on('space_status_changed', (data: { spaceId: string, isOccupied: boolean }) => {
- if (data.spaceId === spaceId && isToday) {
+ socket.on('space_status_changed', (data: { spaceId: string, isOccupied: boolean, reservation?: any }) => {
+ if (data.spaceId !== spaceId) return;
+
+ let isRelevant = false;
+ if (data.reservation) {
+ const start = new Date(data.reservation.startTime);
+ const end = new Date(data.reservation.endTime);
+ const viewStart = new Date(selectedDate.getTime());
+ viewStart.setHours(0, 0, 0, 0);
+ const viewEnd = new Date(selectedDate.getTime());
+ viewEnd.setHours(23, 59, 59, 999);
+
+ isRelevant = (start <= viewEnd && end >= viewStart);
+ } else {
+ isRelevant = isToday;
+ }
+
+ if (isRelevant) {
console.log('Space status updated for:', spaceId, data.isOccupied);
realtimeOccupied = data.isOccupied;
isOccupied = data.isOccupied;