diff --git a/public/widget-loader.js b/public/widget-loader.js new file mode 100644 index 0000000..d74bbd1 --- /dev/null +++ b/public/widget-loader.js @@ -0,0 +1,105 @@ +/* HotelSync Widget Loader — https://hotelsync.ru */ +(function () { + var s = document.currentScript || (function () { + var t = document.getElementsByTagName('script'); + return t[t.length - 1]; + })(); + + var url = s.getAttribute('data-url') || ''; + var mode = s.getAttribute('data-mode') || 'floating'; // 'floating' | 'trigger' + var btn = s.getAttribute('data-btn') || 'Забронировать'; + var color = s.getAttribute('data-color') || '#4F46E5'; + var cls = s.getAttribute('data-class') || 'hotelsync-book'; + + function init() { + /* ── Modal ── */ + var modal = document.createElement('div'); + modal.style.cssText = [ + 'display:none', 'position:fixed', 'inset:0', + 'background:rgba(0,0,0,.65)', 'z-index:99999', + 'align-items:center', 'justify-content:center', + 'padding:16px', 'box-sizing:border-box', + ].join(';'); + + var inner = document.createElement('div'); + inner.style.cssText = [ + 'position:relative', 'width:100%', 'max-width:520px', + 'border-radius:20px', 'overflow:hidden', + 'box-shadow:0 24px 80px rgba(0,0,0,.45)', + ].join(';'); + + var closeBtn = document.createElement('button'); + closeBtn.innerHTML = '×'; + closeBtn.style.cssText = [ + 'position:absolute', 'top:10px', 'right:10px', 'z-index:1', + 'width:32px', 'height:32px', 'border-radius:50%', + 'background:rgba(0,0,0,.55)', 'color:#fff', + 'border:none', 'cursor:pointer', 'font-size:20px', + 'font-weight:700', 'line-height:1', + 'display:flex', 'align-items:center', 'justify-content:center', + ].join(';'); + closeBtn.onclick = function () { modal.style.display = 'none'; }; + + var iframe = document.createElement('iframe'); + iframe.src = url; + iframe.setAttribute('allow', 'payment'); + iframe.style.cssText = 'width:100%;height:680px;border:none;display:block;'; + + inner.appendChild(closeBtn); + inner.appendChild(iframe); + modal.appendChild(inner); + modal.addEventListener('click', function (e) { + if (e.target === modal) modal.style.display = 'none'; + }); + document.body.appendChild(modal); + + window.hsOpenWidget = function () { modal.style.display = 'flex'; }; + + /* ── Floating button ── */ + if (mode === 'floating') { + var fab = document.createElement('button'); + fab.textContent = btn; + fab.style.cssText = [ + 'position:fixed', 'bottom:24px', 'right:24px', + 'background:' + color, 'color:#fff', + 'border:none', 'padding:14px 26px', + 'border-radius:50px', 'font-size:15px', + 'font-family:inherit', 'font-weight:700', + 'cursor:pointer', 'z-index:99997', + 'box-shadow:0 4px 20px rgba(0,0,0,.28)', + 'transition:transform .15s,box-shadow .15s', + ].join(';'); + fab.onmouseenter = function () { + fab.style.transform = 'scale(1.06)'; + fab.style.boxShadow = '0 8px 28px rgba(0,0,0,.38)'; + }; + fab.onmouseleave = function () { + fab.style.transform = 'scale(1)'; + fab.style.boxShadow = '0 4px 20px rgba(0,0,0,.28)'; + }; + fab.onclick = function () { window.hsOpenWidget(); }; + document.body.appendChild(fab); + } + + /* ── Class trigger ── */ + if (mode === 'trigger') { + document.addEventListener('click', function (e) { + var el = e.target; + while (el) { + if (el.classList && el.classList.contains(cls)) { + e.preventDefault(); + window.hsOpenWidget(); + return; + } + el = el.parentElement; + } + }); + } + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); + } else { + init(); + } +})(); diff --git a/src/pages/BookingWidgetPage.tsx b/src/pages/BookingWidgetPage.tsx index 1a182ed..bfa4fd6 100644 --- a/src/pages/BookingWidgetPage.tsx +++ b/src/pages/BookingWidgetPage.tsx @@ -1495,45 +1495,19 @@ export function BookingWidgetPage() { formFields: prev.formFields.filter(f => f.id !== id), })) - const widgetUrl = `https://app.hotelsync.ru/${slug || 'grand-palace'}/book?color=${encodeURIComponent(settings.primaryColor)}&lang=${settings.language}&mode=${settings.roomDisplayMode}&min-nights=${settings.minNights}&rental=${settings.showRental}&promo=${settings.showPromo}&extra-beds=${settings.allowExtraBeds}&children=${settings.allowChildren}` + const widgetUrl = (fullW = false) => `https://app.hotelsync.ru/${slug || 'grand-palace'}/book?color=${encodeURIComponent(settings.primaryColor)}&lang=${settings.language}&mode=${settings.roomDisplayMode}&min-nights=${settings.minNights}&rental=${settings.showRental}&promo=${settings.showPromo}&extra-beds=${settings.allowExtraBeds}&children=${settings.allowChildren}${fullW ? '&width=full' : ''}` + + const iframeUrl = widgetUrl(widgetMaxWidth === '100%') + const modalUrl = widgetUrl(false) + const loaderBase = `https://app.hotelsync.ru/widget-loader.js` const iframeSnippet = widgetMaxWidth === '100%' - ? `` - : `