From 257f9af35896bdaae34d40aaf761454800e9e920 Mon Sep 17 00:00:00 2001 From: Lars Gebhardt-Kusche Date: Tue, 21 Jul 2026 22:43:41 +0200 Subject: [PATCH] ycyxc --- partials/landing/account/community-admin.php | 221 ++++++++++++ partials/landing/account/dashboard.php | 21 +- partials/landing/community/index.php | 341 ++++++++----------- partials/landing/community/sidebar.php | 32 ++ partials/landing/community/thread.php | 338 +++++++++--------- public/assets/css/app.css | 16 + public/page/community-admin.php | 4 + 7 files changed, 598 insertions(+), 375 deletions(-) create mode 100644 partials/landing/account/community-admin.php create mode 100644 partials/landing/community/sidebar.php create mode 100644 public/page/community-admin.php diff --git a/partials/landing/account/community-admin.php b/partials/landing/account/community-admin.php new file mode 100644 index 0000000..07e18e6 --- /dev/null +++ b/partials/landing/account/community-admin.php @@ -0,0 +1,221 @@ +pdo(); +$userId = $_SESSION['user_id'] ?? null; + +if (!$userId) { + redirect('/login'); +} + +$communityCfg = require __DIR__ . '/../../../config/community.php'; +$access = $pdo ? new \App\CommunityAccess($pdo, $communityCfg) : null; +$migration = $pdo ? new \App\CommunityMigration($pdo) : null; + +if (!$access || !$access->canModerateForum((int)$userId)) { + http_response_code(403); + echo '

Kein Zugriff

Dieser Bereich ist nur für Community-Admins freigegeben.

'; + return; +} + +$error = ''; +$info = ''; +$canManageApplications = $access->canManageApplications((int)$userId) && $access->supportsApplications(); +$canManageRoles = $access->canManageRoles((int)$userId); + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $action = (string)($_POST['action'] ?? ''); + try { + if ($action === 'application_decide') { + $access->decideApplication((int)$userId, (int)($_POST['application_id'] ?? 0), (string)($_POST['decision'] ?? ''), (string)($_POST['decision_reason'] ?? '')); + $info = 'Bewerbung wurde bearbeitet.'; + } elseif ($action === 'report_resolve') { + $access->resolveReport((int)$userId, (int)($_POST['report_id'] ?? 0), (string)($_POST['moderator_note'] ?? '')); + $info = 'Meldung wurde abgeschlossen.'; + } elseif ($action === 'role_revoke') { + $access->revokeRole((int)$userId, (int)($_POST['target_user_id'] ?? 0), (string)($_POST['role'] ?? '')); + $info = 'Rolle wurde entzogen.'; + } elseif ($action === 'role_assign') { + $access->assignRole((int)$userId, (int)($_POST['target_user_id'] ?? 0), (string)($_POST['role'] ?? '')); + $info = 'Rolle wurde vergeben.'; + } elseif ($action === 'community_migrate') { + if (!$canManageApplications || !$migration) { + throw new \RuntimeException('Keine Berechtigung für die Community-Migration.'); + } + $migration->apply(); + $info = 'Die Community-Migration wurde ausgeführt.'; + } + } catch (\Throwable $e) { + $error = $e->getMessage(); + } +} + +$applications = $canManageApplications ? $access->listApplications('open') : []; +$reports = $access->supportsReports() ? $access->listOpenReports() : []; +$roleAssignments = $canManageRoles ? $access->listRoleAssignments() : []; +$migrationStatus = ($migration && $canManageApplications) ? $migration->status() : null; +?> +
+
+
+ Home + / + Mitgliederbereich + / + Community-Admin +
+ +
+
+

Community-Admin

+

Moderation, Bewerbungen und Rollen an einem Ort.

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

Offene Bewerbungen

+

Bewerbungen für die Forum-Moderation prüfen.

+
+
+
+ +
+
+ +

+
+
+ + + +
+ + +
+
+
+ + +
Keine offenen Bewerbungen.
+ +
+
+ + +
+
+
+

Offene Meldungen

+

Gemeldete Inhalte prüfen und abschließen.

+
+
+
+ +
+
+ # +

+

Gemeldet von am

+
+
+ + + + +
+
+ + +
Keine offenen Meldungen.
+ +
+
+ + +
+
+
+

Rollen verwalten

+

Community-Rollen vergeben und entziehen.

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

Rolle: · seit

+
+
+ + + + +
+
+ + +
Keine Rollen vergeben.
+ +
+
+ + + +
+
+
+

Migration

+

Status der Community-Datenbank prüfen.

+
+
+
+
    +
  • Status:
  • +
  • Fehlende Bausteine:
  • +
+
+ + +
+
+
+ +
+
+
diff --git a/partials/landing/account/dashboard.php b/partials/landing/account/dashboard.php index cd97f99..f33cff8 100755 --- a/partials/landing/account/dashboard.php +++ b/partials/landing/account/dashboard.php @@ -30,10 +30,13 @@ $allowNoKidsChecked = $editEvent ? ((int)$editEvent['allow_kids'] === 0) : false
- +
Admin
-

Community-Migration

+

Community-Verwaltung

+
  • Status:
  • @@ -42,13 +45,13 @@ $allowNoKidsChecked = $editEvent ? ((int)$editEvent['allow_kids'] === 0) : false

    Migrationsstatus konnte nicht ermittelt werden.

    -
    - - -
    -

    - Führt die für Rollen, Bewerbungen, Meldungen, Bewertungen und Forenstruktur benötigten Datenbank-Erweiterungen aus. -

    + +
    + + +
    + +

    Bündelt Moderation, Bewerbungen, Rollen und bei Bedarf auch die Community-Migration.

diff --git a/partials/landing/community/index.php b/partials/landing/community/index.php index 078c1d9..5c72f20 100644 --- a/partials/landing/community/index.php +++ b/partials/landing/community/index.php @@ -16,10 +16,6 @@ $access = $pdo ? new \App\CommunityAccess($pdo, $communityCfg) : null; $stats = $community ? $community->getStats() : ['threads' => 0, 'posts' => 0, 'members' => 0]; $forumCategories = $community ? $community->listForumCategories() : []; $selectedBoard = ($community && $boardSlug !== '') ? $community->getBoardBySlug($boardSlug) : null; -$userRoles = $access && $userId ? $access->getUserRoles((int)$userId) : []; -$isForumAdmin = $access && $userId ? $access->canModerateForum((int)$userId) : false; -$canManageApplications = $access && $userId ? ($access->canManageApplications((int)$userId) && $access->supportsApplications()) : false; -$canManageRoles = $access && $userId ? $access->canManageRoles((int)$userId) : false; if ($_SERVER['REQUEST_METHOD'] === 'POST' && $community && $access) { $action = (string)($_POST['action'] ?? ''); @@ -34,21 +30,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && $community && $access) { } $community->createThreadInBoard((int)$userId, (string)($_POST['board_slug'] ?? ''), (string)($_POST['title'] ?? ''), (string)($_POST['body'] ?? '')); redirect('/community' . ($boardSlug !== '' ? '?board=' . rawurlencode($boardSlug) : '')); - } elseif ($action === 'application_decide') { - $access->decideApplication((int)$userId, (int)($_POST['application_id'] ?? 0), (string)($_POST['decision'] ?? ''), (string)($_POST['decision_reason'] ?? '')); - $info = 'Bewerbung wurde bearbeitet.'; - } elseif ($action === 'report_resolve') { - $access->resolveReport((int)$userId, (int)($_POST['report_id'] ?? 0), (string)($_POST['moderator_note'] ?? '')); - $info = 'Meldung wurde abgeschlossen.'; - } elseif ($action === 'role_revoke') { - $access->revokeRole((int)$userId, (int)($_POST['target_user_id'] ?? 0), (string)($_POST['role'] ?? '')); - $info = 'Rolle wurde entzogen.'; - } elseif ($action === 'restriction_set') { - $access->setRestriction((int)$userId, (int)($_POST['target_user_id'] ?? 0), (string)($_POST['restriction_type'] ?? ''), (string)($_POST['reason'] ?? '')); - $info = 'Community-Sperre wurde gesetzt.'; - } elseif ($action === 'restriction_clear') { - $access->clearRestriction((int)$userId, (int)($_POST['target_user_id'] ?? 0), (string)($_POST['restriction_type'] ?? '')); - $info = 'Community-Sperre wurde aufgehoben.'; } } catch (\Throwable $e) { $error = $e->getMessage(); @@ -58,9 +39,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && $community && $access) { $threads = $community ? ($search !== '' ? $community->searchThreads($search, 50, $boardSlug !== '' ? $boardSlug : null) : $community->listThreads(50, $boardSlug !== '' ? $boardSlug : null)) : []; -$applications = $canManageApplications && $access ? $access->listApplications('open') : []; -$reports = $isForumAdmin && $access ? $access->listOpenReports() : []; -$roleAssignments = $canManageRoles && $access ? $access->listRoleAssignments() : []; ?>
@@ -117,198 +95,157 @@ $roleAssignments = $canManageRoles && $access ? $access->listRoleAssignments() :
-
- -
-
-
- - -
-
- -
-

- - - -

-

-
- Themen: - Beiträge: + +
+ +
+
+ + +
+
+ Thema + Antworten + Letzte Aktivität +
+ + + computePoints((int)$t['uid']) : 0.0; + $lvl = $community ? $community->membershipLevel($pts) : ['label'=>'','icon'=>'']; + $preview = mb_substr((string)$t['body'], 0, 220); + ?> +
+
+ +
+

+
+ + +
+

220 ? '…' : '' ?>

-
-
- - - - - - Noch keine Themen - -
-
- +
+ + Antworten +
+
+ + +
+ + + + +
In diesem Bereich gibt es noch keine Themen.
+ +
- - -
- -
-
-
-

-

- -

- - Alle Bereiche anzeigen -
- -
-
- Thema - Antworten - Letzte Aktivität -
- - - computePoints((int)$t['uid']) : 0.0; - $lvl = $community ? $community->membershipLevel($pts) : ['label'=>'','icon'=>'']; - $preview = mb_substr((string)$t['body'], 0, 220); - ?> -
-
- -
-

-
- - - - - -
-

220 ? '…' : '' ?>

-
-
-
- - Antworten -
-
- - -
-
- - - -
Keine Themen gefunden.
- -
-
- - -
- -
-
-
-

Offene Bewerbungen

-

Bewerbungen ab Rang Community-Vater prüfen.

-
-
-
- -
-
- -

-
-
- - - -
- - + +
+ +
+
+
+ + +
+
+ +
+

+ + + +

+

+
+ Themen: + Beiträge: +
- -
- - -
Keine offenen Bewerbungen.
- -
-
- - - supportsReports()): ?> -
-
-
-

Offene Meldungen

-

Gemeldete Inhalte prüfen und moderieren.

-
-
-
- -
-
- # -

-

Gemeldet von am

-
- - - - -
-
- - -
Keine offenen Meldungen.
- -
-
- - - hasModerationTables()): ?> -
-
-
-

Rollenübersicht

-

Vergebene Community-Rollen im Blick behalten.

-
-
-
- -
-
- -

Rolle: · seit

+
+ + + + + + Noch keine Themen +
-
- - - - -
- -
Keine Rollen vergeben.
-
- + +
+ +
+
+
+

Neueste Themen

+

Hier siehst du die zuletzt erstellten oder zuletzt aktiven Themen aus der Community.

+
+
+ +
+
+ Thema + Antworten + Letzte Aktivität +
+ + + computePoints((int)$t['uid']) : 0.0; + $lvl = $community ? $community->membershipLevel($pts) : ['label'=>'','icon'=>'']; + $preview = mb_substr((string)$t['body'], 0, 220); + ?> +
+
+ +
+

+
+ + + + + +
+

220 ? '…' : '' ?>

+
+
+
+ + Antworten +
+
+ + +
+
+ + + +
Keine Themen gefunden.
+ +
diff --git a/partials/landing/community/sidebar.php b/partials/landing/community/sidebar.php new file mode 100644 index 0000000..1c67f35 --- /dev/null +++ b/partials/landing/community/sidebar.php @@ -0,0 +1,32 @@ + + diff --git a/partials/landing/community/thread.php b/partials/landing/community/thread.php index 07c7228..886c053 100644 --- a/partials/landing/community/thread.php +++ b/partials/landing/community/thread.php @@ -12,6 +12,7 @@ $editPostId = (int)($_GET['edit_post'] ?? 0); $communityCfg = require __DIR__ . '/../../../config/community.php'; $community = $pdo ? new \App\Community($pdo, $communityCfg) : null; $access = $pdo ? new \App\CommunityAccess($pdo, $communityCfg) : null; +$forumCategories = $community ? $community->listForumCategories() : []; if ($_SERVER['REQUEST_METHOD'] === 'POST' && $community && $access) { $action = (string)($_POST['action'] ?? ''); @@ -123,181 +124,190 @@ $userVotes = ($access && $userId) ? $access->getUserPostVotes((int)$userId, $pos
-
-
-

-

Erstellt von am

- -

Bereich:

- -
-
- - Antworten -
-
- - -
- - -
- - -
- -
-
- - #1 -
-
- -
- supportsReports()): ?> -
- - - - - -
- -
-
- -
-

Antworten

- Beitrag/Beiträge -
- -
- $p): ?> - 0, 'unhelpful' => 0]; - $userVote = $userVotes[(int)$p['id']] ?? 0; - $isHighlighted = !empty($p['highlighted_at']); - ?> -
-
diff --git a/public/assets/css/app.css b/public/assets/css/app.css index 33a00bc..9c143bb 100755 --- a/public/assets/css/app.css +++ b/public/assets/css/app.css @@ -177,6 +177,19 @@ body { .forum-board { background: #fff; border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); overflow: hidden; } .forum-board__head { display: flex; justify-content: space-between; gap: 20px; align-items: end; padding: 22px 24px; border-bottom: 1px solid var(--color-border); background: #fffdfa; } .forum-board__head h2 { margin: 0 0 6px; } +.forum-shell { display: grid; grid-template-columns: 290px minmax(0, 1fr); gap: 24px; margin-top: 24px; align-items: start; } +.forum-shell__main { min-width: 0; } +.forum-sidebar { position: sticky; top: 104px; } +.forum-sidebar__inner { background: #fff; border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); overflow: hidden; } +.forum-sidebar__head { padding: 20px 20px 16px; border-bottom: 1px solid var(--color-border); background: linear-gradient(180deg, #fffdfa, #f8f4ec); } +.forum-sidebar__head h2 { margin: 10px 0 0; font-size: 22px; } +.forum-sidebar__tree { padding: 14px; display: grid; gap: 14px; } +.forum-sidebar__group h3 { margin: 0 0 10px; font-size: 15px; color: var(--color-primary); } +.forum-sidebar__group ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; } +.forum-sidebar__group a { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 12px; border-radius: 12px; color: var(--color-text); transition: background .15s ease, color .15s ease; } +.forum-sidebar__group a:hover { background: #f8f4ec; color: var(--color-primary); } +.forum-sidebar__group a.is-active { background: var(--color-primary); color: var(--color-primary-contrast); } +.forum-sidebar__group small { font-size: 12px; opacity: .8; } .forum-search { display: grid; gap: 8px; min-width: min(100%, 360px); } .forum-search--hero { width: 100%; } .forum-search__row { display: flex; gap: 10px; } @@ -227,6 +240,7 @@ body { .forum-admin-item:first-child { border-top: 0; } .forum-admin-item p { margin: 8px 0 0; } .forum-admin-item__actions { display: grid; gap: 10px; } +.forum-hero--compact { padding-bottom: 8px; } .flex { display:flex; } .between { justify-content: space-between; } @@ -239,6 +253,8 @@ body { .forum-admin-item, .forum-list__header, .forum-row { grid-template-columns: minmax(0, 1fr); } + .forum-shell { grid-template-columns: 1fr; } + .forum-sidebar { position: static; } .forum-row__count, .forum-row__activity { grid-auto-flow: column; justify-content: start; gap: 10px; align-items: baseline; } .forum-post { grid-template-columns: 1fr; } diff --git a/public/page/community-admin.php b/public/page/community-admin.php new file mode 100644 index 0000000..d78fe88 --- /dev/null +++ b/public/page/community-admin.php @@ -0,0 +1,4 @@ +