diff --git a/backend/src/routes/publicWidget.ts b/backend/src/routes/publicWidget.ts index 797530b..a8ea67c 100644 --- a/backend/src/routes/publicWidget.ts +++ b/backend/src/routes/publicWidget.ts @@ -115,7 +115,7 @@ const publicWidget: FastifyPluginAsync = async (fastify) => { if (phone) { const cleanPhone = phone.replace(/\D/g, '') params.push(cleanPhone) - conditions.push(`REGEXP_REPLACE(g.phone, '\\D', '', 'g') = $${params.length}`) + conditions.push(`REGEXP_REPLACE(g.phone, '[^0-9]', '', 'g') = $${params.length}`) } const { rows } = await db.query( @@ -127,8 +127,41 @@ const publicWidget: FastifyPluginAsync = async (fastify) => { params, ) - if (!rows[0]) return reply.code(404).send({ error: 'Guest not found' }) - return rows[0] + if (rows[0]) return rows[0] + + // Fallback: search in past bookings by guest_email / guest_phone + const bConditions: string[] = [] + const bParams: unknown[] = [hotel.id] + if (email) { + bParams.push(email.toLowerCase().trim()) + bConditions.push(`LOWER(b.guest_email) = $${bParams.length}`) + } + if (phone) { + const cleanPhone = phone.replace(/\D/g, '') + bParams.push(cleanPhone) + bConditions.push(`REGEXP_REPLACE(b.guest_phone, '[^0-9]', '', 'g') = $${bParams.length}`) + } + const { rows: bRows } = await db.query( + `SELECT b.guest_name, b.guest_email, b.guest_phone + FROM bookings b + WHERE b.hotel_id = $1 AND (${bConditions.join(' OR ')}) + ORDER BY b.created_at DESC + LIMIT 1`, + bParams, + ) + + if (!bRows[0]) return reply.code(404).send({ error: 'Guest not found' }) + + // Parse guest_name into first/last name (format: "Фамилия Имя Отчество" or "Имя Фамилия") + const nameParts = (bRows[0].guest_name as string || '').trim().split(/\s+/) + return { + first_name: nameParts[1] ?? nameParts[0] ?? '', + last_name: nameParts[0] ?? '', + middle_name: nameParts[2] ?? null, + email: bRows[0].guest_email ?? null, + phone: bRows[0].guest_phone ?? null, + is_blacklisted: false, + } }, ) @@ -289,7 +322,7 @@ const publicWidget: FastifyPluginAsync = async (fastify) => { if (guestPhone) { const cleanPhone = guestPhone.replace(/\D/g, '') blParams.push(cleanPhone) - blConditions.push(`REGEXP_REPLACE(phone, '\\D', '', 'g') = $${blParams.length}`) + blConditions.push(`REGEXP_REPLACE(phone, '[^0-9]', '', 'g') = $${blParams.length}`) } const { rows: blRows } = await db.query( `SELECT id FROM guests WHERE hotel_id = $1 AND is_blacklisted = TRUE AND (${blConditions.join(' OR ')}) LIMIT 1`, diff --git a/src/pages/BookingWidgetPage.tsx b/src/pages/BookingWidgetPage.tsx index 37478e0..c03e7f4 100644 --- a/src/pages/BookingWidgetPage.tsx +++ b/src/pages/BookingWidgetPage.tsx @@ -195,10 +195,12 @@ export function WidgetPreview({ settings, slug, realRooms, realCategories, payme paymentEnabled?: boolean }) { const [previewTab, setPreviewTab] = useState<'rooms' | 'rental'>('rooms') - 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 localDate = (offsetDays = 0) => { + const d = new Date(); d.setDate(d.getDate() + offsetDays) + return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}` + } + const [checkIn, setCheckIn] = useState(() => localDate(0)) + const [checkOut, setCheckOut] = useState(() => localDate(1)) const [guests, setGuests] = useState(2) const [extraBeds, setExtraBeds] = useState(0) const [children, setChildren] = useState(0)