Add date editing with conflict detection and rental booking editing
- BookingDetailPanel: edit dates/room with inline conflict detection; options to force-save or swap conflicting booking's room - BookingsPage + CalendarPage: pass rooms/allBookings/onBulkUpdate to panel - RentalBookingModal: accept editBooking prop to pre-populate fields for editing - RentalPage: add edit (pencil) button per booking row, unify create/update handler Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ interface RentalBookingModalProps {
|
||||
obj: RentalObject
|
||||
date: string // 'yyyy-MM-dd'
|
||||
existingBookings: RentalBooking[]
|
||||
editBooking?: RentalBooking // pass to edit an existing booking
|
||||
onClose: () => void
|
||||
onSave: (b: RentalBooking) => void
|
||||
}
|
||||
@@ -19,14 +20,15 @@ function formatHour(h: number): string {
|
||||
return `${h}:00`
|
||||
}
|
||||
|
||||
export function RentalBookingModal({ obj, date, existingBookings, onClose, onSave }: RentalBookingModalProps) {
|
||||
const [isFullDay, setIsFullDay] = useState(false)
|
||||
const [startHour, setStartHour] = useState(obj.openHour)
|
||||
const [endHour, setEndHour] = useState(Math.min(obj.openHour + 2, obj.closeHour))
|
||||
const [guestName, setGuestName] = useState('')
|
||||
const [guestPhone, setGuestPhone] = useState('')
|
||||
const [notes, setNotes] = useState('')
|
||||
const [paidAmount, setPaidAmount] = useState<string>('')
|
||||
export function RentalBookingModal({ obj, date, existingBookings, editBooking, onClose, onSave }: RentalBookingModalProps) {
|
||||
const isEdit = !!editBooking
|
||||
const [isFullDay, setIsFullDay] = useState(editBooking?.isFullDay ?? false)
|
||||
const [startHour, setStartHour] = useState(editBooking?.startHour ?? obj.openHour)
|
||||
const [endHour, setEndHour] = useState(editBooking?.endHour ?? Math.min(obj.openHour + 2, obj.closeHour))
|
||||
const [guestName, setGuestName] = useState(editBooking?.guestName ?? '')
|
||||
const [guestPhone, setGuestPhone] = useState(editBooking?.guestPhone ?? '')
|
||||
const [notes, setNotes] = useState(editBooking?.notes ?? '')
|
||||
const [paidAmount, setPaidAmount] = useState<string>(editBooking?.paidAmount ? String(editBooking.paidAmount) : '')
|
||||
const [payMethod, setPayMethod] = useState<'cash' | 'card' | 'transfer'>('cash')
|
||||
|
||||
const hours = isFullDay
|
||||
@@ -39,18 +41,19 @@ export function RentalBookingModal({ obj, date, existingBookings, onClose, onSav
|
||||
|
||||
const maxHoursOk = !obj.maxHoursPerSlot || hours <= obj.maxHoursPerSlot
|
||||
|
||||
const isTimeConflict = !isFullDay && existingBookings.some(b =>
|
||||
const otherBookings = existingBookings.filter(b => b.id !== editBooking?.id)
|
||||
const isTimeConflict = !isFullDay && otherBookings.some(b =>
|
||||
!b.isFullDay && b.status !== 'cancelled' &&
|
||||
b.startHour < endHour && b.endHour > startHour,
|
||||
)
|
||||
const hasFullDayConflict = existingBookings.some(b => b.isFullDay && b.status !== 'cancelled')
|
||||
const hasFullDayConflict = otherBookings.some(b => b.isFullDay && b.status !== 'cancelled')
|
||||
|
||||
const canSave = guestName.trim() !== '' && hours > 0 && maxHoursOk && !isTimeConflict && !hasFullDayConflict
|
||||
|
||||
const handleSave = () => {
|
||||
if (!canSave) return
|
||||
onSave({
|
||||
id: `rb-${Date.now()}`,
|
||||
id: editBooking?.id ?? `rb-${Date.now()}`,
|
||||
objectId: obj.id,
|
||||
date,
|
||||
isFullDay,
|
||||
@@ -284,7 +287,7 @@ export function RentalBookingModal({ obj, date, existingBookings, onClose, onSav
|
||||
disabled={!canSave}
|
||||
className="btn-primary disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
Забронировать
|
||||
{isEdit ? 'Сохранить' : 'Забронировать'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user