Wartungs-Abo (50 EUR/Monat) ueber Stripe mit Stundenkonto im Portal
- Bestellung auf der Portal-Startseite: Zusammenfassung, AGB- und Vorab-Leistungs-Zustimmung, Button 'Zahlungspflichtig bestellen', danach Stripe Checkout (Abo, Kleinunternehmer-Fusszeile) - Stripe-Webhook /api/abo/webhook spiegelt Abos nach Appwrite (subscriptions) und schreibt je bezahlter Rechnung 60 min gut (hourCredits, idempotent ueber Invoice-ID, 12 Monate gueltig) - Stundenkonto: FIFO-Verbrauch aus Worksheets mit countsToPlan, 15-Minuten-Takt, Mehraufwand separat ausgewiesen - Stripe-Kundenportal fuer Zahlungsart/Rechnungen/Kuendigung - Oeffentlicher Kuendigungsbutton (§ 312k) und Widerrufsbutton (§ 356a) mit Eingangsbestaetigung per Mail - Abo-Bedingungen inkl. Leistungsbeschreibung und Widerrufsbelehrung, als Anhang der Vertragsbestaetigung Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c3f56ba290
commit
65429aa3ac
17 files changed
+1677
-2
No files matched your search
@@ -105,6 +105,48 @@
|
||||
}
|
||||
.chat-send:disabled { opacity: 0.5; cursor: default; }
|
||||
.chat-hint { font-size: 12px; opacity: 0.55; margin-top: 6px; }
|
||||
|
||||
/* Wartungs-Abo (Startseite) */
|
||||
.abo-card {
|
||||
position: relative; margin: 6px 0 26px; padding: 26px 28px; border-radius: 22px;
|
||||
background: linear-gradient(135deg, rgba(157,61,254,0.20), rgba(255,255,255,0.06) 60%);
|
||||
border: 1px solid rgba(157,61,254,0.45);
|
||||
}
|
||||
.abo-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 18px; flex-wrap: wrap; }
|
||||
.abo-kicker { font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; opacity: 0.7; margin: 0 0 4px; }
|
||||
.abo-title { font-size: 24px; margin: 0; }
|
||||
.abo-price { text-align: right; }
|
||||
.abo-price strong { font-size: 32px; font-variant-numeric: tabular-nums; }
|
||||
.abo-price span { display: block; font-size: 13px; opacity: 0.7; }
|
||||
.abo-features { list-style: none; padding: 0; margin: 18px 0 20px; display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
|
||||
.abo-features li { padding-left: 26px; position: relative; font-size: 15px; }
|
||||
.abo-features li::before { content: '✓'; position: absolute; left: 0; color: #c9a2ff; font-weight: 700; }
|
||||
.abo-features small { display: block; opacity: 0.65; font-size: 13px; }
|
||||
.abo-actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
|
||||
.abo-btn {
|
||||
background: #9d3dfe; border: none; color: #fff; font: inherit; font-weight: 700;
|
||||
padding: 13px 24px; border-radius: 999px; cursor: pointer;
|
||||
}
|
||||
.abo-btn:hover { background: #8a25f0; }
|
||||
.abo-btn:disabled { opacity: 0.5; cursor: default; }
|
||||
.abo-note { font-size: 13px; opacity: 0.7; }
|
||||
.abo-order { margin-top: 20px; padding-top: 18px; border-top: 1px solid rgba(255,255,255,0.14); }
|
||||
.abo-order h3 { margin: 0 0 10px; font-size: 17px; }
|
||||
.abo-summary { width: 100%; border-collapse: collapse; font-size: 14px; margin-bottom: 14px; }
|
||||
.abo-summary td { padding: 6px 0; border-bottom: 1px solid rgba(255,255,255,0.08); vertical-align: top; }
|
||||
.abo-summary td:last-child { text-align: right; }
|
||||
.abo-check { display: flex; gap: 10px; align-items: flex-start; margin: 10px 0; font-size: 14px; line-height: 1.45; cursor: pointer; }
|
||||
.abo-check input { margin-top: 3px; width: 18px; height: 18px; accent-color: #9d3dfe; flex: none; }
|
||||
.abo-card a { color: #d4b4ff; }
|
||||
.abo-balance { display: flex; gap: 28px; flex-wrap: wrap; margin: 18px 0; }
|
||||
.abo-stat strong { display: block; font-size: 34px; line-height: 1.1; font-variant-numeric: tabular-nums; }
|
||||
.abo-stat span { font-size: 13px; opacity: 0.7; }
|
||||
.abo-alert { padding: 10px 14px; border-radius: 12px; margin: 12px 0; font-size: 14px; background: rgba(251,191,36,0.12); border: 1px solid rgba(251,191,36,0.45); }
|
||||
.abo-history { margin-top: 14px; }
|
||||
.abo-history summary { cursor: pointer; font-size: 14px; opacity: 0.85; }
|
||||
.abo-history table { margin-top: 10px; }
|
||||
.portal-legal { margin-top: 40px; font-size: 13px; opacity: 0.7; display: flex; gap: 18px; flex-wrap: wrap; }
|
||||
.portal-legal a { color: inherit; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="portal-page dashboard-page">
|
||||
@@ -127,6 +169,9 @@
|
||||
<h1 class="portal-title">Kundenbereich</h1>
|
||||
<p id="load-error" class="error hidden"></p>
|
||||
|
||||
<!-- Wartungs-Abo: Angebot bzw. Stundenkonto -->
|
||||
<section id="abo-card" class="abo-card hidden" aria-live="polite"></section>
|
||||
|
||||
<div class="portal-tabs">
|
||||
<button class="portal-tab active" data-tab="projects">Projekte</button>
|
||||
<button class="portal-tab" data-tab="activity">Was wurde gemacht</button>
|
||||
@@ -165,6 +210,13 @@
|
||||
<p class="chat-hint">Enter = Senden, Shift+Enter = Zeilenumbruch. Wir antworten in der Regel innerhalb eines Werktags.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer class="portal-legal">
|
||||
<a href="/abo-bedingungen.html" target="_blank" rel="noopener">Abo-Bedingungen</a>
|
||||
<a href="/kuendigen.html">Verträge hier kündigen</a>
|
||||
<a href="/widerrufen.html">Vertrag widerrufen</a>
|
||||
<a href="https://webklar.com/impressum" target="_blank" rel="noopener">Impressum</a>
|
||||
</footer>
|
||||
</main>
|
||||
|
||||
<script src="/app.js"></script>
|
||||
|
||||
Reference in new issue
Block a user