From bd27be72c1d0b60f57d28a45ef8357d728dcfea0 Mon Sep 17 00:00:00 2001 From: HotelSync Date: Wed, 8 Apr 2026 02:10:02 +0300 Subject: [PATCH] fix: widget payment screen always shown, phone mask, today's date default - Always show payment step when paymentEnabled=true even if YooKassa confirmationUrl is null (payment creation failed silently) - Add third payment screen variant: "manager will contact you" when no YooKassa URL and no bank details configured - Add Russian phone mask +7 (___) ___-__-__ on phone type fields - Default check-in/check-out dates to today/tomorrow instead of hardcoded past dates Co-Authored-By: Claude Sonnet 4.6 --- src/pages/BookingWidgetPage.tsx | 58 +++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/src/pages/BookingWidgetPage.tsx b/src/pages/BookingWidgetPage.tsx index d2103f1..4836b69 100644 --- a/src/pages/BookingWidgetPage.tsx +++ b/src/pages/BookingWidgetPage.tsx @@ -196,8 +196,10 @@ export function WidgetPreview({ settings, slug, realRooms, realCategories, payme paymentEnabled?: boolean }) { const [previewTab, setPreviewTab] = useState<'rooms' | 'rental'>('rooms') - const [checkIn, setCheckIn] = useState('2026-03-20') - const [checkOut, setCheckOut] = useState('2026-03-22') + const todayStr = new Date().toISOString().slice(0, 10) + const tomorrowStr = new Date(Date.now() + 86400000).toISOString().slice(0, 10) + const [checkIn, setCheckIn] = useState(todayStr) + const [checkOut, setCheckOut] = useState(tomorrowStr) const [guests, setGuests] = useState(2) const [extraBeds, setExtraBeds] = useState(0) const [children, setChildren] = useState(0) @@ -289,7 +291,8 @@ export function WidgetPreview({ settings, slug, realRooms, realCategories, payme if (result.confirmationUrl) { setConfirmUrl(result.confirmationUrl) setStep('payment') - } else if (settings.bankDetails) { + } else if (settings.bankDetails || needsPayment) { + // YooKassa failed or bank transfer configured — always show payment screen setStep('payment') } else { setStep('success') @@ -379,6 +382,7 @@ export function WidgetPreview({ settings, slug, realRooms, realCategories, payme // ── Payment screen ── if (step === 'payment') { const isYookassa = !!confirmUrl + const hasBankDetails = !isYookassa && !!settings.bankDetails return (
@@ -410,14 +414,14 @@ export function WidgetPreview({ settings, slug, realRooms, realCategories, payme

🔒 Защищённое соединение · ЮKassa

- ) : ( + ) : hasBankDetails ? ( /* Bank transfer details */

{settings.language === 'ru' ? 'Реквизиты для оплаты' : 'Payment details'}

- {settings.bankDetails || 'Реквизиты не указаны'} + {settings.bankDetails}

{settings.language === 'ru' @@ -425,6 +429,16 @@ export function WidgetPreview({ settings, slug, realRooms, realCategories, payme : 'After transfer, the hotel will confirm your booking. Include your name and dates in the payment reference.'}

+ ) : ( + /* No payment configured — pending confirmation */ +
+
+ +
+

+ {settings.language === 'ru' ? 'Бронирование принято. Менеджер отеля свяжется с вами для подтверждения оплаты.' : 'Booking received. Hotel manager will contact you to confirm payment.'} +

+
)} @@ -437,7 +451,7 @@ export function WidgetPreview({ settings, slug, realRooms, realCategories, payme > {settings.language === 'ru' ? `Перейти к оплате · ${grandTotal.toLocaleString('ru-RU')} ₽` : `Proceed to pay · ${grandTotal.toLocaleString('ru-RU')} ₽`} - ) : ( + ) : hasBankDetails ? ( + ) : ( + )} @@ -603,13 +625,29 @@ export function WidgetPreview({ settings, slug, realRooms, realCategories, payme ) : ( { - setFormValues(prev => ({ ...prev, [field.id]: e.target.value })) - if (field.id === 'email') doGuestLookup(e.target.value, formValues['phone']) - if (field.id === 'phone') doGuestLookup(formValues['email'], e.target.value) + let val = e.target.value + if (field.type === 'phone') { + const digits = val.replace(/\D/g, '').slice(0, 11) + if (digits.length === 0) { val = '' } + else { + const d = digits.startsWith('8') ? '7' + digits.slice(1) : digits + const n = d.startsWith('7') ? d : '7' + d + val = '+7' + if (n.length > 1) val += ' (' + n.slice(1, 4) + if (n.length > 4) val += ') ' + n.slice(4, 7) + if (n.length > 7) val += '-' + n.slice(7, 9) + if (n.length > 9) val += '-' + n.slice(9, 11) + } + } + setFormValues(prev => ({ ...prev, [field.id]: val })) + if (field.id === 'email') doGuestLookup(val, formValues['phone']) + if (field.id === 'phone') doGuestLookup(formValues['email'], val) }} /> )}