Sprint 14: Impressum, Datenschutz, Google Analytics (cookieless)
- Impressum-Seite (§5 TMG / §18 MStV) mit René Degelmanns Daten - Datenschutzerklärung (DSGVO) mit GA-Erläuterung und Opt-out - Google Analytics G-YLG780DV3Z, Option B (cookieless, kein Consent nötig) - Sidebar-Footer-Links Impressum / Datenschutz - APP_VER → 86, SW-Cache → by-v110
This commit is contained in:
parent
21e50c6c7b
commit
6698543d14
5 changed files with 327 additions and 22 deletions
|
|
@ -3,7 +3,7 @@
|
|||
Router, State-Management, Navigation, Initialisierung.
|
||||
============================================================ */
|
||||
|
||||
const APP_VER = '81'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
const APP_VER = '86'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
|
||||
const App = (() => {
|
||||
|
||||
|
|
@ -54,6 +54,8 @@ const App = (() => {
|
|||
friends: { title: 'Freunde', module: null, requiresAuth: true },
|
||||
chat: { title: 'Nachrichten', module: null, requiresAuth: true },
|
||||
admin: { title: 'Admin', module: null, requiresAuth: true },
|
||||
impressum: { title: 'Impressum', module: null },
|
||||
datenschutz: { title: 'Datenschutz', module: null },
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
|
@ -179,7 +181,7 @@ const App = (() => {
|
|||
background:var(--c-primary-subtle);
|
||||
display:flex;align-items:center;justify-content:center">
|
||||
<svg style="width:36px;height:36px;color:var(--c-primary)" aria-hidden="true">
|
||||
<use href="/icons/phosphor.svg#${_esc(gate.icon)}"></use>
|
||||
<use href="/icons/phosphor.svg#${UI.escape(gate.icon)}"></use>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
|
|
@ -187,11 +189,11 @@ const App = (() => {
|
|||
<div style="max-width:300px">
|
||||
<h2 style="font-size:var(--text-xl);font-weight:var(--weight-bold);
|
||||
color:var(--c-text);margin:0 0 var(--space-2)">
|
||||
${_esc(title)}
|
||||
${UI.escape(title)}
|
||||
</h2>
|
||||
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);
|
||||
line-height:1.6;margin:0">
|
||||
${_esc(gate.text)}
|
||||
${UI.escape(gate.text)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
@ -472,7 +474,7 @@ const App = (() => {
|
|||
}
|
||||
|
||||
const avHtml = d => d.foto_url
|
||||
? `<img src="${_esc(d.foto_url)}" alt="${_esc(d.name)}">`
|
||||
? `<img src="${UI.escape(d.foto_url)}" alt="${UI.escape(d.name)}">`
|
||||
: `<span>🐕</span>`;
|
||||
|
||||
// Inaktive Hunde rechts
|
||||
|
|
@ -480,7 +482,7 @@ const App = (() => {
|
|||
if (others.length === 1) {
|
||||
othersHtml = `
|
||||
<div class="dog-sw-others">
|
||||
<div class="dog-sw-other" data-dog-id="${others[0].id}" title="${_esc(others[0].name)}">
|
||||
<div class="dog-sw-other" data-dog-id="${others[0].id}" title="${UI.escape(others[0].name)}">
|
||||
${avHtml(others[0])}
|
||||
</div>
|
||||
</div>`;
|
||||
|
|
@ -491,7 +493,7 @@ const App = (() => {
|
|||
<div class="dog-sw-others">
|
||||
<div class="dog-sw-stack" id="dog-sw-stack-${ctxId}">
|
||||
${visible.map((d, i) => `
|
||||
<div class="dog-sw-other dog-sw-other--${i}" data-dog-id="${d.id}" title="${_esc(d.name)}">
|
||||
<div class="dog-sw-other dog-sw-other--${i}" data-dog-id="${d.id}" title="${UI.escape(d.name)}">
|
||||
${avHtml(d)}
|
||||
</div>`).join('')}
|
||||
${extraCount > 0 ? `<div class="dog-sw-more">+${extraCount}</div>` : ''}
|
||||
|
|
@ -500,7 +502,7 @@ const App = (() => {
|
|||
${others.map(d => `
|
||||
<div class="dog-qp-item" data-dog-id="${d.id}">
|
||||
<div class="dog-qp-av">${avHtml(d)}</div>
|
||||
<span>${_esc(d.name)}</span>
|
||||
<span>${UI.escape(d.name)}</span>
|
||||
</div>`).join('')}
|
||||
</div>
|
||||
</div>`;
|
||||
|
|
@ -508,7 +510,7 @@ const App = (() => {
|
|||
|
||||
const titleClass = ctxId === 'sb' ? 'sidebar-logo-text' : 'header-title';
|
||||
el.innerHTML = `
|
||||
<div class="dog-sw-active" id="dog-sw-active-${ctxId}" title="${_esc(dog.name)} bearbeiten">
|
||||
<div class="dog-sw-active" id="dog-sw-active-${ctxId}" title="${UI.escape(dog.name)} bearbeiten">
|
||||
${avHtml(dog)}
|
||||
</div>
|
||||
<span class="${titleClass} dog-sw-title">Ban Yaro</span>
|
||||
|
|
@ -562,12 +564,6 @@ const App = (() => {
|
|||
_notifyDogChange();
|
||||
}
|
||||
|
||||
function _esc(str) {
|
||||
if (!str) return '';
|
||||
return String(str).replace(/&/g, '&').replace(/</g, '<')
|
||||
.replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// INITIALISIERUNG
|
||||
// ----------------------------------------------------------
|
||||
|
|
@ -590,12 +586,24 @@ const App = (() => {
|
|||
navigate(startPage, false, hashParams);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// AUTH-GATE HELPER — einheitlicher "Bitte anmelden"-Block
|
||||
// ----------------------------------------------------------
|
||||
function requireAuth(container, { icon = 'user', text = 'Melde dich an, um diese Funktion zu nutzen.' } = {}) {
|
||||
container.innerHTML = UI.emptyState({
|
||||
icon: UI.icon(icon),
|
||||
title: 'Anmelden erforderlich',
|
||||
text,
|
||||
action: `<button class="btn btn-primary" onclick="App.navigate('settings')">Anmelden</button>`,
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// ÖFFENTLICHE API
|
||||
// (andere Module können App.state, App.navigate etc. nutzen)
|
||||
// ----------------------------------------------------------
|
||||
return { init, navigate, state, setActiveDog, renderDogSwitcher: _renderDogSwitcher,
|
||||
getInstallPrompt: () => _installPrompt };
|
||||
getInstallPrompt: () => _installPrompt, requireAuth };
|
||||
|
||||
})();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue