Fix WS offline: nginx WebSocket headers + keepalive ping + drag-to-move fix

nginx: add /ws location with Upgrade/Connection headers and 1h timeout
useHotelSocket: ping every 30s to prevent idle timeout, read fresh token
  from localStorage on reconnect (handles 1h JWT expiry gracefully)
BookingCalendar: use elementFromPoint for reliable drag-to-move target

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-19 13:24:37 +03:00
parent 3602ea7318
commit 26412a04dd
2 changed files with 55 additions and 9 deletions

View File

@@ -152,12 +152,23 @@ export function BookingCalendar({ rooms, bookings, onBookingCreate, onBookingUpd
}, [dragStart])
const handleMouseMove = useCallback((e: React.MouseEvent) => {
if (!pendingMoveBooking.current || movingBookingRef.current) return
const dx = Math.abs(e.clientX - (moveStartPos.current?.x ?? 0))
const dy = Math.abs(e.clientY - (moveStartPos.current?.y ?? 0))
if (dx > 5 || dy > 5) {
setMovingBooking(pendingMoveBooking.current)
setMoveTargetRoomId(pendingMoveBooking.current.roomId)
// Phase 1: detect drag start
if (pendingMoveBooking.current && !movingBookingRef.current) {
const dx = Math.abs(e.clientX - (moveStartPos.current?.x ?? 0))
const dy = Math.abs(e.clientY - (moveStartPos.current?.y ?? 0))
if (dx > 5 || dy > 5) {
setMovingBooking(pendingMoveBooking.current)
setMoveTargetRoomId(pendingMoveBooking.current.roomId)
}
return
}
// Phase 2: track which room row the cursor is over
if (movingBookingRef.current) {
const el = document.elementFromPoint(e.clientX, e.clientY)
const rowEl = el?.closest('[data-room-id]') as HTMLElement | null
if (rowEl?.dataset.roomId) {
setMoveTargetRoomId(rowEl.dataset.roomId)
}
}
}, [])
@@ -429,12 +440,12 @@ export function BookingCalendar({ rooms, bookings, onBookingCreate, onBookingUpd
rows.push(
<div
key={room.id}
data-room-id={room.id}
className={cn(
'flex border-b border-slate-200 dark:border-slate-700 group hover:bg-slate-50/50 dark:hover:bg-slate-800/30',
movingBooking && moveTargetRoomId === room.id && 'bg-brand-50/60 dark:bg-brand-900/20',
)}
style={{ height: rowHeight }}
onMouseEnter={() => { if (movingBookingRef.current) setMoveTargetRoomId(room.id) }}
>
{/* Room label */}
<div