406 lines
23 KiB
PHP
406 lines
23 KiB
PHP
<?php
|
||
require_once __DIR__ . '/../includes/bootstrap.php';
|
||
$me = require_admin_or_permission('manage_staff');
|
||
$isFullAdmin = $me['role'] === 'admin';
|
||
$canManageTeams = has_permission($me, 'manage_teams');
|
||
$pdo = get_db();
|
||
|
||
$errors = [];
|
||
$departments = $pdo->query('SELECT * FROM departments ORDER BY name')->fetchAll();
|
||
$customRoles = $pdo->query('SELECT * FROM roles ORDER BY name')->fetchAll();
|
||
$teams = $pdo->query('SELECT id, name, is_active FROM teams ORDER BY name')->fetchAll();
|
||
|
||
$permLabels = [
|
||
'reply_ticket' => 'Tickets beantworten',
|
||
'close_ticket' => 'Tickets schließen/lösen',
|
||
'delete_ticket' => 'Tickets löschen',
|
||
'transfer_ticket' => 'Tickets übertragen',
|
||
'post_note' => 'Interne Notizen schreiben',
|
||
'assign_ticket' => 'Tickets zuweisen',
|
||
'manage_canned' => 'Textbausteine verwalten',
|
||
'view_reports' => 'Berichte einsehen',
|
||
'manage_kb' => 'Wissensdatenbank verwalten',
|
||
'create_ticket' => 'Tickets im Namen von Kunden erstellen',
|
||
] + array_diff_key(admin_section_permissions(), ['manage_kb' => 1]);
|
||
|
||
/** Setzt die zusätzlichen Abteilungen (Erweiterter Zugriff) neu. */
|
||
function save_staff_access(PDO $pdo, int $id, ?int $primaryDeptId, array $post): void
|
||
{
|
||
$selected = array_unique(array_filter(array_map('intval', $post['extra_departments'] ?? [])));
|
||
$pdo->prepare('DELETE FROM staff_department WHERE staff_id = ?')->execute([$id]);
|
||
$ins = $pdo->prepare('INSERT INTO staff_department (staff_id, department_id, notify, role_id) VALUES (?,?,?,?)');
|
||
$validRoles = array_map('intval', $pdo->query('SELECT id FROM roles')->fetchAll(PDO::FETCH_COLUMN));
|
||
foreach ($selected as $dId) {
|
||
if ($dId === (int) $primaryDeptId) continue; // Hauptabteilung wird nicht doppelt gespeichert
|
||
$rid = (int) ($post['role_' . $dId] ?? 0);
|
||
$ins->execute([$id, $dId, !empty($post['notify_' . $dId]) ? 1 : 0, in_array($rid, $validRoles, true) ? $rid : null]);
|
||
}
|
||
}
|
||
|
||
/** Setzt die Team-Mitgliedschaften eines Mitarbeiters neu. */
|
||
function save_staff_teams(PDO $pdo, int $id, array $teamIds): void
|
||
{
|
||
$pdo->prepare('DELETE FROM team_members WHERE staff_id = ?')->execute([$id]);
|
||
$ins = $pdo->prepare('INSERT INTO team_members (team_id, staff_id) VALUES (?,?)');
|
||
foreach (array_unique(array_filter(array_map('intval', $teamIds))) as $tid) $ins->execute([$tid, $id]);
|
||
}
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||
verify_csrf();
|
||
$action = $_POST['action'] ?? '';
|
||
|
||
if ($action === 'create' || $action === 'update') {
|
||
$id = (int) ($_POST['id'] ?? 0);
|
||
$name = trim($_POST['name'] ?? '');
|
||
$email = trim($_POST['email'] ?? '');
|
||
// Nur echte Administratoren dürfen die Administrator-Rolle vergeben – sonst könnte sich ein
|
||
// per Co-Admin-Recht (nur manage_staff) berechtigter Agent selbst (oder andere) zum
|
||
// Vollzugriff-Admin machen. Beim Bearbeiten durch einen Co-Admin bleibt die vorhandene
|
||
// Rolle des Ziel-Kontos unverändert, statt sie stillschweigend auf "Mitarbeiter" zu setzen.
|
||
if ($isFullAdmin) {
|
||
$role = ($_POST['role'] ?? '') === 'admin' ? 'admin' : 'agent';
|
||
} elseif ($action === 'update') {
|
||
$currentRoleStmt = $pdo->prepare('SELECT role FROM staff WHERE id = ?');
|
||
$currentRoleStmt->execute([$id]);
|
||
$role = $currentRoleStmt->fetchColumn() === 'admin' ? 'admin' : 'agent';
|
||
} else {
|
||
$role = 'agent';
|
||
}
|
||
$roleId = ($_POST['role_id'] ?? '') !== '' ? (int) $_POST['role_id'] : null;
|
||
$deptId = ($_POST['department_id'] ?? '') !== '' ? (int) $_POST['department_id'] : null;
|
||
$isActive = ($_POST['status'] ?? 'active') === 'active' ? 1 : 0;
|
||
$password = $_POST['password'] ?? '';
|
||
$signature = sanitize_staff_html(trim($_POST['signature'] ?? ''));
|
||
|
||
if ($name === '') $errors[] = 'Bitte einen Namen angeben.';
|
||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) $errors[] = 'Bitte eine gültige E-Mail-Adresse angeben.';
|
||
if ($action === 'create' || $password !== '') {
|
||
$pwErr = validate_password_strength($password);
|
||
if ($pwErr) $errors[] = $pwErr;
|
||
}
|
||
if ($action === 'update' && $id === (int) $me['id'] && !$isActive) $errors[] = 'Sie können Ihr eigenes Konto nicht deaktivieren.';
|
||
$dup = $pdo->prepare('SELECT COUNT(*) FROM staff WHERE LOWER(email) = LOWER(?) AND id <> ?');
|
||
$dup->execute([$email, $id]);
|
||
if ($dup->fetchColumn() > 0) $errors[] = 'Ein Mitarbeiter mit dieser E-Mail-Adresse existiert bereits.';
|
||
|
||
if (!$errors) {
|
||
if ($action === 'create') {
|
||
$pdo->prepare('INSERT INTO staff (name, email, password_hash, role, role_id, department_id, signature, is_active, created_at) VALUES (?,?,?,?,?,?,?,?,?)')
|
||
->execute([$name, $email, password_hash($password, PASSWORD_DEFAULT), $role, $roleId, $deptId, $signature ?: null, $isActive, db_now()]);
|
||
$id = (int) $pdo->lastInsertId();
|
||
audit_log($me['id'], "Mitarbeiter angelegt: {$name} ({$email})");
|
||
flash('success', 'Mitarbeiter angelegt.');
|
||
} else {
|
||
$sql = 'UPDATE staff SET name=?, email=?, role=?, role_id=?, department_id=?, signature=?, is_active=?';
|
||
$params = [$name, $email, $role, $roleId, $deptId, $signature ?: null, $isActive];
|
||
if ($password !== '') { $sql .= ', password_hash=?'; $params[] = password_hash($password, PASSWORD_DEFAULT); }
|
||
$params[] = $id;
|
||
$pdo->prepare($sql . ' WHERE id=?')->execute($params);
|
||
audit_log($me['id'], "Mitarbeiter aktualisiert: {$name} ({$email})");
|
||
flash('success', 'Änderungen gespeichert.');
|
||
}
|
||
save_staff_access($pdo, $id, $deptId, $_POST);
|
||
if ($canManageTeams) save_staff_teams($pdo, $id, (array) ($_POST['teams'] ?? []));
|
||
redirect('/staff/staff_manage.php');
|
||
}
|
||
}
|
||
|
||
// Eigenständiger Zugriffs-Speicher-Aufruf (Rückwärtskompatibilität)
|
||
if ($action === 'save_access') {
|
||
$id = (int) $_POST['id'];
|
||
$stmt = $pdo->prepare('SELECT department_id FROM staff WHERE id = ?');
|
||
$stmt->execute([$id]);
|
||
save_staff_access($pdo, $id, (int) $stmt->fetchColumn(), $_POST);
|
||
audit_log($me['id'], "Abteilungszugriff geändert für Mitarbeiter #{$id}");
|
||
flash('success', 'Abteilungszugriff gespeichert.');
|
||
redirect('/staff/staff_manage.php?edit=' . $id . '&tab=access');
|
||
}
|
||
|
||
if ($action === 'delete') {
|
||
$id = (int) $_POST['id'];
|
||
if ($id === (int) $me['id']) {
|
||
flash('error', 'Sie können Ihr eigenes Konto nicht löschen.');
|
||
} else {
|
||
$pdo->prepare('UPDATE tickets SET assigned_staff_id = NULL WHERE assigned_staff_id = ?')->execute([$id]);
|
||
$pdo->prepare('DELETE FROM staff WHERE id = ?')->execute([$id]);
|
||
audit_log($me['id'], "Mitarbeiter gelöscht: #{$id}");
|
||
flash('success', 'Mitarbeiter gelöscht.');
|
||
}
|
||
redirect('/staff/staff_manage.php');
|
||
}
|
||
}
|
||
|
||
$isNew = isset($_GET['new']);
|
||
$editId = (int) ($_GET['edit'] ?? 0);
|
||
$showForm = $isNew || $editId || ($errors && in_array($_POST['action'] ?? '', ['create', 'update'], true));
|
||
|
||
$editStaff = null;
|
||
$extraAccess = []; // department_id => ['notify' => 0/1, 'role_id' => ?int]
|
||
$memberTeams = [];
|
||
if ($editId) {
|
||
$stmt = $pdo->prepare('SELECT * FROM staff WHERE id = ?');
|
||
$stmt->execute([$editId]);
|
||
$editStaff = $stmt->fetch() ?: null;
|
||
if ($editStaff) {
|
||
$stmt = $pdo->prepare('SELECT department_id, notify, role_id FROM staff_department WHERE staff_id = ?');
|
||
$stmt->execute([$editId]);
|
||
foreach ($stmt->fetchAll() as $row) $extraAccess[(int) $row['department_id']] = ['notify' => (int) $row['notify'], 'role_id' => $row['role_id'] !== null ? (int) $row['role_id'] : null];
|
||
$stmt = $pdo->prepare('SELECT team_id FROM team_members WHERE staff_id = ?');
|
||
$stmt->execute([$editId]);
|
||
$memberTeams = array_map('intval', $stmt->fetchAll(PDO::FETCH_COLUMN));
|
||
}
|
||
}
|
||
if ($_POST && $errors) { // eingegebene Auswahl bei Fehlern erhalten
|
||
$extraAccess = [];
|
||
foreach (array_filter(array_map('intval', $_POST['extra_departments'] ?? [])) as $dId) {
|
||
$extraAccess[$dId] = ['notify' => !empty($_POST['notify_' . $dId]) ? 1 : 0, 'role_id' => ($_POST['role_' . $dId] ?? '') !== '' ? (int) $_POST['role_' . $dId] : null];
|
||
}
|
||
$memberTeams = array_map('intval', (array) ($_POST['teams'] ?? []));
|
||
}
|
||
|
||
$allStaff = $pdo->query(
|
||
'SELECT s.*, d.name AS department_name,
|
||
(SELECT COUNT(*) FROM team_members tm WHERE tm.staff_id = s.id) AS team_count
|
||
FROM staff s LEFT JOIN departments d ON d.id = s.department_id ORDER BY s.name'
|
||
)->fetchAll();
|
||
$fmt = fn(?string $dt) => $dt ? date('d.m.Y', strtotime($dt)) : '–';
|
||
|
||
$pageTitle = 'Mitarbeiter';
|
||
$activePage = 'staff';
|
||
require __DIR__ . '/_header.php';
|
||
?>
|
||
|
||
<?php foreach ($errors as $err): ?>
|
||
<div class="flash error"><?= e($err) ?></div>
|
||
<?php endforeach; ?>
|
||
|
||
<?php if ($showForm): ?>
|
||
<?php
|
||
$f = fn(string $k, $default = '') => $_POST[$k] ?? $default;
|
||
$v = fn(string $k, string $col, $default = '') => $f($k, $editStaff[$col] ?? $default);
|
||
$curStatus = $_POST ? ($_POST['status'] ?? 'active') : (($editStaff['is_active'] ?? 1) ? 'active' : 'locked');
|
||
$curRole = (string) $v('role', 'role', 'agent');
|
||
$curRoleId = (string) $v('role_id', 'role_id');
|
||
$curDept = (string) $v('department_id', 'department_id');
|
||
$startTab = in_array($_GET['tab'] ?? '', ['account', 'access', 'perms', 'teams'], true) ? $_GET['tab'] : 'account';
|
||
$rolePerms = [];
|
||
foreach ($customRoles as $r) $rolePerms[$r['id']] = json_decode($r['permissions'], true) ?: [];
|
||
$agentDefaults = default_permissions('agent');
|
||
$adminDefaults = default_permissions('admin');
|
||
?>
|
||
<h1>
|
||
<?= $editStaff ? 'Agenten verwalten' : 'Neuer Agent' ?>
|
||
<?php if ($editStaff): ?><span class="muted" style="font-size:1rem;font-weight:400">— <?= e($editStaff['name']) ?></span><?php endif; ?>
|
||
</h1>
|
||
|
||
<form method="post" class="card" style="padding:0" autocomplete="off">
|
||
<?= csrf_field() ?>
|
||
<input type="hidden" name="action" value="<?= $editStaff ? 'update' : 'create' ?>">
|
||
<?php if ($editStaff): ?><input type="hidden" name="id" value="<?= (int) $editStaff['id'] ?>"><?php endif; ?>
|
||
|
||
<div style="display:flex;gap:4px;padding:10px 12px 0;border-bottom:1px solid var(--border)">
|
||
<button type="button" class="tab-btn" data-tab="account">Konto</button>
|
||
<button type="button" class="tab-btn" data-tab="access">Zugang</button>
|
||
<button type="button" class="tab-btn" data-tab="perms">Berechtigungen</button>
|
||
<button type="button" class="tab-btn" data-tab="teams">Teams</button>
|
||
</div>
|
||
|
||
<!-- Konto -->
|
||
<div class="tab-pane" data-pane="account" style="padding:16px 20px">
|
||
<h3 style="margin-top:0">Kontoinformationen</h3>
|
||
<label for="name">Name *</label>
|
||
<input type="text" id="name" name="name" value="<?= e($v('name', 'name')) ?>" required>
|
||
<label for="email">E-Mail-Adresse *</label>
|
||
<input type="email" id="email" name="email" value="<?= e($v('email', 'email')) ?>" required>
|
||
<label>Status *</label>
|
||
<div style="display:flex;gap:18px;margin:4px 0 10px">
|
||
<label style="display:flex;align-items:center;gap:6px;margin:0"><input type="radio" name="status" value="active" style="width:auto" <?= $curStatus === 'active' ? 'checked' : '' ?>> <strong>Aktiv</strong></label>
|
||
<label style="display:flex;align-items:center;gap:6px;margin:0"><input type="radio" name="status" value="locked" style="width:auto" <?= $curStatus !== 'active' ? 'checked' : '' ?>> Gesperrt</label>
|
||
</div>
|
||
<label for="password"><?= $editStaff ? 'Neues Passwort (leer = unverändert)' : 'Passwort *' ?></label>
|
||
<input type="password" id="password" name="password" autocomplete="new-password" <?= $editStaff ? '' : 'required' ?>>
|
||
<label for="signature">Signatur (E-Mail-Fuß für eigene Antworten)</label>
|
||
<textarea id="signature" name="signature" data-richtext data-image-upload-url="/staff/upload_signature_image.php" style="min-height:90px" placeholder="z. B. Mit freundlichen Grüßen Max Mustermann"><?= e($v('signature', 'signature')) ?></textarea>
|
||
</div>
|
||
|
||
<!-- Zugang -->
|
||
<div class="tab-pane" data-pane="access" style="padding:16px 20px;display:none">
|
||
<h3 style="margin-top:0">Zugang</h3>
|
||
<p class="muted" style="margin-top:0">Wähle die Abteilungen, zu denen der Agent Zugang haben soll.</p>
|
||
|
||
<h4 style="border-bottom:1px dotted var(--border);padding-bottom:4px">Hauptabteilung <span style="color:#dc2626">*</span></h4>
|
||
<div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap">
|
||
<select name="department_id" id="department_id" style="max-width:320px">
|
||
<option value="">–</option>
|
||
<?php foreach ($departments as $d): ?>
|
||
<option value="<?= $d['id'] ?>" <?= $curDept === (string) $d['id'] ? 'selected' : '' ?>><?= e($d['name']) ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
<span class="muted" style="font-size:.85rem">Rolle: <strong id="primary-role-label">–</strong> <span style="font-size:.78rem">(Reiter „Berechtigungen“)</span></span>
|
||
</div>
|
||
|
||
<h4 style="border-bottom:1px dotted var(--border);padding-bottom:4px;margin-top:22px">Erweiterter Zugriff</h4>
|
||
<div id="extra-rows"></div>
|
||
<div style="display:flex;align-items:center;gap:8px;margin-top:10px">
|
||
<select id="extra-add" style="max-width:260px"><option value="">— Abteilung auswählen —</option></select>
|
||
<button type="button" class="btn secondary" id="extra-add-btn">Hinzufügen</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Berechtigungen -->
|
||
<div class="tab-pane" data-pane="perms" style="padding:16px 20px;display:none">
|
||
<h3 style="margin-top:0">Berechtigungen</h3>
|
||
<label for="role">Kontotyp</label>
|
||
<select name="role" id="role" style="max-width:320px" <?= $isFullAdmin ? '' : 'disabled' ?>>
|
||
<option value="agent" <?= $curRole === 'agent' ? 'selected' : '' ?>>Mitarbeiter</option>
|
||
<option value="admin" <?= $curRole === 'admin' ? 'selected' : '' ?>>Administrator (alle Rechte)</option>
|
||
</select>
|
||
<?php if (!$isFullAdmin): ?>
|
||
<input type="hidden" name="role" value="<?= e($curRole) ?>">
|
||
<p class="muted" style="font-size:.78rem;margin-top:2px">Nur Administratoren können die Administrator-Rolle vergeben.</p>
|
||
<?php endif; ?>
|
||
<div id="role-id-box">
|
||
<label for="role_id">Rolle (für Mitarbeiter)</label>
|
||
<select name="role_id" id="role_id" style="max-width:320px">
|
||
<option value="">– Standard-Mitarbeiterrechte –</option>
|
||
<?php foreach ($customRoles as $cr): ?>
|
||
<option value="<?= $cr['id'] ?>" <?= $curRoleId === (string) $cr['id'] ? 'selected' : '' ?>><?= e($cr['name']) ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
<p class="muted" style="font-size:.78rem">Rollen legst du unter <a href="/staff/roles.php">Rollen</a> an.</p>
|
||
</div>
|
||
<h4 style="border-bottom:1px dotted var(--border);padding-bottom:4px">Wirksame Rechte</h4>
|
||
<div id="perm-list" style="columns:2;column-gap:24px;font-size:.88rem"></div>
|
||
</div>
|
||
|
||
<!-- Teams -->
|
||
<div class="tab-pane" data-pane="teams" style="padding:16px 20px;display:none">
|
||
<h3 style="margin-top:0">Teams</h3>
|
||
<?php if (!$teams): ?>
|
||
<p class="muted">Es sind noch keine Teams angelegt. Teams legst du unter <a href="/staff/teams.php">Teams</a> an.</p>
|
||
<?php else: ?>
|
||
<p class="muted" style="margin-top:0">Der Agent ist Mitglied in folgenden Teams.<?= $canManageTeams ? '' : ' (Zum Ändern fehlt das Recht „Teams verwalten“.)' ?></p>
|
||
<?php foreach ($teams as $t): ?>
|
||
<label style="display:flex;align-items:center;gap:8px;margin:6px 0">
|
||
<input type="checkbox" name="teams[]" value="<?= $t['id'] ?>" style="width:auto" <?= in_array((int) $t['id'], $memberTeams, true) ? 'checked' : '' ?> <?= $canManageTeams ? '' : 'disabled' ?>>
|
||
<?= e($t['name']) ?><?= $t['is_active'] ? '' : ' <span class="muted">(deaktiviert)</span>' ?>
|
||
</label>
|
||
<?php endforeach; ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<div class="btn-row" style="padding:0 20px 18px">
|
||
<button type="submit" class="btn"><?= $editStaff ? 'Änderungen speichern' : 'Agent anlegen' ?></button>
|
||
<a href="/staff/staff_manage.php" class="btn secondary">Abbrechen</a>
|
||
</div>
|
||
</form>
|
||
|
||
<style>
|
||
.tab-btn{background:none;border:1px solid transparent;border-bottom:none;padding:8px 16px;cursor:pointer;border-radius:6px 6px 0 0;color:var(--muted)}
|
||
.tab-btn.active{background:var(--card-bg,#fff);border-color:var(--border);color:inherit;font-weight:600;position:relative;top:1px}
|
||
.extra-row{display:flex;align-items:center;gap:12px;padding:6px 0;border-bottom:1px dotted var(--border)}
|
||
.extra-row .nm{flex:1}
|
||
.extra-row button{background:none;border:none;color:#dc2626;cursor:pointer;font-size:1rem}
|
||
</style>
|
||
<script>
|
||
(function () {
|
||
var btns = document.querySelectorAll('.tab-btn'), panes = document.querySelectorAll('.tab-pane');
|
||
function show(t) {
|
||
btns.forEach(function (b) { b.classList.toggle('active', b.dataset.tab === t); });
|
||
panes.forEach(function (p) { p.style.display = p.dataset.pane === t ? '' : 'none'; });
|
||
}
|
||
btns.forEach(function (b) { b.addEventListener('click', function () { show(b.dataset.tab); }); });
|
||
show(<?= json_encode($startTab) ?>);
|
||
|
||
// Erweiterter Zugriff
|
||
var depts = <?= json_encode(array_map(fn($d) => ['id' => (int) $d['id'], 'name' => $d['name']], $departments), JSON_UNESCAPED_UNICODE) ?>;
|
||
var extra = <?= json_encode((object) $extraAccess) ?>; // id -> {notify, role_id}
|
||
var roles = <?= json_encode(array_map(fn($r) => ['id' => (int) $r['id'], 'name' => $r['name']], $customRoles), JSON_UNESCAPED_UNICODE) ?>;
|
||
var rows = document.getElementById('extra-rows'), addSel = document.getElementById('extra-add'), primary = document.getElementById('department_id');
|
||
function esc(s) { var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }
|
||
function render() {
|
||
var p = primary.value;
|
||
delete extra[p]; // Hauptabteilung nicht doppelt
|
||
rows.innerHTML = '';
|
||
depts.forEach(function (d) {
|
||
if (!(d.id in extra)) return;
|
||
var div = document.createElement('div'); div.className = 'extra-row';
|
||
var opts = '<option value="">Hauptrolle</option>' + roles.map(function (r) { return '<option value="' + r.id + '"' + (String(extra[d.id].role_id) === String(r.id) ? ' selected' : '') + '>' + esc(r.name) + '</option>'; }).join('');
|
||
div.innerHTML = '<span class="nm">' + esc(d.name) + '<input type="hidden" name="extra_departments[]" value="' + d.id + '"></span>' +
|
||
'<select name="role_' + d.id + '" style="max-width:200px" title="Rolle in dieser Abteilung">' + opts + '</select>' +
|
||
'<label style="display:flex;align-items:center;gap:6px;margin:0"><input type="checkbox" name="notify_' + d.id + '" style="width:auto"' + (extra[d.id].notify ? ' checked' : '') + '> Benachrichtigungen</label>' +
|
||
'<button type="button" title="Entfernen" aria-label="Entfernen">🗑</button>';
|
||
div.querySelector('input[type=checkbox]').addEventListener('change', function (e) { extra[d.id].notify = e.target.checked ? 1 : 0; });
|
||
div.querySelector('select').addEventListener('change', function (e) { extra[d.id].role_id = e.target.value === '' ? null : parseInt(e.target.value, 10); });
|
||
div.querySelector('button').addEventListener('click', function () { delete extra[d.id]; render(); });
|
||
rows.appendChild(div);
|
||
});
|
||
addSel.innerHTML = '<option value="">— Abteilung auswählen —</option>';
|
||
depts.forEach(function (d) { if (!(d.id in extra) && String(d.id) !== p) addSel.insertAdjacentHTML('beforeend', '<option value="' + d.id + '">' + esc(d.name) + '</option>'); });
|
||
}
|
||
document.getElementById('extra-add-btn').addEventListener('click', function () { if (addSel.value) { extra[addSel.value] = { notify: 1, role_id: null }; render(); } });
|
||
primary.addEventListener('change', render);
|
||
render();
|
||
|
||
// Wirksame Rechte
|
||
var labels = <?= json_encode($permLabels, JSON_UNESCAPED_UNICODE) ?>;
|
||
var roleDefs = <?= json_encode((object) $rolePerms) ?>, agentDef = <?= json_encode($agentDefaults) ?>, adminDef = <?= json_encode($adminDefaults) ?>;
|
||
var roleSel = document.getElementById('role'), roleIdSel = document.getElementById('role_id'), list = document.getElementById('perm-list');
|
||
function perms() {
|
||
if (roleSel.value === 'admin') return adminDef;
|
||
return roleIdSel.value && roleDefs[roleIdSel.value] ? roleDefs[roleIdSel.value] : agentDef;
|
||
}
|
||
function primaryRoleLabel() {
|
||
if (roleSel.value === 'admin') return 'Administrator';
|
||
var r = roles.filter(function (x) { return String(x.id) === roleIdSel.value; })[0];
|
||
return r ? r.name : 'Standard-Mitarbeiterrechte';
|
||
}
|
||
function renderPerms() {
|
||
document.getElementById('primary-role-label').textContent = primaryRoleLabel();
|
||
document.getElementById('role-id-box').style.display = roleSel.value === 'admin' ? 'none' : '';
|
||
var p = perms(); list.innerHTML = '';
|
||
Object.keys(labels).forEach(function (k) {
|
||
list.insertAdjacentHTML('beforeend', '<div style="padding:2px 0">' + (p[k] ? '✓' : '<span class="muted">✗</span>') + ' ' + esc(labels[k]) + '</div>');
|
||
});
|
||
}
|
||
roleSel.addEventListener('change', renderPerms); roleIdSel.addEventListener('change', renderPerms); renderPerms();
|
||
})();
|
||
</script>
|
||
|
||
<?php else: ?>
|
||
<div style="display:flex;justify-content:space-between;align-items:center;gap:12px">
|
||
<h1 style="margin:0">Mitarbeiter</h1>
|
||
<a href="/staff/staff_manage.php?new=1" class="btn">Neuen Agenten hinzufügen</a>
|
||
</div>
|
||
|
||
<div class="card" style="margin-top:14px">
|
||
<table>
|
||
<thead><tr><th>Name</th><th>E-Mail</th><th>Typ</th><th>Status</th><th>Hauptabteilung</th><th style="text-align:center">Teams</th><th>Erstellt</th><th></th></tr></thead>
|
||
<tbody>
|
||
<?php foreach ($allStaff as $s): ?>
|
||
<tr>
|
||
<td><a href="/staff/staff_manage.php?edit=<?= (int) $s['id'] ?>"><?= e($s['name']) ?></a></td>
|
||
<td><?= e($s['email']) ?></td>
|
||
<td><?= $s['role'] === 'admin' ? 'Administrator' : 'Mitarbeiter' ?></td>
|
||
<td><strong><?= $s['is_active'] ? 'Aktiv' : 'Gesperrt' ?></strong></td>
|
||
<td><?= e($s['department_name'] ?? '–') ?></td>
|
||
<td style="text-align:center"><?= (int) $s['team_count'] ?></td>
|
||
<td class="muted" style="font-size:.82rem"><?= e($fmt($s['created_at'] ?? null)) ?></td>
|
||
<td style="white-space:nowrap">
|
||
<a href="/staff/staff_manage.php?edit=<?= (int) $s['id'] ?>">Bearbeiten</a> ·
|
||
<form method="post" style="display:inline" onsubmit="return confirm('Mitarbeiter wirklich löschen?');">
|
||
<?= csrf_field() ?>
|
||
<input type="hidden" name="action" value="delete">
|
||
<input type="hidden" name="id" value="<?= (int) $s['id'] ?>">
|
||
<button type="submit" style="background:none;border:none;color:#dc2626;cursor:pointer;padding:0;font-size:.9rem">Löschen</button>
|
||
</form>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php require __DIR__ . '/_footer.php'; ?>
|