- Track guestIsKnown: true when selected from dropdown, false when typed manually
- If guest is new (typed manually): phone field is required (red border + hint)
- On save: if new guest + slug available, call api.guests.create before saving rental
- Button shows 'Сохранение...' while saving, disabled during async flow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- BookingCalendar: normalize date comparison with .slice(0,10) to fix PostgreSQL DATE ISO format mismatch
- CalendarPage: show alert on rental booking save failure
- RentalBookingModal: add debounced DB guest search (api.guests.list) with 300ms delay
- RentalBookingModal: combine booking suggestions + DB results in unified dropdown
- Pass slug prop to RentalBookingModal for API access
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Guest name field shows dropdown with matching guests from all bookings
- Checked-in guests (🏠) shown first, then confirmed (📅)
- Selecting a guest auto-fills name and phone
- New 'Привязать к номеру' dropdown to link rental to a room booking
- Selecting a linked room auto-fills guest name if empty
- Pass bookings + rooms props from BookingCalendar to modal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Left column: 80px on mobile (was 160px), hide room name/price/type badge
- Category headers: truncate text, reduce padding on mobile
- Toolbar: hide "Вид" button on mobile (sm:hidden)
- Toolbar: add compact "+" button next to month label on mobile only
- Original "+" button hidden on mobile (hidden sm:inline-flex)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Migration 014: add passport_issued_by, passport_issue_date to guests table
- guests.ts: include new fields in SELECT, INSERT, PATCH + encrypt/decrypt
- booking-guests.ts: sync issued_by/issue_date back to guests on update
- GuestApiType: add passportIssuedBy, passportIssueDate fields
- selectAcGuest: fill passport_issued_by and passport_issue_date from guest profile
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add lastName/firstName/middleName/phone fields to booking form
- Remove 'Документы гостя' tab entirely from BookingModal
- Auto-parse existing guestName into FIO parts when editing
- Add guestPhone to Booking type and propagate through CalendarPage/BookingsPage API calls
- Add middle_name to guests table (migration 011)
- Update guests backend route to include middle_name in all queries
- Add middleName to GuestApiType in api.ts
- Fix selectAcGuest in BookingDetailPanel to also fill middle_name
- Auto-open guest form pre-filled with booking FIO when no guests exist
- Add passport series+number lookup in BookingDetailPanel guest form
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
drag-to-move: use window-level mousemove/mouseup listeners for reliable
drag detection — React synthetic events on container were unreliable
WS keepalive: server sends ping JSON every 25s so nginx proxy_read_timeout
never fires; client ignores pings (not broadcast to peers anymore)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
- Filter cancelled bookings from calendar grid (they no longer appear as red blocks)
- Remove cancelled from legend
- Drag-to-move: left-click drag a booking block to a different room row; click without dragging still opens the detail panel
- checked_out bookings are now semi-transparent and pointer-events-none so clicking through them creates a new booking
- Conflict detection in BookingDetailPanel now excludes checked_out bookings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix api.ts getToken/saveToken to read from localStorage (matching AuthContext) — was reading sessionStorage causing all API requests to fail auth until refresh
- Fix session cleanup on 401 to use localStorage
- Add isConflict/availableRooms helpers to BookingModal; show amber warning when selected room is occupied with clickable free room suggestions
- Pass bookings prop to BookingModal via BookingCalendar
- Add paid_amount to backend POST /bookings INSERT
- Show alert() when booking creation fails so user sees the error
- Pass paidAmount in CalendarPage handleCreate
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ThemeContext: add 'auto' mode that switches light 7:00-22:00, dark otherwise, re-checks every minute
- Topbar: cycle through 3 modes on click, show Monitor icon for auto mode
- Settings → Внешний вид: 3-button grid with split preview for auto
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Abbreviate price to ₽/д (fits in label width without wrapping)
- Rental rows always use normal height (56px min) regardless of compact mode
- Whitespace-nowrap on price line
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New types: BedItem, ExtraPlace, ChildPolicy on Room interface
- New 'Места' tab in RoomModal with 3 sections:
· Beds constructor: add/remove/count any combo of bed types (1-sp, 2-sp,
queen, king, twin, sofa, bunk, cot) with emoji icons and ±1 steppers
· Extra places: toggle + count (max 5) + price per night
· Child policy: toggle + free-under-age stepper + charge-from-age stepper
with green/amber visual cards and summary text
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
group-hover:bg-slate-750 doesn't exist in Tailwind — replaced with bg-slate-800
so dark mode hover stays dark instead of flashing white.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Notifications panel: fixed positioning on mobile (full-width below topbar,
no more overflow behind calendar)
- BookingModal: two-column layout stacks vertically on mobile (flex-col sm:flex-row)
- TariffsPage cards: price + actions merged into right column, no text overlap
- DiscountsPage cards: same fix, price text reduced to text-lg
- ReviewsPage: action buttons moved inside content div (no longer overlap guest name)
- RoomCategoriesPage: edit/delete buttons stack as column, 'Номера' text hidden on mobile
- PosPage: show desktop-only message on mobile instead of broken layout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- BookingsPage: hide Номер/Выезд/Источник columns on small screens, show nights inline on mobile
- GuestsPage: stats grid 2→4 cols (grid-cols-2 lg:grid-cols-4), table columns hidden on mobile (md/lg breakpoints), GuestModal stats 2→4 cols on sm+
- BookingDetailPanel: full-width on mobile (w-full sm:w-[400px])
- Topbar: notifications panel full-width on mobile (w-[calc(100vw-1rem)] sm:w-96)
- LoyaltyPage, MaintenancePage, DiscountsPage, TariffsPage: stats grids grid-cols-2 lg:grid-cols-4
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- UsersPage: add "Роли и права" tab with per-module permission editor per role; create/delete custom roles
- LoyaltyPage: add "Правила начисления" tab with togglable accrual rules editor; add "Ручное начисление" tab with guest search by name/phone/email, add/deduct points with reason and history; fix banner text (HotelSync is a PMS, not a hotel chain)
- GuestsPage: add "Статусы гостей" tab (moved from Settings)
- SettingsPage: remove Guests section; add compact calendar toggle in Appearance; toggle persists via localStorage
- BookingCalendar: read compact mode default from localStorage
- App.tsx: add public route /room-service/:slug → GuestRoomServicePage
- GuestRoomServicePage: new public guest-facing page for ordering room service with menu, cart, payment, and order status tracking
- RoomServicePage: QR/link sharing, payment mode toggles, new order notifications
- RentalPage/rentalData: buffer time between bookings (bufferMinutes field)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- HousekeepingPage: 3-level severity for maintenance reports (Не срочно / Средняя / Экстренно!); Экстренно automatically blocks the room and triggers an urgent notification; severity displayed as colored badge on task card
- NotificationsContext: extract shared notifications state from Topbar into context so any page can push notifications; add 'maintenance' type with wrench icon
- Topbar: migrate to NotificationsContext; add maintenance notification type with red Wrench icon
- BookingWidgetPage: add payment step after guest form when payment provider is connected (card number/expiry/CVV/name form); Без оплаты mode skips payment and shows "pay on site" message; hourly services (unit='ч') show date + time-from/time-to picker in form step
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Calendar: show clock icon + hours on hourly bookings (detect [Почасово:] prefix in notes)
- BookingModal: add extra beds counter (max 4, 1500₽/place/night) included in total
- RoomCategoriesPage: custom amenity input — type any amenity and add it alongside predefined list
- TariffsPage: collapsible Справочники section with full add/edit/delete for meal plan types and room inclusions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- TariffsPage (/tariffs): rate plan builder — meal plans (RO/BB/HB/FB/AI),
inclusions picker, price modifier (% or ₽), min nights, cancellation policy
- DynamicPricingPage (/dynamic-pricing): rule engine for weekends, holidays,
seasons, custom date ranges, weather; interactive price calendar preview
with colour-coded effective rates per day
- LoyaltyPage (/loyalty): program settings (points/₽, point value, expiry),
4-level structure (Bronze/Silver/Gold/Platinum) with editable perks,
guest portal preview mockup, top-guests leaderboard
- MaintenancePage (/maintenance): scheduled room & service downtime records;
status flow (scheduled → in_progress → done); time range support for services
- DiscountsPage (/discounts): discount catalogue — % or ₽, category (all /
loyalty / corporate / promo), min nights, validity dates, active toggle
- BookingModal: discount now selected from dropdown of active discounts only
(replaces free-form input); summary shows discount name + saved amount
- Sidebar: new "Цены и тарифы" section (Тарифы, Динамические цены, Скидки);
Управление extended with Лояльность and Тех. перерывы
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Click bell → dropdown panel (396px wide, scrollable, max-height ~100vh)
- Unread count badge on bell (shows 9+ when >9)
- Two tabs: «Все» and «Непрочитанные» with counts
- Notification types with distinct icons+colors: booking_new, booking_cancelled, booking_checkin, booking_checkout, housekeeping, channel_error, payment, review, system
- Unread items: highlighted background + left blue dot + bold title
- «Прочитать все» button when there are unread items
- Per-item: click marks as read and navigates to linked page; hover shows × to dismiss; «Перейти» hint on hover
- relativeTime helper: только что / N мин. назад / N ч. назад / вчера / дата
- Empty state for both tabs
- Closes when clicking backdrop or opening user menu
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
LoginPage:
- Toggle between login and registration mode
- 2-step registration: step 1 (hotel name + legal entity: type ООО/ИП/АО/ПАО/Другое, company name, INN, KPP hidden for ИП, legal address), step 2 (first/last name, email, phone, password with strength indicator, confirm)
- Step indicator dots, validation with inline errors, success screen after submit
- Left panel shows benefits list when in registration mode
- «Зарегистрировать отель» / «Войти» toggle links
UsersPage (/users):
- Staff list table: avatar with custom color, name, role badge, position, contacts, last login, active status
- Roles: hotel_manager, receptionist, housekeeper, accountant, security — each with label+color
- Stats cards by role (clickable to filter)
- Search by name/email/position + role filter buttons
- UserModal: avatar color picker, name/email/phone, role selector (6 roles), position field with quick-pick suggestions per role, password field, active toggle
- Delete confirmation dialog
- Sidebar: «Сотрудники» link added to Управление section
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sidebar restructure:
- Основное: Шахматка, Бронирования, Номера, Категории номеров, Доступность
- Модули: Уборка + all active addon modules (including Documents)
- Управление: План этажей, Каналы, Модули, Настройки
- Разработчикам: API
ModulesContext: documents module now active by default (version bump to 3)
HousekeepingPage: added «Планы уборки» tab with:
- Уборка при выезде: auto task creation, priority (high/normal), inspection toggle
- Ежедневная уборка: interval (every 1/2/3/7 days), start from day N of stay
- Уборка по запросу: guest-initiated via QR, priority selection
- Генеральная уборка: deep clean every N days toggle
- Проверка после уборки: inspection task after any cleaning
- Автоназначение горничной: assign based on shift schedule
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>