-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathConsentBanner.astro
More file actions
150 lines (143 loc) · 6.02 KB
/
Copy pathConsentBanner.astro
File metadata and controls
150 lines (143 loc) · 6.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
---
// OPT-IN KVKK/GDPR consent notice (K-005). Rendered (hidden) in <body>; the
// analytics bootstrap in Analytics.astro reveals it on astro:page-load only when
// the visitor has made no prior choice and isn't sending Do-Not-Track. Nothing
// (GA4 / PostHog) loads until "Kabul et" or a granular selection grants it.
//
// KVKK "eşit seçenekler": the three actions (Reddet / Tercihleri yönet / Kabul
// et) share one neutral button style — no primary-button bias / dark pattern.
// The granular panel's checkboxes are UNCHECKED by default (opt-in). Every
// decision is persisted via /api/consent-record. No client script lives here, so
// it survives view transitions without re-binding (the delegated listener is in
// Analytics.astro).
---
<div id="dmg-consent" class="consent" role="dialog" aria-live="polite" aria-label="Çerez tercihi" hidden>
<div class="consent-card card">
<p class="consent-text">
Topluluğu büyütmek ve deneyimini ölçmek için <strong>analiz çerezleri</strong>
kullanmak istiyoruz. Bunlar yalnızca <strong>onayınla</strong> çalışır; reddetmen
siteyi kullanmana engel olmaz. Ayrıntılar:
<a href="/privacy" class="consent-link">Aydınlatma Metni</a> ·
<a href="/privacy/cerez-politikasi" class="consent-link">Çerez Politikası</a>.
</p>
<div id="dmg-consent-prefs" class="consent-prefs" hidden>
<label class="consent-opt">
<input type="checkbox" id="dmg-cat-essential" checked disabled />
<span><strong>Zorunlu:</strong> sitenin çalışması ve rıza tercihin (her zaman açık)</span>
</label>
<label class="consent-opt">
<input type="checkbox" id="dmg-cat-analytics" />
<span><strong>Analitik:</strong> Google Analytics 4, PostHog (kullanım ölçümü)</span>
</label>
<label class="consent-opt">
<input type="checkbox" id="dmg-cat-marketing" />
<span><strong>Pazarlama:</strong> şu an kullanılmıyor</span>
</label>
<button type="button" class="btn btn-ghost consent-btn" data-consent-save>Seçimi kaydet</button>
</div>
<div class="consent-actions">
<button type="button" class="btn btn-ghost consent-btn" data-consent="denied">Reddet</button>
<button type="button" class="btn btn-ghost consent-btn" data-consent-manage>Tercihleri yönet</button>
<button type="button" class="btn btn-ghost consent-btn" data-consent="granted">Kabul et</button>
</div>
</div>
</div>
<script is:inline>
// Fallback consent-UI handler. When the full analytics layer is active
// (apex + keys), Analytics.astro owns all consent handling and sets
// __dmgAnalyticsBound before this runs — so we no-op to avoid double-binding.
// When analytics is inert (staging / localhost / no keys) the banner element
// still renders, so the footer "Çerez Tercihleri" link needs *something* to
// open it. This handler provides that (open / manage / persist choice) without
// loading any tracker — there are none to load in that state.
(function () {
var w = window, d = document;
if (w.__dmgAnalyticsBound || w.__dmgConsentFallback) return;
w.__dmgConsentFallback = true;
var CK = "dmg_consent";
function banner() { return d.getElementById("dmg-consent"); }
function prefs() { return d.getElementById("dmg-consent-prefs"); }
function close(choice) {
if (choice) { try { localStorage.setItem(CK, choice); } catch (e) {} }
var b = banner(); if (b) b.setAttribute("hidden", "");
var p = prefs(); if (p) p.hidden = true;
}
function onClick(e) {
var t = e.target; if (!t || !t.closest) return;
if (t.closest("[data-consent-open]")) {
e.preventDefault();
var b = banner(); if (b) b.removeAttribute("hidden");
var p = prefs(); if (p) p.hidden = false;
return;
}
if (t.closest("[data-consent-manage]")) { var pm = prefs(); if (pm) pm.hidden = !pm.hidden; return; }
if (t.closest("[data-consent='granted']")) { close("granted"); return; }
if (t.closest("[data-consent='denied']")) { close("denied"); return; }
if (t.closest("[data-consent-save]")) {
var a = d.getElementById("dmg-cat-analytics");
close(a && a.checked ? "granted" : "denied");
return;
}
}
d.addEventListener("click", onClick);
})();
</script>
<style>
.consent {
position: fixed;
left: 50%;
bottom: 1rem;
transform: translateX(-50%);
z-index: 80;
width: min(42rem, calc(100vw - 2rem));
}
.consent[hidden] { display: none; }
.consent-card {
display: flex;
flex-direction: column;
gap: 0.85rem;
padding: 1rem 1.15rem;
box-shadow: 0 18px 50px -12px rgba(0, 0, 0, 0.85);
}
.consent-text {
margin: 0;
font-size: 0.82rem;
line-height: 1.5;
color: var(--color-ink-dim);
}
.consent-link { color: var(--color-ink-body); text-decoration: underline; text-underline-offset: 2px; }
.consent-link:hover { color: var(--color-ink); }
.consent-prefs {
display: flex;
flex-direction: column;
gap: 0.55rem;
padding: 0.5rem 0;
border-top: 1px solid var(--color-hairline, rgba(255, 255, 255, 0.08));
border-bottom: 1px solid var(--color-hairline, rgba(255, 255, 255, 0.08));
}
.consent-prefs[hidden] { display: none; }
.consent-opt {
display: flex;
align-items: flex-start;
gap: 0.55rem;
font-size: 0.8rem;
line-height: 1.4;
color: var(--color-ink-dim);
cursor: pointer;
}
.consent-opt input { margin-top: 0.15rem; accent-color: var(--color-ink-body, #c2c2c8); }
.consent-opt input:disabled { cursor: not-allowed; }
.consent-prefs .consent-btn { align-self: flex-start; margin-top: 0.2rem; }
/* Eşit seçenekler: all three actions share one neutral weight (no dark pattern). */
.consent-actions {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
justify-content: flex-end;
}
.consent-btn { padding-inline: 1rem; font-size: 0.82rem; }
@media (max-width: 32rem) {
.consent-actions { justify-content: stretch; }
.consent-actions .consent-btn { flex: 1 1 auto; }
}
</style>