PageSourceSearch

https://vita.augustow.pl/feedback-widget.js?v=20260716layout

js vita.augustow.pl collected 2026-10-08 07:33:12 UTC 10,025 bytes, 158 lines download raw bytes

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.