fix: rental booking buffer applied to end times + phone mask

- getMaxEndHour now subtracts breakHours from next booking's start,
  so you can't book right up to a slot that needs buffer time before it
- effectiveStartHour moved before availableEndHours so equal start/end
  times are no longer possible
- maskPhone (+7 (XXX) XXX-XX-XX) applied to phone field in RentalBookingModal

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-21 22:16:12 +03:00
parent 31858ca5cc
commit 3961585196
2 changed files with 15 additions and 6 deletions

View File

@@ -21,6 +21,15 @@ function hourOptions(from: number, to: number): number[] {
return Array.from({ length: to - from + 1 }, (_, i) => from + i)
}
function maskPhone(raw: string): string {
const d = raw.replace(/\D/g, '').replace(/^8/, '7').replace(/^(?!7)/, '7').slice(0, 11)
if (d.length <= 1) return d.length === 0 ? '' : '+7'
if (d.length <= 4) return `+7 (${d.slice(1)}`
if (d.length <= 7) return `+7 (${d.slice(1, 4)}) ${d.slice(4)}`
if (d.length <= 9) return `+7 (${d.slice(1, 4)}) ${d.slice(4, 7)}-${d.slice(7)}`
return `+7 (${d.slice(1, 4)}) ${d.slice(4, 7)}-${d.slice(7, 9)}-${d.slice(9, 11)}`
}
function formatHour(h: number): string {
return `${h}:00`
}
@@ -100,21 +109,21 @@ export function RentalBookingModal({
!timedBookings.some(b => h >= b.startHour && h < b.endHour + breakHours),
)
// Max end hour for a given start: limited by the next booking that starts after `start`
// Max end hour for a given start: limited by next booking minus buffer
const getMaxEndHour = (start: number) => {
const next = timedBookings
.filter(b => b.startHour >= start + 1)
.sort((a, b) => a.startHour - b.startHour)[0]
return next ? next.startHour : obj.closeHour
return next ? next.startHour - breakHours : obj.closeHour
}
const availableEndHours = hourOptions(startHour + 1, getMaxEndHour(startHour))
// If current startHour is blocked, snap to first available
const effectiveStartHour = availableStartHours.includes(startHour)
? startHour
: (availableStartHours[0] ?? obj.openHour)
const availableEndHours = hourOptions(effectiveStartHour + 1, getMaxEndHour(effectiveStartHour))
const hours = isFullDay
? obj.closeHour - obj.openHour
: Math.max(0, endHour - effectiveStartHour)
@@ -400,7 +409,7 @@ export function RentalBookingModal({
className={cn('input pl-8 text-sm', phoneRequired && !guestPhone.trim() && 'border-red-400 focus:ring-red-400')}
placeholder={phoneRequired ? '+7 999 000 11 22 (обязательно)' : '+7 999 000 11 22'}
value={guestPhone}
onChange={e => setGuestPhone(e.target.value)}
onChange={e => setGuestPhone(maskPhone(e.target.value))}
/>
</div>
{phoneRequired && !guestPhone.trim() && (