Commit Graph

8 Commits

Author SHA1 Message Date
e614905ca1 fix: widget embed — full-width support + one-liner script tags via hosted loader
- Standalone page: ?width=full removes max-w-lg container constraint
- iframeSnippet: passes &width=full to URL when 100% width selected
- public/widget-loader.js: hosted script, reads data-* attrs, no inline code needed
  - data-mode="floating" → styled FAB button bottom-right
  - data-mode="trigger"  → listens for .hotelsync-book class clicks
  - Proper modal with close button and backdrop click
- Code tab snippets for floating/trigger are now single <script src> lines

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 01:15:36 +03:00
c153e12543 feat: widget additional services — sourced from rental objects module
- Additional services in widget are now derived from rental_objects (not a separate list)
- Settings page shows rental objects with enable/disable toggle; link to rental module
- Saves only {id, enabled}[] to widget_services — rental objects manage name/price/icon
- Standalone widget also derives additionalServices from config.rentalObjects
- Widget config API includes services[] in widgetSettings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 12:13:13 +03:00
59307ba6b4 feat: widget rental tab — real objects, time slots, actual rental_bookings
- Add rental_objects to /api/widget/:slug/config response
- Add POST /api/widget/:slug/rental-bookings endpoint with availability check
- Widget rental tab now shows real rental objects (not additionalServices)
- Date picker, hourly or full-day toggle, start/end hour selectors
- Booking submit creates actual rental_booking record in DB
- Success screen shows rental object, date and time slot
- WidgetRentalObject + WidgetRentalBookingPayload types added to api.ts
- BookingWidgetStandalonePage passes rentalObjects to WidgetPreview

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 11:32:10 +03:00
fb7d907b40 feat: YooKassa webhook, payment timeout, reserved status, BookingConfirmPage
- Add YooKassa webhook handler (POST /api/yookassa/webhook) that updates
  booking to confirmed+paid on payment.succeeded, cancelled on payment.canceled
- Add public status endpoint GET /api/online-bookings/:id for return URL polling
- Add 'reserved' booking status (violet) shown in calendar while awaiting payment
- Add 'website' to BookingSource type
- Payment timeout job (every 2 min) auto-cancels expired unpaid bookings
- Widget setting: "Время ожидания оплаты" (5–60 min, default 15)
- BookingConfirmPage at /booking-confirm/:id — polls status, countdown timer,
  shows success/pending/cancelled state
- Widget bookings now use status='reserved' instead of 'inquiry' when YooKassa
  is configured; set to 'confirmed' by webhook on payment.succeeded
- Migration 070: add 'reserved' to bookings status constraint + payment_expires_at

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 02:55:24 +03:00
85b4ae4ee0 fix: booking widget payment flow and success message
- On API error: show error message instead of false success screen
- Success message: "Оплата прошла успешно" only when paidViaGateway=true (user actually clicked pay in YooKassa); otherwise "Бронирование принято. Менеджер свяжется с вами" or "Оплата на месте"
- Payment screen: simplified to YooKassa-only redirect (removed bank transfer variant)
- Removed bankDetails from WidgetSettings entirely (not needed per product decision)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 02:21:55 +03:00
2b20fc18b3 feat: blacklist, guest lookup, bank transfer payment page
- Add is_blacklisted column to guests (migration 068)
- POST /widget/bookings: block blacklisted guests (403, generic message)
- GET /widget/:slug/guests/lookup: find existing guest by email/phone for auto-fill
- Widget form: debounce guest lookup on email/phone input, show "Заполнить" suggestion
- Widget payment screen: replace fake card form with proper YooKassa redirect screen or bank transfer details page
- Add bank transfer details field to widget settings (saved as widget_bank_details)
- GuestsPage: blacklist toggle button in edit modal + 🚫 ЧС badge in table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 01:31:10 +03:00
08d6629ae8 fix: standalone /book page applies saved widget settings from backend
BookingWidgetStandalonePage now fetches widgetSettings from the public
config API and applies them (color, language, mode, etc.) instead of
always falling back to URL param defaults. URL params still work as
overrides if present.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 22:36:44 +03:00
a02cf342a2 feat: widget iframe embed — standalone /:slug/book page 2026-04-07 21:57:46 +03:00