generated from knso/webklar-preview-template
Worker (/demo auf behoerdenklar-proxy): - Turnstile-Verifikation serverseitig (Bot-Mauer) - Analyse 1 anonym (1x pro IP/30 Tage), Analyse 2 nur mit E-Mail (SHA-256-Hash mit Pepper, dauerhaft — nie Klartext gespeichert) - IP-Gesamtlimit 3/30 Tage, globales Tagesbudget 100 (~2,50 EUR Deckel) - Wegwerf-Mail-Blockliste, 5-MB-Limit, CORS nur eigene Domain - Prompt/Schema identisch zur App (ohne Antwort-Generator) Webseite: - demo.html im Papier-Design: Einwilligung, Upload mit Client-Downscaling (2000px/JPEG wie App), Ampel-Logik, Ergebnis-Karten, Warteliste-CTA mit vorbelegter E-Mail, gestaffelter Ablauf 1. anonym / 2. mit E-Mail - Startseite verlinkt Demo im Hero - Datenschutz: neuer Abschnitt 8 Gratis-Demo (Einwilligung, Turnstile, E-Mail-Hash), Folgeabschnitte neu nummeriert; Sitemap + /demo Ende-zu-Ende getestet: echte Analyse (Jobcenter-Testbrief korrekt erklärt, Ampel erkennt fruehere Absagefrist), Schummler-Szenarien (Browser-Loeschen, doppelte E-Mail) serverseitig abgefangen. Dabei entdeckt: Anthropic-Key war ungueltig -> erneuert (App-Analyse funktionierte wieder). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
551 lines
24 KiB
HTML
551 lines
24 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Gratis-Demo: Behördenbrief online erklären lassen | BehördenKlar</title>
|
|
<meta name="description" content="Testen Sie BehördenKlar direkt im Browser: Brief fotografieren, hochladen, in einfacher Sprache erklärt bekommen. 2 Analysen gratis, ohne Konto.">
|
|
<link rel="canonical" href="https://behoerdenklar.pages.dev/demo">
|
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
|
<meta property="og:site_name" content="BehördenKlar">
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:locale" content="de_DE">
|
|
<meta property="og:url" content="https://behoerdenklar.pages.dev/demo">
|
|
<meta property="og:title" content="Probieren Sie es aus: Ihr Behördenbrief, einfach erklärt">
|
|
<meta property="og:description" content="Direkt im Browser testen — 2 Gratis-Analysen, ohne Konto. Brief fotografieren, Klartext lesen.">
|
|
<meta property="og:image" content="https://behoerdenklar.pages.dev/vorschau.png">
|
|
<meta property="og:image:width" content="1200">
|
|
<meta property="og:image:height" content="630">
|
|
<meta name="twitter:card" content="summary_large_image">
|
|
<style>
|
|
:root {
|
|
--papier: #faf7f0;
|
|
--papier-dunkel: #f1ecdf;
|
|
--tinte: #21211d;
|
|
--grau: #6b675e;
|
|
--amtsblau: #1d4e89;
|
|
--stempelrot: #b3372b;
|
|
--marker: #ffe66b;
|
|
--gruen: #2e7d4f;
|
|
--rot: #b3372b;
|
|
--gelb: #a06b00;
|
|
color-scheme: light;
|
|
}
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
html { scroll-behavior: smooth; }
|
|
body {
|
|
font-family: Georgia, 'Times New Roman', serif;
|
|
background:
|
|
repeating-linear-gradient(0deg, transparent 0 34px, rgba(33, 33, 29, 0.025) 34px 35px),
|
|
var(--papier);
|
|
color: var(--tinte);
|
|
line-height: 1.7;
|
|
font-size: 17px;
|
|
}
|
|
.mono { font-family: 'Courier New', ui-monospace, monospace; letter-spacing: 0.02em; }
|
|
.wrap { max-width: 720px; margin: 0 auto; padding: 0 20px 72px; }
|
|
|
|
.briefkopf {
|
|
display: flex; justify-content: space-between; align-items: baseline;
|
|
padding: 20px 0 12px; border-bottom: 2px solid var(--tinte);
|
|
font-size: 14px;
|
|
}
|
|
.briefkopf .absender { font-weight: 700; font-size: 16px; }
|
|
.briefkopf .absender a { color: inherit; text-decoration: none; }
|
|
.briefkopf .az { color: var(--grau); font-size: 13px; }
|
|
|
|
header { padding: 40px 0 8px; }
|
|
.betreff-label {
|
|
font-size: 13px; color: var(--grau); text-transform: uppercase;
|
|
letter-spacing: 0.14em; margin-bottom: 10px;
|
|
}
|
|
h1 {
|
|
font-size: clamp(30px, 6vw, 44px);
|
|
line-height: 1.15; font-weight: 700; letter-spacing: -0.01em;
|
|
}
|
|
.markiert {
|
|
background: linear-gradient(104deg, transparent 2%, var(--marker) 4%, var(--marker) 96%, transparent 98%);
|
|
padding: 0 6px; box-decoration-break: clone; -webkit-box-decoration-break: clone;
|
|
}
|
|
.anrede { margin-top: 20px; font-size: 18px; max-width: 580px; }
|
|
|
|
section { margin-top: 44px; }
|
|
h2 {
|
|
font-size: 15px; text-transform: uppercase; letter-spacing: 0.14em;
|
|
color: var(--grau); font-weight: 400; margin-bottom: 20px;
|
|
display: flex; align-items: center; gap: 12px;
|
|
}
|
|
h2::after { content: ''; flex: 1; border-top: 1px solid rgba(33,33,29,0.25); }
|
|
h2 .nr { font-family: 'Courier New', ui-monospace, monospace; }
|
|
|
|
.antrag {
|
|
background: #fff; border: 2px solid var(--tinte);
|
|
box-shadow: 7px 8px 0 rgba(33, 33, 29, 0.9);
|
|
padding: 28px 26px; position: relative;
|
|
}
|
|
.formular-kopf {
|
|
font-family: 'Courier New', ui-monospace, monospace;
|
|
font-size: 13px; text-transform: uppercase; letter-spacing: 0.1em;
|
|
color: var(--grau); margin-bottom: 10px;
|
|
}
|
|
.cta {
|
|
display: inline-block; width: 100%; padding: 17px 30px;
|
|
background: var(--amtsblau); color: #fff; text-decoration: none;
|
|
font-family: inherit; font-size: 18px; font-weight: 700; text-align: center;
|
|
border: 2px solid var(--tinte);
|
|
box-shadow: 5px 5px 0 var(--tinte);
|
|
transition: transform 0.12s ease, box-shadow 0.12s ease;
|
|
cursor: pointer;
|
|
}
|
|
.cta:hover:not(:disabled) { transform: translate(2px, 2px); box-shadow: 3px 3px 0 var(--tinte); }
|
|
.cta:disabled { opacity: 0.45; cursor: not-allowed; }
|
|
|
|
.konsens {
|
|
display: flex; gap: 12px; align-items: flex-start;
|
|
font-size: 15px; color: var(--grau); margin: 14px 0 18px;
|
|
}
|
|
.konsens input { width: 22px; height: 22px; margin-top: 4px; flex-shrink: 0; accent-color: var(--amtsblau); }
|
|
.konsens a { color: var(--amtsblau); }
|
|
|
|
.klein { font-size: 13.5px; color: var(--grau); margin-top: 12px; }
|
|
.klein a { color: var(--grau); }
|
|
|
|
.status { text-align: center; padding: 26px 10px; display: none; }
|
|
.status .gross { font-size: 20px; font-weight: 700; }
|
|
.status .sub { color: var(--grau); margin-top: 6px; font-size: 15px; }
|
|
.sanduhr {
|
|
display: inline-block; font-size: 34px;
|
|
animation: drehen 2.4s linear infinite;
|
|
}
|
|
@keyframes drehen { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
|
|
|
|
.fehlerbox {
|
|
display: none; margin-top: 16px;
|
|
border: 2px solid var(--stempelrot); background: #fdf1ef;
|
|
color: #7c2018; padding: 14px 16px; font-size: 16px;
|
|
}
|
|
|
|
.email-teil { display: none; margin-top: 16px; }
|
|
.wl-input {
|
|
width: 100%; padding: 15px 16px; font-size: 17px; font-family: inherit;
|
|
border: 2px solid var(--tinte); background: #fff; color: var(--tinte);
|
|
margin-bottom: 12px;
|
|
}
|
|
.wl-input::placeholder { color: #9a958a; }
|
|
|
|
/* Ergebnis */
|
|
#ergebnis { display: none; }
|
|
.brief-karte {
|
|
background: #fff; border: 1px solid rgba(33, 33, 29, 0.28);
|
|
padding: 22px 24px; position: relative; margin-top: 22px;
|
|
box-shadow: 4px 5px 0 rgba(33, 33, 29, 0.08);
|
|
}
|
|
.karten-label {
|
|
position: absolute; top: -12px; left: 16px;
|
|
font-family: 'Courier New', ui-monospace, monospace; font-size: 12px;
|
|
text-transform: uppercase; letter-spacing: 0.1em;
|
|
background: var(--gruen); color: var(--papier); padding: 3px 10px;
|
|
}
|
|
.karten-label.neutral { background: var(--tinte); }
|
|
.ampelzeile {
|
|
margin-top: 14px; padding-top: 12px;
|
|
border-top: 1px dashed rgba(33, 33, 29, 0.3);
|
|
font-size: 16px; font-weight: 700;
|
|
}
|
|
.todo { padding: 8px 0 8px 2px; border-bottom: 1px dotted rgba(33,33,29,0.3); font-size: 16.5px; }
|
|
.todo::before { content: '☐'; margin-right: 10px; color: var(--amtsblau); font-size: 18px; }
|
|
details { border-bottom: 1px solid rgba(33, 33, 29, 0.2); padding: 12px 4px; }
|
|
summary { font-weight: 700; cursor: pointer; font-size: 16.5px; list-style: none; }
|
|
summary::-webkit-details-marker { display: none; }
|
|
details p { margin-top: 8px; color: var(--grau); font-size: 15.5px; }
|
|
|
|
.stempel {
|
|
display: inline-block; padding: 7px 14px;
|
|
border: 2.5px solid var(--stempelrot); color: var(--stempelrot);
|
|
font-family: 'Courier New', ui-monospace, monospace; font-weight: 700;
|
|
font-size: 14px; letter-spacing: 0.1em; text-transform: uppercase;
|
|
transform: rotate(-4deg); opacity: 0.9;
|
|
}
|
|
.hinweis-recht {
|
|
margin-top: 18px; font-size: 14px; color: var(--grau);
|
|
border-top: 1px dashed rgba(33,33,29,0.3); padding-top: 12px;
|
|
}
|
|
|
|
/* Warteliste-Formular (wie Startseite) */
|
|
.wl-form { display: flex; flex-direction: column; gap: 12px; margin-top: 4px; }
|
|
.bonus-zeile {
|
|
margin: 14px 0; padding: 12px 16px;
|
|
background: linear-gradient(104deg, transparent 1%, var(--marker) 3%, var(--marker) 97%, transparent 99%);
|
|
font-size: 16px;
|
|
}
|
|
footer { margin-top: 48px; font-size: 14.5px; color: var(--grau); }
|
|
footer a { color: var(--grau); }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="wrap">
|
|
|
|
<div class="briefkopf">
|
|
<span class="absender"><a href="index.html">📬 BehördenKlar</a></span>
|
|
<span class="az mono">Formular D-01 · Gratis-Demo</span>
|
|
</div>
|
|
|
|
<header>
|
|
<p class="betreff-label">Betreff</p>
|
|
<h1>Probieren Sie es aus —<br><span class="markiert">mit Ihrem eigenen Brief.</span></h1>
|
|
<p class="anrede">
|
|
Kein Konto. Keine App-Installation. Laden Sie ein Foto Ihres
|
|
Behördenbriefs hoch — in etwa einer Minute lesen Sie ihn in einfacher
|
|
Sprache. <strong>2 Analysen gratis.</strong>
|
|
</p>
|
|
</header>
|
|
|
|
<section id="demo">
|
|
<h2><span class="nr">§ 1</span> Brief hochladen</h2>
|
|
<div class="antrag">
|
|
<p class="formular-kopf">Antrag auf Klartext · 2 Gratis-Analysen</p>
|
|
|
|
<div id="eingabe">
|
|
<label class="konsens">
|
|
<input type="checkbox" id="konsens">
|
|
<span>
|
|
Ich bin einverstanden, dass mein Brief-Foto zur Analyse an den
|
|
Server von BehördenKlar und an den KI-Dienst Anthropic (USA)
|
|
geschickt wird. Es wird dort nicht dauerhaft gespeichert.
|
|
Behördenbriefe enthalten persönliche Daten — laden Sie nur hoch,
|
|
was Sie analysieren lassen möchten.
|
|
<a href="datenschutz.html" target="_blank">Datenschutzerklärung</a>
|
|
</span>
|
|
</label>
|
|
|
|
<div id="emailTeil" class="email-teil">
|
|
<p style="margin-bottom: 10px;">
|
|
🎉 <strong>Ihre erste Analyse ist verbraucht.</strong> Für die
|
|
zweite geben Sie bitte Ihre E-Mail-Adresse ein — so stellen wir
|
|
sicher, dass jeder genau 2 Gratis-Analysen bekommt.
|
|
</p>
|
|
<input class="wl-input" type="email" id="email" placeholder="Ihre E-Mail-Adresse" autocomplete="email">
|
|
<p class="klein" style="margin: 0 0 12px;">
|
|
Die Adresse wird nur verschlüsselt (als Prüfsumme) gespeichert,
|
|
um mitzuzählen — Sie bekommen dadurch keine E-Mails von uns.
|
|
</p>
|
|
</div>
|
|
|
|
<input type="file" id="datei" accept="image/jpeg,image/png,application/pdf" style="display: none;">
|
|
<button class="cta" id="startKnopf" disabled>📷 Brief auswählen & erklären lassen</button>
|
|
|
|
<div class="cf-turnstile" data-sitekey="0x4AAAAAAD8vfEq7X2EX-Krk" data-action="turnstile-spin-v1" style="margin-top: 14px;"></div>
|
|
|
|
<p class="klein">
|
|
Geht mit Foto (JPG/PNG) oder PDF, max. 5 MB. Tipp: gutes Licht,
|
|
Brief von oben, ganzer Text im Bild.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="status" id="status">
|
|
<span class="sanduhr">⏳</span>
|
|
<p class="gross">Ihr Brief wird analysiert…</p>
|
|
<p class="sub">Das dauert bis zu einer Minute. Bitte lassen Sie die Seite geöffnet.</p>
|
|
</div>
|
|
|
|
<div class="fehlerbox" id="fehler"></div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="ergebnis">
|
|
<h2><span class="nr">§ 2</span> Ihr Brief in Klartext</h2>
|
|
|
|
<div class="brief-karte">
|
|
<span class="karten-label neutral" id="ergBrieftyp">Brief</span>
|
|
<p style="margin-top: 6px;"><strong id="ergKern"></strong></p>
|
|
<p class="ampelzeile" id="ergAmpel" style="display: none;"></p>
|
|
</div>
|
|
|
|
<div class="brief-karte">
|
|
<span class="karten-label">Einfach erklärt</span>
|
|
<p id="ergErklaerung" style="white-space: pre-line;"></p>
|
|
</div>
|
|
|
|
<div class="brief-karte" id="ergChecklisteKarte" style="display: none;">
|
|
<span class="karten-label neutral">Das müssen Sie tun</span>
|
|
<div id="ergCheckliste"></div>
|
|
</div>
|
|
|
|
<div class="brief-karte" id="ergBegriffeKarte" style="display: none;">
|
|
<span class="karten-label neutral">Schwere Wörter erklärt</span>
|
|
<div id="ergBegriffe"></div>
|
|
</div>
|
|
|
|
<p class="hinweis-recht">
|
|
⚖️ BehördenKlar erklärt Briefe, ersetzt aber keine Rechtsberatung. Bei
|
|
wichtigen Entscheidungen hilft eine Beratungsstelle oder ein Anwalt.
|
|
</p>
|
|
</section>
|
|
|
|
<section id="werbung" style="display: none;">
|
|
<h2><span class="nr">§ 3</span> Wie geht es weiter?</h2>
|
|
<div class="antrag">
|
|
<p class="formular-kopf" id="restZeile">Warteliste</p>
|
|
<h3 id="wlTitel" style="font-size: 24px; line-height: 1.3;">Das hat Ihnen geholfen?</h3>
|
|
<p style="margin-top: 10px;">
|
|
Die App kann noch mehr: Briefe <strong>übersetzen in 9 Sprachen</strong>,
|
|
Fristen mit <strong>Erinnerung</strong>, fertige
|
|
<strong>Antwort-Entwürfe</strong> — und Ihre Briefe bleiben
|
|
verschlüsselt auf Ihrem Handy gespeichert.
|
|
</p>
|
|
<p class="bonus-zeile">
|
|
🎁 Warteliste = <strong>5 Gratis-Analysen</strong> in der App statt 3.
|
|
</p>
|
|
<p id="nochmalZeile" style="display: none; margin-bottom: 14px;">
|
|
<a href="#demo" style="color: var(--amtsblau); font-weight: 700;">↑ Noch einen
|
|
Brief testen? Ihre zweite Gratis-Analyse wartet oben.</a>
|
|
</p>
|
|
<form class="wl-form" action="https://86550585.sibforms.com/serve/MUIFAAvOQCpFg148k-xD2Ze2PDVKKaFEIaLECCCMe9fGKd_uIurPljyn_IhTrkR0EkM_pQp_8VBzcHZ6N9sKDX5GBZi9elYKN6isXGPUUxcAgO37OKhTFZyMlJiC9ikRmPI8Q2tU2GvqP6esJ5ReGfv1htZV_OfXRIgW59P6pkeUsYKxqdXA7nWOaWxNTYz4MzzoGg7czJMJ2fxuEg==" method="POST">
|
|
<input class="wl-input" style="margin-bottom: 0;" type="email" name="EMAIL" id="wlEmail" placeholder="Ihre E-Mail-Adresse" required autocomplete="email">
|
|
<input type="text" name="email_address_check" value="" style="position:absolute; left:-5000px;" tabindex="-1" autocomplete="off" aria-hidden="true">
|
|
<input type="hidden" name="locale" value="de">
|
|
<input type="hidden" name="html_type" value="simple">
|
|
<button class="cta" type="submit">Auf die Warteliste eintragen →</button>
|
|
</form>
|
|
<p class="klein">
|
|
Eine E-Mail zum Start, keine Werbung, jederzeit abmeldbar —
|
|
<a href="datenschutz.html">Datenschutzerklärung</a>.
|
|
</p>
|
|
<div style="margin-top: 16px;"><span class="stempel">Bald im App Store</span></div>
|
|
</div>
|
|
</section>
|
|
|
|
<footer>
|
|
<a href="index.html">← Zur Startseite</a> ·
|
|
<a href="impressum.html">Impressum</a> ·
|
|
<a href="datenschutz.html">Datenschutzerklärung</a>
|
|
</footer>
|
|
|
|
</div>
|
|
|
|
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
|
|
<script>
|
|
(function () {
|
|
'use strict';
|
|
var ENDPUNKT = 'https://behoerdenklar-proxy.behoerdenbrief.workers.dev/demo';
|
|
var MAX_KANTE = 2000; // wie in der App: reicht für A4, spart Datenvolumen
|
|
|
|
var konsens = document.getElementById('konsens');
|
|
var startKnopf = document.getElementById('startKnopf');
|
|
var dateiFeld = document.getElementById('datei');
|
|
var emailTeil = document.getElementById('emailTeil');
|
|
var emailFeld = document.getElementById('email');
|
|
var status = document.getElementById('status');
|
|
var eingabe = document.getElementById('eingabe');
|
|
var fehlerBox = document.getElementById('fehler');
|
|
|
|
function benutzt() { return parseInt(localStorage.getItem('bk_demo_benutzt') || '0', 10); }
|
|
function setzeBenutzt(n) { localStorage.setItem('bk_demo_benutzt', String(n)); }
|
|
|
|
function zeigeStand() {
|
|
// 2. Versuch: E-Mail-Feld einblenden; alles verbraucht: Eingabe sperren
|
|
if (benutzt() >= 2) {
|
|
eingabe.style.display = 'none';
|
|
fehlerBox.style.display = 'block';
|
|
fehlerBox.innerHTML = 'Ihre 2 Gratis-Analysen sind verbraucht. 🎁 In der <strong>App</strong> gibt es 3 weitere gratis — mit Warteliste sogar 5. Tragen Sie sich unten ein!';
|
|
document.getElementById('werbung').style.display = 'block';
|
|
} else if (benutzt() === 1) {
|
|
emailTeil.style.display = 'block';
|
|
}
|
|
}
|
|
|
|
konsens.addEventListener('change', function () { startKnopf.disabled = !konsens.checked; });
|
|
startKnopf.addEventListener('click', function () {
|
|
fehlerBox.style.display = 'none';
|
|
if (benutzt() >= 1 && !emailFeld.value.trim()) {
|
|
emailTeil.style.display = 'block';
|
|
emailFeld.focus();
|
|
zeigeFehler('Bitte geben Sie zuerst Ihre E-Mail-Adresse ein — dann wählen Sie den Brief aus.');
|
|
return;
|
|
}
|
|
dateiFeld.click();
|
|
});
|
|
dateiFeld.addEventListener('change', function () {
|
|
if (dateiFeld.files && dateiFeld.files[0]) starteAnalyse(dateiFeld.files[0]);
|
|
});
|
|
|
|
function zeigeFehler(text) {
|
|
fehlerBox.style.display = 'block';
|
|
fehlerBox.textContent = text;
|
|
}
|
|
|
|
function turnstileToken() {
|
|
var feld = document.querySelector('[name="cf-turnstile-response"]');
|
|
return feld ? feld.value : '';
|
|
}
|
|
|
|
/** Foto verkleinern (max 2000px, JPEG 60%) — wie in der App. */
|
|
function bildVerkleinern(datei) {
|
|
return new Promise(function (resolve, reject) {
|
|
var img = new Image();
|
|
var url = URL.createObjectURL(datei);
|
|
img.onload = function () {
|
|
URL.revokeObjectURL(url);
|
|
var f = Math.min(1, MAX_KANTE / Math.max(img.width, img.height));
|
|
var c = document.createElement('canvas');
|
|
c.width = Math.round(img.width * f);
|
|
c.height = Math.round(img.height * f);
|
|
c.getContext('2d').drawImage(img, 0, 0, c.width, c.height);
|
|
resolve(c.toDataURL('image/jpeg', 0.6).split(',')[1]);
|
|
};
|
|
img.onerror = function () { URL.revokeObjectURL(url); reject(new Error('Bild unlesbar')); };
|
|
img.src = url;
|
|
});
|
|
}
|
|
|
|
function pdfAlsBase64(datei) {
|
|
return new Promise(function (resolve, reject) {
|
|
var leser = new FileReader();
|
|
leser.onload = function () { resolve(String(leser.result).split(',')[1]); };
|
|
leser.onerror = function () { reject(new Error('Datei unlesbar')); };
|
|
leser.readAsDataURL(datei);
|
|
});
|
|
}
|
|
|
|
async function starteAnalyse(datei) {
|
|
fehlerBox.style.display = 'none';
|
|
if (datei.size > 5 * 1024 * 1024 && datei.type === 'application/pdf') {
|
|
zeigeFehler('Die PDF-Datei ist zu groß (max. 5 MB). Tipp: Fotografieren Sie den Brief stattdessen.');
|
|
return;
|
|
}
|
|
var token = turnstileToken();
|
|
if (!token) {
|
|
zeigeFehler('Die Sicherheitsprüfung lädt noch — bitte warten Sie 2 Sekunden und versuchen Sie es erneut.');
|
|
return;
|
|
}
|
|
|
|
eingabe.style.display = 'none';
|
|
status.style.display = 'block';
|
|
|
|
try {
|
|
var istPdf = datei.type === 'application/pdf';
|
|
var base64 = istPdf ? await pdfAlsBase64(datei) : await bildVerkleinern(datei);
|
|
var body = {
|
|
bild: base64,
|
|
mimeType: istPdf ? 'application/pdf' : 'image/jpeg',
|
|
turnstileToken: token,
|
|
};
|
|
var email = emailFeld.value.trim();
|
|
if (benutzt() >= 1 && email) body.email = email;
|
|
|
|
var antwort = await fetch(ENDPUNKT, {
|
|
method: 'POST',
|
|
headers: { 'content-type': 'application/json' },
|
|
body: JSON.stringify(body),
|
|
});
|
|
var daten = await antwort.json();
|
|
|
|
if (!antwort.ok) {
|
|
status.style.display = 'none';
|
|
eingabe.style.display = 'block';
|
|
if (window.turnstile) window.turnstile.reset();
|
|
if (daten.code === 'email_noetig') {
|
|
setzeBenutzt(Math.max(benutzt(), 1));
|
|
emailTeil.style.display = 'block';
|
|
emailFeld.focus();
|
|
}
|
|
if (daten.code === 'aufgebraucht') {
|
|
setzeBenutzt(2);
|
|
zeigeStand();
|
|
return;
|
|
}
|
|
zeigeFehler(daten.meldung || 'Etwas ist schiefgelaufen. Bitte erneut versuchen.');
|
|
return;
|
|
}
|
|
|
|
setzeBenutzt(Math.max(benutzt(), daten.versuch));
|
|
if (email) document.getElementById('wlEmail').value = email;
|
|
// Token erneuern — sonst würde die 2. Analyse ein "Seite neu laden" verlangen
|
|
if (window.turnstile) window.turnstile.reset();
|
|
zeigeErgebnis(daten.analyse, daten.versuch);
|
|
} catch (e) {
|
|
status.style.display = 'none';
|
|
eingabe.style.display = 'block';
|
|
if (window.turnstile) window.turnstile.reset();
|
|
zeigeFehler('Verbindung fehlgeschlagen. Bitte prüfen Sie Ihr Internet und versuchen Sie es erneut.');
|
|
}
|
|
}
|
|
|
|
/** Ampel wie in der App: rot ≤ 7 Tage, gelb ≤ 21, sonst grün. */
|
|
function ampel(analyse) {
|
|
var daten = [];
|
|
if (analyse.frist && analyse.frist.datum) daten.push(analyse.frist.datum);
|
|
if (analyse.termin && analyse.termin.datum) daten.push(analyse.termin.datum);
|
|
if (!daten.length) return null;
|
|
daten.sort();
|
|
var tage = Math.ceil((new Date(daten[0] + 'T12:00:00') - new Date()) / 86400000);
|
|
if (isNaN(tage)) return null;
|
|
var farbe = tage <= 7 ? 'var(--rot)' : tage <= 21 ? 'var(--gelb)' : 'var(--gruen)';
|
|
var punkt = tage <= 7 ? '🔴' : tage <= 21 ? '🟡' : '🟢';
|
|
var text = tage < 0 ? 'Die Frist ist womöglich schon vorbei!' :
|
|
tage === 0 ? 'HEUTE ist der wichtige Tag!' :
|
|
'Noch ' + tage + ' Tage Zeit (' + daten[0].split('-').reverse().join('.') + ')';
|
|
return { farbe: farbe, text: punkt + ' ' + text };
|
|
}
|
|
|
|
function zeigeErgebnis(analyse, versuch) {
|
|
status.style.display = 'none';
|
|
document.getElementById('ergBrieftyp').textContent = analyse.brieftyp || 'Ihr Brief';
|
|
document.getElementById('ergKern').textContent = analyse.kernaussage || '';
|
|
document.getElementById('ergErklaerung').textContent = analyse.erklaerung_einfach || '';
|
|
|
|
var a = ampel(analyse);
|
|
var ampelEl = document.getElementById('ergAmpel');
|
|
if (a) {
|
|
ampelEl.style.display = 'block';
|
|
ampelEl.style.color = a.farbe;
|
|
var teile = [a.text];
|
|
if (analyse.frist && analyse.frist.aktion) teile.push(analyse.frist.aktion);
|
|
ampelEl.textContent = teile.join(' · ');
|
|
}
|
|
|
|
if (analyse.checkliste && analyse.checkliste.length) {
|
|
document.getElementById('ergChecklisteKarte').style.display = 'block';
|
|
document.getElementById('ergCheckliste').innerHTML = analyse.checkliste
|
|
.map(function (t) { var d = document.createElement('div'); d.className = 'todo'; d.textContent = t; return d.outerHTML; })
|
|
.join('');
|
|
}
|
|
if (analyse.fachbegriffe && analyse.fachbegriffe.length) {
|
|
document.getElementById('ergBegriffeKarte').style.display = 'block';
|
|
document.getElementById('ergBegriffe').innerHTML = analyse.fachbegriffe
|
|
.map(function (b) {
|
|
var det = document.createElement('details');
|
|
var sum = document.createElement('summary');
|
|
sum.textContent = b.begriff;
|
|
var p = document.createElement('p');
|
|
p.textContent = b.erklaerung;
|
|
det.appendChild(sum); det.appendChild(p);
|
|
return det.outerHTML;
|
|
})
|
|
.join('');
|
|
}
|
|
|
|
document.getElementById('ergebnis').style.display = 'block';
|
|
var rest = 2 - benutzt();
|
|
document.getElementById('restZeile').textContent =
|
|
rest > 0 ? 'Noch ' + rest + ' Gratis-Analyse übrig' : 'Ihre 2 Gratis-Analysen sind verbraucht';
|
|
document.getElementById('wlTitel').textContent =
|
|
rest > 0 ? 'Das hat Ihnen geholfen?' : 'Weiter geht es in der App';
|
|
document.getElementById('werbung').style.display = 'block';
|
|
if (rest > 0) {
|
|
// Upload-Bereich für die 2. Analyse wieder anbieten (mit E-Mail-Feld)
|
|
eingabe.style.display = 'block';
|
|
emailTeil.style.display = 'block';
|
|
document.getElementById('nochmalZeile').style.display = 'block';
|
|
}
|
|
document.getElementById('ergebnis').scrollIntoView({ behavior: 'smooth' });
|
|
}
|
|
|
|
zeigeStand();
|
|
})();
|
|
</script>
|
|
<!-- Cloudflare Web Analytics: cookielose Reichweitenmessung, keine Nutzer-Profile -->
|
|
<script type='module' src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "11f017e9a707466b9151921db6125dde"}'></script>
|
|
</body>
|
|
</html>
|