1/* Feedback Widget â VITA Augustów */ 2(function(){ 3 if(document.getElementById('fbWidget')) return; 4 var API='https://webhook.nocio.pl/api/hellovita/feedback'; 5 var cat=''; 6 var lastFocus=null; 7 8 // CSS 9 var css=document.createElement('style'); 10 css.textContent='\ 11@keyframes fbSlideIn{from{opacity:0;transform:translateX(40px)}to{opacity:1;transform:translateX(0)}}\ 12@keyframes fbFadeIn{from{opacity:0}to{opacity:1}}\ 13#fbWidget{position:fixed;bottom:66px;left:20px;z-index:9997;font-family:Inter,sans-serif}\ 14#fbBtn{width:44px;height:44px;border-radius:50%;background:#1B3A5C;color:#fff;border:none;cursor:pointer;box-shadow:0 2px 10px rgba(0,0,0,0.2);font-size:18px;display:flex;align-items:center;justify-content:center;transition:all 0.2s;opacity:0.8;padding:0}\ 15#fbBtn:hover{opacity:1}\ 16#fbBtn:hover{transform:scale(1.1)}\ 17#fbOverlay{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(15,34,56,0.25);z-index:10500;font-family:Inter,sans-serif;animation:fbFadeIn 0.2s ease}\ 18#fbOverlay.active{display:block}\ 19#fbBox{position:fixed;bottom:20px;left:20px;width:380px;background:#fff;border-radius:16px;padding:28px;box-shadow:0 16px 48px rgba(0,0,0,0.2);animation:fbSlideIn 0.3s ease;z-index:10501;max-height:calc(100vh - 40px);overflow-y:auto}\ 20#fbClose{position:absolute;top:12px;right:16px;background:none;border:none;font-size:20px;cursor:pointer;color:#999;line-height:1}\ 21#fbClose:hover{color:#333}\ 22#fbBtn:focus-visible,#fbClose:focus-visible,.fbCat:focus-visible,#fbSend:focus-visible{outline:2px solid #D4A574;outline-offset:2px}\ 23#fbTitle{margin:0 0 4px;color:#1B3A5C;font-size:1.15rem;font-weight:700}\ 24#fbSubtitle{margin:0 0 16px;color:#888;font-size:0.82rem}\ 25#fbCatLabel{display:block;margin-bottom:8px;font-size:0.82rem;color:#555;font-weight:600}\ 26.fbCat{padding:7px 16px;border-radius:20px;border:1.5px solid #ddd;background:#fff;cursor:pointer;font-size:0.85rem;color:#555;transition:all 0.2s}\ 27.fbCat:hover{border-color:#1B3A5C;color:#1B3A5C}\ 28.fbCat.active{background:#1B3A5C;color:#fff;border-color:#1B3A5C}\ 29#fbMsgLabel{display:block;margin:16px 0 6px;font-size:0.82rem;color:#555;font-weight:600}\ 30#fbMsg{width:100%;border:1.5px solid #ddd;border-radius:10px;padding:10px 12px;font-family:Inter,sans-serif;font-size:0.9rem;resize:vertical;box-sizing:border-box;min-height:80px}\ 31#fbMsg:focus{border-color:#1B3A5C}\ 32#fbMsg:focus-visible{outline:2px solid #D4A574;outline-offset:2px}\ 33#fbMsgHint{font-size:0.75rem;color:#aaa;margin-top:4px}\ 34#fbEmailLabel{display:block;margin:12px 0 6px;font-size:0.82rem;color:#555;font-weight:600}\ 35#fbEmail{width:100%;border:1.5px solid #ddd;border-radius:10px;padding:8px 12px;font-family:Inter,sans-serif;font-size:0.85rem;box-sizing:border-box}\ 36#fbEmail:focus{border-color:#1B3A5C}\ 37#fbEmail:focus-visible{outline:2px solid #D4A574;outline-offset:2px}\ 38#fbPrivacy{display:flex;align-items:flex-start;gap:8px;margin-top:14px;font-size:0.8rem;color:#666;line-height:1.4}\ 39#fbPrivacy input{margin-top:2px;flex-shrink:0;cursor:pointer}\ 40#fbPrivacy a{color:#1B3A5C;text-decoration:underline}\ 41#fbSend{width:100%;margin-top:14px;padding:13px;background:#1B3A5C;color:#fff;border:none;border-radius:10px;font-size:0.95rem;font-weight:600;cursor:pointer;transition:background 0.2s}\ 42#fbSend:hover{background:#2A5080}\ 43#fbSend:disabled{background:#a0b4c8;cursor:not-allowed}\ 44@media(max-width:520px){#fbBox{left:0;right:0;bottom:0;width:100%;border-radius:16px 16px 0 0;max-height:85vh;box-sizing:border-box}#fbWidget{bottom:20px;left:14px;right:auto}#fbBtn{width:46px;height:46px;font-size:18px}}\ 45@media(min-width:521px){body.has-sticky-cta #fbWidget{bottom:140px}}\ 46@media(max-width:520px){body.has-sticky-cta #fbWidget{bottom:80px}}\ 47@media(prefers-reduced-motion:reduce){#fbBtn,.fbCat,#fbSend,#fbBox,#fbOverlay{animation:none!important;transition:none!important}}\ 48@media print{#fbWidget,#fbOverlay{display:none!important}}\ 49'; 50 document.head.appendChild(css); 51 52 // HTML 53 var w=document.createElement('div'); 54 w.innerHTML='\ 55<div id="fbWidget"><button id="fbBtn" type="button" aria-label="Podziel siÄ opiniÄ " aria-haspopup="dialog" aria-controls="fbOverlay"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false">
55<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg></button></div>\ 56<div id="fbOverlay" role="dialog" aria-modal="true" aria-labelledby="fbTitle" aria-describedby="fbSubtitle"><div id="fbBox">\ 57<button id="fbClose" type="button" aria-label="Zamknij formularz opinii">â</button>\ 58<h3 id="fbTitle">Podziel siÄ opiniÄ </h3>\ 59<p id="fbSubtitle">Twoja opinia pomoże nam siÄ poprawiÄ</p>\ 60<label id="fbCatLabel">Typ</label>\ 61<div id="fbCats" style="display:flex;gap:8px;flex-wrap:wrap">\ 62<button class="fbCat" type="button" data-cat="Rezerwacja" aria-pressed="false">Rezerwacja</button>\ 63<button class="fbCat" type="button" data-cat="Pobyt" aria-pressed="false">Pobyt</button>\ 64<button class="fbCat" type="button" data-cat="Strona" aria-pressed="false">Strona</button>\ 65<button class="fbCat" type="button" data-cat="Inny" aria-pressed="false">Inny</button>\ 66</div>\ 67<label id="fbMsgLabel">WiadomoÅÄ *</label>\ 68<textarea id="fbMsg" rows="3" placeholder="Opisz swojÄ opiniÄ..."></textarea>\ 69<div id="fbMsgHint">od 3 do 2000 znaków</div>\ 70<label id="fbEmailLabel">Adres e-mail (opcjonalnie)</label>\ 71<input id="fbEmail" type="email" placeholder="twó[email protected]">\ 72<label id="fbPrivacy"><input type="checkbox" id="fbPrivacyCheck"> AkceptujÄ <a href="/polityka-prywatnosci-vita/" target="_blank" rel="noopener">politykÄ prywatnoÅci</a> VITA Augustów.</label>\ 73<button id="fbSend" type="button" disabled>WyÅlij</button>\ 74<div id="fbOk" style="display:none;text-align:center;padding:24px 0"><div style="font-size:2rem;margin-bottom:8px">â</div><p style="color:#1B3A5C;font-weight:600;margin:0">DziÄkujemy!</p><p style="color:#666;font-size:0.85rem;margin:4px 0 0">Twoja opinia jest\u00a0dla nas ważna.</p></div>\ 75</div></div>'; 76 document.body.appendChild(w); 77 78 // Events 79 var fbBtn=document.getElementById('fbBtn'); 80 var fbOverlay=document.getElementById('fbOverlay'); 81 var fbWidget=document.getElementById('fbWidget'); 82 var fbClose=document.getElementById('fbClose'); 83 fbBtn.onclick=function(){ 84 lastFocus=document.activeElement; 85 fbOverlay.classList.add('active'); 86 fbWidget.style.display='none'; 87 setTimeout(function(){fbClose.focus();},0); 88 }; 89 function closePanel(){ 90 fbOverlay.classList.remove('active'); 91 fbWidget.style.display='block'; 92 if(lastFocus&&typeof lastFocus.focus==='function') lastFocus.focus(); 93 } 94 fbClose.onclick=closePanel; 95 fbOverlay.onclick=function(e){if(e.target===this)closePanel()}; 96 document.addEventListener('keydown',function(e){ 97 if(!fbOverlay.classList.contains('active')) return; 98 if(e.key==='Escape'){closePanel();return;} 99 if(e.key!=='Tab') return; 100 var focusable=fbOverlay.querySelectorAll('button,[href],input,textarea,select,[tabindex]:not([tabindex="-1"])'); 101 if(!focusable.length) return; 102 var first=focusable[0]; 103 var last=focusable[focusable.length-1]; 104 if(e.shiftKey&&document.activeElement===first){e.preventDefault();last.focus();} 105 else if(!e.shiftKey&&document.activeElement===last){e.preventDefault();first.focus();} 106 }); 107 108 // Live validation â button enabled only when message + privacy 109 function fbValidate(){ 110 var msg=document.getElementById('fbMsg').value.trim(); 111 var privacy=document.getElementById('fbPrivacyCheck').checked; 112 document.getElementById('fbSend').disabled=!(cat && msg.length>=3 && privacy); 113 } 114 document.getElementById('fbMsg').addEventListener('input',fbValidate); 115 document.getElementById('fbPrivacyCheck').addEventListener('change',fbValidate); 116 117 document.querySelectorAll('.fbCat').forEach(function(b){ 118 b.onclick=function(){ 119 document.querySelectorAll('.fbCat').forEach(function(c){c.classList.remove('active');c.setAttribute('aria-pressed','false')}); 120 b.classList.add('active'); 121 b.setAttribute('aria-pressed','true'); 122 cat=b.dataset.cat; 123 fbValidate(); 124 }; 125 }); 126 127 document.getElementById('fbSend').onclick=function(){ 128 var msg=document.getElementById('fbMsg').value.trim(); 129 if(!cat){var el=document.getElementById('fbCatLabel');if(el)el.style.color='#EF4444';return;} 130 var btn=this;btn.disabled=true;btn.textContent='WysyÅanie...'; 131 fetch(API,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({ 132 project:'vita',category:cat,message:msg, 133 email:document.getElementById('fbEmail').value||null, 134 page_url:location.href 135 })}).then(function(r){ 136 if(!r.ok)throw new Error(); 137 document.getElementById('fbCats').parentElement.querySelectorAll('#fbCatLabel,#fbCats,#fbMsgLabel,#fbMsg,#fbMsgHint,#fbEmailLabel,#fbEmail,#fbPrivacy,#fbSubtitle').forEach(function(el){el.style.display='none'}); 138 btn.style.display='none'; 139 document.getElementById('fbOk').style.display='block'; 140 setTimeout(function(){ 141 closePanel(); 142 // Reset 143 document.querySelectorAll('#fbCatLabel,#fbCats,#fbMsgLabel,#fbMsg,#fbMsgHint,#fbEmailLabel,#fbEmail,#fbPrivacy,#fbSubtitle').forEach(function(el){el.style.display=''}); 144 btn.style.display='block'; 145 document.getElementById('fbOk').style.display='none'; 146 document.getElementById('fbMsg').value=''; 147 document.getElementById('fbEmail').value=''; 148 document.getElementById('fbPrivacyCheck').checked=false; 149 cat=''; 150 document.querySelectorAll('.fbCat').forEach(function(c){c.classList.remove('active')}); 151 btn.disabled=true;btn.textContent='WyÅlij'; 152 },2500); 153 }).catch(function(){ 154 btn.textContent='BÅÄ d - spróbuj ponownie';btn.style.background='#EF4444';btn.style.color='#fff'; 155 setTimeout(function(){btn.style.background='';btn.style.color='';btn.textContent='WyÅlij';fbValidate();},3000); 156 }); 157 }; 158})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.