Impressum, Datenschutzerklärung und DSGVO-Löschfunktion
- /impressum (§ 5 DDG) und /datenschutz als öffentliche Seiten im Brand-Look; Betreiber-Angaben (Name, Anschrift, E-Mail, Zusatz) liegen als Settings und sind bewusst Owner-only — Team-Mitglieder mit settings-Scope kommen an die private Anschrift nicht heran - Die Datenschutzerklärung beschreibt die tatsächliche Verarbeitung dieser Instanz: Server-Logs, Session-Cookies (einwilligungsfrei nach § 25 Abs. 2 TDDDG, kein Tracking), Discord-Login, Level, Wünsche, Geburtstage, Playtester/Alpha-Keys, Bewerbungen, Tickets/Modmail, Erinnerungen, Moderation und Audit-Log - DSGVO Art. 17: DELETE /api/profile löscht XP, Geburtstag, Playtester-Eintrag, Abstimmungen, Erinnerungen, Rollen-Sicherung, Giveaway-Teilnahmen und gibt den Alpha-Key wieder frei; Button im Profil unter „Meine Daten", Löschung landet im Audit-Log - Footer verlinkt beide Rechtstexte, neues GET /api/legal (öffentlich) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,8 @@ import Profil from './pages/Profil.jsx';
|
||||
import Server from './pages/Server.jsx';
|
||||
import Home from './pages/Home.jsx';
|
||||
import DevlogDetail from './pages/DevlogDetail.jsx';
|
||||
import Impressum from './pages/Impressum.jsx';
|
||||
import Datenschutz from './pages/Datenschutz.jsx';
|
||||
|
||||
const COMMUNITY_LINKS = [
|
||||
['/galerie', 'Galerie'],
|
||||
@@ -196,6 +198,8 @@ export default function App() {
|
||||
<Route path="/events" element={<Events />} />
|
||||
<Route path="/changelog" element={<Changelog />} />
|
||||
<Route path="/profil" element={<Profil me={me} />} />
|
||||
<Route path="/impressum" element={<Impressum />} />
|
||||
<Route path="/datenschutz" element={<Datenschutz />} />
|
||||
<Route path="/commits" element={<Commits me={me} />} />
|
||||
<Route path="/settings" element={<Settings me={me} />} />
|
||||
<Route path="*" element={<Navigate to="/devlogs" replace />} />
|
||||
@@ -208,6 +212,9 @@ export default function App() {
|
||||
<a href="https://git.d4rkst3r.de/D4rkst3r" target="_blank" rel="noreferrer">
|
||||
git.d4rkst3r.de
|
||||
</a>
|
||||
<span className="footer-sep">//</span>
|
||||
<NavLink to="/impressum">Impressum</NavLink>
|
||||
<NavLink to="/datenschutz">Datenschutz</NavLink>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
// Datenschutzerklärung — beschreibt die tatsächliche Verarbeitung dieser Instanz
|
||||
// (Discord-Login, Community-Funktionen, Moderation). Betreiber-Angaben aus den Settings.
|
||||
import { useEffect, useState } from 'react';
|
||||
import { apiGet } from '../api.js';
|
||||
|
||||
export default function Datenschutz() {
|
||||
const [data, setData] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
apiGet('/api/legal').then(setData).catch(() => setData({ legal: {} }));
|
||||
window.scrollTo(0, 0);
|
||||
}, []);
|
||||
|
||||
const legal = data?.legal ?? {};
|
||||
const brand = data?.brand ?? 'Wir';
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className="page-header">
|
||||
<div className="page-bg-text">LEGAL</div>
|
||||
<div className="page-header-grid" aria-hidden="true" />
|
||||
<div className="page-header-content">
|
||||
<div className="page-tag">// DSGVO</div>
|
||||
<h1 className="page-title">Datenschutz</h1>
|
||||
<p className="page-subtitle">
|
||||
Welche Daten hier verarbeitet werden, warum — und wie du sie wieder loswirst.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="content legal-text">
|
||||
<h2 className="settings-title">// 1. Verantwortlicher</h2>
|
||||
<p>
|
||||
Verantwortlich für die Datenverarbeitung auf dieser Webseite im Sinne der
|
||||
Datenschutz-Grundverordnung (DSGVO) ist:<br /><br />
|
||||
{legal.name || '—'}<br />
|
||||
{(legal.address || '').split('\n').map((line, i) => (
|
||||
<span key={i}>{line}<br /></span>
|
||||
))}
|
||||
{legal.email && <>E-Mail: <a href={`mailto:${legal.email}`}>{legal.email}</a></>}
|
||||
</p>
|
||||
|
||||
<h2 className="settings-title">// 2. Aufruf der Webseite (Server-Logs)</h2>
|
||||
<p>
|
||||
Beim Aufruf dieser Seite verarbeitet der Server technische Zugriffsdaten:
|
||||
IP-Adresse, Zeitpunkt der Anfrage, aufgerufene Adresse, HTTP-Statuscode und
|
||||
die Browserkennung. Diese Daten sind technisch erforderlich, um die Seite
|
||||
auszuliefern und Störungen sowie Angriffe erkennen zu können. Rechtsgrundlage
|
||||
ist Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse am sicheren und
|
||||
stabilen Betrieb). Die Logdaten werden nicht mit anderen Datenquellen
|
||||
zusammengeführt und nach kurzer Zeit im Rahmen der üblichen Rotation gelöscht.
|
||||
</p>
|
||||
|
||||
<h2 className="settings-title">// 3. Cookies</h2>
|
||||
<p>
|
||||
Diese Seite verwendet ausschließlich technisch notwendige Cookies. Konkret
|
||||
wird nach einem Login ein signiertes Sitzungs-Cookie gesetzt, damit du
|
||||
eingeloggt bleibst; ein weiteres kurzlebiges Cookie sichert den Login-Vorgang
|
||||
gegen Missbrauch ab (CSRF-Schutz). Diese Cookies sind für den von dir
|
||||
gewünschten Dienst unbedingt erforderlich und daher nach § 25 Abs. 2 Nr. 2
|
||||
TDDDG einwilligungsfrei. Es findet <strong>kein Tracking</strong>, keine
|
||||
Reichweitenmessung und keine Werbung statt. Die verwendeten Schriftarten
|
||||
werden lokal von diesem Server ausgeliefert — es entsteht dabei keine
|
||||
Verbindung zu Dritten.
|
||||
</p>
|
||||
|
||||
<h2 className="settings-title">// 4. Login mit Discord</h2>
|
||||
<p>
|
||||
Für den Mitglieder-Bereich kannst du dich freiwillig mit deinem
|
||||
Discord-Konto anmelden (OAuth2, Berechtigung <code>identify</code>). Dabei
|
||||
erhalten wir von Discord deine Benutzer-ID, deinen Benutzernamen und dein
|
||||
Profilbild. Diese Angaben werden in dem oben genannten Sitzungs-Cookie
|
||||
gespeichert; ein Zugriffstoken speichern wir nicht. Zusätzlich prüfen wir
|
||||
beim Login, ob du Mitglied unseres Discord-Servers bist, da der Zugang
|
||||
Mitgliedern vorbehalten ist. Rechtsgrundlage ist Art. 6 Abs. 1 lit. a DSGVO
|
||||
(Einwilligung durch die Anmeldung) bzw. lit. b DSGVO für die Bereitstellung
|
||||
des Mitglieder-Bereichs. Du kannst dich jederzeit über den Logout abmelden;
|
||||
das Cookie wird dann gelöscht.
|
||||
</p>
|
||||
<p>
|
||||
Anbieter ist Discord Netherlands BV bzw. Discord Inc., 444 De Haro Street,
|
||||
San Francisco, CA 94107, USA. Beim Login und beim Anzeigen von Profilbildern
|
||||
(<code>cdn.discordapp.com</code>) werden Daten an Discord übertragen und
|
||||
gegebenenfalls in den USA verarbeitet. Details findest du in der
|
||||
Datenschutzerklärung von Discord.
|
||||
</p>
|
||||
|
||||
<h2 className="settings-title">// 5. Community-Funktionen</h2>
|
||||
<p>
|
||||
{brand} betreibt einen eigenen Discord-Bot, der zur Verwaltung der Community
|
||||
Daten speichert. Verarbeitet werden — je nachdem, welche Funktionen du nutzt:
|
||||
</p>
|
||||
<ul className="legal-list">
|
||||
<li>
|
||||
<strong>Level-System:</strong> Benutzer-ID, Anzeigename und gesammelte
|
||||
Erfahrungspunkte, um eine Bestenliste anzuzeigen.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Feature-Wünsche & Abstimmungen:</strong> dein Anzeigename und der
|
||||
Text deines Vorschlags, bei Abstimmungen deine Benutzer-ID (damit jede
|
||||
Person nur einmal abstimmt).
|
||||
</li>
|
||||
<li>
|
||||
<strong>Geburtstage:</strong> Tag und Monat deines Geburtstags — nur wenn du
|
||||
sie selbst per Befehl einträgst, jederzeit selbst wieder entfernbar.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Playtester & Zugangsschlüssel:</strong> Benutzer-ID, Anzeigename und
|
||||
Zeitpunkt der Anmeldung sowie ein dir zugeteilter Alpha-Key.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Bewerbungen:</strong> deine Antworten auf die Formularfragen sowie das
|
||||
Ergebnis der Prüfung.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Support & Kontakt:</strong> Inhalte von Tickets und Direktnachrichten
|
||||
an den Bot, damit das Team antworten kann; beim Schließen eines Tickets
|
||||
wird auf Wunsch ein Gesprächsverlauf erstellt.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Erinnerungen:</strong> Text und Zeitpunkt, bis die Erinnerung
|
||||
zugestellt wurde.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Veröffentlichte Beiträge:</strong> Entwicklungsberichte und
|
||||
Community-Screenshots werden mit Anzeigenamen archiviert und auf dieser
|
||||
Webseite dargestellt.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Rechtsgrundlage ist Art. 6 Abs. 1 lit. a DSGVO (Einwilligung) für alle
|
||||
freiwilligen Angaben und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse
|
||||
am Betrieb einer funktionierenden Community) für den technischen Betrieb.
|
||||
</p>
|
||||
|
||||
<h2 className="settings-title">// 6. Moderation und Protokolle</h2>
|
||||
<p>
|
||||
Zur Durchsetzung der Serverregeln werden Verwarnungen mit Benutzer-ID, Grund
|
||||
und Zeitpunkt gespeichert. Änderungen im Administrationsbereich der Webseite
|
||||
werden in einem Protokoll festgehalten (wer wann welche Einstellung geändert
|
||||
hat), um Missbrauch nachvollziehen zu können. Rechtsgrundlage ist Art. 6
|
||||
Abs. 1 lit. f DSGVO.
|
||||
</p>
|
||||
|
||||
<h2 className="settings-title">// 7. Speicherdauer</h2>
|
||||
<p>
|
||||
Wir speichern personenbezogene Daten so lange, wie du Mitglied der Community
|
||||
bist oder die jeweilige Funktion nutzt. Verlässt du den Discord-Server, kannst
|
||||
du die Löschung deiner Daten verlangen (siehe Punkt 9). Sitzungs-Cookies
|
||||
laufen spätestens nach sieben Tagen ab. Von der Datenbank werden verschlüsselte
|
||||
Sicherungskopien erstellt, die nach spätestens 14 Tagen automatisch gelöscht
|
||||
werden.
|
||||
</p>
|
||||
|
||||
<h2 className="settings-title">// 8. Weitergabe an Dritte</h2>
|
||||
<p>
|
||||
Eine Weitergabe deiner Daten zu Werbezwecken findet nicht statt. Ein Verkauf
|
||||
von Daten erfolgt nicht. Übermittlungen erfolgen nur an Discord, soweit dies
|
||||
für die Nutzung des Discord-Servers und des Logins technisch notwendig ist.
|
||||
</p>
|
||||
|
||||
<h2 className="settings-title">// 9. Deine Rechte</h2>
|
||||
<p>
|
||||
Du hast jederzeit das Recht auf Auskunft über die zu deiner Person
|
||||
gespeicherten Daten (Art. 15 DSGVO), auf Berichtigung (Art. 16), auf Löschung
|
||||
(Art. 17), auf Einschränkung der Verarbeitung (Art. 18), auf
|
||||
Datenübertragbarkeit (Art. 20) sowie auf Widerspruch gegen die Verarbeitung
|
||||
(Art. 21). Eine erteilte Einwilligung kannst du jederzeit mit Wirkung für die
|
||||
Zukunft widerrufen.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Selbst löschen:</strong> Eingeloggte Mitglieder können ihre gespeicherten
|
||||
Daten direkt auf der Profilseite löschen — dort findest du unten den Bereich
|
||||
„Meine Daten löschen". Beiträge, die im Discord stehen (etwa Screenshots oder
|
||||
Nachrichten), löschst du bitte dort; melde dich sonst gerne bei uns.
|
||||
</p>
|
||||
<p>
|
||||
Für Anfragen genügt eine formlose Nachricht an
|
||||
{' '}{legal.email ? <a href={`mailto:${legal.email}`}>{legal.email}</a> : 'die im Impressum genannte Adresse'}.
|
||||
</p>
|
||||
|
||||
<h2 className="settings-title">// 10. Beschwerderecht</h2>
|
||||
<p>
|
||||
Wenn du der Ansicht bist, dass die Verarbeitung deiner Daten gegen die DSGVO
|
||||
verstößt, kannst du dich bei einer Datenschutz-Aufsichtsbehörde beschweren —
|
||||
etwa bei der für deinen Wohnsitz zuständigen Landesdatenschutzbehörde.
|
||||
</p>
|
||||
|
||||
<h2 className="settings-title">// 11. Änderungen</h2>
|
||||
<p>
|
||||
Wir passen diese Datenschutzerklärung an, wenn sich die angebotenen Funktionen
|
||||
ändern. Es gilt jeweils die hier veröffentlichte Fassung.
|
||||
</p>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
// Impressum nach § 5 DDG — die Betreiber-Angaben kommen aus den Settings
|
||||
// (System-Tab, nur Owner), damit hier nichts hartkodiert im Repo landet.
|
||||
import { useEffect, useState } from 'react';
|
||||
import { apiGet } from '../api.js';
|
||||
|
||||
export default function Impressum() {
|
||||
const [data, setData] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
apiGet('/api/legal').then(setData).catch(() => setData({ legal: {} }));
|
||||
window.scrollTo(0, 0);
|
||||
}, []);
|
||||
|
||||
const legal = data?.legal ?? {};
|
||||
const incomplete = !legal.name || !legal.address || !legal.email;
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className="page-header">
|
||||
<div className="page-bg-text">LEGAL</div>
|
||||
<div className="page-header-grid" aria-hidden="true" />
|
||||
<div className="page-header-content">
|
||||
<div className="page-tag">// Pflichtangaben</div>
|
||||
<h1 className="page-title">Impressum</h1>
|
||||
<p className="page-subtitle">Angaben gemäß § 5 Digitale-Dienste-Gesetz (DDG).</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="content legal-text">
|
||||
{incomplete && (
|
||||
<p className="notice">
|
||||
⚠️ Die Impressums-Angaben sind noch nicht vollständig hinterlegt
|
||||
(Setup → System → Impressum).
|
||||
</p>
|
||||
)}
|
||||
|
||||
<h2 className="settings-title">// Diensteanbieter</h2>
|
||||
<p>
|
||||
{legal.name || '—'}<br />
|
||||
{(legal.address || '').split('\n').map((line, i) => (
|
||||
<span key={i}>{line}<br /></span>
|
||||
))}
|
||||
</p>
|
||||
|
||||
<h2 className="settings-title">// Kontakt</h2>
|
||||
<p>
|
||||
E-Mail: {legal.email ? <a href={`mailto:${legal.email}`}>{legal.email}</a> : '—'}
|
||||
</p>
|
||||
|
||||
{legal.extra && (
|
||||
<>
|
||||
<h2 className="settings-title">// Weitere Angaben</h2>
|
||||
<p>{legal.extra.split('\n').map((line, i) => <span key={i}>{line}<br /></span>)}</p>
|
||||
</>
|
||||
)}
|
||||
|
||||
<h2 className="settings-title">// Verantwortlich für den Inhalt</h2>
|
||||
<p>
|
||||
Verantwortlich für journalistisch-redaktionelle Inhalte nach § 18 Abs. 2 MStV:
|
||||
{' '}{legal.name || '—'}{legal.address ? `, ${legal.address.replace(/\n/g, ', ')}` : ''}
|
||||
</p>
|
||||
|
||||
<h2 className="settings-title">// Haftung für Inhalte</h2>
|
||||
<p>
|
||||
Als Diensteanbieter sind wir für eigene Inhalte auf diesen Seiten nach den
|
||||
allgemeinen Gesetzen verantwortlich. Wir sind jedoch nicht verpflichtet,
|
||||
übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach
|
||||
Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen.
|
||||
Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen
|
||||
nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche
|
||||
Haftung ist jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten
|
||||
Rechtsverletzung möglich. Bei Bekanntwerden entsprechender Rechtsverletzungen
|
||||
entfernen wir diese Inhalte umgehend.
|
||||
</p>
|
||||
|
||||
<h2 className="settings-title">// Haftung für Links</h2>
|
||||
<p>
|
||||
Unser Angebot enthält Links zu externen Webseiten Dritter, auf deren Inhalte
|
||||
wir keinen Einfluss haben. Deshalb können wir für diese fremden Inhalte auch
|
||||
keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der
|
||||
jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Bei Bekanntwerden
|
||||
von Rechtsverletzungen entfernen wir derartige Links umgehend.
|
||||
</p>
|
||||
|
||||
<h2 className="settings-title">// Urheberrecht</h2>
|
||||
<p>
|
||||
Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten
|
||||
unterliegen dem deutschen Urheberrecht. Beiträge Dritter — insbesondere
|
||||
Screenshots aus der Community-Galerie — sind als solche gekennzeichnet.
|
||||
Sollten Sie auf eine Urheberrechtsverletzung aufmerksam werden, bitten wir um
|
||||
einen entsprechenden Hinweis; bei Bekanntwerden entfernen wir die Inhalte
|
||||
umgehend.
|
||||
</p>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
// Member-Profil: Rang & XP, Discord-Rollen, Alpha-Key, Playtester-Status
|
||||
// + Rollen-Selfservice (Rollen-Menüs direkt im Browser togglen).
|
||||
import { useEffect, useState } from 'react';
|
||||
import { apiGet, apiPost } from '../api.js';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { apiGet, apiPost, apiDelete } from '../api.js';
|
||||
|
||||
function fmtDate(iso) {
|
||||
if (!iso) return '—';
|
||||
@@ -15,6 +16,7 @@ export default function Profil({ me }) {
|
||||
const [error, setError] = useState(null);
|
||||
const [busy, setBusy] = useState('');
|
||||
const [copied, setCopied] = useState(false);
|
||||
const [wipeMsg, setWipeMsg] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
apiGet('/api/profile').then(setProfile).catch((e) => setError(e?.message ?? 'Fehler'));
|
||||
@@ -40,6 +42,23 @@ export default function Profil({ me }) {
|
||||
setBusy('');
|
||||
}
|
||||
|
||||
async function wipeData() {
|
||||
if (!window.confirm(
|
||||
'Wirklich alle gespeicherten Daten löschen?\n\n' +
|
||||
'Betrifft: XP/Level, Geburtstag, Playtester-Eintrag, Abstimmungen, ' +
|
||||
'Erinnerungen, Rollen-Sicherung und deinen Alpha-Key.\n\n' +
|
||||
'Das lässt sich nicht rückgängig machen.'
|
||||
)) return;
|
||||
try {
|
||||
const res = await apiDelete('/api/profile');
|
||||
const total = Object.values(res.deleted).reduce((a, b) => a + b, 0);
|
||||
setWipeMsg(`✅ ${total} Einträge gelöscht.`);
|
||||
apiGet('/api/profile').then(setProfile).catch(() => {});
|
||||
} catch {
|
||||
setWipeMsg('⚠️ Löschen fehlgeschlagen — melde dich bitte beim Team.');
|
||||
}
|
||||
}
|
||||
|
||||
async function copyKey() {
|
||||
try {
|
||||
await navigator.clipboard.writeText(profile.alphaKey);
|
||||
@@ -156,6 +175,22 @@ export default function Profil({ me }) {
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* DSGVO Art. 17: eigene Daten löschen */}
|
||||
<div className="roadmap-group danger-zone">
|
||||
<h2 className="settings-title">// Meine Daten</h2>
|
||||
<p className="field-hint">
|
||||
Du kannst jederzeit alle Daten löschen, die hier zu dir gespeichert
|
||||
sind: XP/Level, Geburtstag, Playtester-Eintrag, Abstimmungen,
|
||||
Erinnerungen, Rollen-Sicherung und einen zugeteilten Alpha-Key.
|
||||
Was du im Discord gepostet hast, löschst du bitte dort. Details im{' '}
|
||||
<Link to="/datenschutz" style={{ textDecoration: 'underline' }}>Datenschutz</Link>.
|
||||
</p>
|
||||
<div className="field-row" style={{ marginTop: '.8rem' }}>
|
||||
<button className="btn btn-danger" onClick={wipeData}>Meine Daten löschen</button>
|
||||
</div>
|
||||
{wipeMsg && <p className="notice" style={{ padding: '.6rem 0 0' }}>{wipeMsg}</p>}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</section>
|
||||
|
||||
@@ -1219,6 +1219,31 @@ export default function Settings({ me }) {
|
||||
</div>
|
||||
|
||||
|
||||
<div className="settings-section">
|
||||
<h2 className="settings-title">// Impressum & Datenschutz</h2>
|
||||
<p className="field-hint" style={{ marginBottom: '.9rem' }}>
|
||||
Erscheint auf <code>/impressum</code> und <code>/datenschutz</code>. Für § 5 DDG
|
||||
ist eine ladungsfähige Anschrift nötig (kein Postfach) — nur der Owner sieht
|
||||
und ändert diese Felder.
|
||||
</p>
|
||||
<div className="field">
|
||||
<label>Name / Verantwortlicher</label>
|
||||
<input type="text" placeholder="Vorname Nachname" value={form.legal_name ?? ''} onChange={(e) => setForm({ ...form, legal_name: e.target.value })} />
|
||||
</div>
|
||||
<div className="field">
|
||||
<label>Anschrift <span className="field-hint">mehrzeilig: Straße, PLZ Ort, Land</span></label>
|
||||
<textarea rows={3} placeholder={'Musterstraße 1\n12345 Musterstadt\nDeutschland'} value={form.legal_address ?? ''} onChange={(e) => setForm({ ...form, legal_address: e.target.value })} />
|
||||
</div>
|
||||
<div className="field">
|
||||
<label>Kontakt-E-Mail <span className="field-hint">Pflichtangabe — muss erreichbar sein</span></label>
|
||||
<input type="email" placeholder="kontakt@d4rkst3r.de" value={form.legal_email ?? ''} onChange={(e) => setForm({ ...form, legal_email: e.target.value })} />
|
||||
</div>
|
||||
<div className="field">
|
||||
<label>Weitere Angaben <span className="field-hint">optional: USt-ID, Telefon, Handelsregister …</span></label>
|
||||
<textarea rows={2} placeholder="USt-IdNr.: DE123456789" value={form.legal_extra ?? ''} onChange={(e) => setForm({ ...form, legal_extra: e.target.value })} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="settings-section">
|
||||
<h2 className="settings-title">// Web-Login (Member)</h2>
|
||||
<div className="field">
|
||||
|
||||
@@ -1473,3 +1473,41 @@ a.sha:hover { border-color: var(--neon); background: rgba(245, 197, 24, .07); }
|
||||
text-decoration: none;
|
||||
}
|
||||
.card-permalink:hover { opacity: 1; }
|
||||
|
||||
/* ── RECHTSTEXTE (Impressum / Datenschutz) ─────────── */
|
||||
.legal-text { max-width: 780px; }
|
||||
.legal-text .settings-title { margin-top: 2.2rem; }
|
||||
.legal-text .settings-title:first-of-type { margin-top: 0; }
|
||||
.legal-text p {
|
||||
color: var(--muted); font-weight: 300; line-height: 1.75;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.legal-text strong { color: var(--text); font-weight: 600; }
|
||||
.legal-text a { color: var(--neon); border-bottom: 1px solid rgba(245, 197, 24, .3); }
|
||||
.legal-text a:hover { border-bottom-color: var(--neon); }
|
||||
.legal-text code {
|
||||
font-family: var(--mono); font-size: .85em;
|
||||
background: var(--bg3); border: 1px solid var(--border);
|
||||
border-radius: 4px; padding: .05rem .35rem; color: var(--text);
|
||||
}
|
||||
.legal-list { list-style: none; margin: 0 0 1rem; padding: 0; }
|
||||
.legal-list li {
|
||||
position: relative; padding-left: 1.4rem; margin-bottom: .7rem;
|
||||
color: var(--muted); font-weight: 300; line-height: 1.7;
|
||||
}
|
||||
.legal-list li::before {
|
||||
content: '▸'; position: absolute; left: 0; color: var(--neon2);
|
||||
}
|
||||
|
||||
/* Lösch-Bereich im Profil */
|
||||
.danger-zone {
|
||||
border: 1px solid rgba(242, 63, 67, .25);
|
||||
border-radius: 12px; padding: 1.2rem 1.4rem;
|
||||
background: rgba(242, 63, 67, .03);
|
||||
}
|
||||
.danger-zone .settings-title { color: #f23f43; }
|
||||
.danger-zone .settings-title::after {
|
||||
background: linear-gradient(90deg, rgba(242, 63, 67, .35), transparent);
|
||||
}
|
||||
.btn-danger { border-color: rgba(242, 63, 67, .5); color: #f23f43; }
|
||||
.btn-danger:hover { border-color: #f23f43; background: rgba(242, 63, 67, .1); }
|
||||
|
||||
Reference in New Issue
Block a user