Files
hotelsync/src/pages/BookingWidgetStandalonePage.tsx
HotelSync 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

72 lines
3.1 KiB
TypeScript

import { useState, useEffect } from 'react'
import { useParams, useSearchParams } from 'react-router-dom'
import { api, type WidgetRoom, type WidgetCategory } from '../lib/api'
import { WidgetPreview, DEFAULT_FORM_FIELDS, DEFAULT_SERVICES } from './BookingWidgetPage'
import type { WidgetSettings } from './BookingWidgetPage'
export function BookingWidgetStandalonePage() {
const { slug } = useParams<{ slug: string }>()
const [searchParams] = useSearchParams()
const [realRooms, setRealRooms] = useState<WidgetRoom[]>([])
const [realCategories, setRealCategories] = useState<WidgetCategory[]>([])
const [paymentEnabled, setPaymentEnabled] = useState<boolean | undefined>(undefined)
const [settings, setSettings] = useState<WidgetSettings>({
hotelName: '',
primaryColor: searchParams.get('color') ?? '#4F46E5',
language: (searchParams.get('lang') ?? 'ru') as 'ru' | 'en',
showRooms: true,
showRental: searchParams.get('rental') === 'true',
roomDisplayMode: (searchParams.get('mode') ?? 'rooms') as 'rooms' | 'categories',
minNights: parseInt(searchParams.get('min-nights') ?? '1') || 1,
paymentProvider: 'yukassa',
showPromo: searchParams.get('promo') !== 'false',
allowExtraBeds: searchParams.get('extra-beds') !== 'false',
allowChildren: searchParams.get('children') !== 'false',
formFields: DEFAULT_FORM_FIELDS,
additionalServices: DEFAULT_SERVICES,
})
useEffect(() => {
if (!slug) return
api.widget.getConfig(slug)
.then(config => {
setRealRooms(config.rooms ?? [])
setRealCategories(config.categories ?? [])
setPaymentEnabled(config.paymentEnabled)
if (config.widgetSettings) {
const ws = config.widgetSettings
setSettings(prev => ({
...prev,
hotelName: ws.hotelName ?? config.hotelName ?? prev.hotelName,
primaryColor: ws.primaryColor ?? prev.primaryColor,
language: (ws.language ?? prev.language) as 'ru' | 'en',
roomDisplayMode: (ws.roomDisplayMode ?? prev.roomDisplayMode) as 'rooms' | 'categories',
minNights: ws.minNights ?? prev.minNights,
showRental: ws.showRental ?? prev.showRental,
showPromo: ws.showPromo ?? prev.showPromo,
allowExtraBeds: ws.allowExtraBeds ?? prev.allowExtraBeds,
allowChildren: ws.allowChildren ?? prev.allowChildren,
}))
} else {
setSettings(prev => ({ ...prev, hotelName: config.hotelName ?? prev.hotelName }))
}
})
.catch(() => {})
}, [slug])
return (
<div className="min-h-screen bg-slate-50 flex items-start justify-center py-6 px-3">
<div className="w-full max-w-lg">
<WidgetPreview
settings={settings}
slug={slug}
realRooms={realRooms.length > 0 ? realRooms : undefined}
realCategories={realCategories.length > 0 ? realCategories : undefined}
paymentEnabled={paymentEnabled}
/>
</div>
</div>
)
}