diff --git a/src/components/rental/RentalBookingModal.tsx b/src/components/rental/RentalBookingModal.tsx index a27efd9..4151751 100644 --- a/src/components/rental/RentalBookingModal.tsx +++ b/src/components/rental/RentalBookingModal.tsx @@ -38,6 +38,8 @@ export function RentalBookingModal({ const [paidAmount, setPaidAmount] = useState(editBooking?.paidAmount ? String(editBooking.paidAmount) : '') const [payMethod, setPayMethod] = useState<'cash' | 'card' | 'transfer'>('cash') const [linkedBookingId, setLinkedBookingId] = useState(editBooking?.linkedRoomId ?? '') + // true = selected from dropdown (existing guest), false = typed manually (new guest) + const [guestIsKnown, setGuestIsKnown] = useState(isEdit) // Guest search const [showSuggestions, setShowSuggestions] = useState(false) @@ -46,6 +48,7 @@ export function RentalBookingModal({ // DB guest search const [dbResults, setDbResults] = useState<{ id: string; firstName: string; lastName: string; phone: string | null }[]>([]) const searchTimerRef = useRef | null>(null) + const [saving, setSaving] = useState(false) // Bookings with guest info — checked_in first, then confirmed const checkedIn = bookings.filter(b => b.status === 'checked_in') @@ -80,6 +83,7 @@ export function RentalBookingModal({ setGuestPhone(b.guestPhone ?? '') setLinkedBookingId(b.id) setShowSuggestions(false) + setGuestIsKnown(true) } const hours = isFullDay @@ -96,26 +100,45 @@ export function RentalBookingModal({ ) const hasFullDayConflict = otherBookings.some(b => b.isFullDay && b.status !== 'cancelled') - const canSave = guestName.trim() !== '' && hours > 0 && maxHoursOk && !isTimeConflict && !hasFullDayConflict + // For new (unknown) guests, phone is required + const phoneRequired = !guestIsKnown + const canSave = guestName.trim() !== '' && + (!phoneRequired || guestPhone.trim() !== '') && + hours > 0 && maxHoursOk && !isTimeConflict && !hasFullDayConflict - const handleSave = () => { - if (!canSave) return - const linked = bookings.find(b => b.id === linkedBookingId) - onSave({ - id: editBooking?.id ?? `rb-${Date.now()}`, - objectId: obj.id, - date, - isFullDay, - startHour: isFullDay ? obj.openHour : startHour, - endHour: isFullDay ? obj.closeHour : endHour, - guestName: guestName.trim(), - guestPhone: guestPhone.trim(), - linkedRoomId: (linked?.roomId ?? linkedBookingId) || undefined, - notes: notes.trim() || undefined, - totalAmount, - paidAmount: parseFloat(paidAmount) || 0, - status: 'confirmed', - }) + const handleSave = async () => { + if (!canSave || saving) return + setSaving(true) + try { + // If guest is new (typed manually), create them in the guests DB + if (!guestIsKnown && slug) { + const nameParts = guestName.trim().split(' ') + await api.guests.create(slug, { + last_name: nameParts[0] ?? '', + first_name: nameParts[1] ?? '', + middle_name: nameParts.slice(2).join(' ') || undefined, + phone: guestPhone.trim() || undefined, + }) + } + const linked = bookings.find(b => b.id === linkedBookingId) + onSave({ + id: editBooking?.id ?? `rb-${Date.now()}`, + objectId: obj.id, + date, + isFullDay, + startHour: isFullDay ? obj.openHour : startHour, + endHour: isFullDay ? obj.closeHour : endHour, + guestName: guestName.trim(), + guestPhone: guestPhone.trim(), + linkedRoomId: (linked?.roomId ?? linkedBookingId) || undefined, + notes: notes.trim() || undefined, + totalAmount, + paidAmount: parseFloat(paidAmount) || 0, + status: 'confirmed', + }) + } finally { + setSaving(false) + } } const displayDate = new Intl.DateTimeFormat('ru-RU', { @@ -243,6 +266,7 @@ export function RentalBookingModal({ onChange={e => { const val = e.target.value setGuestName(val) + setGuestIsKnown(false) // manual typing = new guest setShowSuggestions(true) if (searchTimerRef.current) clearTimeout(searchTimerRef.current) if (val.trim().length >= 2 && slug) { @@ -298,6 +322,7 @@ export function RentalBookingModal({ setGuestPhone(g.phone ?? '') setShowSuggestions(false) setDbResults([]) + setGuestIsKnown(true) }} className="w-full flex items-center gap-2.5 px-3 py-2.5 hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors text-left" > @@ -318,18 +343,21 @@ export function RentalBookingModal({
setGuestPhone(e.target.value)} />
+ {phoneRequired && !guestPhone.trim() && ( +

Для нового гостя необходим телефон — он будет добавлен в базу

+ )}
{/* Link to room */} @@ -437,11 +465,11 @@ export function RentalBookingModal({