Commit Graph

60 Commits

Author SHA1 Message Date
c656d0c6ae Log NetUP request/response body; fix reservation_id to be numeric
- reservation_id converted to integer (NetUP likely requires number not UUID string)
- Log requestBody sent to NetUP and responseBody received from NetUP
- Push event rows now expandable: click to see URL, request JSON, NetUP error response
- Same for checkout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 12:29:45 +03:00
44fa9d24f1 Improve NetUP diagnostics: push event log + test check-in button
- notifyNetupCheckin/Checkout now log every attempt (ok/error/skipped)
  with room number, NetUP room, URL, HTTP status, error message
- Push log exposed via GET /netup/log alongside pull request log
- New POST /netup/test-checkin: manually trigger a test check-in from UI
- Diagnostics tab split into two sections:
  - Outgoing (push): table of check-in/check-out events with status dots
  - Incoming (pull): NetUP poll requests (if TravelLine integration works)
- Test button picks first mapped room and fires a real check-in call

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 12:19:48 +03:00
142be49211 Add Diagnostics tab to TV Welcome: view NetUP poll requests in UI
- Rename pull endpoint /travelline → /netup-pms (cleaner branding)
- Add GET/DELETE /api/hotels/:slug/netup/log endpoints
- TvWelcomePage: new 'Диагностика' tab shows incoming NetUP requests
  with method, URL, timestamp list + detail panel (headers, query, body)
- Remove 'TravelLine' wording from UI, replace with 'Pull-интеграция'

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 19:08:57 +03:00
8350309645 Add TravelLine pull integration for NetUP: capture endpoint + tl_token
- New /travelline route: accepts all NetUP polls, logs them to in-memory
  ring buffer (GET /travelline/_log to inspect), responds with active
  reservations in a generic PMS format
- Migration 007: adds tl_token column to netup_settings
- PATCH netup/settings now saves tl_token; GET returns it
- TvWelcomePage: new TravelLine section with read-only API URL + copy
  button and token input field

Setup in NetUP: Integration type = TravelLine,
API URL = https://api.hotelsync.ru/travelline, Token = <tl_token>

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 18:57:10 +03:00
05d0c94a9a Fix NetUP settings not loading: snake_case → camelCase (transformKeys)
req() auto-converts server_url→serverUrl, default_language→defaultLanguage,
netup_room_number→netupRoomNumber. Fixed both type declarations and component reads.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 18:39:01 +03:00
61d25628ae Add NetUP IPTV integration module (TV Welcome settings page)
- DB: migrations/002_netup.sql — netup_settings + netup_room_mapping tables
- Backend: routes/netup.ts — GET/PATCH settings, POST test, GET/POST room
  mappings, POST send TV message; notifyNetupCheckin/Checkout helpers
- Backend: bookings PATCH — fire-and-forget NetUP check-in/out on status change
- Frontend: TvWelcomePage — connection settings tab + room mapping tab
- Frontend: sidebarItem added to tv-welcome module (shows in sidebar menu)
- Frontend: ModulesPage Settings button navigates to /tv-welcome
- Frontend: BookingModal — "Сообщение гостю на TV" panel for existing bookings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 18:18:41 +03:00
cbd85c5c7e Clear stale WS locks on reconnect to fix phantom overlays
When WS reconnects after a disconnect, the browser may have missed unlock/booking:created
messages, leaving gray striped overlays stuck forever. Clearing all locks on reconnect
ensures stale state is removed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 20:13:10 +03:00
684073c4ad Fix booking creation: localStorage token, conflict detection, paid_amount
- 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>
2026-03-17 19:48:37 +03:00
e59bc752b0 Add password letter requirement + labeled strength UI + auto-capitalize name fields
- Reject pure-numeric passwords (must contain ≥1 letter) in RegisterForm, ResetPasswordPage, and backend register/reset-password handlers
- Replace bare strength bars with labeled 2×2 grid: ≥8 символов, Содержит букву, Заглавная буква, Цифра
- Auto-capitalize first letter of each word in "Название отеля" and "Контактное лицо" fields (autoCapitalize="words" + JS handler)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 19:35:54 +03:00
e3f37744b0 Improve login UX for unconfirmed email + resend confirmation
- LoginForm: detect 403 separately, show amber warning with email address
- Add 'Resend confirmation email' button (calls POST /api/auth/resend-confirmation)
- Backend: POST /api/auth/resend-confirmation endpoint (generates new token, resends email)
- api.ts: add resendConfirmation method

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 19:05:55 +03:00
352d22a101 Add WS reconnect logic + connection indicator in calendar
- useHotelSocket: reconnect with exponential backoff (up to 30s), return connected state, log errors to console
- BookingCalendar: show green/gray dot + Online/Offline label in toolbar
- CalendarPage: pass wsConnected prop

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 18:51:32 +03:00
02c3b7452a Fix login page UX + add password reset flow
- Move Field component outside RegisterForm — fixes focus loss on every keystroke
- Remove setError('') at submit start — fixes error "flash" that looked like page reload
- Clear errors onChange instead, so error persists until user starts correcting
- Add 'Forgot password?' link in LoginForm
- Add ForgotPasswordForm (email input, success state)
- Add ResetPasswordPage at /reset-password?token=...
- Backend: POST /api/auth/forgot-password — generates 1h token, sends email
- Backend: POST /api/auth/reset-password — validates token, updates password hash
- Backend: migration 006 — reset_token/reset_token_expires columns
- Backend: sendPasswordResetEmail in email.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 18:43:05 +03:00
dd9a2a3da9 Add auto theme mode (light/dark/auto by time of day)
- 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>
2026-03-17 18:22:37 +03:00
3506105fc1 Add real-time booking collaboration via WebSocket
- Backend: /ws relay endpoint (@fastify/websocket)
- Frontend: useHotelSocket hook with lock/unlock/booking events
- Calendar: lock overlay with diagonal stripes shows other manager editing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 18:05:09 +03:00
1d24e5a4c4 Add delete room button in RoomModal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 18:02:08 +03:00
152a8c0463 Add hotel registration with email confirmation (nodemailer, confirm-email endpoint)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 17:30:07 +03:00
c06f4bf553 Fix login spinner stuck on API error (add try/catch in handleSubmit)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 17:04:05 +03:00
56f4d997a2 Show API save errors in RoomModal footer
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 16:55:08 +03:00
55a34dc0dc Connect ChannelsPage, FloorMapPage, SettingsPage, UsersPage to real API
- ChannelsPage: load from API, toggle/sync call real endpoints; normalize
  enabled→isEnabled, lastSyncedAt→lastSyncAt, add displayName/mappings defaults
- FloorMapPage: load rooms+bookings from API; create booking via API
- SettingsPage: load hotel via GET /api/hotels/:slug; save general section
  via PATCH (name, address, timezone, currency, check_in/out times)
- UsersPage: load users from API; create/update/delete via API;
  map backend User (name/role) → StaffUser (firstName/lastName/StaffRole)
- api.ts: add hotels.get/update, users.delete, channel normalization,
  HotelPayload/toHotelPayload
- types/index.ts: extend Hotel with phone/checkInTime/checkOutTime/optional fields;
  add User.createdAt/updatedAt
- backend/routes/hotels.ts: extend PATCH to allow address/phone/check_in_time/check_out_time
- backend/migrations/004_hotels_contacts.sql: add address/phone/check_in/out_time to hotels

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 14:21:45 +03:00
728b20417a Connect frontend to real API — rooms, bookings, housekeeping, calendar
- src/lib/api.ts: central API client with JWT auto-refresh, snake_case→camelCase transform
- src/contexts/AuthContext.tsx: real login via POST /api/auth/login
- src/pages/RoomsPage.tsx: load rooms from API, create/update via API
- src/pages/BookingsPage.tsx: load bookings + rooms from API
- src/pages/HousekeepingPage.tsx: load today's tasks from API, update status via API
- src/pages/CalendarPage.tsx: load rooms + bookings from API
- src/types/index.ts: fix HousekeepingTask.priority to match DB (medium/urgent)
- backend/src/routes/rooms.ts: update to use new column names (max_guests, base_rate) + all new fields
- backend/src/routes/bookings.ts: update price_per_night→base_rate, add paid_amount to PATCH
- backend/migrations/003_fix_constraints.sql: fix rooms.status values, add paid_amount, inquiry status, other source
- public/robots.txt + index.html: noindex for SPA inner pages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 13:49:30 +03:00
5429b272f9 Fix mobile UI bugs from screenshots
- 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>
2026-03-17 00:47:24 +03:00
eeadbf0f5a Simplify hotel registration form to single step
Remove legal entity section (ОПФ, ИНН, КПП), two-step flow,
and confirm password. Keep: hotel name, address, contact person,
email, phone, password.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 00:32:29 +03:00
2fc66d1e84 Fix mobile responsiveness across all pages
- PosPage: rooms list becomes horizontal scroll row on mobile instead of w-56 sidebar
- AvailabilityPage: edit panel stacks below grid on mobile (was fixed w-80 side panel)
- UsersPage roles tab: sidebar stacks above permissions on mobile
- All page containers: p-6 → p-4 md:p-6 (TariffsPage, DiscountsPage, MaintenancePage, ReportsPage, DynamicPricingPage, GuestsPage, LoyaltyPage)
- Stats grids: lg:grid-cols-4 → md:grid-cols-4 (GuestsPage, TariffsPage, DiscountsPage, MaintenancePage, ReportsPage, LoyaltyPage)
- Modal form grids: grid-cols-3 → grid-cols-1 sm:grid-cols-3, grid-cols-5 → grid-cols-3 sm:grid-cols-5, grid-cols-4 → grid-cols-2 sm:grid-cols-4
- PosPage modals: fixed w-80/w-96 → responsive w-[calc(100vw-2rem)] sm:w-80/96

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 00:27:43 +03:00
91e58ff994 Fix infinite redirect loop: super_admin no longer redirects to /admin
The /admin route was removed when CP was moved to cp.hotelsync.ru.
Logged-in super_admin sessions were causing a redirect loop to a
non-existent route, resulting in a blank page on app.hotelsync.ru.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 00:16:29 +03:00
e9830975ab Add separate CP admin panel at cp.hotelsync.ru
- CpLoginPage: dark themed login page with email/password auth, only for cp subdomain
- CpLayout: separate dark sidebar layout with Shield icon, nav for Обзор/Отели/Пользователи/Тарифы/Мониторинг/Настройки
- App.tsx: detect hostname — cp.hotelsync.ru renders CP app, app.hotelsync.ru renders PMS (no /admin route)
- CpGuard: protects CP routes, redirects to /login if not authenticated
- Admin panel completely removed from app.hotelsync.ru

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 20:58:03 +03:00
15c3471e7f Fix mobile responsiveness across all pages
- 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>
2026-03-16 20:51:56 +03:00
e81de90855 Move guest links to guest.hotelsync.ru subdomain
/review/:slug and /room-service/:slug guest pages now link to
guest.hotelsync.ru instead of app.hotelsync.ru

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 20:29:14 +03:00
d661bbbc84 Add role permissions, loyalty accrual rules, guest statuses, and room service guest page
- 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>
2026-03-16 20:13:22 +03:00
26da3eafa8 Fix TypeScript build errors
- GuestReviewPage: fix hotel config lookup type (slug && obj returns '' | obj)
- PosPage, ReviewsPage: change ComponentType<{size?:number}> to ElementType for Lucide icon compatibility

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 19:43:20 +03:00
dc3e68dbe2 Add guest review page + switch to 5-star rating system
- New public page /review/:slug — guest-facing review form with 5-star selector, optional comment, positive flow (redirect buttons to platforms), negative flow (thank you message)
- Switch all rating scales from 10-point to 5-star in ReviewsPage: mock data, StarRating component, avgRating sub-label, NPS thresholds, threshold slider (1–4), settings cards
- Rating badge in review list now shows number + star icon
- Register route in App.tsx as public (no auth required)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 19:27:34 +03:00
5e3fca5471 Fix POS: АТОЛ is a fiscal register, not a payment method
- Remove АТОЛ from payment method selector (now only Наличные / Терминал)
- Add fiscal receipt block below payment: shows АТОЛ connection status + toggle to print fiscal receipt
- Remove atolRevenue/atolCount from shift totals and X-report
- Add АТОЛ connection status line to X-report
- Success overlay shows 'Фискальный чек распечатан' when АТОЛ connected and print enabled

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 19:22:05 +03:00
6dabb29b61 Redesign POS and Reviews modules
- POS: 3-tab layout (Касса/X-Z-отчёт/АТОЛ), compact guest list sidebar, compact receipt log with per-method totals, X-report card with dark header, close shift confirmation with Z-report, ATOL TCP/USB/COM connection settings with cashier name and tax system
- Reviews: remove redirect_pending tab, add auto-redirect logic by booking source, add Preview tab with phone-frame mockup and customization panel, add Settings tab with sending timing/channel/retry, threshold slider, redirect logic table, platform management

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 19:09:15 +03:00
c981b2ac27 Add expandable room detail panel to booking widget with photo gallery, amenities, and 3D tour placeholder
Each room card in the widget can now be expanded via chevron button to reveal:
- Photo gallery with navigation arrows, dot indicators, and thumbnail strip (gradient placeholders per room)
- Room description, area (m²), bed count
- Amenities chips with icons (Wi-Fi, TV, AC, etc.)
- 3D tour button for rooms that support it (Делюкс, Пентхаус); placeholder notice for others
- "Выбрать этот номер" button inside detail panel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 16:13:35 +03:00
c431ea1486 Add maintenance severity levels, notifications context, and widget payment step
- 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>
2026-03-16 16:04:19 +03:00
f62ccdd3f7 Add occupancy analytics, housekeeping maintenance notes, and booking widget form flow
- DynamicPricingPage: add 'Нагрузка' tab with monthly occupancy bar chart (2025/2026 data), year selector, summary stats, and editable occupancy-based pricing rules (threshold ranges → price modifiers)
- HousekeepingPage: add maintenance note button (wrench icon) on task cards — housekeeper can report broken items with a description that gets sent to technical service; notes displayed in orange badge
- BookingWidgetPage: fix 'Забронировать' button with full form flow (browse → form → success), add configurable form fields (required/optional/custom), add additional services toggle in settings and at checkout, add extra beds + children count in guest selector with auto-pricing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 15:51:31 +03:00
87455c2710 Add centralized amenities directory and hourly booking example
- AmenitiesContext: shared amenities list with add/edit/delete, available app-wide
- RoomsPage: collapsible Справочник удобств section (add/rename/delete)
- RoomModal + RoomCategoriesPage: use amenities from context, no hardcoded lists
- RoomCategoriesPage: removed custom amenity input (use справочник instead)
- mockData: room 103 now has allowHourly=true, added sample hourly booking (today, 10-13ч)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 15:40:01 +03:00
c347c99228 Add hourly indicator in calendar, extra beds, custom amenities, meal/inclusion management
- 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>
2026-03-16 15:28:43 +03:00
92f0270290 Make rental booking rows clickable to open edit modal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 15:20:48 +03:00
a787affa72 Add edit button for rental bookings in Bookings page rental tab
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 15:18:23 +03:00
913ddeedc9 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>
2026-03-16 15:13:49 +03:00
2e7abc2b7a Apply 7 calendar/booking UI improvements
1. Remove redundant "Шахматка бронирований" header from CalendarPage
2. Fix Saturday abbreviation: "су" → "сб" (use EEEEEE format)
3. Compact toggle: add "Вид" text label to button
4. Booking bars: check-in starts at 1/3 cell, check-out ends at 1/3 cell
5. BookingModal: move "Статус гостя" tags to left column
6. BookingDetailPanel: add scan button + print package in Docs tab
7. RentalBookingModal: add payment method + amount section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 14:48:06 +03:00
abf5f83675 Remove Tetris animation from login page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 20:44:07 +03:00
fb067816b0 Rewrite Tetris overlay with real tetrominoes (I/O/T/S/Z/J/L shapes)
White cells with colored borders, proper grid-based stacking collision.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 20:39:17 +03:00
6e5b042f57 Add calendar compact mode, Tetris login animation, maintenance rental support
- BookingCalendar: sort rooms by category, compact row height toggle
- LoginPage: Tetris tile animation after delay (module names fall & stack)
- MaintenancePage: rental objects support with filter tab and icons

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 20:31:36 +03:00
78788f68b0 Add pricing, tariffs, loyalty, maintenance, discounts features
- 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>
2026-03-15 19:56:17 +03:00
acc17387a7 Add Guests page with history/ratings and booking discounts
- New /guests page: searchable guest list with stay history, payment
  summary, rating (1-5 stars), loyalty status (Базовый/Серебряный/Золотой),
  tags (VIP, Постоянный, Корпоративный, Медовый месяц, Проблемный),
  per-guest notes, inline payments tab with debt tracking
- Guest detail modal: 3 tabs — Обзор / История проживания / Платежи
- Sidebar: added "Гости" link (UsersRound icon) in Основное section
- BookingModal: discount block — % or fixed ₽ amount, free-stay checkbox
  that zeroes room cost; summary shows strikethrough original + discount line;
  total reflects discount applied before services

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 16:42:39 +03:00
c3723dec90 Add hotel registration flow on login page and staff users management page
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>
2026-03-11 22:45:11 +03:00
401825c01e Activate documents module, reorganize sidebar, add cleaning plans to housekeeping
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>
2026-03-11 22:38:00 +03:00
de5b56c577 Add Telegram bot notifications for managers in settings
In Settings → Notifications, new «Telegram-уведомления» section:
- Bot token input (from @BotFather)
- Step-by-step instructions: manager sends /start to bot, gets Chat ID, admin adds it
- Copyable bot invite link
- Event checkboxes: new booking, cancellation, check-in, check-out, channel error, payment
- Manager list with avatar initials, name, Chat ID, delete button
- Add manager form: name + Chat ID input
- Test message button (shown when at least one manager is added)
- Full section only visible after token is entered

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 22:32:36 +03:00
96dfd755ed Add room categories, documents module, guest settings, and booking improvements
- New pages: RoomCategoriesPage (category CRUD with photos, color, amenities) and DocumentsPage (template constructor with variable substitution, print packages)
- Sidebar: added "Категории номеров" link under rooms, Documents module via modulesData
- App.tsx: routes for /room-categories and /documents
- RoomModal: now accepts categories prop for categoryId select
- BookingModal: added additional services dropdown (breakfast, transfer, parking etc.) accumulating into booking total; summary shows services breakdown
- SettingsPage: new "Гости" section with guest tag CRUD (add/edit/remove, color picker, live preview); booking section toggle "Показывать поле Источник бронирования"
- modulesData: added Documents module entry (free tier, sidebar item)
- RoomsPage: passes MOCK_CATEGORIES to RoomModal
- ReviewsPage: rewritten with auto-redirect logic, threshold slider, platform settings tab

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 22:17:54 +03:00