Files
deskhub/DeskHub-Webseite/staff/teams.php
T
2026-10-16 19:12:24 +00:00

181 lines
9.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
require_once __DIR__ . '/../includes/bootstrap.php';
$staff = require_admin_or_permission('manage_teams');
$pdo = get_db();
$errors = [];
$allStaff = $pdo->query('SELECT id, name FROM staff WHERE is_active = 1 ORDER BY name')->fetchAll();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
verify_csrf();
$action = $_POST['action'] ?? '';
if ($action === 'create' || $action === 'update') {
$id = $action === 'update' ? (int) ($_POST['id'] ?? 0) : 0;
try {
team_save($pdo, $id, [
'name' => $_POST['name'] ?? '', 'lead_id' => $_POST['lead_id'] ?? null, 'notes' => $_POST['notes'] ?? '',
'is_active' => ($_POST['status'] ?? 'active') === 'active', 'no_alerts' => !empty($_POST['no_alerts']),
'members' => $_POST['members'] ?? [],
]);
audit_log($staff['id'], ($action === 'create' ? 'Team erstellt: ' : 'Team aktualisiert: ') . trim($_POST['name'] ?? ''));
flash('success', $action === 'create' ? 'Team erstellt.' : 'Änderungen gespeichert.');
redirect('/staff/teams.php');
} catch (AdminModelException $e) {
$errors[] = $e->getMessage();
}
}
if ($action === 'delete') {
$deleted = team_delete($pdo, (int) $_POST['id']);
audit_log($staff['id'], "Team gelöscht: {$deleted}");
flash('success', 'Team gelöscht.');
redirect('/staff/teams.php');
}
}
$isNew = isset($_GET['new']);
$editId = (int) ($_GET['edit'] ?? 0);
$showForm = $isNew || $editId || ($errors && in_array($_POST['action'] ?? '', ['create', 'update'], true));
$editTeam = null; $editMembers = [];
if ($editId) {
$es = $pdo->prepare('SELECT * FROM teams WHERE id = ?'); $es->execute([$editId]);
$editTeam = $es->fetch() ?: null;
$em = $pdo->prepare('SELECT staff_id FROM team_members WHERE team_id = ?'); $em->execute([$editId]);
$editMembers = array_map('intval', $em->fetchAll(PDO::FETCH_COLUMN));
}
if ($_POST && $errors) $editMembers = array_map('intval', (array) ($_POST['members'] ?? []));
$teams = $pdo->query(
'SELECT t.*, s.name AS lead_name,
(SELECT COUNT(*) FROM team_members tm WHERE tm.team_id = t.id) AS member_count
FROM teams t LEFT JOIN staff s ON s.id = t.lead_id ORDER BY t.name'
)->fetchAll();
$fmt = fn(?string $dt) => $dt ? date('d.m.Y H:i', strtotime($dt)) : '–';
$pageTitle = 'Teams'; $activePage = 'teams';
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, $editTeam[$col] ?? $default);
$curStatus = $_POST ? ($_POST['status'] ?? 'active') : (($editTeam['is_active'] ?? 1) ? 'active' : 'inactive');
$curLead = (string) $v('lead_id', 'lead_id');
$noAlerts = $_POST ? !empty($_POST['no_alerts']) : !empty($editTeam['no_alerts']);
?>
<h1>
<?= $editTeam ? 'Team aktualisieren' : 'Neues Team' ?>
<?php if ($editTeam): ?><span class="muted" style="font-size:1rem;font-weight:400">— <?= e($editTeam['name']) ?></span><?php endif; ?>
</h1>
<form method="post" class="card" style="padding:0">
<?= csrf_field() ?>
<input type="hidden" name="action" value="<?= $editTeam ? 'update' : 'create' ?>">
<?php if ($editTeam): ?><input type="hidden" name="id" value="<?= (int) $editTeam['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="team">Team</button>
<button type="button" class="tab-btn" data-tab="members">Mitglieder (<?= count($editMembers) ?>)</button>
</div>
<div class="tab-pane" data-pane="team" style="padding:16px 20px">
<h3 style="margin-top:0">Teaminformationen</h3>
<label for="name">Name *</label>
<input type="text" id="name" name="name" value="<?= e($v('name', 'name')) ?>" 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="inactive" style="width:auto" <?= $curStatus !== 'active' ? 'checked' : '' ?>> Deaktiviert</label>
</div>
<label for="lead_id">Teamleiter</label>
<select name="lead_id" id="lead_id" style="max-width:320px">
<option value="">— Keine(r) —</option>
<?php foreach ($allStaff as $s): ?>
<option value="<?= $s['id'] ?>" <?= $curLead === (string) $s['id'] ? 'selected' : '' ?>><?= e($s['name']) ?></option>
<?php endforeach; ?>
</select>
<label style="display:flex;align-items:center;gap:8px;margin-top:14px">
<input type="checkbox" name="no_alerts" style="width:auto" <?= $noAlerts ? 'checked' : '' ?>>
Benachrichtigung bei Ticketzuweisung für dieses Team <strong>deaktivieren</strong>
</label>
<h3>Administratornotizen <span class="muted" style="font-weight:400;font-size:.85rem">– Interne Notizen, sichtbar für alle Administratoren</span></h3>
<textarea id="notes" name="notes" rows="6"><?= e($v('notes', 'notes')) ?></textarea>
</div>
<div class="tab-pane" data-pane="members" style="padding:16px 20px;display:none">
<h3 style="margin-top:0">Mitglieder</h3>
<?php if (!$allStaff): ?>
<p class="muted">Es gibt keine aktiven Mitarbeiter.</p>
<?php else: foreach ($allStaff as $s): ?>
<label style="display:flex;align-items:center;gap:8px;padding:4px 0;font-weight:400;cursor:pointer">
<input type="checkbox" name="members[]" value="<?= $s['id'] ?>" style="width:auto" <?= in_array((int) $s['id'], $editMembers, true) ? 'checked' : '' ?>>
<?= e($s['name']) ?>
</label>
<?php endforeach; endif; ?>
</div>
<div class="btn-row" style="padding:0 20px 18px">
<button type="submit" class="btn"><?= $editTeam ? 'Änderungen speichern' : 'Erstellen' ?></button>
<a href="/staff/teams.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}
</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('team');
})();
</script>
<?php else: ?>
<div style="display:flex;justify-content:space-between;align-items:center;gap:12px">
<h1 style="margin:0">Teams</h1>
<a href="/staff/teams.php?new=1" class="btn">Neues Team hinzufügen</a>
</div>
<p class="muted">Abteilungsübergreifende Mitarbeiter-Gruppen. Tickets können einem Team statt einem einzelnen Mitarbeiter zugewiesen werden; die Mitglieder werden dabei benachrichtigt.</p>
<div class="card">
<table>
<thead><tr><th>Teamname</th><th>Status</th><th style="text-align:center">Mitglieder</th><th>Teamleiter</th><th>Erstellt</th><th>Zuletzt aktualisiert</th><th></th></tr></thead>
<tbody>
<?php foreach ($teams as $t): ?>
<tr>
<td><a href="/staff/teams.php?edit=<?= (int) $t['id'] ?>"><?= e($t['name']) ?></a></td>
<td><strong><?= $t['is_active'] ? 'Aktiv' : 'Deaktiviert' ?></strong></td>
<td style="text-align:center"><a href="/staff/teams.php?edit=<?= (int) $t['id'] ?>"><?= (int) $t['member_count'] ?></a></td>
<td><?= e($t['lead_name'] ?? '') ?></td>
<td class="muted" style="font-size:.82rem"><?= e($fmt($t['created_at'] ?? null)) ?></td>
<td class="muted" style="font-size:.82rem"><?= e($fmt($t['updated_at'] ?? null)) ?></td>
<td style="white-space:nowrap">
<a href="/staff/teams.php?edit=<?= (int) $t['id'] ?>">Bearbeiten</a> ·
<form method="post" style="display:inline" onsubmit="return confirm('Team wirklich löschen?')">
<?= csrf_field() ?>
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?= (int) $t['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; ?>
<?php if (!$teams): ?><tr><td colspan="7" class="muted">Noch keine Teams angelegt.</td></tr><?php endif; ?>
</tbody>
</table>
</div>
<?php endif; ?>
<?php require __DIR__ . '/_footer.php'; ?>