From bc0dca66089803b8b9092a28d3863468f95506b9 Mon Sep 17 00:00:00 2001 From: Blink1986 Date: Tue, 28 Jul 2026 10:12:57 +0000 Subject: [PATCH] Dateien nach "/" hochladen --- admin.php | 207 +++++++++++++++++++++++++++++++++++++++++++++++++++++ login.php | 82 +++++++++++++++++++++ logout.php | 6 ++ setup.php | 90 +++++++++++++++++++++++ style.css | 169 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 554 insertions(+) create mode 100644 admin.php create mode 100644 login.php create mode 100644 logout.php create mode 100644 setup.php create mode 100644 style.css diff --git a/admin.php b/admin.php new file mode 100644 index 0000000..2be7e21 --- /dev/null +++ b/admin.php @@ -0,0 +1,207 @@ +prepare('INSERT INTO eintraege (type, title, entry_date, body, author_name) VALUES (?, ?, ?, ?, ?)'); + $stmt->execute([$type, $title, $date, $body, current_user_name()]); + $success = 'Eintrag wurde gespeichert.'; + } else { + $id = (int)($_POST['id'] ?? 0); + $stmt = $pdo->prepare('UPDATE eintraege SET type=?, title=?, entry_date=?, body=? WHERE id=?'); + $stmt->execute([$type, $title, $date, $body, $id]); + $success = 'Eintrag wurde aktualisiert.'; + } + } + } + + if ($action === 'delete_entry') { + $id = (int)($_POST['id'] ?? 0); + $stmt = $pdo->prepare('DELETE FROM eintraege WHERE id=?'); + $stmt->execute([$id]); + $success = 'Eintrag wurde gelöscht.'; + } + + if ($action === 'add_user') { + $name = trim($_POST['new_name'] ?? ''); + $username = trim($_POST['new_username'] ?? ''); + $password = $_POST['new_password'] ?? ''; + + if ($name === '' || $username === '' || strlen($password) < 8) { + $error = 'Bitte Name und Benutzername ausfüllen — das Passwort braucht mindestens 8 Zeichen.'; + } else { + $exists = $pdo->prepare('SELECT COUNT(*) FROM users WHERE username = ?'); + $exists->execute([$username]); + if ($exists->fetchColumn() > 0) { + $error = 'Dieser Benutzername ist bereits vergeben.'; + } else { + $stmt = $pdo->prepare('INSERT INTO users (username, password_hash, name) VALUES (?, ?, ?)'); + $stmt->execute([$username, password_hash($password, PASSWORD_DEFAULT), $name]); + $success = 'Neues Mitgliedskonto für ' . $name . ' wurde angelegt.'; + } + } + } +} + +// ---- Daten für die Anzeige laden ---- +$editEntry = null; +if (isset($_GET['edit'])) { + $stmt = $pdo->prepare('SELECT * FROM eintraege WHERE id = ?'); + $stmt->execute([(int)$_GET['edit']]); + $editEntry = $stmt->fetch(PDO::FETCH_ASSOC); +} + +$eintraege = $pdo->query("SELECT * FROM eintraege ORDER BY (entry_date IS NULL), entry_date DESC, created_at DESC")->fetchAll(PDO::FETCH_ASSOC); +$users = $pdo->query("SELECT id, name, username, created_at FROM users ORDER BY created_at ASC")->fetchAll(PDO::FETCH_ASSOC); + +if (isset($_GET['willkommen'])) { + $success = 'Konto eingerichtet — willkommen im Mitgliederbereich!'; +} +?> + + + + + +Mitgliederbereich · Geburtsverein Ernsthausen + + + + + + + + +
+
+

Angemeldet als

+

Mitgliederbereich

+

Hier trägst du Termine und Neuigkeiten ein, die auf der Startseite unter „Aktuelles" erscheinen — und kannst weitere Mitglieder freischalten.

+
+
+ +
+
+
+ +
+
+
+

+
+ + + + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + Abbrechen +
+
+ +
+

Neues Mitglied freischalten

+

Jedes Vereinsmitglied bekommt einen eigenen Zugang zum Mitgliederbereich.

+
+ + +
+ + +
+
+ + +
+
+ + +
+ +
+
+
+ +
+

Bestehende Einträge

+
+ +

Noch keine Einträge vorhanden.

+ +
+
+
+ +

+

+ +
+
+ Bearbeiten +
+ + + + +
+
+
+ +
+ +

Mitglieder mit Zugang

+
+ +
+
+

+

Benutzername:

+
+
+
+ +
+
+
+
+ + + + diff --git a/login.php b/login.php new file mode 100644 index 0000000..4b877c6 --- /dev/null +++ b/login.php @@ -0,0 +1,82 @@ +query('SELECT COUNT(*) FROM users')->fetchColumn(); +if ($userCount === 0) { + header('Location: setup.php'); + exit; +} + +if (is_logged_in()) { + header('Location: admin.php'); + exit; +} + +$error = ''; + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + csrf_check(); + $username = trim($_POST['username'] ?? ''); + $password = $_POST['password'] ?? ''; + + $stmt = $pdo->prepare('SELECT * FROM users WHERE username = ?'); + $stmt->execute([$username]); + $user = $stmt->fetch(PDO::FETCH_ASSOC); + + if ($user && password_verify($password, $user['password_hash'])) { + session_regenerate_id(true); + $_SESSION['user_id'] = $user['id']; + $_SESSION['user_name'] = $user['name']; + header('Location: admin.php'); + exit; + } else { + $error = 'Benutzername oder Passwort ist falsch.'; + } +} +?> + + + + + +Mitglieder-Login · Geburtsverein Ernsthausen + + + + + + + + +
+
+

Mitgliederbereich

+

Anmelden

+

Mit deinem persönlichen Zugang kannst du Termine und Neuigkeiten für die Vereinsseite eintragen.

+
+
+ +
+
+
+
+ +
+ + +
+
+ + +
+ +
+
+
+ + + + diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..f68c8be --- /dev/null +++ b/logout.php @@ -0,0 +1,6 @@ +query('SELECT COUNT(*) FROM users')->fetchColumn(); + +// Sobald ein Mitglied existiert, ist die Ersteinrichtung für immer gesperrt. +if ($userCount > 0) { + header('Location: login.php'); + exit; +} + +$error = ''; + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + csrf_check(); + $name = trim($_POST['name'] ?? ''); + $username = trim($_POST['username'] ?? ''); + $password = $_POST['password'] ?? ''; + $password2 = $_POST['password2'] ?? ''; + + if ($name === '' || $username === '' || $password === '') { + $error = 'Bitte alle Felder ausfüllen.'; + } elseif (strlen($password) < 8) { + $error = 'Das Passwort sollte mindestens 8 Zeichen haben.'; + } elseif ($password !== $password2) { + $error = 'Die beiden Passwörter stimmen nicht überein.'; + } else { + $stmt = $pdo->prepare('INSERT INTO users (username, password_hash, name) VALUES (?, ?, ?)'); + $stmt->execute([$username, password_hash($password, PASSWORD_DEFAULT), $name]); + session_regenerate_id(true); + $_SESSION['user_id'] = $pdo->lastInsertId(); + $_SESSION['user_name'] = $name; + header('Location: admin.php?willkommen=1'); + exit; + } +} +?> + + + + + +Ersteinrichtung · Geburtsverein Ernsthausen + + + + + + + + +
+
+

Einmalige Ersteinrichtung

+

Erstes Mitgliedskonto anlegen

+

Diese Seite ist nur sichtbar, solange noch kein Mitgliedskonto existiert. Danach ist sie automatisch gesperrt. Lege hier den ersten Zugang an — weitere Mitglieder können später im Mitgliederbereich selbst hinzugefügt werden.

+
+
+ +
+
+
+
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+ + + + diff --git a/style.css b/style.css new file mode 100644 index 0000000..02d773d --- /dev/null +++ b/style.css @@ -0,0 +1,169 @@ +:root{ + --paper:#efeee0; + --paper-2:#e6e3d1; + --ink:#23301f; + --ink-soft:#4a5644; + --cover:#1f2e22; + --cover-2:#182319; + --sage:#7e9471; + --sage-deep:#556b48; + --gold:#c9a05c; + --line: rgba(35,48,31,0.16); + --line-dark: rgba(239,238,224,0.16); + --red:#a94438; +} +*{box-sizing:border-box;} +html{scroll-behavior:smooth;} +body{ + margin:0; + background:var(--paper); + color:var(--ink); + font-family:'Libre Franklin', sans-serif; + font-size:17px; + line-height:1.6; + -webkit-font-smoothing:antialiased; +} +h1,h2,h3{ + font-family:'Fraunces', serif; + font-weight:700; + margin:0; + color:inherit; +} +a{color:inherit;} +.kicker{ + font-family:'Space Mono', monospace; + font-size:12.5px; + letter-spacing:0.14em; + text-transform:uppercase; + color:var(--sage-deep); +} +.kicker.on-dark{color:var(--sage);} + +/* NAV */ +header{ + position:sticky; top:0; z-index:50; + background:rgba(239,238,224,0.92); + backdrop-filter:blur(8px); + border-bottom:1px solid var(--line); +} +nav{ + max-width:1080px; margin:0 auto; + display:flex; align-items:center; justify-content:space-between; + padding:16px 24px; +} +.brand{ + font-family:'Fraunces', serif; font-weight:700; font-size:18px; + letter-spacing:0.01em; text-decoration:none; color:var(--ink); +} +.brand span{color:var(--sage-deep);} +.navlinks{display:flex; align-items:center; gap:26px; list-style:none; margin:0; padding:0;} +.navlinks a{ + font-size:14.5px; text-decoration:none; color:var(--ink-soft); + font-weight:600; letter-spacing:0.01em; + transition:color .2s ease; +} +.navlinks a:hover, .navlinks a:focus-visible{color:var(--sage-deep);} +.navlinks a.pill{ + background:var(--cover); color:var(--paper); padding:9px 16px; border-radius:2px; +} +.navlinks a.pill:hover{background:var(--sage-deep); color:var(--paper);} + +/* PAGE HEAD (non-hero pages) */ +.pagehead{ + background:radial-gradient(120% 140% at 50% -10%, var(--cover) 0%, var(--cover-2) 65%); + color:var(--paper); + padding:56px 24px 44px; +} +.pagehead-inner{max-width:1080px; margin:0 auto;} +.pagehead h1{font-size:clamp(28px,4vw,40px); color:var(--paper); margin-bottom:8px;} +.pagehead p{color:rgba(239,238,224,0.75); margin:0; max-width:60ch;} + +/* SECTIONS */ +section{max-width:1080px; margin:0 auto; padding:56px 24px;} +.section-head{margin-bottom:32px; max-width:60ch;} +.section-head h2{font-size:clamp(24px,3.2vw,32px); margin-top:8px; color:var(--ink);} +.divider{border:none; border-top:1px solid var(--line); margin:0;} + +/* LOG / AKTUELLES */ +.log{border-top:1px solid var(--line);} +.log-entry{ + display:grid; grid-template-columns:140px 1fr; gap:24px; + padding:22px 0; border-bottom:1px solid var(--line); +} +.log-entry .date{font-family:'Space Mono', monospace; font-size:13.5px; color:var(--sage-deep); padding-top:2px;} +.log-entry .tag{ + display:inline-block; font-family:'Space Mono', monospace; font-size:10.5px; text-transform:uppercase; + letter-spacing:.08em; background:var(--paper-2); color:var(--ink-soft); padding:2px 8px; border-radius:2px; margin-bottom:6px; +} +.log-entry h3{font-size:18px; margin-bottom:6px;} +.log-entry p{margin:0; color:var(--ink-soft); font-size:15px; white-space:pre-line;} +.log-empty{color:var(--ink-soft); font-style:italic; padding:20px 0;} + +/* FORMS */ +.form-card{ + background:var(--paper-2); border:1px solid var(--line); border-radius:3px; + padding:28px; max-width:640px; +} +.form-card h2, .form-card h3{margin-bottom:18px;} +.field{margin-bottom:16px;} +.field label{display:block; font-size:13.5px; font-weight:600; margin-bottom:6px; color:var(--ink-soft);} +.field input[type=text], .field input[type=password], .field input[type=date], .field select, .field textarea{ + width:100%; padding:11px 12px; border:1px solid var(--line); border-radius:2px; + background:var(--paper); font-family:'Libre Franklin', sans-serif; font-size:15px; color:var(--ink); +} +.field textarea{min-height:110px; resize:vertical; font-family:inherit;} +.field input:focus, .field select:focus, .field textarea:focus{ + outline:2px solid var(--sage); outline-offset:1px; +} +.btn{ + display:inline-flex; align-items:center; gap:8px; cursor:pointer; + background:var(--gold); color:var(--cover-2); text-decoration:none; border:none; + padding:12px 22px; border-radius:2px; font-weight:700; font-size:14.5px; + font-family:inherit; white-space:nowrap; + transition:background .2s ease; +} +.btn:hover{background:#dab371;} +.btn.secondary{background:transparent; color:var(--ink); border:1px solid var(--line);} +.btn.secondary:hover{background:var(--paper);} +.btn.danger{background:transparent; color:var(--red); border:1px solid var(--red);} +.btn.danger:hover{background:var(--red); color:var(--paper);} + +.alert{ + padding:13px 16px; border-radius:2px; font-size:14.5px; margin-bottom:20px; +} +.alert.error{background:#f4dcd8; color:var(--red); border:1px solid var(--red);} +.alert.success{background:#e2ead9; color:var(--sage-deep); border:1px solid var(--sage-deep);} + +/* ADMIN LIST */ +.admin-list{border-top:1px solid var(--line); margin-top:8px;} +.admin-row{ + display:grid; grid-template-columns:110px 1fr auto; gap:16px; align-items:start; + padding:16px 0; border-bottom:1px solid var(--line); +} +.admin-row .date{font-family:'Space Mono', monospace; font-size:13px; color:var(--sage-deep); padding-top:3px;} +.admin-row .content h4{margin:0 0 4px; font-family:'Fraunces', serif; font-size:16.5px;} +.admin-row .content p{margin:0; font-size:14px; color:var(--ink-soft); white-space:pre-line;} +.admin-row .actions{display:flex; gap:8px; align-items:flex-start;} +.admin-row .actions form{display:inline;} +.byline{font-family:'Space Mono', monospace; font-size:11px; color:var(--ink-soft); margin-top:6px; display:block;} + +.two-col{display:grid; grid-template-columns:1.1fr 0.9fr; gap:32px; align-items:start;} + +footer{ + background:var(--cover-2); color:rgba(239,238,224,0.7); + padding:40px 24px 28px; +} +.foot-inner{max-width:1080px; margin:0 auto; display:flex; justify-content:space-between; gap:24px; flex-wrap:wrap; align-items:flex-end;} +footer .brand{color:var(--paper);} +footer .brand span{color:var(--sage);} +footer p{font-size:13.5px; margin:6px 0 0;} +footer .foot-links{display:flex; gap:20px; list-style:none; padding:0; margin:0; font-size:13.5px;} +footer .foot-links a{text-decoration:none; color:rgba(239,238,224,0.7);} +footer .foot-links a:hover{color:var(--gold);} + +@media (max-width:760px){ + .navlinks{gap:14px;} + .two-col{grid-template-columns:1fr;} + .admin-row{grid-template-columns:1fr; gap:6px;} + .foot-inner{flex-direction:column; align-items:flex-start;} +}