Add GDPR compliant cookie banner and update footer/privacy policy to include GA and Clarity; added e2e and unit tests for cookie handling; updated snapshots
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/deploy Pipeline was successful

This commit is contained in:
2026-03-12 15:04:49 -03:00
parent 4ad45d5625
commit a5989b03b1
28 changed files with 607 additions and 9 deletions

View File

@@ -0,0 +1,113 @@
// Cookie consent banner & third-party analytics loader
// - Stores preference in localStorage
// - Shows a bottom banner until user accepts or rejects
// - Loads Google Analytics and Microsoft Clarity only when accepted
(function () {
'use strict';
var STORAGE_KEY = 'mifi-ventures-cookie-consent';
var BANNER_ID = 'cookie-banner';
var BANNER_VISIBLE_CLASS = 'is-visible';
var hasLoadedThirdParty = false;
function loadThirdPartyAnalytics() {
if (hasLoadedThirdParty) return;
hasLoadedThirdParty = true;
// Google Analytics (gtag.js + ga-init.js)
try {
var gtagScript = document.createElement('script');
gtagScript.async = true;
gtagScript.src =
'https://www.googletagmanager.com/gtag/js?id=G-36F29PDKRT';
gtagScript.onload = function () {
// Load the existing ga-init.js helper once gtag is ready
var gaInit = document.createElement('script');
gaInit.defer = true;
gaInit.src = '/assets/js/ga-init.js';
document.head.appendChild(gaInit);
};
document.head.appendChild(gtagScript);
} catch (e) {
// Fail silently analytics are non-essential
console.error('Failed to load Google Analytics', e);
}
// Microsoft Clarity
try {
var clarityScript = document.createElement('script');
clarityScript.defer = true;
clarityScript.src = 'https://www.clarity.ms/tag/vuo5q3yf79?ref=bwt';
document.head.appendChild(clarityScript);
} catch (e2) {
console.error('Failed to load Microsoft Clarity', e2);
}
}
function hideBanner(banner) {
if (!banner) return;
banner.classList.remove(BANNER_VISIBLE_CLASS);
}
function showBanner(banner) {
if (!banner) return;
banner.classList.add(BANNER_VISIBLE_CLASS);
}
function init() {
var banner = document.getElementById(BANNER_ID);
if (!banner) return;
var acceptBtn = banner.querySelector('[data-consent="accept"]');
var rejectBtn = banner.querySelector('[data-consent="reject"]');
var pref;
try {
pref = window.localStorage.getItem(STORAGE_KEY);
} catch (_) {
pref = null;
}
if (pref === 'accept') {
hideBanner(banner);
loadThirdPartyAnalytics();
} else if (pref === 'reject') {
hideBanner(banner);
} else {
showBanner(banner);
}
if (acceptBtn) {
acceptBtn.addEventListener('click', function () {
try {
window.localStorage.setItem(STORAGE_KEY, 'accept');
} catch (_) {
// ignore
}
hideBanner(banner);
loadThirdPartyAnalytics();
});
}
if (rejectBtn) {
rejectBtn.addEventListener('click', function () {
try {
window.localStorage.setItem(STORAGE_KEY, 'reject');
} catch (_) {
// ignore
}
hideBanner(banner);
});
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();