Jump to content
Followers 0
GanGster

[TUTORIAL] Banner GDPR minimalist (fara pluginuri, 100% legal)

Recommended Posts

Banner GDPR „white-hat”: blochează din start cookie-urile și scripturile neesențiale până la accept, oferă butoane Acceptă, Refuză și Preferințe, plus panou de setări. Fără pluginuri, doar HTML/CSS/JS.

1) Principii legale pe scurt

  • Implicit = blocat: orice cookie/script neesențial (analytics, ads, social) e oprit până la accept explicit (opt-in).
  • Granularitate: utilizatorul poate alege pe categorii (ex. Analiză, Marketing). Esențialele sunt mereu active.
  • Drept de retragere: un buton „Preferințe cookie” permanent (în footer) pentru a modifica decizia.
  • Dovada consimțământului: salvezi decizia (timestamp, versiune politici) în localStorage/cookie.
  • Transparență: link vizibil la Politica de cookies / Confidențialitate.

2) HTML & CSS pentru banner + panou preferințe

Lipeste codul în pagină (de preferat înainte de </body>). Stilul e minimal, accesibil și prietenos cu dark mode.

<!-- Banner GDPR minimal -->
<div id="gdpr-banner" role="dialog" aria-live="polite" aria-label="Setări cookie" style="position:fixed;inset:auto 12px 12px 12px;z-index:9999;background:#0b0d12;border:1px solid rgba(255,255,255,.12);color:#e8ecf3;padding:16px;border-radius:12px;box-shadow:0 10px 30px rgba(0,0,0,.45);display:none;max-width:760px;margin:0 auto">
  <div style="display:flex;gap:16px;align-items:flex-start">
    <div style="font-size:22px">🍪</div>
    <div style="flex:1;min-width:0">
      <strong style="display:block;font-size:16px;margin-bottom:4px">Respectăm confidențialitatea ta</strong>
      <p style="margin:0;color:#a7afc0;font-size:14px">
        Folosim cookie-uri <em>esențiale</em> pentru funcționare și, opțional, pentru <strong>Analiză</strong> și <strong>Marketing</strong>. Alege mai jos:
        <a href="/politica-cookies" target="_blank" rel="noopener nofollow" style="color:#22c55e">Politica cookies</a>.
      </p>
      <div style="margin-top:10px;display:flex;flex-wrap:wrap;gap:10px">
        <button type="button" id="gdpr-accept-all" style="padding:10px 14px;border-radius:10px;border:0;background:#22c55e;color:white;font-weight:700;cursor:pointer">Acceptă tot</button>
        <button type="button" id="gdpr-reject-all" style="padding:10px 14px;border-radius:10px;border:1px solid rgba(255,255,255,.2);background:#12151c;color:#e8ecf3;font-weight:700;cursor:pointer">Refuză neesențialele</button>
        <button type="button" id="gdpr-open-prefs" style="padding:10px 14px;border-radius:10px;border:1px solid rgba(255,255,255,.2);background:#12151c;color:#e8ecf3;cursor:pointer">Preferințe</button>
      </div>
    </div>
  </div>
</div>

<!-- Panou preferințe cookie -->
<div id="gdpr-prefs" role="dialog" aria-modal="true" aria-label="Preferințe cookie" style="position:fixed;inset:0;z-index:10000;background:rgba(0,0,0,.55);display:none">
  <div style="max-width:720px;margin:8vh auto;background:#0b0d12;border:1px solid rgba(255,255,255,.12);border-radius:14px;color:#e8ecf3;box-shadow:0 10px 30px rgba(0,0,0,.5);padding:16px">
    <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px">
      <strong style="font-size:18px">Preferințe cookie</strong>
      <button type="button" id="gdpr-close-prefs" aria-label="Închide" style="background:transparent;border:0;color:#a7afc0;font-size:22px;cursor:pointer">×</button>
    </div>

    <div style="display:grid;gap:10px;font-size:14px;color:#cdd3df">
      <label style="display:flex;align-items:center;gap:10px;padding:10px;border-radius:10px;background:#11141a;border:1px solid rgba(255,255,255,.08)">
        <input type="checkbox" disabled checked>
        <div><strong>Esențiale</strong> — necesare pentru funcționare (mereu active).</div>
      </label>

      <label style="display:flex;align-items:center;gap:10px;padding:10px;border-radius:10px;background:#11141a;border:1px solid rgba(255,255,255,.08)">
        <input type="checkbox" id="consent-analytics">
        <div><strong>Analiză</strong> — trafic anonim (ex. Google Analytics).</div>
      </label>

      <label style="display:flex;align-items:center;gap:10px;padding:10px;border-radius:10px;background:#11141a;border:1px solid rgba(255,255,255,.08)">
        <input type="checkbox" id="consent-marketing">
        <div><strong>Marketing</strong> — reclame personalizate, trackere terțe.</div>
      </label>
    </div>

    <div style="display:flex;gap:10px;justify-content:flex-end;margin-top:14px">
      <button type="button" id="gdpr-save-prefs" style="padding:10px 14px;border-radius:10px;border:0;background:#22c55e;color:white;font-weight:700;cursor:pointer">Salvează preferințele</button>
      <button type="button" id="gdpr-decline-prefs" style="padding:10px 14px;border-radius:10px;border:1px solid rgba(255,255,255,.2);background:#12151c;color:#e8ecf3;cursor:pointer">Refuză neesențialele</button>
    </div>
  </div>
</div>

<!-- Buton persistent (footer/colț) pentru redeschidere preferințe) -->
<button type="button" id="gdpr-manage" aria-label="Preferințe cookie" style="position:fixed;right:12px;bottom:64px;z-index:9998;background:#12151c;border:1px solid rgba(255,255,255,.18);color:#e8ecf3;border-radius:999px;padding:10px 12px;cursor:pointer;display:none">Preferințe cookie</button>

3) JS: logica de consimțământ + salvare

Codul de mai jos gestionează: afișarea bannerului, preferințele, salvarea în localStorage, dovada (timestamp + versiune), și aplicarea imediată a setărilor.

<script>
(function(){
  const KEY = "gdprConsent.v1";
  const POLICY_VERSION = "2025-11-04"; // actualizează la modificări de politică
  const ui = {
    banner: document.getElementById('gdpr-banner'),
    prefs: document.getElementById('gdpr-prefs'),
    btnAcceptAll: document.getElementById('gdpr-accept-all'),
    btnRejectAll: document.getElementById('gdpr-reject-all'),
    btnOpenPrefs: document.getElementById('gdpr-open-prefs'),
    btnClosePrefs: document.getElementById('gdpr-close-prefs'),
    btnSavePrefs: document.getElementById('gdpr-save-prefs'),
    btnDeclinePrefs: document.getElementById('gdpr-decline-prefs'),
    btnManage: document.getElementById('gdpr-manage'),
    chkAnalytics: document.getElementById('consent-analytics'),
    chkMarketing: document.getElementById('consent-marketing')
  };

  function getConsent(){
    try { return JSON.parse(localStorage.getItem(KEY) || "{}"); }
    catch(_) { return {}; }
  }
  function setConsent(c){
    const payload = {
      ...c,
      ts: new Date().toISOString(),
      policyVersion: POLICY_VERSION
    };
    localStorage.setItem(KEY, JSON.stringify(payload));
    return payload;
  }

  function applyConsent(c){
    // activează/dezactivează scripturile marcate cu data-cookie-category
    document.querySelectorAll('script[data-cookie-category]')
      .forEach(el => {
        const cat = el.getAttribute('data-cookie-category');
        const allowed = (cat === 'essential')
          || (cat === 'analytics' && c.analytics === true)
          || (cat === 'marketing' && c.marketing === true);

        // dacă nu e încă injectat și e permis, îl creăm dinamic
        if (allowed && !el.dataset.applied){
          const s = document.createElement('script');
          s.type = el.type === 'module' ? 'module' : 'text/javascript';
          s.text = el.textContent; // sau, dacă are data-src, folosește src
          if (el.dataset.src) s.src = el.dataset.src;
          el.after(s);
          el.dataset.applied = "1";
        }
        // dacă nu e permis, nu facem nimic (rămâne blocat)
      });

    // exemple opționale: pornește iframe-uri doar dacă analytics/marketing e true
    document.querySelectorAll('[data-cookie-category][data-src]').forEach(el=>{
      const cat = el.getAttribute('data-cookie-category');
      const allowed = (cat==='analytics' && c.analytics) || (cat==='marketing' && c.marketing);
      if (allowed && !el.getAttribute('src')) {
        el.setAttribute('src', el.getAttribute('data-src'));
      }
    });
  }

  function showBanner(){ ui.banner.style.display = 'block'; }
  function hideBanner(){ ui.banner.style.display = 'none'; }
  function openPrefs(){ ui.prefs.style.display = 'block'; }
  function closePrefs(){ ui.prefs.style.display = 'none'; }

  // inițializare
  const saved = getConsent();
  if (!('analytics' in saved) && !('marketing' in saved)) {
    showBanner();
  } else {
    applyConsent(saved);
    ui.btnManage.style.display = 'block';
  }

  // butoane banner
  ui.btnAcceptAll.addEventListener('click', ()=>{
    const c = setConsent({analytics:true, marketing:true});
    applyConsent(c); hideBanner(); ui.btnManage.style.display = 'block';
  });
  ui.btnRejectAll.addEventListener('click', ()=>{
    const c = setConsent({analytics:false, marketing:false});
    applyConsent(c); hideBanner(); ui.btnManage.style.display = 'block';
  });
  ui.btnOpenPrefs.addEventListener('click', openPrefs);

  // panou preferințe
  ui.btnClosePrefs.addEventListener('click', closePrefs);
  ui.btnDeclinePrefs.addEventListener('click', ()=>{
    ui.chkAnalytics.checked = false; ui.chkMarketing.checked = false;
  });
  ui.btnSavePrefs.addEventListener('click', ()=>{
    const c = setConsent({analytics: ui.chkAnalytics.checked, marketing: ui.chkMarketing.checked});
    applyConsent(c); hideBanner(); closePrefs(); ui.btnManage.style.display = 'block';
  });

  // buton persistent de administrare
  ui.btnManage.addEventListener('click', ()=>{
    const c = getConsent();
    ui.chkAnalytics.checked = !!c.analytics;
    ui.chkMarketing.checked = !!c.marketing;
    openPrefs();
  });
})();
</script>

4) Cum blochezi / pornești scripturile terțe

Orice script terț se marchează cu data-cookie-category="analytics|marketing" și NU pornește până nu primește consimțământ. Poți încorpora codul direct (în textContent) sau încărca prin data-src.

<!-- Exemplu script ANALYTICS blocat implicit -->
<script data-cookie-category="analytics">
// codul tău analytics (nu rulează până când userul acceptă Analiză)
</script>

<!-- Exemplu script MARKETING încărcat la nevoie (extern) -->
<script data-cookie-category="marketing" data-src="https://cdn.exemplu-ads.com/sdk.js"></script>

<!-- Exemplu iframe YouTube blocat până la acceptul Marketing -->
<iframe width="560" height="315"
        data-cookie-category="marketing"
        data-src="https://www.youtube-nocookie.com/embed/VIDEOID"
        title="YouTube video player"
        frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

5) Exemplu integrat: Google Analytics (gtag) după accept

Înlocuiește G-XXXXXXX cu ID-ul tău. Scriptul nu pornește până utilizatorul acceptă categoria „Analiză”.

<script data-cookie-category="analytics">
/* Inițializare GA după consimțământ */
window.dataLayer = window.dataLayer || [];
function gtag(){ dataLayer.push(arguments); }
gtag('consent', 'default', { 'ad_storage': 'denied', 'analytics_storage': 'denied' });
gtag('js', new Date());
gtag('config', 'G-XXXXXXX');
</script>

<script data-cookie-category="analytics" data-src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>

6) Bune practici & checklist

  • Implicit blocat pentru analytics/marketing până la accept.
  • Buton Refuză la fel de vizibil ca Acceptă.
  • Preferințe cu granularitate (Analiză / Marketing).
  • Dovadă consimțământ (timestamp + versiune politică salvate).
  • Link la Politica de cookies + Confidențialitate.
  • Buton persistent „Preferințe cookie” pentru retragere/modificare.
  • Viewport corect (fără user-scalable=no; păstrăm initial-scale=1).
  • Accesibilitate: role/aria, focus, contrast suficient.

7) FAQ

Pot stoca dovada în localStorage?
Da — pentru preferințe este ok. Dacă ai cerințe stricte (ex. audit enterprise), salvează și pe server (anonimizat).

Trebuie GeoIP?
Nu neapărat. Pentru simplitate, afișează bannerul tuturor utilizatorilor UE/EEE sau, mai sigur, tuturor utilizatorilor.

Contează ordinea scripturilor?
Da. Nu încărca scripturi terțe neesențiale înainte de banner; marchează-le cu data-cookie-category și lasă logica să le injecteze după accept.

💡 Pro tip: Pentru site-uri statice, această soluție este suficientă și legală. La actualizarea politicilor, schimbă POLICY_VERSION — utilizatorii vor fi rugați să reconsimtă.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Followers 0
HAPPYHALLOWEEN PUBZONE

Theme Made by Zayon

×
×
  • Create New...