Fix: drag ghost visual, check-in date auto-fill, backend room_id patch
- BookingCalendar: replace tiny ghost badge with full-size booking block (same color, correct width based on nights × cell width, centered on cursor) - BookingModal: auto-set check-out to check-in+1 day when check-in changes - Backend PATCH /bookings/🆔 add room_id to allowed fields so drag-to-move saves correctly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useState } from 'react'
|
||||
import { format } from 'date-fns'
|
||||
import { format, addDays } from 'date-fns'
|
||||
import { Star, Banknote, CreditCard, AlertCircle, Map, Plus, Trash2, Tag, Minus, BedDouble, Tv2, Send, Loader2, CheckCircle2 } from 'lucide-react'
|
||||
import { MOCK_DISCOUNTS } from '../../pages/DiscountsPage'
|
||||
import type { Discount } from '../../pages/DiscountsPage'
|
||||
@@ -298,7 +298,13 @@ export function BookingModal({ open, draft, rooms, bookings = [], onClose, onSav
|
||||
<input
|
||||
type="date" className="input"
|
||||
value={form.checkIn}
|
||||
onChange={e => set('checkIn', e.target.value)}
|
||||
onChange={e => {
|
||||
const newCheckIn = e.target.value
|
||||
set('checkIn', newCheckIn)
|
||||
if (newCheckIn && (!form.checkOut || form.checkOut <= newCheckIn)) {
|
||||
set('checkOut', format(addDays(new Date(newCheckIn), 1), 'yyyy-MM-dd'))
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@@ -753,17 +753,26 @@ export function BookingCalendar({ rooms, bookings, slug, onBookingCreate, onBook
|
||||
)}
|
||||
|
||||
{/* Drag ghost element */}
|
||||
{movingBooking && ghostPos && (
|
||||
<div
|
||||
className={cn(
|
||||
'fixed z-[9999] pointer-events-none px-3 py-1.5 rounded-lg text-white text-xs font-semibold shadow-xl border-2 border-white/40',
|
||||
BOOKING_STATUS_COLORS[movingBooking.status],
|
||||
)}
|
||||
style={{ left: ghostPos.x + 14, top: ghostPos.y - 16 }}
|
||||
>
|
||||
{movingBooking.guestName}
|
||||
</div>
|
||||
)}
|
||||
{movingBooking && ghostPos && (() => {
|
||||
const nights = differenceInDays(parseISO(movingBooking.checkOut), parseISO(movingBooking.checkIn))
|
||||
const ghostWidth = Math.max(80, Math.min(nights * CELL_WIDTH - 4, 320))
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'fixed z-[9999] pointer-events-none flex items-center px-2 rounded-md text-white text-xs font-semibold shadow-2xl border-l-4 opacity-90',
|
||||
BOOKING_STATUS_COLORS[movingBooking.status],
|
||||
)}
|
||||
style={{
|
||||
left: ghostPos.x - ghostWidth / 2,
|
||||
top: ghostPos.y - ROW_HEIGHT / 2 + 4,
|
||||
width: ghostWidth,
|
||||
height: ROW_HEIGHT - 8,
|
||||
}}
|
||||
>
|
||||
<span className="truncate drop-shadow-sm">{movingBooking.guestName}</span>
|
||||
</div>
|
||||
)
|
||||
})()}
|
||||
|
||||
{/* Rental booking modal */}
|
||||
{rentalModal && (
|
||||
|
||||
Reference in New Issue
Block a user