Analyse: Portal-Texte, Verantwortlichen-Vorschau und Bestätigungen nach geprüftem Wortlaut
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ddb91a9950
commit
3bac4093af
8 files changed
+253
-25
No files matched your search
+27
-17
@@ -3,10 +3,9 @@
|
||||
Buchungsseite (off), Einrichtungsstatus (ordered/setup) oder Editor (active). Styles: funktionen.css.
|
||||
Kundentexte kommen nur ueber esc() bzw. textContent in die Seite. */
|
||||
|
||||
import { bannerColor, chartModel, barRows, countryName, flagEmoji, refLabel, DEVICE_LABELS, CONTACT_LABELS } from '/analyse-view.js'
|
||||
import { bannerColor, BANNER_PREVIEW_TEXT, controllerLines, chartModel, barRows, countryName, flagEmoji, refLabel, DEVICE_LABELS, CONTACT_LABELS } from '/analyse-view.js'
|
||||
|
||||
const PRICE = '30 €'
|
||||
const AVV_URL = '/rechtliches/avv-website-analyse.html'
|
||||
const LEISTUNGSBESCHREIBUNG = '/vertragsunterlagen/funktionen-leistungsbeschreibung.html'
|
||||
const PHOTO_ACCEPT = 'image/jpeg,image/png,image/webp' // iOS wandelt HEIC dann selbst in JPEG um
|
||||
const PHOTO_MAX_BYTES = 10 * 1024 * 1024
|
||||
@@ -592,23 +591,29 @@ function bannerPreview(color) {
|
||||
const btn = `style="background:${c};border-color:${c};color:#fff"`
|
||||
return `
|
||||
<div class="an-bn" role="img" aria-label="Vorschau des Banners auf deiner Website">
|
||||
<p class="an-bn-text">Wir möchten mit deiner Zustimmung anonym auswerten, wie unsere Website genutzt wird (keine Cookies, keine Weitergabe). Details: <span class="an-bn-link">Datenschutz</span></p>
|
||||
<p class="an-bn-text">${esc(BANNER_PREVIEW_TEXT)}<span class="an-bn-link">Datenschutz</span></p>
|
||||
<div class="an-bn-row"><span class="an-bn-btn" ${btn}>Ablehnen</span><span class="an-bn-btn" ${btn}>Annehmen</span></div>
|
||||
</div>`
|
||||
}
|
||||
|
||||
function renderAnalyseActivation(stage, project, reload) {
|
||||
const MISSING_PRIVACY_HINT = 'Für die Zusatzseite fehlen in Deinen Kundendaten Firma oder Name und eine gültige E-Mail-Adresse. Schreib uns im Chat, wir ergänzen sie.'
|
||||
|
||||
// Vorschau der Verantwortlichen-Angaben; sind sie unvollstaendig, bleibt "Analyse einschalten" gesperrt
|
||||
function controllerBlock(controller) {
|
||||
if (controller.ok !== true) return `<p class="error an-missing" id="an-missing" role="alert">${esc(MISSING_PRIVACY_HINT)}</p>`
|
||||
return `<div class="an-ctl" id="an-ctl"><p>Auf der Datenschutz-Zusatzseite Deiner Website erscheinen als Verantwortlicher:</p><p><strong>${controllerLines(controller).map(esc).join(' · ')}</strong></p><p>Stimmt etwas nicht? Schreib uns im Chat, bevor Du einschaltest.</p></div>`
|
||||
}
|
||||
|
||||
export function renderAnalyseActivation(stage, project, reload) {
|
||||
const a = analyseOf(project)
|
||||
const legal = a.legal || {}
|
||||
const controller = a.controller || { ok: false }
|
||||
let color = HEX_RE.test(a.accentColor || '') ? a.accentColor.toLowerCase() : '#111111'
|
||||
stage.innerHTML = `
|
||||
<div class="kb-panel an-panel">
|
||||
<h3>Analyse für ${esc(project.projectName)} einschalten</h3>
|
||||
<p>Du siehst, wie oft deine Website aufgerufen wird, woher die Besucher kommen und was sie sich ansehen. Wir speichern <strong>keine IP-Adressen</strong> und setzen <strong>keine Cookies</strong>. Alles läuft auf einem eigenen Server in Deutschland.</p>
|
||||
<ul class="kb-checks">
|
||||
<li>Ohne Zustimmung zählen wir nur, wie oft eine Seite aufgerufen wird – anonym, ohne Wiedererkennung.</li>
|
||||
<li>Mit Zustimmung kommen Besucher, Verweildauer, Klicks und Heatmaps dazu.</li>
|
||||
<li>Auf deiner Website erscheint dafür ein Hinweis-Banner mit „Ablehnen“ und „Annehmen“.</li>
|
||||
</ul>
|
||||
<p>Du siehst, wie oft deine Website aufgerufen wird, woher die Besucher kommen und was sie sich ansehen.</p>
|
||||
<p>Ohne Zustimmung der Besucher zählen wir nur Seitenaufrufe mit Land und Geräteklasse, ohne Kennung. Wer zustimmt, wird zusätzlich mit Herkunftsseite, Verweildauer, Scrolltiefe und Klicks gemessen. Wir speichern keine IP-Adressen und setzen keine Cookies. Die Messung läuft auf unserem Server bei Hetzner in Deutschland. Wer ablehnt, wird nicht weiter gemessen; gezählt wird nur, dass abgelehnt wurde.</p>
|
||||
<h4 class="an-h4">Farbe des Banners</h4>
|
||||
<div class="an-colors">
|
||||
<input type="color" id="an-color" value="${esc(color)}" aria-label="Farbe wählen">
|
||||
@@ -616,7 +621,8 @@ function renderAnalyseActivation(stage, project, reload) {
|
||||
</div>
|
||||
<p class="an-hint hidden" id="an-hint">Diese Farbe ist für weiße Schrift zu hell. Der Banner nutzt dann Schwarz (#111111).</p>
|
||||
<div id="an-preview"></div>
|
||||
<label class="fn-consent"><input type="checkbox" id="an-avv"><span>Ich beauftrage WEBklar mit der Verarbeitung der Analysedaten gemäß Auftragsverarbeitungsvertrag (Fassung ${esc(a.avvVersion)}). <a href="${esc(AVV_URL)}" target="_blank" rel="noopener">AVV lesen</a></span></label>
|
||||
${controllerBlock(controller)}
|
||||
<label class="fn-consent"><input type="checkbox" id="an-avv"><span>Ich beauftrage WEBklar mit der Website-Analyse und stimme dem <a href="${esc(legal.avv || '')}" target="_blank" rel="noopener">Auftragsverarbeitungsvertrag Website-Analyse</a> und der <a href="${esc(legal.lb || '')}" target="_blank" rel="noopener">Leistungsbeschreibung Website-Analyse</a> (Fassung ${esc(a.avvVersion)}) zu. Meine Website richtet sich nicht gezielt an Kinder unter 16 Jahren.</span></label>
|
||||
<p class="error hidden" id="an-error" role="alert"></p>
|
||||
<div class="abo-actions"><button type="button" class="abo-btn" id="an-on" disabled>Analyse einschalten</button></div>
|
||||
</div>`
|
||||
@@ -632,9 +638,9 @@ function renderAnalyseActivation(stage, project, reload) {
|
||||
const box = stage.querySelector('#an-avv')
|
||||
const button = stage.querySelector('#an-on')
|
||||
const error = stage.querySelector('#an-error')
|
||||
box.addEventListener('change', () => { button.disabled = !box.checked })
|
||||
box.addEventListener('change', () => { button.disabled = !box.checked || controller.ok !== true })
|
||||
button.addEventListener('click', async () => {
|
||||
if (!box.checked) return
|
||||
if (!box.checked || controller.ok !== true) return
|
||||
button.disabled = true
|
||||
error.classList.add('hidden')
|
||||
try {
|
||||
@@ -643,7 +649,7 @@ function renderAnalyseActivation(stage, project, reload) {
|
||||
} catch (err) {
|
||||
error.textContent = err.message
|
||||
error.classList.remove('hidden')
|
||||
button.disabled = !box.checked
|
||||
button.disabled = !box.checked || controller.ok !== true
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -757,10 +763,10 @@ function renderAnalyseHeat(box, projectId, pages) {
|
||||
}
|
||||
|
||||
// Ausschalten mit Bestaetigung in der Seite (zweiter Klick), ohne Browser-Dialog
|
||||
function renderAnalyseOff(box, projectId, reload) {
|
||||
export function renderAnalyseOff(box, projectId, reload) {
|
||||
box.innerHTML = `
|
||||
<h3>Analyse ausschalten</h3>
|
||||
<p>Danach werden keine neuen Daten mehr gesammelt und der Banner verschwindet von deiner Website. Die bisherigen Daten bleiben noch 60 Tage erhalten.</p>
|
||||
<p>Danach werden keine neuen Daten mehr gespeichert, und das Banner erscheint nicht mehr. Skript und Zusatzseite entfernen wir mit der nächsten Veröffentlichung Deiner Website, in der Regel sofort. Die bisherigen Daten löschen wir nach 60 Tagen; bis zum 46. Tag kannst Du eine Kopie anfordern.</p>
|
||||
<p class="error hidden" id="an-off-error" role="alert"></p>
|
||||
<div class="nw-confirm" id="an-off-actions"><button type="button" class="an-ghost" id="an-off-ask">Analyse ausschalten</button></div>`
|
||||
const actions = box.querySelector('#an-off-actions')
|
||||
@@ -772,7 +778,11 @@ function renderAnalyseOff(box, projectId, reload) {
|
||||
ev.currentTarget.disabled = true
|
||||
try {
|
||||
await request('/api/funktionen/analyse/deactivate', { method: 'POST', body: { projectId } })
|
||||
reload()
|
||||
box.innerHTML = `
|
||||
<h3>Analyse ausgeschaltet</h3>
|
||||
<p id="an-off-done">Die Website-Analyse ist ausgeschaltet. Ab jetzt werden keine Daten mehr gespeichert.</p>
|
||||
<div class="abo-actions"><button type="button" class="abo-btn" id="an-off-ok">OK</button></div>`
|
||||
box.querySelector('#an-off-ok').addEventListener('click', () => reload())
|
||||
} catch (err) {
|
||||
renderAnalyseOff(box, projectId, reload)
|
||||
const e2 = box.querySelector('#an-off-error')
|
||||
|
||||
Reference in new issue
Block a user