1305 lines
42 KiB
PHP
1305 lines
42 KiB
PHP
<?php /* Name: admin.php
|
||
Beschreibung: Administration Panel */
|
||
|
||
// Initialisierung
|
||
require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/initialise.php';
|
||
|
||
/**
|
||
* Gibt alle echten Rollen-Spalten aus user_permissions zurück.
|
||
* Dadurch werden auch künftig neu ergänzte Rollen automatisch angezeigt.
|
||
*/
|
||
function getPermissionRoles(PDO $pdo): array {
|
||
$roles = [];
|
||
$sql = "SELECT column_name FROM information_schema.columns WHERE table_name = 'user_permissions' AND table_schema = 'public'";
|
||
$result = $pdo->query($sql);
|
||
|
||
while ($column = $result->fetch(PDO::FETCH_ASSOC)) {
|
||
$field = $column['column_name'];
|
||
if (!in_array($field, ['p_id', 'user_id'], true)) {
|
||
$roles[] = $field;
|
||
}
|
||
}
|
||
|
||
return $roles;
|
||
}
|
||
|
||
function quoteIdentifier(string $identifier): string {
|
||
return '"' . str_replace('"', '""', $identifier) . '"';
|
||
}
|
||
|
||
function getProfileImageUrl(array $group, string $g_profilePicturePath): string {
|
||
$profileImg = glob($g_profilePicturePath."{$group['user_id']}-*.jpg");
|
||
if (!empty($profileImg)) {
|
||
usort($profileImg, function($a, $b) {
|
||
return filemtime($b) - filemtime($a);
|
||
});
|
||
$latestProfileImg = $profileImg[0];
|
||
return str_replace($_SERVER['DOCUMENT_ROOT'], '', $latestProfileImg);
|
||
}
|
||
|
||
return '/intranet_repo/general_files/profile_pictures/default.jpg';
|
||
}
|
||
|
||
function getDisplayName(array $group): string {
|
||
$fullName = trim(($group['first_name'] ?? '') . ' ' . ($group['last_name'] ?? ''));
|
||
return $fullName !== '' ? $fullName : ($group['mail'] ?? 'Unbekannt');
|
||
}
|
||
|
||
$permissionRoles = getPermissionRoles($pdo);
|
||
|
||
/* Besondere Admin-Rechte checken */
|
||
$stmt = $pdo->prepare("SELECT up.* FROM user_permissions up WHERE up.user_id = ? LIMIT 1");
|
||
$stmt->execute([$_SESSION["user_id"]]);
|
||
$isAdmin = $stmt->fetch(PDO::FETCH_ASSOC);
|
||
|
||
if (!$isAdmin || (int)($isAdmin["Admin"] ?? 0) !== 1) {
|
||
header("Location: {$g_httpHomePath}");
|
||
exit();
|
||
}
|
||
|
||
// Neuen Nutzer inklusive Rollen anlegen
|
||
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["addRecord"])) {
|
||
$newMail = trim($_POST["newMail"] ?? '');
|
||
$newFirstName = trim($_POST["newFirstName"] ?? '');
|
||
$newLastName = trim($_POST["newLastName"] ?? '');
|
||
$selectedRoles = $_POST["newRoles"] ?? [];
|
||
if (!is_array($selectedRoles)) {
|
||
$selectedRoles = [];
|
||
}
|
||
|
||
if (empty($newMail) || empty($newFirstName) || empty($newLastName)) {
|
||
header("Location: admin.php?message=7");
|
||
exit();
|
||
}
|
||
|
||
$checkSql = "SELECT COUNT(*) FROM user_general_information WHERE mail=?";
|
||
$checkStmt = $pdo->prepare($checkSql);
|
||
$checkStmt->execute([$newMail]);
|
||
$count = $checkStmt->fetchColumn();
|
||
|
||
if ($count > 0) {
|
||
header("Location: admin.php?message=4");
|
||
exit();
|
||
}
|
||
|
||
$pdo->beginTransaction();
|
||
try {
|
||
$insertSql = "INSERT INTO user_general_information (mail, first_name, last_name) VALUES (?, ?, ?)";
|
||
$stmt = $pdo->prepare($insertSql);
|
||
$stmt->execute([$newMail, $newFirstName, $newLastName]);
|
||
$newId = $pdo->lastInsertId();
|
||
|
||
// Fallback, falls insert_id wegen DB-Konfiguration nicht gesetzt ist
|
||
if (!$newId) {
|
||
$checkSql = "SELECT user_id FROM user_general_information WHERE mail=?";
|
||
$checkStmt = $pdo->prepare($checkSql);
|
||
$checkStmt->execute([$newMail]);
|
||
$row = $checkStmt->fetch(PDO::FETCH_ASSOC);
|
||
$newId = $row['user_id'];
|
||
}
|
||
|
||
$roleColumns = array_map('quoteIdentifier', $permissionRoles);
|
||
$columns = array_merge(['user_id'], $roleColumns);
|
||
$placeholders = array_fill(0, count($columns), '?');
|
||
$roleValues = [];
|
||
foreach ($permissionRoles as $role) {
|
||
$roleValues[] = in_array($role, $selectedRoles, true) ? 1 : 0;
|
||
}
|
||
$params = array_merge([(int)$newId], $roleValues);
|
||
|
||
$insertPermissionsSql = "INSERT INTO user_permissions (" . implode(', ', $columns) . ") VALUES (" . implode(', ', $placeholders) . ")";
|
||
$stmt = $pdo->prepare($insertPermissionsSql);
|
||
$stmt->execute($params);
|
||
|
||
$pdo->commit();
|
||
} catch (Throwable $e) {
|
||
$pdo->rollBack();
|
||
throw $e;
|
||
}
|
||
|
||
// Einladungsmail an den neuen Nutzer senden
|
||
require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/ini/send_mail.php';
|
||
$displayName = trim("{$newFirstName} {$newLastName}");
|
||
$greeting = !empty($displayName) ? "Hallo {$newFirstName}" : "Hallo";
|
||
$signupUrl = "https://" . $_SERVER['HTTP_HOST'] . "/intranet_repo/projects/authorization/signup.php";
|
||
|
||
$userBetreff = "Einladung zum Intranet NAK Reinickendorf";
|
||
$userNachricht = "{$greeting},\n\n";
|
||
$userNachricht .= "Sie wurden zum Intranet der NAK Reinickendorf eingeladen.\n\n";
|
||
$userNachricht .= "Bitte registrieren Sie sich mit der E-Mail-Adresse {$newMail} über den folgenden Link, um Ihren Zugang zu aktivieren.";
|
||
|
||
send_intranet_mail($newMail, $userBetreff, $userNachricht, null, "intranet@nak-reinickendorf.de", "Jetzt registrieren", $signupUrl);
|
||
|
||
// Info-Mail an Admins
|
||
$adminName = trim(($user['first_name'] ?? '') . ' ' . ($user['last_name'] ?? ''));
|
||
if (empty($adminName)) $adminName = 'Ein Administrator';
|
||
$nutzerAnzeige = !empty($displayName) ? $displayName : $newMail;
|
||
|
||
$adminBetreff = "Neuer Nutzer angelegt: {$nutzerAnzeige}";
|
||
$adminNachricht = "{$adminName} hat einen neuen Nutzer angelegt:\n\n";
|
||
$adminNachricht .= "Name: " . (!empty($displayName) ? $displayName : '(kein Name)') . "\n";
|
||
$adminNachricht .= "E-Mail: {$newMail}\n";
|
||
$adminNachricht .= "Rollen: " . (!empty($selectedRoles) ? implode(', ', $selectedRoles) : 'Keine');
|
||
|
||
send_admin_team_mail($pdo, $adminBetreff, $adminNachricht);
|
||
|
||
header("Location: admin.php?message=3");
|
||
exit();
|
||
}
|
||
|
||
// Einladungsmail erneut senden
|
||
if ($_SERVER["REQUEST_METHOD"] === "GET" && isset($_GET["resendInvite"])) {
|
||
$resendUserId = (int)($_GET["resendInvite"] ?? 0);
|
||
if ($resendUserId > 0) {
|
||
require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/ini/send_mail.php';
|
||
$stmt = $pdo->prepare("SELECT mail, first_name, last_name FROM user_general_information WHERE user_id = ?");
|
||
$stmt->execute([$resendUserId]);
|
||
$invUser = $stmt->fetch(PDO::FETCH_ASSOC);
|
||
|
||
if ($invUser) {
|
||
$displayName = trim(($invUser['first_name'] ?? '') . ' ' . ($invUser['last_name'] ?? ''));
|
||
$greeting = !empty($invUser['first_name']) ? "Hallo {$invUser['first_name']}" : "Hallo";
|
||
$signupUrl = "https://" . $_SERVER['HTTP_HOST'] . "/intranet_repo/projects/authorization/signup.php";
|
||
|
||
$userBetreff = "Erinnerung: Einladung zum Intranet NAK Reinickendorf";
|
||
$userNachricht = "{$greeting},\n\n";
|
||
$userNachricht .= "Sie wurden zum Intranet der NAK Reinickendorf eingeladen und haben sich noch nicht registriert.\n\n";
|
||
$userNachricht .= "Bitte registrieren Sie sich mit der E-Mail-Adresse {$invUser['mail']} über den folgenden Link, um Ihren Zugang zu aktivieren.";
|
||
|
||
send_intranet_mail($invUser['mail'], $userBetreff, $userNachricht, null, "intranet@nak-reinickendorf.de", "Jetzt registrieren", $signupUrl);
|
||
}
|
||
}
|
||
header("Location: admin.php?message=6");
|
||
exit();
|
||
}
|
||
|
||
// Rollen speichern
|
||
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["editRecord"])) {
|
||
$editedID = (int)($_POST["editedID"] ?? 0);
|
||
$selectedRoles = $_POST["roles"] ?? [];
|
||
if (!is_array($selectedRoles)) {
|
||
$selectedRoles = [];
|
||
}
|
||
|
||
// Update name, email and phone in user_general_information
|
||
$editFirstName = trim($_POST["edit_first_name"] ?? '');
|
||
$editLastName = trim($_POST["edit_last_name"] ?? '');
|
||
$editMail = trim($_POST["edit_mail"] ?? '');
|
||
$editPhone = trim($_POST["edit_phone"] ?? '');
|
||
$editPhoneVal = ($editPhone !== '') ? $editPhone : null;
|
||
|
||
if ($editMail !== '') {
|
||
$stmtInfo = $pdo->prepare("UPDATE user_general_information SET first_name=?, last_name=?, mail=?, phone=? WHERE user_id=?");
|
||
$stmtInfo->execute([$editFirstName, $editLastName, $editMail, $editPhoneVal, $editedID]);
|
||
}
|
||
|
||
// Update roles in user_permissions
|
||
$setParts = [];
|
||
$params = [];
|
||
foreach ($permissionRoles as $role) {
|
||
$setParts[] = quoteIdentifier($role) . "=?";
|
||
$params[] = in_array($role, $selectedRoles, true) ? 1 : 0;
|
||
}
|
||
$params[] = $editedID;
|
||
|
||
$updateSql = "UPDATE user_permissions SET " . implode(', ', $setParts) . " WHERE user_id=?";
|
||
$stmt = $pdo->prepare($updateSql);
|
||
$stmt->execute($params);
|
||
|
||
// Vermerk in erledigte Tasks
|
||
$stmt = $pdo->prepare("SELECT mail, first_name, last_name FROM user_general_information WHERE user_id = ?");
|
||
$stmt->execute([$editedID]);
|
||
$editedUser = $stmt->fetch(PDO::FETCH_ASSOC);
|
||
|
||
$adminName = trim(($user['first_name'] ?? '') . ' ' . ($user['last_name'] ?? ''));
|
||
if (empty($adminName)) $adminName = 'Ein Administrator';
|
||
$editedUserName = trim(($editedUser['first_name'] ?? '') . ' ' . ($editedUser['last_name'] ?? ''));
|
||
if (empty($editedUserName)) $editedUserName = $editedUser['mail'] ?? 'Unbekannt';
|
||
$assignedRoles = !empty($selectedRoles) ? implode(', ', $selectedRoles) : 'Keine';
|
||
|
||
$taskSubject = "Profil aktualisiert: {$editedUserName}";
|
||
$taskMessage = "{$adminName} hat das Profil von {$editedUserName} aktualisiert.\nNeue Rollen: {$assignedRoles}";
|
||
|
||
$stmt = $pdo->prepare("INSERT INTO admin_messages (type, sender_name, sender_email, subject, message, status, processed_at, created_at) VALUES ('system', ?, ?, ?, ?, 'done', NOW(), NOW())");
|
||
$senderMail = $editedUser['mail'] ?? '';
|
||
$stmt->execute([$adminName, $senderMail, $taskSubject, $taskMessage]);
|
||
|
||
header("Location: admin.php?message=5");
|
||
exit();
|
||
}
|
||
|
||
if ($_SERVER["REQUEST_METHOD"] === "GET" && isset($_GET["delete"])) {
|
||
$deleteUserId = (int)$_GET["delete"];
|
||
|
||
$deleteSql = "DELETE FROM user_general_information WHERE user_id=?";
|
||
$stmt = $pdo->prepare($deleteSql);
|
||
$stmt->execute([$deleteUserId]);
|
||
|
||
header("Location: admin.php?message=2");
|
||
exit();
|
||
}
|
||
|
||
if ($_SERVER["REQUEST_METHOD"] === "GET" && isset($_GET["resetPassword"])) {
|
||
$resetUserId = (int)$_GET["resetPassword"];
|
||
|
||
// Login-Daten löschen (Name und Telefon bleiben erhalten)
|
||
$deleteSql = "DELETE FROM user_login WHERE user_id=?";
|
||
$stmt = $pdo->prepare($deleteSql);
|
||
$stmt->execute([$resetUserId]);
|
||
|
||
// User-Daten für Mail laden
|
||
$stmt = $pdo->prepare("SELECT mail, first_name, last_name FROM user_general_information WHERE user_id = ?");
|
||
$stmt->execute([$resetUserId]);
|
||
$resetUser = $stmt->fetch(PDO::FETCH_ASSOC);
|
||
|
||
if ($resetUser) {
|
||
require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/ini/send_mail.php';
|
||
$signupUrl = "https://" . $_SERVER['HTTP_HOST'] . "/intranet_repo/projects/authorization/signup.php";
|
||
$greeting = !empty($resetUser['first_name']) ? "Hallo {$resetUser['first_name']}" : "Hallo";
|
||
|
||
$userBetreff = "Passwort zurückgesetzt";
|
||
$userNachricht = "{$greeting},\n\n";
|
||
$userNachricht .= "Ihr Passwort für das Intranet der NAK Reinickendorf wurde von einem Administrator zurückgesetzt.\n\n";
|
||
$userNachricht .= "Bitte registrieren Sie sich erneut über den folgenden Link, um ein neues Passwort festzulegen.";
|
||
|
||
send_intranet_mail($resetUser['mail'], $userBetreff, $userNachricht, null, "intranet@nak-reinickendorf.de", "Jetzt neu registrieren", $signupUrl);
|
||
|
||
// Vermerk in erledigte Tasks schreiben
|
||
$adminName = trim(($user['first_name'] ?? '') . ' ' . ($user['last_name'] ?? ''));
|
||
if (empty($adminName)) $adminName = 'Ein Administrator';
|
||
$resetUserName = trim(($resetUser['first_name'] ?? '') . ' ' . ($resetUser['last_name'] ?? ''));
|
||
if (empty($resetUserName)) $resetUserName = $resetUser['mail'];
|
||
|
||
$taskSubject = "Passwort zurückgesetzt: {$resetUserName}";
|
||
$taskMessage = "{$adminName} hat das Passwort von {$resetUserName} ({$resetUser['mail']}) zurückgesetzt. Eine Registrierungsmail wurde versendet.";
|
||
|
||
$stmt = $pdo->prepare("INSERT INTO admin_messages (type, sender_name, sender_email, subject, message, status, processed_at, created_at) VALUES ('system', ?, ?, ?, ?, 'done', NOW(), NOW())");
|
||
$stmt->execute([$adminName, $resetUser['mail'], $taskSubject, $taskMessage]);
|
||
}
|
||
|
||
header("Location: admin.php?message=1");
|
||
exit();
|
||
}
|
||
|
||
if (isset($_GET['partner_id'])) {
|
||
$_SESSION["profile_id"] = (int)$_GET['partner_id'];
|
||
header("Location: admin_profiles.php");
|
||
exit();
|
||
}
|
||
|
||
// Nutzer inklusive aller Rechte laden: Registrierte Nutzer zuerst, dann Name, dann Mail.
|
||
$sql_groups = "SELECT up.*, ugi.mail, ugi.first_name, ugi.last_name, ugi.phone,
|
||
CASE WHEN ul.user_id IS NOT NULL THEN 1 ELSE 0 END AS \"IstRegistriert\"
|
||
FROM user_permissions up
|
||
LEFT JOIN user_general_information ugi ON up.user_id = ugi.user_id
|
||
LEFT JOIN user_login ul ON up.user_id = ul.user_id
|
||
ORDER BY \"IstRegistriert\" DESC, COALESCE(ugi.last_name, ''), COALESCE(ugi.first_name, ''), ugi.mail";
|
||
$result_groups = $pdo->query($sql_groups);
|
||
$groups = $result_groups->fetchAll(PDO::FETCH_ASSOC);
|
||
|
||
?>
|
||
<!DOCTYPE html>
|
||
<html lang="de" dir="ltr">
|
||
<head>
|
||
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/html_head.php'; ?>
|
||
<style>
|
||
|
||
/* Controls moved to table header */
|
||
.admin-list-controls {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
.admin-list-filter-control {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 7px;
|
||
padding: 5px 9px;
|
||
min-height: 30px;
|
||
background: rgba(120, 140, 160, 0.08);
|
||
border: 1px solid rgba(120, 140, 160, 0.2);
|
||
}
|
||
.admin-list-filter-control svg {
|
||
width: 15px;
|
||
height: 15px;
|
||
fill: none;
|
||
stroke: hsl(210, 16%, 46%);
|
||
stroke-width: 2;
|
||
stroke-linecap: round;
|
||
stroke-linejoin: round;
|
||
opacity: 0.8;
|
||
}
|
||
.admin-list-filter-wrap {
|
||
position: relative;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
}
|
||
.admin-list-filter-wrap::after {
|
||
content: '▾';
|
||
position: absolute;
|
||
right: 2px;
|
||
font-size: 0.7em;
|
||
pointer-events: none;
|
||
opacity: 0.6;
|
||
color: hsl(210, 16%, 46%);
|
||
}
|
||
.admin-list-filter-control select {
|
||
appearance: none;
|
||
-webkit-appearance: none;
|
||
min-width: 120px;
|
||
max-width: 22vw;
|
||
padding: 2px 20px 2px 2px;
|
||
color: hsl(210, 20%, 25%);
|
||
background: transparent;
|
||
border: none;
|
||
outline: none;
|
||
font-size: 0.86em;
|
||
font-weight: 650;
|
||
cursor: pointer;
|
||
}
|
||
.admin-list-filter-control select option {
|
||
color: hsl(210, 20%, 15%);
|
||
background: #FFFFFF;
|
||
}
|
||
.admin-list-add-btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
padding: 7px 14px;
|
||
color: #FFFFFF;
|
||
background: linear-gradient(135deg, var(--gray-800), var(--gray-900));
|
||
border: 1px solid var(--gray-900);
|
||
border-radius: 0;
|
||
font-size: 0.86em;
|
||
font-weight: 850;
|
||
cursor: pointer;
|
||
text-decoration: none;
|
||
white-space: nowrap;
|
||
box-shadow: 0 4px 12px rgba(31,38,46,0.06);
|
||
}
|
||
.admin-list-add-btn:hover {
|
||
background: linear-gradient(135deg, var(--gray-900), #1a1a2e);
|
||
color: #FFFFFF;
|
||
text-decoration: none;
|
||
}
|
||
.admin-users-shell {
|
||
padding: 18px;
|
||
background: linear-gradient(135deg, var(--gray-50) 0%, var(--theme-light, var(--nak-blue-light)) 100%);
|
||
min-height: 100%;
|
||
}
|
||
.admin-table-card {
|
||
overflow: hidden;
|
||
border: 1px solid rgba(120, 140, 160, 0.22);
|
||
border-radius: 0;
|
||
background: rgba(255,255,255,0.86);
|
||
box-shadow: 0 20px 45px rgba(31, 38, 46, 0.10), 0 1px 0 rgba(255,255,255,0.9) inset;
|
||
}
|
||
.admin-list-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 12px;
|
||
padding: 16px 18px 12px 18px;
|
||
border-bottom: 1px solid rgba(120, 140, 160, 0.16);
|
||
background: linear-gradient(180deg, rgba(255,255,255,0.92), rgba(255,255,255,0.72));
|
||
}
|
||
.admin-list-title {
|
||
font-size: 1.05em;
|
||
font-weight: 800;
|
||
color: hsl(210, 20%, 15%);
|
||
}
|
||
.admin-list-hint {
|
||
font-size: 0.86em;
|
||
color: hsl(210, 15%, 46%);
|
||
}
|
||
table.admin-user-table {
|
||
display: table !important;
|
||
width: calc(100% - 24px);
|
||
margin: 8px 12px 14px 12px;
|
||
border-collapse: separate;
|
||
border-spacing: 0 8px;
|
||
padding: 0;
|
||
background: transparent;
|
||
overflow: visible;
|
||
}
|
||
.admin-user-table:after { display: none; }
|
||
.admin-user-table thead th {
|
||
position: sticky;
|
||
top: 0;
|
||
padding: 10px 14px;
|
||
color: hsl(210, 16%, 46%);
|
||
font-size: 0.78em;
|
||
font-weight: 800;
|
||
text-align: left;
|
||
letter-spacing: 0.04em;
|
||
text-transform: uppercase;
|
||
background: transparent !important;
|
||
border: none !important;
|
||
box-shadow: none;
|
||
}
|
||
.admin-user-table thead th::after { display: none; }
|
||
.admin-user-table tbody tr.admin-user-row {
|
||
position: relative;
|
||
cursor: pointer;
|
||
background: rgba(255, 255, 255, 0.92);
|
||
border-radius: 0;
|
||
box-shadow: 0 6px 18px rgba(31, 38, 46, 0.06);
|
||
transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
|
||
}
|
||
.admin-user-table tbody tr.admin-user-row:hover,
|
||
.admin-user-table tbody tr.admin-user-row:focus {
|
||
transform: translateY(-1px);
|
||
background: #FFFFFF;
|
||
box-shadow: 0 12px 26px rgba(31, 38, 46, 0.13);
|
||
outline: none !important;
|
||
filter: none !important;
|
||
}
|
||
.admin-user-table td {
|
||
padding: 12px 14px !important;
|
||
vertical-align: middle;
|
||
border: none !important;
|
||
background: transparent !important;
|
||
}
|
||
.admin-user-table tbody tr.admin-user-row td:first-child {
|
||
position: static !important;
|
||
width: 82px;
|
||
min-width: 82px;
|
||
max-width: 82px;
|
||
border-radius: 0;
|
||
}
|
||
.admin-user-table tbody tr.admin-user-row td:last-child {
|
||
border-radius: 0;
|
||
}
|
||
.admin-profile-button,
|
||
.admin-name-button {
|
||
padding: 0;
|
||
margin: 0;
|
||
border: 0;
|
||
background: transparent;
|
||
font: inherit;
|
||
color: inherit;
|
||
cursor: pointer;
|
||
text-align: left;
|
||
}
|
||
.admin-profile-button {
|
||
display: block;
|
||
width: 58px;
|
||
height: 58px;
|
||
border-radius: 12px;
|
||
overflow: hidden;
|
||
box-shadow: 0 8px 20px rgba(31, 38, 46, 0.18), 0 0 0 3px rgba(255,255,255,0.95);
|
||
}
|
||
.admin-profile-button img,
|
||
.admin-user-table img {
|
||
display: block;
|
||
width: 58px !important;
|
||
height: 58px !important;
|
||
padding: 0 !important;
|
||
object-fit: cover;
|
||
border: none !important;
|
||
border-radius: 12px !important;
|
||
transition: transform 0.2s ease;
|
||
}
|
||
.admin-profile-button:hover img,
|
||
.admin-user-table tbody tr.admin-user-row:hover .admin-profile-button img,
|
||
.admin-user-table tbody tr.admin-user-row:focus .admin-profile-button img {
|
||
transform: scale(1.08);
|
||
}
|
||
.admin-user-name {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
font-size: 1em;
|
||
font-weight: 800;
|
||
color: hsl(210, 20%, 15%);
|
||
}
|
||
.admin-name-button:hover .admin-user-name {
|
||
color: var(--theme-color, var(--nak-blue));
|
||
text-decoration: none;
|
||
}
|
||
.admin-registration-badge {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
padding: 2px 7px;
|
||
border-radius: 0;
|
||
font-size: 0.72em;
|
||
font-weight: 800;
|
||
color: hsl(145, 50%, 32%);
|
||
background: hsl(145, 50%, 93%);
|
||
}
|
||
.admin-registration-badge.is-muted {
|
||
color: hsl(210, 12%, 48%);
|
||
background: hsl(210, 12%, 92%);
|
||
}
|
||
.admin-user-mail {
|
||
color: hsl(210, 14%, 40%);
|
||
font-weight: 600;
|
||
}
|
||
.admin-role-pills {
|
||
display: flex;
|
||
flex-flow: row wrap;
|
||
gap: 6px;
|
||
max-width: 460px;
|
||
}
|
||
.admin-role-pill {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
padding: 4px 8px;
|
||
border-radius: 0;
|
||
color: hsl(210, 57%, 34%);
|
||
background: hsl(210, 57%, 94%);
|
||
border: 1px solid hsl(210, 57%, 88%);
|
||
font-size: 0.78em;
|
||
font-weight: 750;
|
||
}
|
||
.admin-role-more {
|
||
color: hsl(210, 12%, 42%);
|
||
background: hsl(210, 12%, 94%);
|
||
border-color: hsl(210, 12%, 88%);
|
||
}
|
||
.admin-empty-filter-row td {
|
||
padding: 24px !important;
|
||
text-align: center !important;
|
||
color: hsl(210, 20%, 45%);
|
||
background: #FFFFFF !important;
|
||
border-radius: 0;
|
||
}
|
||
.admin-modal-card {
|
||
position: relative;
|
||
width: min(860px, calc(100vw - 24px));
|
||
max-height: min(860px, calc(100vh - 24px));
|
||
overflow: auto;
|
||
padding: 0;
|
||
background: #FFFFFF;
|
||
border-radius: 0;
|
||
box-shadow: 0 24px 70px rgba(0,0,0,0.36);
|
||
}
|
||
.admin-modal-hero {
|
||
position: relative;
|
||
display: grid;
|
||
grid-template-columns: 112px 1fr;
|
||
gap: 18px;
|
||
align-items: center;
|
||
padding: 24px;
|
||
color: #FFFFFF;
|
||
background:
|
||
radial-gradient(circle at 10% 0%, rgba(255,255,255,0.24), transparent 32%),
|
||
linear-gradient(135deg, var(--gray-800), var(--gray-900));
|
||
}
|
||
.admin-modal-profile-img {
|
||
width: 104px;
|
||
height: 104px;
|
||
object-fit: cover;
|
||
border-radius: 16px;
|
||
box-shadow: 0 12px 28px rgba(0,0,0,0.32), 0 0 0 4px rgba(255,255,255,0.18);
|
||
}
|
||
.admin-modal-title {
|
||
margin: 0 42px 6px 0;
|
||
font-size: 1.45em;
|
||
font-weight: 850;
|
||
color: #FFFFFF;
|
||
}
|
||
.admin-modal-subtitle {
|
||
display: flex;
|
||
flex-flow: row wrap;
|
||
gap: 8px;
|
||
align-items: center;
|
||
margin-bottom: 10px;
|
||
color: rgba(255,255,255,0.86);
|
||
font-weight: 600;
|
||
}
|
||
.admin-modal-chip {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
padding: 4px 9px;
|
||
border-radius: 9999px;
|
||
background: rgba(255,255,255,0.14);
|
||
border: 1px solid rgba(255,255,255,0.18);
|
||
font-size: 0.82em;
|
||
}
|
||
.admin-modal-body {
|
||
padding: 22px 24px 24px 24px;
|
||
}
|
||
.admin-section-title {
|
||
margin: 0 0 10px 0;
|
||
font-size: 0.9em;
|
||
font-weight: 850;
|
||
letter-spacing: 0.04em;
|
||
text-transform: uppercase;
|
||
color: hsl(210, 18%, 36%);
|
||
}
|
||
.admin-name-grid {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 10px;
|
||
margin-bottom: 6px;
|
||
}
|
||
.admin-role-checklist {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||
gap: 10px;
|
||
margin: 0 0 20px 0;
|
||
}
|
||
.admin-role-checklist label {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
padding: 11px 12px;
|
||
border: 1px solid hsl(210, 18%, 88%);
|
||
border-radius: 0;
|
||
background: hsl(210, 12%, 98%);
|
||
color: hsl(210, 20%, 20%);
|
||
font-weight: 750;
|
||
cursor: pointer;
|
||
transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
|
||
hyphens: auto;
|
||
-webkit-hyphens: auto;
|
||
overflow-wrap: break-word;
|
||
word-break: break-word;
|
||
}
|
||
.admin-role-checklist label:hover {
|
||
transform: translateY(-1px);
|
||
background: hsl(210, 57%, 97%);
|
||
border-color: hsl(210, 57%, 78%);
|
||
}
|
||
.admin-role-checklist input[type="checkbox"] {
|
||
width: 20px;
|
||
height: 20px;
|
||
min-width: 20px;
|
||
min-height: 20px;
|
||
flex-shrink: 0;
|
||
margin: 0;
|
||
accent-color: var(--nak-blue);
|
||
}
|
||
.admin-modal-actions {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
gap: 10px;
|
||
border-top: 1px solid hsl(210, 18%, 90%);
|
||
padding-top: 16px;
|
||
}
|
||
.admin-modal-actions-left,
|
||
.admin-modal-actions-right {
|
||
display: flex;
|
||
flex-flow: row wrap;
|
||
gap: 8px;
|
||
}
|
||
.admin-modal-actions button,
|
||
.admin-modal-actions a {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-align: center;
|
||
min-height: 36px;
|
||
padding: 8px 13px;
|
||
border: 1px solid hsl(210, 18%, 84%);
|
||
border-radius: 0;
|
||
background: #FFFFFF;
|
||
color: hsl(210, 20%, 22%);
|
||
font-size: 0.86em;
|
||
font-weight: 850;
|
||
text-decoration: none;
|
||
cursor: pointer;
|
||
box-shadow: 0 4px 12px rgba(31,38,46,0.06);
|
||
white-space: nowrap;
|
||
}
|
||
.admin-modal-actions button:hover,
|
||
.admin-modal-actions a:hover {
|
||
background: hsl(210, 57%, 96%);
|
||
text-decoration: none;
|
||
}
|
||
.admin-save-button {
|
||
color: #FFFFFF !important;
|
||
background: linear-gradient(135deg, var(--nak-blue), var(--nak-blue-hover)) !important;
|
||
border-color: var(--nak-blue-hover) !important;
|
||
}
|
||
.admin-danger-button {
|
||
color: var(--nak-red) !important;
|
||
border-color: hsl(352, 72%, 88%) !important;
|
||
background: hsl(352, 72%, 97%) !important;
|
||
}
|
||
.admin-warning-button {
|
||
color: hsl(35, 78%, 35%) !important;
|
||
border-color: hsl(42, 90%, 82%) !important;
|
||
background: hsl(45, 90%, 96%) !important;
|
||
}
|
||
.admin-modal-card .exit {
|
||
position: absolute;
|
||
top: 14px;
|
||
right: 14px;
|
||
width: 34px;
|
||
height: 34px;
|
||
border-radius: 0;
|
||
border: 1px solid rgba(255,255,255,0.25);
|
||
background: rgba(255,255,255,0.16);
|
||
color: #FFFFFF;
|
||
font-size: 1.35em;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
}
|
||
.admin-add-mail-field {
|
||
width: 100%;
|
||
padding: 13px 14px;
|
||
border: 1px solid hsl(210, 18%, 84%);
|
||
border-radius: 0;
|
||
background: hsl(210, 12%, 98%);
|
||
color: hsl(210, 20%, 18%);
|
||
font-size: 1em;
|
||
font-weight: 650;
|
||
outline: none;
|
||
box-shadow: inset 0 1px 2px rgba(31,38,46,0.04);
|
||
transition: border-color 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
|
||
box-sizing: border-box;
|
||
}
|
||
.admin-add-mail-field:focus {
|
||
border-color: hsl(210, 57%, 55%);
|
||
background: #FFFFFF;
|
||
box-shadow: 0 0 0 4px hsla(210, 57%, 55%, 0.14);
|
||
}
|
||
.admin-field-help {
|
||
margin: 7px 0 18px 0;
|
||
color: hsl(210, 14%, 45%);
|
||
font-size: 0.88em;
|
||
font-weight: 600;
|
||
}
|
||
.admin-add-summary {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 10px;
|
||
margin-bottom: 18px;
|
||
}
|
||
.admin-add-summary-card {
|
||
padding: 12px 14px;
|
||
border: 1px solid hsl(210, 18%, 88%);
|
||
border-radius: 0;
|
||
background: linear-gradient(180deg, #FFFFFF, hsl(210, 12%, 98%));
|
||
}
|
||
.admin-add-summary-label {
|
||
margin-bottom: 3px;
|
||
color: hsl(210, 14%, 46%);
|
||
font-size: 0.74em;
|
||
font-weight: 850;
|
||
letter-spacing: 0.04em;
|
||
text-transform: uppercase;
|
||
}
|
||
.admin-add-summary-value {
|
||
color: hsl(210, 20%, 18%);
|
||
font-size: 1.02em;
|
||
font-weight: 850;
|
||
}
|
||
@media (max-width: 780px) {
|
||
.admin-list-header {
|
||
align-items: flex-start;
|
||
flex-direction: column;
|
||
padding: 14px;
|
||
gap: 8px;
|
||
}
|
||
.admin-list-controls {
|
||
width: 100%;
|
||
justify-content: space-between;
|
||
}
|
||
#fullsize.content {
|
||
top: 0;
|
||
min-height: calc(100vh - var(--header-height) - var(--header-title-height) - 2px);
|
||
}
|
||
.admin-users-shell {
|
||
padding: 10px;
|
||
}
|
||
.admin-list-header {
|
||
align-items: flex-start;
|
||
flex-direction: column;
|
||
padding: 14px;
|
||
}
|
||
table.admin-user-table {
|
||
display: block !important;
|
||
width: auto;
|
||
margin: 8px;
|
||
padding: 0;
|
||
border-spacing: 0;
|
||
}
|
||
.admin-user-table thead {
|
||
display: none;
|
||
}
|
||
.admin-user-table tbody {
|
||
display: grid;
|
||
gap: 10px;
|
||
}
|
||
.admin-user-table tbody tr.admin-user-row {
|
||
display: grid;
|
||
grid-template-columns: 72px minmax(0, 1fr);
|
||
gap: 0 12px;
|
||
padding: 12px;
|
||
border: 1px solid rgba(120, 140, 160, 0.16);
|
||
border-radius: 0;
|
||
box-shadow: 0 8px 22px rgba(31, 38, 46, 0.08);
|
||
}
|
||
.admin-user-table tbody tr.admin-user-row td {
|
||
display: block;
|
||
padding: 0 !important;
|
||
border-radius: 0 !important;
|
||
}
|
||
.admin-user-table tbody tr.admin-user-row td:first-child {
|
||
grid-row: 1 / span 2;
|
||
width: 72px;
|
||
min-width: 72px;
|
||
max-width: 72px;
|
||
}
|
||
.admin-user-table tbody tr.admin-user-row td:nth-child(2) {
|
||
align-self: end;
|
||
min-width: 0;
|
||
}
|
||
.admin-user-table tbody tr.admin-user-row td:nth-child(3) {
|
||
align-self: start;
|
||
min-width: 0;
|
||
padding-top: 5px !important;
|
||
}
|
||
.admin-profile-button,
|
||
.admin-profile-button img,
|
||
.admin-user-table img {
|
||
width: 64px !important;
|
||
height: 64px !important;
|
||
border-radius: 12px !important;
|
||
}
|
||
.admin-user-name,
|
||
.admin-user-mail {
|
||
max-width: 100%;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.admin-registration-badge {
|
||
margin-top: 2px;
|
||
}
|
||
.admin-empty-filter-row {
|
||
display: block !important;
|
||
}
|
||
.admin-empty-filter-row[style*="display:none"] {
|
||
display: none !important;
|
||
}
|
||
.admin-empty-filter-row td {
|
||
display: block;
|
||
}
|
||
.admin-modal-card {
|
||
width: calc(100vw - 12px);
|
||
max-height: calc(100dvh - 12px);
|
||
border-radius: 0;
|
||
}
|
||
.admin-modal-hero {
|
||
grid-template-columns: 78px minmax(0, 1fr);
|
||
gap: 14px;
|
||
padding: 18px;
|
||
}
|
||
.admin-modal-profile-img {
|
||
width: 72px;
|
||
height: 72px;
|
||
border-radius: 14px;
|
||
}
|
||
.admin-modal-title {
|
||
margin-right: 40px;
|
||
font-size: 1.15em;
|
||
}
|
||
.admin-modal-subtitle {
|
||
font-size: 0.9em;
|
||
}
|
||
.admin-modal-body {
|
||
padding: 18px;
|
||
}
|
||
.admin-role-checklist {
|
||
grid-template-columns: 1fr;
|
||
gap: 8px;
|
||
}
|
||
.admin-modal-actions {
|
||
flex-direction: column-reverse;
|
||
}
|
||
.admin-modal-actions-left,
|
||
.admin-modal-actions-right {
|
||
width: 100%;
|
||
}
|
||
.admin-modal-actions button,
|
||
.admin-modal-actions a {
|
||
flex: 1 1 100%;
|
||
width: 100%;
|
||
max-width: 100%;
|
||
box-sizing: border-box;
|
||
white-space: normal;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 480px) {
|
||
.admin-users-shell {
|
||
padding: 8px;
|
||
}
|
||
.admin-table-card {
|
||
overflow: hidden;
|
||
border-radius: 0;
|
||
}
|
||
.admin-list-title {
|
||
font-size: 1em;
|
||
}
|
||
.admin-list-hint {
|
||
font-size: 0.8em;
|
||
}
|
||
.admin-user-table tbody tr.admin-user-row {
|
||
grid-template-columns: 62px minmax(0, 1fr);
|
||
gap: 0 10px;
|
||
padding: 10px;
|
||
}
|
||
.admin-profile-button,
|
||
.admin-profile-button img,
|
||
.admin-user-table img {
|
||
width: 56px !important;
|
||
height: 56px !important;
|
||
border-radius: 10px !important;
|
||
}
|
||
.admin-user-name {
|
||
font-size: 0.96em;
|
||
}
|
||
.admin-user-mail {
|
||
font-size: 0.88em;
|
||
}
|
||
.admin-modal-body [style*="grid-template-columns: 1fr 1fr"] {
|
||
grid-template-columns: 1fr !important;
|
||
}
|
||
.admin-name-grid {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
.admin-modal-actions-left,
|
||
.admin-modal-actions-right {
|
||
flex-direction: column;
|
||
}
|
||
.admin-modal-actions button,
|
||
.admin-modal-actions a {
|
||
width: 100%;
|
||
max-width: 100%;
|
||
box-sizing: border-box;
|
||
align-self: stretch;
|
||
white-space: normal;
|
||
}
|
||
.admin-modal-actions-left,
|
||
.admin-modal-actions-right {
|
||
flex-direction: column;
|
||
align-items: stretch;
|
||
width: 100%;
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
<body class="theme-admin">
|
||
|
||
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/header.php'; ?>
|
||
|
||
<?php
|
||
include $g_phpSnippetsPath.'overlay_message.php';
|
||
?>
|
||
|
||
<div class="header_title ht_admin text_white unselectable" id="header_title">
|
||
<span class="header_title_text">Adminpanel</span>
|
||
</div>
|
||
|
||
<div class="content" id="fullsize">
|
||
<?php $adminActiveTab = 'users'; require __DIR__.'/_tabs.php'; ?>
|
||
<?php if (isset($_SESSION["user_id"])): ?>
|
||
|
||
<div class="admin-users-shell">
|
||
<div class="admin-table-card">
|
||
<div class="admin-list-header">
|
||
<div class="admin-list-hint"><span id="visibleUserCount"><?= count($groups) ?></span> Nutzer angezeigt</div>
|
||
<div class="admin-list-controls">
|
||
<div class="admin-list-filter-control" title="Nach Rolle filtern">
|
||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||
<path d="M3 5h18"></path>
|
||
<path d="M6 12h12"></path>
|
||
<path d="M10 19h4"></path>
|
||
</svg>
|
||
<div class="admin-list-filter-wrap">
|
||
<select id="roleFilter" onchange="filterUsersByRole()" aria-label="Nach Rolle filtern">
|
||
<option value="">Alle Rollen</option>
|
||
<?php foreach ($permissionRoles as $role): ?>
|
||
<option value="<?= htmlspecialchars($role) ?>"><?= htmlspecialchars(genderRole($role)) ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<a href="#" class="admin-list-add-btn" onclick="openAddUserModal(); return false;" title="Neuen Nutzer anlegen">
|
||
+ Neu
|
||
</a>
|
||
</div>
|
||
</div>
|
||
|
||
<table class="eventbox_table admin-user-table" id="admintable">
|
||
<thead class="unselectable">
|
||
<tr>
|
||
<th>Profil</th>
|
||
<th>Name</th>
|
||
<th>E-Mail-Adresse</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($groups as $group): ?>
|
||
<?php
|
||
$activeRoles = [];
|
||
foreach ($permissionRoles as $role) {
|
||
if ((int)($group[$role] ?? 0) === 1) {
|
||
$activeRoles[] = $role;
|
||
}
|
||
}
|
||
|
||
$nameOutput = getDisplayName($group);
|
||
$isRegistered = ((int)($group['IstRegistriert'] ?? 0) === 1);
|
||
$mailOutput = $group['mail'] ?? '';
|
||
$profileUrl = getProfileImageUrl($group, $g_profilePicturePath);
|
||
?>
|
||
<tr class="admin-user-row" id="row-<?= (int)$group['user_id'] ?>" tabindex="0" role="button" aria-label="<?= htmlspecialchars($nameOutput) ?> bearbeiten" data-roles="<?= htmlspecialchars('|'.implode('|', $activeRoles).'|') ?>" onclick="openRoleModal(<?= (int)$group['user_id'] ?>)" onkeydown="openRoleModalByKeyboard(event, <?= (int)$group['user_id'] ?>)">
|
||
<td>
|
||
<button class="admin-profile-button" type="button" tabindex="-1" aria-hidden="true">
|
||
<img src="<?= htmlspecialchars($profileUrl) ?>" alt="Profilbild von <?= htmlspecialchars($nameOutput) ?>">
|
||
</button>
|
||
</td>
|
||
<td>
|
||
<button class="admin-name-button" type="button" tabindex="-1" aria-hidden="true">
|
||
<span class="admin-user-name"><?= htmlspecialchars($nameOutput) ?></span>
|
||
</button>
|
||
<div style="margin-top:6px;">
|
||
<span class="admin-registration-badge <?= $isRegistered ? '' : 'is-muted' ?>">
|
||
<?= $isRegistered ? 'registriert' : 'nicht registriert' ?>
|
||
</span>
|
||
</div>
|
||
</td>
|
||
<td><span class="admin-user-mail"><?= htmlspecialchars($mailOutput) ?></span></td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
<tr id="emptyFilterRow" class="admin-empty-filter-row" style="display:none;">
|
||
<td colspan="3">Keine Nutzer mit dieser Rolle gefunden.</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="standard_overlay" id="addNewUser" onclick="closeAddUserModalOnBackdrop(event)">
|
||
<div class="admin-modal-card">
|
||
<button type="button" class="exit" aria-label="Schließen" onclick="closeAddUserModal()">×</button>
|
||
|
||
<div class="admin-modal-hero">
|
||
<img class="admin-modal-profile-img" src="/intranet_repo/general_files/profile_pictures/default.jpg" alt="Neuer Nutzer">
|
||
<div>
|
||
<div class="admin-modal-title">Neuen Nutzer anlegen</div>
|
||
<div class="admin-modal-subtitle">
|
||
<span class="admin-modal-chip">neues Profil</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="admin-modal-body">
|
||
<form method="post" action="">
|
||
<div class="admin-section-title">Name</div>
|
||
<div class="admin-name-grid">
|
||
<input class="admin-add-mail-field" type="text" name="newFirstName" placeholder="Vorname" required>
|
||
<input class="admin-add-mail-field" type="text" name="newLastName" placeholder="Nachname" required>
|
||
</div>
|
||
|
||
<div class="admin-section-title">E-Mail-Adresse</div>
|
||
<input class="admin-add-mail-field" type="email" name="newMail" placeholder="name@example.de" autocomplete="email" required>
|
||
<div class="admin-field-help">Der Nutzer erhält eine Einladungsmail zur Registrierung.</div>
|
||
|
||
<div class="admin-section-title">Rollen vergeben</div>
|
||
<div class="admin-role-checklist">
|
||
<?php foreach ($permissionRoles as $role): ?>
|
||
<label>
|
||
<input type="checkbox" name="newRoles[]" value="<?= htmlspecialchars($role) ?>">
|
||
<span><?= htmlspecialchars(genderRole($role)) ?></span>
|
||
</label>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<div class="admin-modal-actions">
|
||
<div class="admin-modal-actions-left"></div>
|
||
<div class="admin-modal-actions-right">
|
||
<button type="button" onclick="closeAddUserModal()">Abbrechen</button>
|
||
<button class="admin-save-button" type="submit" name="addRecord" value="1">Nutzer anlegen</button>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<?php foreach ($groups as $group): ?>
|
||
<?php
|
||
$nameOutput = getDisplayName($group);
|
||
$isRegistered = ((int)($group['IstRegistriert'] ?? 0) === 1);
|
||
$profileUrl = getProfileImageUrl($group, $g_profilePicturePath);
|
||
$mailOutput = $group['mail'] ?? '';
|
||
?>
|
||
<div class="standard_overlay" id="roleModal-<?= (int)$group['user_id'] ?>" onclick="closeRoleModalOnBackdrop(event, <?= (int)$group['user_id'] ?>)">
|
||
<div class="admin-modal-card">
|
||
<button type="button" class="exit" aria-label="Schließen" onclick="closeRoleModal(<?= (int)$group['user_id'] ?>)">×</button>
|
||
|
||
<div class="admin-modal-hero">
|
||
<img class="admin-modal-profile-img" src="<?= htmlspecialchars($profileUrl) ?>" alt="Profilbild von <?= htmlspecialchars($nameOutput) ?>">
|
||
<div>
|
||
<div class="admin-modal-title"><?= htmlspecialchars($nameOutput) ?></div>
|
||
<div class="admin-modal-subtitle">
|
||
<span><?= htmlspecialchars($mailOutput) ?></span>
|
||
<span class="admin-modal-chip"><?= $isRegistered ? 'Registriertes Profil' : 'Noch nicht registriert' ?></span>
|
||
<span class="admin-modal-chip">ID <?= (int)$group['user_id'] ?></span>
|
||
</div>
|
||
<div class="admin-modal-subtitle" style="margin-bottom:0;">Rollen und Kontoaktionen verwalten</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="admin-modal-body">
|
||
<form method="post" action="">
|
||
<input type="hidden" name="editedID" value="<?= (int)$group['user_id'] ?>">
|
||
|
||
<div class="admin-section-title">Nutzerdaten</div>
|
||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--space-sm);margin-bottom:var(--space-md);">
|
||
<div style="display:flex;flex-direction:column;gap:4px;">
|
||
<label style="font-size:var(--font-size-xs);font-weight:600;color:var(--gray-600);">Vorname</label>
|
||
<input type="text" name="edit_first_name" value="<?= htmlspecialchars($group['first_name'] ?? '') ?>" style="padding:8px 10px;font-size:var(--font-size-sm);font-family:var(--font-primary);border:1px solid var(--gray-300);background:var(--gray-50);width:100%;box-sizing:border-box;">
|
||
</div>
|
||
<div style="display:flex;flex-direction:column;gap:4px;">
|
||
<label style="font-size:var(--font-size-xs);font-weight:600;color:var(--gray-600);">Nachname</label>
|
||
<input type="text" name="edit_last_name" value="<?= htmlspecialchars($group['last_name'] ?? '') ?>" style="padding:8px 10px;font-size:var(--font-size-sm);font-family:var(--font-primary);border:1px solid var(--gray-300);background:var(--gray-50);width:100%;box-sizing:border-box;">
|
||
</div>
|
||
</div>
|
||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--space-sm);margin-bottom:var(--space-lg);">
|
||
<div style="display:flex;flex-direction:column;gap:4px;">
|
||
<label style="font-size:var(--font-size-xs);font-weight:600;color:var(--gray-600);">E-Mail-Adresse</label>
|
||
<input type="email" name="edit_mail" value="<?= htmlspecialchars($mailOutput) ?>" required style="padding:8px 10px;font-size:var(--font-size-sm);font-family:var(--font-primary);border:1px solid var(--gray-300);background:var(--gray-50);width:100%;box-sizing:border-box;">
|
||
</div>
|
||
<div style="display:flex;flex-direction:column;gap:4px;">
|
||
<label style="font-size:var(--font-size-xs);font-weight:600;color:var(--gray-600);">Telefonnummer</label>
|
||
<div style="display:flex;align-items:stretch;">
|
||
<div class="input-prefix" style="padding:8px 10px;font-size:var(--font-size-sm);border-radius:0;">+49</div>
|
||
<input type="tel" name="edit_phone" value="<?= htmlspecialchars($group['phone'] ?? '') ?>" class="phone-input" style="padding:8px 10px;font-size:var(--font-size-sm);font-family:var(--font-primary);border:1px solid var(--gray-300);border-left:none;background:var(--gray-50);width:100%;box-sizing:border-box;flex:1;">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="admin-section-title">Rollen</div>
|
||
<div class="admin-role-checklist">
|
||
<?php foreach ($permissionRoles as $role): ?>
|
||
<?php $checked = ((int)($group[$role] ?? 0) === 1); ?>
|
||
<label>
|
||
<input type="checkbox" name="roles[]" value="<?= htmlspecialchars($role) ?>" <?= $checked ? 'checked' : '' ?>>
|
||
<span><?= htmlspecialchars(genderRole($role)) ?></span>
|
||
</label>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<div class="admin-modal-actions">
|
||
<div class="admin-modal-actions-left">
|
||
<?php if (!$isRegistered): ?>
|
||
<a class="admin-save-button" style="background:linear-gradient(135deg, hsl(145,55%,42%), hsl(145,55%,34%)) !important;border-color:hsl(145,55%,34%) !important;" href="?resendInvite=<?= (int)$group['user_id'] ?>" onclick="return confirm('Einladungsmail erneut senden?')">Einladung senden</a>
|
||
<?php endif; ?>
|
||
<a class="admin-warning-button" href="?resetPassword=<?= (int)$group['user_id'] ?>" onclick="return confirm('Sind Sie sicher, dass Sie das Passwort dieses Nutzers zurücksetzen möchten?')">Passwort zurücksetzen</a>
|
||
<a class="admin-danger-button" href="?delete=<?= (int)$group['user_id'] ?>" onclick="return confirm('Sind Sie sicher, dass Sie diesen Nutzer löschen möchten?')">Nutzer löschen</a>
|
||
</div>
|
||
<div class="admin-modal-actions-right">
|
||
<button type="button" onclick="closeRoleModal(<?= (int)$group['user_id'] ?>)">Abbrechen</button>
|
||
<button class="admin-save-button" type="submit" name="editRecord" value="1">Änderungen speichern</button>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
|
||
<?php else:
|
||
header("Location: $g_httpLoginPath");
|
||
exit();
|
||
endif; ?>
|
||
</div><!-- EOD: content fullsize -->
|
||
|
||
<script>
|
||
function openAddUserModal() {
|
||
const modal = document.getElementById('addNewUser');
|
||
if (modal) {
|
||
modal.style.display = 'flex';
|
||
const mailField = modal.querySelector('input[name="newMail"]');
|
||
if (mailField) {
|
||
setTimeout(() => mailField.focus(), 80);
|
||
}
|
||
}
|
||
}
|
||
|
||
function closeAddUserModal() {
|
||
const modal = document.getElementById('addNewUser');
|
||
if (modal) {
|
||
modal.style.display = 'none';
|
||
}
|
||
}
|
||
|
||
function closeAddUserModalOnBackdrop(event) {
|
||
if (event.target.id === 'addNewUser') {
|
||
closeAddUserModal();
|
||
}
|
||
}
|
||
|
||
function openRoleModal(userId) {
|
||
const modal = document.getElementById('roleModal-' + userId);
|
||
if (modal) {
|
||
modal.style.display = 'flex';
|
||
}
|
||
}
|
||
|
||
function closeRoleModal(userId) {
|
||
const modal = document.getElementById('roleModal-' + userId);
|
||
if (modal) {
|
||
modal.style.display = 'none';
|
||
}
|
||
}
|
||
|
||
function closeRoleModalOnBackdrop(event, userId) {
|
||
if (event.target.id === 'roleModal-' + userId) {
|
||
closeRoleModal(userId);
|
||
}
|
||
}
|
||
|
||
function openRoleModalByKeyboard(event, userId) {
|
||
if (event.key === 'Enter' || event.key === ' ') {
|
||
event.preventDefault();
|
||
openRoleModal(userId);
|
||
}
|
||
}
|
||
|
||
function filterUsersByRole() {
|
||
const selectedRole = document.getElementById('roleFilter').value;
|
||
const rows = document.querySelectorAll('#admintable tbody tr[data-roles]');
|
||
const emptyRow = document.getElementById('emptyFilterRow');
|
||
const visibleUserCount = document.getElementById('visibleUserCount');
|
||
let visibleRows = 0;
|
||
|
||
rows.forEach(row => {
|
||
const roles = row.dataset.roles || '';
|
||
const showRow = selectedRole === '' || roles.includes('|' + selectedRole + '|');
|
||
row.style.display = showRow ? '' : 'none';
|
||
if (showRow) {
|
||
visibleRows++;
|
||
}
|
||
});
|
||
|
||
if (emptyRow) {
|
||
emptyRow.style.display = visibleRows === 0 ? '' : 'none';
|
||
}
|
||
if (visibleUserCount) {
|
||
visibleUserCount.textContent = visibleRows;
|
||
}
|
||
}
|
||
|
||
document.addEventListener('keydown', function(event) {
|
||
if (event.key === 'Escape') {
|
||
document.querySelectorAll('.standard_overlay[id^="roleModal-"], #addNewUser').forEach(modal => {
|
||
modal.style.display = 'none';
|
||
});
|
||
}
|
||
});
|
||
</script>
|
||
|
||
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/footer.php'; ?>
|
||
|
||
</body>
|
||
</html>
|