diff --git a/Internal/de/PROJECT_CONTEXT.md b/Internal/de/PROJECT_CONTEXT.md index a24baf4..2561be1 100644 --- a/Internal/de/PROJECT_CONTEXT.md +++ b/Internal/de/PROJECT_CONTEXT.md @@ -19,6 +19,7 @@ Papa-Kind-Treff ist eine PHP-basierte Plattform für Väter. Kernbereiche sind l - Das Profilmenü oben rechts enthält nur `Profil`, für berechtigte Nutzer zusätzlich `Admin-Einstellungen`, sowie `Abmelden`. - Der Profilbereich enthält persönliche Angaben, Kinder, eigene Events, eigene Orte und Veranstaltungen, Cookie-/Kontoeinstellungen sowie Community-Informationen. - Der Admin-Bereich ist getrennt vom Profilbereich und enthält abhängig von der Berechtigung Profil-Levels, Kategorien, System-Einstellungen sowie Community-Moderation und Listing-Freigaben. +- Die Admin-Unterbereiche bleiben im selben Dashboard-Layout. Listing-Freigaben zeigen ausschließlich noch nicht veröffentlichte Orte und Veranstaltungen inklusive direkter Bearbeitung; Community-Moderation zeigt nur offene Bewerbungen und Meldungen; Rollen und System-Levels liegen im User Management, die Community-Migration liegt unter System. - Bestehende Direktlinks zu `Kategorien`, `Profil-Levels` und `System` werden automatisch in den Admin-Bereich eingeordnet. - Kinder können angelegt, bearbeitet und gelöscht werden. - Wenn ein Geburtsdatum gesetzt ist, wird das Alter automatisch berechnet und später bei Bedarf aktualisiert. diff --git a/Internal/de/PROJECT_STRUCTURE.md b/Internal/de/PROJECT_STRUCTURE.md index 4632e95..1c5cf1d 100644 --- a/Internal/de/PROJECT_STRUCTURE.md +++ b/Internal/de/PROJECT_STRUCTURE.md @@ -17,6 +17,7 @@ Stand: 2026-08-10 - Avatar-Verwaltung: `src/App/Avatar/AvatarManager.php` - aktive Styles: `src/App/Avatar/Lorelei.php`, `src/App/Avatar/Croodles.php` - Profil- und Admin-Bereiche mit getrennten Seitennavigationen: `partials/landing/account/dashboard.php`, Zugriffskontext in `src/App/AccountPages.php`, Einstieg über `partials/structure/nav.php` +- Admin-Freigaben, Community-Moderation, User Management und Migration werden im Dashboard durch `src/App/AccountPages.php` verarbeitet und in `partials/landing/account/dashboard.php` dargestellt. - Event-Quellen aus Datenbank plus Speicherung der Event-Location-Herkunft: `partials/landing/account/dashboard.php`, `src/App/AccountPages.php`, `Internal/db/schema.sql` - Consent- und rechtliche Texte: `public/page/datenschutz.php` - System-Einstellungen: `src/App/SystemSettings.php` @@ -25,11 +26,11 @@ Stand: 2026-08-10 - Kalender-Export und abonnierbarer Feed: `src/App/CalendarSync.php` plus `public/page/calendar/export.php` und `public/page/calendar/feed.php` - UI für getrennte Bereiche `Events` und `Orte & Veranstaltungen` im Mitgliederbereich: `partials/landing/account/dashboard.php` - eigener Mitgliederbereichspunkt `Kategorien` für neue Kategorien und deren Zusammenführung per Vorschlagsfeld: `partials/landing/account/dashboard.php`, `src/App/AccountPages.php`, `src/App/ListingCatalog.php` -- Community-Level-Rechte für Kategorien und Orts-/Veranstaltungsfreigaben: `config/community.php`, `src/App/Community.php`, `src/App/CommunityAccess.php`, `partials/landing/account/community-admin.php` +- Community-Level-Rechte für Kategorien und Orts-/Veranstaltungsfreigaben: `config/community.php`, `src/App/Community.php`, `src/App/CommunityAccess.php`, `src/App/AccountPages.php`, `partials/landing/account/dashboard.php` - Preis-, Bild- und Ortseingabe für Orte und Veranstaltungen sowie reduzierte Event-Maske: `partials/landing/account/dashboard.php` plus Speicherung in `src/App/ListingCatalog.php` -- Freigaben sowie Änderungs- und Löschanfragen für Orte und Veranstaltungen: `src/App/ListingCatalog.php`, `partials/landing/account/dashboard.php`, `partials/landing/account/community-admin.php` +- Freigaben sowie Änderungs- und Löschanfragen für Orte und Veranstaltungen: `src/App/ListingCatalog.php`, `src/App/AccountPages.php`, `partials/landing/account/dashboard.php` - Direktbearbeitung noch nicht veröffentlichter Orts- und Veranstaltungsvorschläge sowie Rechteauflösung für deren Freigabe: `src/App/CommunityAccess.php`, `src/App/AccountPages.php`, `src/App/ListingCatalog.php`, `partials/landing/account/dashboard.php` -- Rollenvergabe per Benutzersuche im Community-Admin: `partials/landing/account/community-admin.php`, `src/App/CommunityAccess.php` +- Rollenvergabe per Benutzersuche im User Management: `src/App/AccountPages.php`, `partials/landing/account/dashboard.php`, `src/App/CommunityAccess.php` - Legacy-Eigen-Events wurden erweitert in `src/App/AccountPages.php` und `Internal/db/schema.sql` um Kategorie- und Bildfelder - Kategorien-Prüfung und Zusammenführung für Seiten-Admins liegen ebenfalls in `partials/landing/account/dashboard.php` mit Logik in `src/App/ListingCatalog.php` diff --git a/Internal/de/README.md b/Internal/de/README.md index ea2324a..202a584 100644 --- a/Internal/de/README.md +++ b/Internal/de/README.md @@ -19,6 +19,7 @@ Papa-Kind-Treff ist eine PHP-basierte Plattform für Väter mit Fokus auf lokale - Profilmenü oben rechts mit `Profil` sowie für Berechtigte `Admin-Einstellungen` - Profilbereich für persönliche Angaben, Kinder, eigene Events, eigene Orte und Veranstaltungen, Einstellungen und Community-Informationen - Separater Admin-Bereich für Profil-Levels, Kategorien, System-Einstellungen sowie Moderation und Freigaben von Orten und Veranstaltungen +- Admin-Unterbereiche bleiben im selben Dashboard-Layout getrennt: Freigaben zeigen nur noch nicht veröffentlichte Orte und Veranstaltungen, Community-Moderation nur offene Bewerbungen und Meldungen, User Management enthält Rollen und System-Levels, System enthält die Community-Migration. - Konto-E-Mails sowie sensible Profilfelder werden app-seitig verschlüsselt gespeichert - Kinder können angelegt, bearbeitet und gelöscht werden - Profiladresse mit verschlüsselter Straße/Hausnummer, Adresssuche, Browser-Übernahme und Validierung diff --git a/Internal/en/PROJECT_CONTEXT.md b/Internal/en/PROJECT_CONTEXT.md index a6ebde0..a754387 100644 --- a/Internal/en/PROJECT_CONTEXT.md +++ b/Internal/en/PROJECT_CONTEXT.md @@ -19,6 +19,7 @@ Papa-Kind-Treff is a PHP-based platform for fathers. Core areas are local events - The top-right profile menu only contains `Profile`, `Admin Settings` for authorized users, and `Logout`. - The profile area contains personal information, children, own events, own places and event-style entries, cookie/account settings, and community information. - The admin area is separated from the profile area and contains, depending on permissions, profile levels, categories, system settings, community moderation, and listing approvals. +- Admin subsections stay within the same dashboard layout. Listing approvals only show not-yet-published places and event-style entries and allow direct editing; community moderation only shows open applications and reports; roles and system levels live in User Management, while the community migration lives under System. - Existing direct links to `Categories`, `Profile Levels`, and `System` are automatically assigned to the admin area. - Children can be created, edited, and deleted. - If a birth date is set, age is calculated automatically and updated later when needed. diff --git a/Internal/en/PROJECT_STRUCTURE.md b/Internal/en/PROJECT_STRUCTURE.md index 3a27455..8adb2a4 100644 --- a/Internal/en/PROJECT_STRUCTURE.md +++ b/Internal/en/PROJECT_STRUCTURE.md @@ -17,6 +17,7 @@ Updated: 2026-08-10 - avatar management: `src/App/Avatar/AvatarManager.php` - active avatar styles: `src/App/Avatar/Lorelei.php`, `src/App/Avatar/Croodles.php` - separated profile and admin navigation inside the member area: `partials/landing/account/dashboard.php`, access context in `src/App/AccountPages.php`, entry through `partials/structure/nav.php` +- admin approvals, community moderation, user management, and migration are processed in `src/App/AccountPages.php` and rendered within `partials/landing/account/dashboard.php`. - database-backed event location sources plus persisted event location origin: `partials/landing/account/dashboard.php`, `src/App/AccountPages.php`, `Internal/db/schema.sql` - consent and legal texts: `public/page/datenschutz.php` - system settings: `src/App/SystemSettings.php` @@ -25,11 +26,11 @@ Updated: 2026-08-10 - calendar export and subscribable feed: `src/App/CalendarSync.php` plus `public/page/calendar/export.php` and `public/page/calendar/feed.php` - separated `Events` and `Places & Events` UI in member area: `partials/landing/account/dashboard.php` - dedicated member-area section `Categories` for new categories and merging through a suggestion field: `partials/landing/account/dashboard.php`, `src/App/AccountPages.php`, `src/App/ListingCatalog.php` -- community-level rights for categories and place/event approvals: `config/community.php`, `src/App/Community.php`, `src/App/CommunityAccess.php`, `partials/landing/account/community-admin.php` +- community-level rights for categories and place/event approvals: `config/community.php`, `src/App/Community.php`, `src/App/CommunityAccess.php`, `src/App/AccountPages.php`, `partials/landing/account/dashboard.php` - pricing, image upload, and place/address input for places and event-style entries plus a reduced own-event form: `partials/landing/account/dashboard.php` with persistence in `src/App/ListingCatalog.php` -- approvals as well as change and deletion requests for places and event-style entries: `src/App/ListingCatalog.php`, `partials/landing/account/dashboard.php`, `partials/landing/account/community-admin.php` +- approvals as well as change and deletion requests for places and event-style entries: `src/App/ListingCatalog.php`, `src/App/AccountPages.php`, `partials/landing/account/dashboard.php` - direct editing for not-yet-published place and event-style suggestions plus approval-right resolution: `src/App/CommunityAccess.php`, `src/App/AccountPages.php`, `src/App/ListingCatalog.php`, `partials/landing/account/dashboard.php` -- role assignment via user search in community admin: `partials/landing/account/community-admin.php`, `src/App/CommunityAccess.php` +- role assignment via user search in User Management: `src/App/AccountPages.php`, `partials/landing/account/dashboard.php`, `src/App/CommunityAccess.php` - legacy own events were extended in `src/App/AccountPages.php` and `Internal/db/schema.sql` with category and image fields ## Documentation Rule diff --git a/Internal/en/README.md b/Internal/en/README.md index 2ae2385..c9e4f83 100644 --- a/Internal/en/README.md +++ b/Internal/en/README.md @@ -19,6 +19,7 @@ Papa-Kind-Treff is a PHP-based platform for fathers focused on local events, app - top-right profile menu with `Profile` and, for authorized users, `Admin Settings` - profile area for personal information, children, own events, own places and event-style entries, settings, and community information - separate admin area for profile levels, categories, system settings, and moderation and approvals for places and event-style entries +- Admin subsections stay inside the same dashboard layout: approvals only show not-yet-published places and event-style entries, community moderation only shows open applications and reports, User Management contains roles and system levels, and System contains the community migration. - account emails and sensitive profile fields are stored encrypted application-side - children can be created, edited, and deleted - profile address supports encrypted street/house number, address search, browser import, and validation diff --git a/README.md b/README.md index 8f3bd36..1f08ba9 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ Papa-Kind-Treff ist eine PHP-basierte Plattform für Väter mit Fokus auf: - Das Profilmenü oben rechts trennt klar zwischen `Profil` und dem nur für Berechtigte sichtbaren Punkt `Admin-Einstellungen`. - Der Profilbereich bündelt persönliche Angaben, Kinder, eigene Events, eigene Orte und Veranstaltungen, Cookie-/Kontoeinstellungen sowie Community-Informationen. - Der Admin-Bereich bündelt getrennt Profil-Levels, Kategorien, System-Einstellungen sowie die Moderation und Freigabe von Orten und Veranstaltungen. +- Innerhalb des Admin-Bereichs bleiben Freigaben, Community-Moderation, User Management, Profil-Levels und System im selben Dashboard-Layout getrennt; Rollen und System-Levels liegen im User Management, die Community-Migration im System. - In `Profil-Levels` kann der `SiteOwner` Community-Level pflegen, Benutzer suchen und Community-Punkte manuell mit Begründung erhöhen - In `Profil-Levels` werden zusätzlich Nutzer angezeigt, die in den letzten 30 Tagen mindestens den Rang `Säule der Väter-Community` erreicht haben - Im Bereich `Community-Admin` läuft die Rollenvergabe jetzt über eine Benutzersuche statt über rohe Benutzer-IDs; `Site-Admins` bleiben dabei auf die vorhandene Rollenlogik begrenzt diff --git a/partials/landing/account/dashboard.php b/partials/landing/account/dashboard.php index 02d3209..aa49d1c 100755 --- a/partials/landing/account/dashboard.php +++ b/partials/landing/account/dashboard.php @@ -147,7 +147,19 @@ $sectionLinks = $isAdminArea 'settings' => 'Einstellungen', ]; $showEventTypeChoice = !$editing && (($section ?? 'events') === 'places') && $requestedCreateListingKind === null; - $modalSectionTarget = ($editingListing || ($section ?? '') === 'places') ? 'places' : 'events'; +$modalSectionTarget = $isAdminArea && $editingListing + ? 'listing-review' + : (($editingListing || ($section ?? '') === 'places') ? 'places' : 'events'); +$modalActionArea = $isAdminArea && $editingListing ? 'area=admin&' : ''; +if ($isAdminArea && !empty($canReviewListings)) { + $sectionLinks['listing-review'] = 'Orte & Veranstaltungen freigeben'; +} +if ($isAdminArea && (!empty($canModerateForum) || !empty($canManageSystemSettings))) { + $sectionLinks['community-moderation'] = 'Community-Moderation'; +} +if ($isAdminArea && !empty($canManageUserManagement)) { + $sectionLinks['user-management'] = 'User Management'; +} if ($isAdminArea && !empty($canManageCategories)) { $sectionLinks['categories'] = 'Kategorien'; } @@ -188,10 +200,6 @@ if ($isAdminArea && !empty($canManageSystemSettings)) { - - Orte & Veranstaltungen freigeben - Community-Moderation - Zum Profil @@ -208,16 +216,25 @@ if ($isAdminArea && !empty($canManageSystemSettings)) {
- - + + Freigaben Orte & Veranstaltungen -

Neue Einträge sowie Änderungs- und Löschanfragen prüfen.

+

Noch nicht veröffentlichte Orte und Veranstaltungen prüfen.

- + + + Moderation Community -

Meldungen, Bewerbungen und Rollen verwalten.

+

Offene Bewerbungen und Meldungen bearbeiten.

+
+ + + + Zugriffe + User Management +

Systemrollen und Benutzerzugriffe verwalten.

@@ -231,7 +248,7 @@ if ($isAdminArea && !empty($canManageSystemSettings)) { Community Profil-Levels -

Level, Punkte und Systemrollen verwalten.

+

Community-Level und Community-Punkte verwalten.

@@ -245,6 +262,45 @@ if ($isAdminArea && !empty($canManageSystemSettings)) {
+ +
+ + +
+ + +
+ + +
+
@@ -569,33 +612,6 @@ if ($isAdminArea && !empty($canManageSystemSettings)) {
-
- System-Level -
- -
- - -
- Aktuell: - -
- -
    - -
  • - -
-
- -
-
@@ -1015,6 +1031,15 @@ if ($isAdminArea && !empty($canManageSystemSettings)) {
  • Fehlende Tabellen:
  • + + +
    + Community-Migration +

    Status:

    +

    Fehlende Bausteine:

    +
    +
    + @@ -1530,7 +1555,7 @@ if ($isAdminArea && !empty($canManageSystemSettings)) {

    -
    + diff --git a/public/page/community-admin.php b/public/page/community-admin.php index d78fe88..a9138f6 100644 --- a/public/page/community-admin.php +++ b/public/page/community-admin.php @@ -1,4 +1,4 @@ computePoints($userId) : 0.0; $canManageCategories = $communityAccess ? $communityAccess->canManageCategories($userId, $communityPointsForAccess) : false; $canReviewListings = $communityAccess ? $communityAccess->canReviewListings($userId, $communityPointsForAccess) : false; + $canModerateForum = $communityAccess ? $communityAccess->canModerateForum($userId) : false; $canAccessCommunityAdmin = $communityAccess ? $communityAccess->canAccessCommunityAdmin($userId, $communityPointsForAccess) : false; + $canManageUserManagement = $canManageProfileLevels || $canManageSystemSettings; $canAccessAdminArea = $canAccessCommunityAdmin || $canManageCategories || $canManageSystemSettings || $canManageProfileLevels; // Alte Deep Links zu Verwaltungssektionen bleiben gültig, landen aber im getrennten Admin-Bereich. @@ -211,6 +213,15 @@ final class AccountPages if ($area === 'admin' && $canManageProfileLevels) { $allowedSections[] = 'profile-levels'; } + if ($area === 'admin' && $canReviewListings) { + $allowedSections[] = 'listing-review'; + } + if ($area === 'admin' && ($canModerateForum || $canManageSystemSettings)) { + $allowedSections[] = 'community-moderation'; + } + if ($area === 'admin' && $canManageUserManagement) { + $allowedSections[] = 'user-management'; + } if ($systemSettings) { $systemSettings->ensureSchema(); @@ -705,6 +716,42 @@ final class AccountPages } $communityAccess->submitApplication($userId, (string)($_POST['motivation'] ?? '')); $info = 'Deine Bewerbung wurde eingereicht.'; + } elseif ($action === 'listing_request_decide') { + if (!$canReviewListings || !$listingCatalog) { + throw new \RuntimeException('Keine Berechtigung für Listing-Freigaben.'); + } + $listingCatalog->decideModerationRequest($userId, (int)($_POST['request_id'] ?? 0), (string)($_POST['decision'] ?? ''), (string)($_POST['review_note'] ?? '')); + $info = 'Ort oder Veranstaltung wurde bearbeitet.'; + } elseif ($action === 'application_decide') { + if (!$canManageSystemSettings || !$communityAccess) { + throw new \RuntimeException('Keine Berechtigung für Bewerbungen.'); + } + $communityAccess->decideApplication($userId, (int)($_POST['application_id'] ?? 0), (string)($_POST['decision'] ?? ''), (string)($_POST['decision_reason'] ?? '')); + $info = 'Bewerbung wurde bearbeitet.'; + } elseif ($action === 'report_resolve') { + if (!$canModerateForum || !$communityAccess) { + throw new \RuntimeException('Keine Berechtigung für Meldungen.'); + } + $communityAccess->resolveReport($userId, (int)($_POST['report_id'] ?? 0), (string)($_POST['moderator_note'] ?? '')); + $info = 'Meldung wurde abgeschlossen.'; + } elseif ($action === 'role_assign') { + if (!$canManageUserManagement || !$communityAccess) { + throw new \RuntimeException('Keine Berechtigung für die Benutzerverwaltung.'); + } + $communityAccess->assignRole($userId, (int)($_POST['target_user_id'] ?? 0), (string)($_POST['role'] ?? '')); + $info = 'Rolle wurde vergeben.'; + } elseif ($action === 'role_revoke') { + if (!$canManageUserManagement || !$communityAccess) { + throw new \RuntimeException('Keine Berechtigung für die Benutzerverwaltung.'); + } + $communityAccess->revokeRole($userId, (int)($_POST['target_user_id'] ?? 0), (string)($_POST['role'] ?? '')); + $info = 'Rolle wurde entzogen.'; + } elseif ($action === 'community_migrate') { + if (!$canManageSystemSettings || !$communityMigration) { + throw new \RuntimeException('Keine Berechtigung für die Community-Migration.'); + } + $communityMigration->apply(); + $info = 'Die Community-Migration wurde ausgeführt.'; } elseif ($action === 'community_level_save') { if (!$canManageProfileLevels || !$community) { throw new \RuntimeException('Keine Berechtigung für Profil-Levels.'); @@ -1010,7 +1057,17 @@ final class AccountPages $communityLevelDefinitions = $community ? $community->listMembershipLevels() : []; $communityLevelRightDefinitions = Community::membershipRightDefinitions(); $communityRoles = $communityAccess ? $communityAccess->getUserRoles($userId) : []; - $systemRoleAssignments = $communityAccess && $canManageProfileLevels ? $communityAccess->listRoleAssignments() : []; + $systemRoleAssignments = $communityAccess && $canManageUserManagement ? $communityAccess->listRoleAssignments() : []; + $listingReviewRequests = $canReviewListings && $listingCatalog + ? array_values(array_filter($listingCatalog->listOpenModerationRequests(), static fn(array $request): bool => (string)($request['request_type'] ?? '') === 'create')) + : []; + $communityApplications = $canManageSystemSettings && $communityAccess ? $communityAccess->listApplications('open') : []; + $communityReports = $canModerateForum && $communityAccess && $communityAccess->supportsReports() ? $communityAccess->listOpenReports() : []; + $userManagementSearchQuery = trim((string)($_GET['user_management_query'] ?? '')); + $userManagementSearchResults = $canManageUserManagement && $communityAccess && $userManagementSearchQuery !== '' + ? $communityAccess->searchUsers($userManagementSearchQuery, 12) + : []; + $communityMigrationStatus = $communityMigration && $canManageSystemSettings ? $communityMigration->status() : null; $recentHighLevelUsers = []; $recentHighLevelThresholdLabel = ''; $profileLevelUserSearchQuery = ''; @@ -1122,9 +1179,17 @@ final class AccountPages 'communityLevelRightDefinitions', 'communityRoles', 'canReviewListings', + 'canModerateForum', 'canAccessCommunityAdmin', 'canAccessAdminArea', + 'canManageUserManagement', 'systemRoleAssignments', + 'listingReviewRequests', + 'communityApplications', + 'communityReports', + 'userManagementSearchQuery', + 'userManagementSearchResults', + 'communityMigrationStatus', 'recentHighLevelUsers', 'recentHighLevelThresholdLabel', 'profileLevelUserSearchQuery',