Files
umbyte-landing/frontend/public/cookies.js
T
zeroday 0dbbc7487e feat(landing): уведомление о куки и баннер
Баннер сделан по образцу АгроТО, но БЕЗ выбора категорий. На umbyte.ru нет
ни аналитики, ни рекламных пикселей, ни форм — только техническая сессия
админки. Окно настроек с переключателями, которые ничего не переключают,
показывало бы пользователю выбор, которого нет. Две кнопки: «Хорошо» и
«Отклонить», выбор помнится 180 дней.

Рядом /cookies.html — короткое уведомление: что за куки, откуда, на какой
срок, как отказаться, и прямо сказано, что персональные данные посетителей
сайт не собирает (кнопка связи открывает почтовый клиент, форм нет). Поэтому
полноценная политика обработки ПДн здесь не нужна — в отношении посетителей
компания не выступает оператором.

Если появится Метрика или форма обратной связи — берём полный вариант с
категориями из АгроТО, механика хранения совпадает.
2026-08-25 22:40:34 +03:00

112 lines
5.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Куки-баннер сайта «Умный Байт».
*
* Сделан по образцу баннера АгроТО (там он живёт в public/landing/cookies.js),
* но без выбора категорий: на umbyte.ru нет ни аналитики, ни рекламных
* пикселей, ни форм — только техническая сессия админки. Городить окно
* настроек с переключателями, которые ничего не переключают, честнее не
* делать: пользователю показывают выбор, которого нет.
*
* Если на сайте появится Метрика или форма обратной связи — берём полный
* вариант с категориями из АгроТО, механика хранения совпадает.
*
* Хранение: localStorage["umbyte_cookie_consent_v1"] = {accepted, ts}
* Программно: window.umbyteCookies.show() / .get() / .reset()
*/
(function () {
'use strict';
var STORAGE_KEY = 'umbyte_cookie_consent_v1';
var TTL_DAYS = 180;
function read() {
try {
var raw = localStorage.getItem(STORAGE_KEY);
if (!raw) return null;
var p = JSON.parse(raw);
if (!p || !p.ts) return null;
if ((Date.now() - new Date(p.ts).getTime()) / 86400000 > TTL_DAYS) return null;
return p;
} catch (e) { return null; }
}
function write(accepted) {
var data = { accepted: !!accepted, ts: new Date().toISOString() };
try { localStorage.setItem(STORAGE_KEY, JSON.stringify(data)); } catch (e) {}
return data;
}
var css = [
'.umb-cc{position:fixed;inset:auto 0 0 0;z-index:9999;display:flex;justify-content:center;padding:16px;pointer-events:none;font-family:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif}',
'.umb-cc-bar{pointer-events:auto;background:#fff;border:1px solid #e2e8f0;border-radius:14px;box-shadow:0 12px 40px rgba(15,23,42,.12);padding:16px 20px;max-width:860px;width:100%;display:flex;gap:16px;align-items:center;animation:umbUp .25s ease-out}',
'@keyframes umbUp{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}',
'.umb-cc-text{flex:1;margin:0;font-size:13.5px;line-height:1.5;color:#475569}',
'.umb-cc-text a{color:#0f172a;text-decoration:underline;text-underline-offset:2px}',
'.umb-cc-actions{display:flex;gap:8px;flex-shrink:0}',
'.umb-cc-btn{font-family:inherit;font-size:13px;font-weight:500;padding:9px 18px;border-radius:9px;border:1.5px solid #e2e8f0;background:#fff;color:#475569;cursor:pointer;transition:all .15s;white-space:nowrap}',
'.umb-cc-btn:hover{border-color:#94a3b8;color:#0f172a}',
'.umb-cc-btn-primary{background:#0f172a;color:#fff;border-color:#0f172a}',
'.umb-cc-btn-primary:hover{background:#1e293b;border-color:#1e293b;color:#fff}',
/* На телефоне: узкие отступы, мелкий шрифт, кнопки в один ряд с переносом
текста внутри — иначе длинная подпись обрезается многоточием. */
'@media(max-width:640px){',
'.umb-cc{padding:8px}',
'.umb-cc-bar{flex-direction:column;align-items:stretch;gap:10px;padding:12px 14px;border-radius:12px}',
'.umb-cc-text{font-size:12.5px;line-height:1.4}',
'.umb-cc-actions{width:100%;gap:6px}',
'.umb-cc-btn{flex:1;padding:8px 6px;font-size:11.5px;white-space:normal;line-height:1.2;display:flex;align-items:center;justify-content:center}',
'}'
].join('');
function injectCss() {
if (document.getElementById('umb-cc-style')) return;
var s = document.createElement('style');
s.id = 'umb-cc-style';
s.textContent = css;
document.head.appendChild(s);
}
function show() {
if (document.getElementById('umb-cc-bar')) return;
injectCss();
var el = document.createElement('div');
el.id = 'umb-cc-bar';
el.className = 'umb-cc';
el.innerHTML = ''
+ '<div class="umb-cc-bar" role="dialog" aria-label="Файлы cookie">'
+ '<p class="umb-cc-text">Мы используем только технические куки — они нужны, чтобы сайт работал. '
+ 'Аналитики и рекламных сервисов на сайте нет. Подробнее в <a href="/cookies.html">уведомлении о куки</a>.</p>'
+ '<div class="umb-cc-actions">'
+ '<button type="button" class="umb-cc-btn" data-act="no">Отклонить</button>'
+ '<button type="button" class="umb-cc-btn umb-cc-btn-primary" data-act="yes">Хорошо</button>'
+ '</div>'
+ '</div>';
el.addEventListener('click', function (e) {
var act = e.target && e.target.getAttribute && e.target.getAttribute('data-act');
if (!act) return;
write(act === 'yes');
var b = document.getElementById('umb-cc-bar');
if (b) b.remove();
});
document.body.appendChild(el);
}
window.umbyteCookies = {
show: show,
get: read,
reset: function () {
try { localStorage.removeItem(STORAGE_KEY); } catch (e) {}
var b = document.getElementById('umb-cc-bar');
if (b) b.remove();
show();
}
};
function init() { if (!read()) show(); }
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();