Files
Webklar-Kundenbereich/public/dashboard.html
T
ClaudeandClaude Sonnet 5.5 43e4826ae3 Terminplaner: Portal-Ansicht, Kachel, Termine
Kachel in Funktionen (Kommt bald / Aus / Aktiv mit Anfragen-Zahl / Abgeschaltet),
Ansicht #termine als Unterseite von Funktionen: Projektauswahl, Vorlagenauswahl
beim ersten Oeffnen, Reiter-Geruest (Platzhalter fuer Leistungen, Team & Plaetze,
Einstellungen) und der Reiter Termine mit Tag/Woche/Monat, Filtern, Aktionen mit
Rueckfragen in der Seite, Termin eintragen und Zeit sperren.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-03 08:17:44 +00:00

307 lines
17 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, interactive-widget=resizes-content">
<title>Kundenbereich – WEBklar</title>
<!-- Als App auf den Homescreen: Manifest, Icons, Statusleiste (App-Ansicht auf dem Handy, kundenbereich.css) -->
<link rel="manifest" href="/manifest.webmanifest">
<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/img/apple-touch-icon.png">
<meta name="theme-color" content="#000000">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- Durchsichtige Statusleiste: der lila Hintergrund reicht bis in die Notch. Damit fixierte Leisten
trotzdem ganz unten sitzen, bleibt die Seite in der installierten App immer 1 px scrollbar
(siehe "Installierte App auf dem iPhone" in login.css/kundenbereich.css) -->
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="WEBklar">
<link rel="stylesheet" href="/login.css">
<link rel="stylesheet" href="/kundenbereich.css">
<link rel="stylesheet" href="/chat-composer.css">
<link rel="stylesheet" href="/funktionen.css">
<link rel="stylesheet" href="/termine.css">
</head>
<body class="portal-page dashboard-page kb-page">
<div class="dot-background" aria-hidden="true">
<div class="dot-pattern"></div>
<div class="dot-fade"></div>
</div>
<div class="kb-glow" aria-hidden="true"></div>
<header class="kb-header">
<!-- App-Ansicht: Zurueck aus Unterseiten (Verträge, Projektdetails; Text setzt updateAppBar), Seitentitel beim Scrollen (initAppShell) -->
<button type="button" class="kb-back hidden" id="kb-back" aria-label="Zurück zu Verträge">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15 18l-6-6 6-6"/></svg>
<span>Verträge</span>
</button>
<div class="kb-bar-title">
<a class="kb-logo" href="/dashboard.html"><svg class="kb-logo-mark" viewBox="0 0 512 512" aria-hidden="true"><rect width="512" height="512" fill="#fff"/><g transform="translate(256 256) scale(0.9) translate(-256 -256)"><ellipse cx="256" cy="256" rx="210" ry="150" fill="#111" transform="rotate(-28 256 256)"/><circle cx="356" cy="172" r="18" fill="#fff"/><path transform="translate(256 256) rotate(-28)" d="M 0,-170 C 22,-105 60,-72 120,-56 C 60,-40 22,-8 0,64 C -22,-8 -60,-40 -120,-56 C -60,-72 -22,-105 0,-170 Z" fill="#fff"/></g></svg>WEBKLAR</a>
<span class="kb-app-title" id="kb-app-title" aria-hidden="true"></span>
</div>
<div class="kb-account">
<div class="kb-account-text">
<strong id="customer-name"></strong>
<span id="customer-meta"></span>
</div>
<button type="button" class="kb-avatar" id="customer-avatar" aria-label="Mein Konto" title="Mein Konto" aria-haspopup="dialog" aria-controls="kb-sheet"></button>
</div>
</header>
<!-- Konto: auf dem Handy als Bottom-Sheet, am Desktop als Popover unter dem Avatar (initAccountSheet).
Alles zu den Verträgen und "Abmelden" steht im Kundenbereich nur hier. Einzige Ausnahme: während
der Widerrufsfrist zeigt die Vertragskarte "Vertrag widerrufen" (§ 356a BGB: hervorgehoben platziert).
Öffentlich, ohne Anmeldung: Login-Seite und Footer von webklar.com. -->
<dialog class="kb-sheet" id="kb-sheet" aria-label="Mein Konto">
<div class="kb-sheet-panel">
<div class="kb-sheet-grip" aria-hidden="true"></div>
<div class="kb-sheet-me">
<span class="kb-avatar" id="kb-sheet-avatar" aria-hidden="true"></span>
<div class="kb-sheet-me-text">
<strong id="kb-sheet-name">Mein Konto</strong>
<span id="kb-sheet-meta"></span>
</div>
<button type="button" class="kb-sheet-x" data-sheet-close aria-label="Schließen">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg>
</button>
</div>
<!-- App-Ansicht: hierher wandert die Karte "Dein Ansprechpartner" aus der Seitenleiste -->
<div id="kb-contact-slot"></div>
<div class="kb-install hidden" data-install></div>
<p class="kb-label kb-sheet-label">Verträge</p>
<nav class="kb-sheet-links" aria-label="Verträge">
<button type="button" data-view="vertraege">Mein Vertrag</button>
<!-- Nur mit Abo: Stripe-Kundenportal; Name wie in den Bedingungen § 7 ("Abo verwalten") -->
<button type="button" class="kb-sheet-ext hidden" id="kb-sheet-abo">Abo verwalten &amp; Rechnungen</button>
<a href="/abo-bedingungen.html" target="_blank" rel="noopener" id="kb-sheet-terms">Vertragsbedingungen</a>
<a class="legal-strong" href="/kuendigen.html">Verträge hier kündigen</a>
<a class="legal-strong" href="/widerrufen.html">Vertrag widerrufen</a>
</nav>
<p class="error hidden" id="kb-sheet-error"></p>
<p class="kb-label kb-sheet-label">Konto</p>
<nav class="kb-sheet-links" aria-label="Konto">
<button type="button" data-view="passwort">Passwort ändern</button>
</nav>
<nav class="kb-sheet-links" aria-label="Rechtliches">
<a href="/datenschutz.html" target="_blank" rel="noopener">Datenschutz</a>
<a href="https://webklar.com/impressum" target="_blank" rel="noopener">Impressum</a>
</nav>
<button type="button" class="kb-sheet-logout" id="kb-sheet-logout">Abmelden</button>
</div>
</dialog>
<div class="kb-shell dashboard-content-reveal">
<!-- Seitenleiste: Navigation, Ansprechpartner, Abo-Karte. In der App-Ansicht (Handy)
wird die Navigation zur Tab-Leiste unten; die Karten wandern in Konto-Sheet bzw. Tab "Verträge". -->
<aside class="kb-side">
<p class="kb-label">Kundenbereich</p>
<nav class="kb-nav" aria-label="Kundenbereich">
<button type="button" class="kb-nav-item active" data-view="projects">
<svg class="kb-tab-ico" viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="4" width="18" height="16" rx="3"/><path d="M3 9h18M6.5 6.5h.01M9.5 6.5h.01"/></svg>
<span class="kb-tab-label">Projekte</span> <span class="kb-count" id="projects-count"></span></button>
<button type="button" class="kb-nav-item" data-view="funktionen">
<svg class="kb-tab-ico" viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="3" width="7.5" height="7.5" rx="2"/><rect x="13.5" y="3" width="7.5" height="7.5" rx="2"/><rect x="3" y="13.5" width="7.5" height="7.5" rx="2"/><path d="M17.25 13.5v7.5M13.5 17.25H21"/></svg>
<span class="kb-tab-label">Funktionen</span></button>
<button type="button" class="kb-nav-item" data-view="invoices">
<svg class="kb-tab-ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 3h12v18l-3-2-3 2-3-2-3 2z"/><path d="M9 8h6M9 12h6M9 16h3"/></svg>
<span class="kb-tab-label">Rechnungen</span> <span class="kb-badge kb-badge-red hidden" id="invoices-badge" title="offene Rechnungen"></span></button>
<button type="button" class="kb-nav-item" data-view="chat">
<svg class="kb-tab-ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M20 14.5a2.5 2.5 0 0 1-2.5 2.5H8l-4 4V5.5A2.5 2.5 0 0 1 6.5 3h11A2.5 2.5 0 0 1 20 5.5z"/></svg>
<span class="kb-tab-label">Chat</span> <span class="kb-badge hidden" id="chat-badge" title="ungelesene Nachrichten"></span></button>
<button type="button" class="kb-nav-item kb-tab-vertraege" data-view="vertraege" id="kb-tab-vertraege">
<svg class="kb-tab-ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3l7 3v5.5c0 4.3-2.9 8.1-7 9.5-4.1-1.4-7-5.2-7-9.5V6z"/><path d="M9 12l2 2 4-4"/></svg>
<span class="kb-tab-label">Verträge</span> <span class="kb-badge hidden" id="kb-tab-vertraege-badge"></span></button>
</nav>
<section class="kb-card kb-contact" aria-label="Ansprechpartner">
<p class="kb-label">Dein Ansprechpartner</p>
<strong id="contact-name">WEBklar-Team</strong>
<span id="contact-response">Antwort meist &lt; 1 Werktag</span>
<button type="button" data-view="chat">Nachricht schreiben</button>
</section>
<!-- Abo: Angebot bzw. Status (app.js) -->
<section class="kb-abo hidden" id="abo-card" aria-live="polite"></section>
</aside>
<main class="kb-main">
<div id="viewas-banner" class="viewas-banner hidden"></div>
<p id="load-error" class="error hidden"></p>
<!-- Projekte -->
<section class="kb-view active" id="view-projects">
<header class="kb-head">
<h1>Projekte</h1>
<p id="projects-subtitle">Deine Website – Vorschau, Status und Details.</p>
</header>
<!-- App-Ansicht im Browser: Hinweis "Zum Homescreen hinzufügen" (ausblendbar) -->
<div class="kb-install kb-install-card hidden" data-install data-install-dismissible></div>
<p id="loading" class="kb-empty">Projekte werden geladen…</p>
<ul id="projects" class="kb-projects hidden"></ul>
<div id="empty" class="kb-panel kb-empty hidden">Noch keine Website-Projekte zugewiesen.</div>
<!-- Fortschritt: die neuesten Aufträge (app.js, loadCustomerActivity); Direktlink #fortschritt -->
<section class="kb-activity" id="pj-activity" aria-labelledby="pj-activity-title">
<h2 id="pj-activity-title">Was wir zuletzt erledigt haben</h2>
<div id="activity-body"><p class="kb-empty">Lade…</p></div>
</section>
</section>
<!-- App-Ansicht: Projektdetails als eigene Seite mit Zurueck zu "Projekte" (app.js, openProjectPage);
am Desktop klappen die Details in der Projektkarte auf -->
<section class="kb-view" id="view-projekt">
<header class="kb-head">
<h1>Projekt</h1>
<p>Stand des Auftrags, letzte Änderungen und Dateien.</p>
</header>
<div class="kb-details pd-page"></div>
</section>
<!-- Funktionen: Kacheln (funktionen.js, initFunktionen); News ist auf dem Handy eine Unterseite davon -->
<section class="kb-view" id="view-funktionen">
<header class="kb-head">
<h1>Funktionen</h1>
<p>Zusätzliche Bausteine für deine Website – ein Klick, wir richten sie ein.</p>
</header>
<div id="funktionen-body"><p class="kb-empty">Lade…</p></div>
</section>
<!-- News-Pinnwand: Buchung, Einrichtungsstatus oder Editor (funktionen.js, initNews) -->
<section class="kb-view" id="view-news">
<header class="kb-head">
<h1>News-Pinnwand</h1>
<p>Kurze Neuigkeiten, die auf deiner Website hängen.</p>
</header>
<div id="news-body"><p class="kb-empty">Lade…</p></div>
</section>
<!-- Analyse: Einschalten oder Auswertung (funktionen.js, initAnalyse) -->
<section class="kb-view" id="view-analyse">
<header class="kb-head">
<h1>Analyse</h1>
<p>Sieh, wie deine Website genutzt wird – ohne Cookies.</p>
</header>
<div id="analyse-body"><p class="kb-empty">Lade…</p></div>
</section>
<!-- Terminplaner: Vorlage, Termine, Leistungen, Team & Plätze, Einstellungen (termine.js, initTermine); Unterseite von Funktionen -->
<section class="kb-view" id="view-termine">
<header class="kb-head">
<h1>Terminplaner</h1>
<p>Termine, die deine Kundschaft über deine Website bucht – und was du selbst einträgst.</p>
</header>
<div id="termine-body"><p class="kb-empty">Lade…</p></div>
</section>
<!-- Rechnungen -->
<section class="kb-view" id="view-invoices">
<header class="kb-head">
<h1>Rechnungen</h1>
<p>Deine Rechnungen ansehen, bezahlen und herunterladen.</p>
</header>
<div class="kb-panel" id="invoices-body"><p class="kb-empty">Lade…</p></div>
<p class="kb-note hidden" id="invoices-abo-note">Die Zahlungsart für dein Abo änderst du über dein <button type="button" class="kb-link" data-open-account>Profilbild</button> oben rechts unter „Abo verwalten &amp; Rechnungen“.</p>
</section>
<!-- Chat -->
<section class="kb-view" id="view-chat">
<header class="kb-head">
<h1>Chat</h1>
<p>Schreib uns – wir antworten meist innerhalb eines Werktags.</p>
</header>
<div class="kb-panel chat-box">
<div class="chat-messages" id="chat-messages"></div>
<!-- Eingabezeile mit Bild, Kamera, Datei und Sprachnachricht (chat-composer.js) -->
<div id="chat-composer"></div>
<p class="chat-hint">Enter = Senden, Shift+Enter = neue Zeile. Bilder und Dateien bis 25 MB – auch per Einfügen oder Hineinziehen.</p>
</div>
</section>
<!-- Tab "Verträge": Mein Vertrag, Vergleich, Wechsel, Zusatzspeicher (app.js); in der App-Ansicht steht die Abo-Karte der Seitenleiste darüber;
Stundenkonto, Bestellung, Wechsel und Übernahmegutschrift öffnen sich als Unterseiten -->
<section class="kb-view" id="view-vertraege">
<header class="kb-head">
<h1>Verträge</h1>
<p>Ihre Verträge mit WEBklar: Hosting, Wartung und Zusatzspeicher.</p>
</header>
<div id="kb-abo-slot"><p class="kb-empty">Lade…</p></div>
<div id="kb-contracts"></div>
</section>
<!-- Stundenkonto (Wartungs-Abo), Bestellungen und Wechsel (app.js, Aufgaben 15 bis 18) -->
<section class="kb-view" id="view-stunden" aria-live="polite"></section>
<section class="kb-view" id="view-bestellen-hosting" aria-live="polite"></section>
<section class="kb-view" id="view-bestellen-wartung" aria-live="polite"></section>
<section class="kb-view" id="view-wechsel" aria-live="polite"></section>
<!-- Übernahmegutschrift (app.js) -->
<section class="kb-view" id="view-takeover">
<header class="kb-head">
<h1>Übernahmegutschrift</h1>
<p>Schon woanders bezahlt? Wir rechnen die doppelt bezahlte Zeit an.</p>
</header>
<div id="takeover-card" aria-live="polite"><p class="kb-empty">Lade…</p></div>
</section>
<!-- Passwort ändern (Konto-Menü; app.js initPasswordView). In der App-Ansicht eine Unterseite
des Tabs, aus dem das Menü geöffnet wurde -->
<section class="kb-view" id="view-passwort">
<header class="kb-head">
<h1>Passwort ändern</h1>
<p>Für deine Anmeldung im Kundenbereich.</p>
</header>
<div class="kb-panel pw-panel">
<form id="pw-form" class="pw-form" method="post" action="/api/auth/password" novalidate>
<!-- Für Passwort-Manager: zu welchem Zugang das neue Passwort gehört -->
<input type="text" id="pw-username" name="username" autocomplete="username" hidden>
<div class="tk-field">
<label for="pw-current">Aktuelles Passwort</label>
<input type="password" id="pw-current" name="current-password" autocomplete="current-password" required enterkeyhint="next">
</div>
<div class="tk-field">
<label for="pw-new">Neues Passwort</label>
<input type="password" id="pw-new" name="new-password" autocomplete="new-password" minlength="8" required aria-describedby="pw-rule" enterkeyhint="next">
<small class="pw-rule" id="pw-rule">Mindestens 8 Zeichen. Am sichersten ist ein langer Satz, den nur du kennst.</small>
</div>
<div class="tk-field">
<label for="pw-repeat">Neues Passwort wiederholen</label>
<input type="password" id="pw-repeat" name="new-password-repeat" autocomplete="new-password" required enterkeyhint="done">
</div>
<label class="abo-check pw-show"><input type="checkbox" id="pw-show"> Passwörter anzeigen</label>
<p class="error hidden" id="pw-error" role="alert"></p>
<div class="abo-actions">
<button type="submit" class="abo-btn" id="pw-submit">Passwort ändern</button>
</div>
<p class="kb-note pw-foot">Danach bist du auf deinen anderen Geräten abgemeldet. Aktuelles Passwort vergessen? <button type="button" class="kb-link" data-view="chat">Schreib uns im Chat</button> – wir setzen es zurück.</p>
</form>
<div class="pw-done hidden" id="pw-done" role="status" tabindex="-1">
<svg class="pw-done-ico" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M8 12.5l2.6 2.6L16 9.5"/></svg>
<div>
<strong>Dein Passwort wurde geändert.</strong>
<p>Melde dich ab jetzt mit dem neuen Passwort an. Auf deinen anderen Geräten bist du abgemeldet.</p>
<button type="button" class="kb-btn-outline" id="pw-done-btn">Fertig</button>
</div>
</div>
</div>
</section>
<footer class="kb-legal">
<a href="/abo-bedingungen.html" target="_blank" rel="noopener">Vertragsbedingungen</a>
<a href="/datenschutz.html" target="_blank" rel="noopener">Datenschutz</a>
<a href="https://webklar.com/impressum" target="_blank" rel="noopener">Impressum</a>
</footer>
</main>
</div>
<!-- Kundenansicht: Kennung an jeder /api-Anfrage, Hinweis bei ersetzter/abgelaufener Ansicht (vor allen anderen Skripten) -->
<script src="/kundenansicht.js"></script>
<script src="/chat-composer.js"></script>
<script src="/app.js"></script>
<script>
initDashboardPage();
</script>
</body>
</html>