Files
awo-hamburg-intranet/module/tasks/pages/user/my_tasks.php

285 lines
12 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
if (!isset($assignments) && !isset($error)) {
require_once dirname(dirname(__DIR__)) . '/actions/user/my_tasks_action.php';
$viewData = task_cert_user_my_tasks_action();
if (is_array($viewData)) {
extract($viewData, EXTR_SKIP);
}
}
$error = $error ?? null;
$assignments = $assignments ?? [];
$statusLabels = TaskCertConstants::assignmentStatusLabels();
$completedStatuses = TaskCertConstants::COMPLETED_STATUSES;
if (!function_exists('task_cert_render_styles')) {
require_once dirname(dirname(__DIR__)) . '/bootstrap.php';
}
task_cert_render_styles(['user']);
$taskDetailUrl = task_cert_view_url('user.task_detail');
$myTasksUrl = task_cert_view_url('user.my_tasks');
$now = new DateTimeImmutable('now');
$statusFilter = TaskCertRequest::queryString('status', '');
if ($statusFilter !== '' && !array_key_exists($statusFilter, $statusLabels)) {
$statusFilter = '';
}
if ($statusFilter !== '') {
$assignments = array_values(array_filter($assignments, static function (array $a) use ($statusFilter): bool {
return ($a['status'] ?? '') === $statusFilter;
}));
}
// Active & completed assignments: alle Zyklen separat anzeigen.
// Aktive: älteste zuerst (überfällige Rückstände oben).
// Abgeschlossene: neueste zuerst (unter <details> im UI eingeklappt).
$byTaskId = [];
foreach ($assignments as $a) {
$byTaskId[(int) ($a['task_id'] ?? 0)][] = $a;
}
$assignments = [];
foreach ($byTaskId as $taskAssignments) {
$active = [];
$completed = [];
foreach ($taskAssignments as $a) {
if (in_array($a['status'] ?? '', $completedStatuses, true)) {
$completed[] = $a;
} else {
$active[] = $a;
}
}
if ($active !== []) {
usort($active, static function (array $a, array $b): int {
$aDue = strtotime((string) ($a['due_at'] ?? '9999-12-31'));
$bDue = strtotime((string) ($b['due_at'] ?? '9999-12-31'));
return $aDue <=> $bDue;
});
foreach ($active as $a) {
$assignments[] = $a;
}
}
if ($completed !== []) {
usort($completed, static function (array $a, array $b): int {
return strtotime((string) ($b['completed_at'] ?? '0')) - strtotime((string) ($a['completed_at'] ?? '0'));
});
foreach ($completed as $a) {
$assignments[] = $a;
}
}
}
$formatDateShort = static function ($value): string {
$value = trim((string) $value);
if ($value === '') {
return '';
}
try {
return (new DateTimeImmutable($value))->format('d.m.Y');
} catch (Throwable $throwable) {
return $value;
}
};
$getCardMeta = static function (array $assignment) use ($formatDateShort): string {
$parts = [];
$dueAt = trim((string) ($assignment['due_at'] ?? ''));
if ($dueAt !== '') {
$parts[] = 'Fällig bis ' . $formatDateShort($dueAt);
} else {
$parts[] = 'Kein Fälligkeitsdatum';
}
// Zyklus-Zeitraum nur anzeigen, wenn die Aufgabe wiederkehrend ist
// (bei 'once' irrelevant). So versteht der User bei Rückständen,
// welcher Zyklus welcher Karte zugeordnet ist.
$cycleKey = (string) ($assignment['cycle_key'] ?? '');
$cycleStart = trim((string) ($assignment['cycle_start_at'] ?? ''));
$cycleEnd = trim((string) ($assignment['cycle_end_at'] ?? ''));
$showCyclePeriod = (int) ($assignment['show_cycle_period'] ?? 0) === 1;
if ($showCyclePeriod && $cycleKey !== '' && $cycleKey !== 'once' && $cycleStart !== '' && $cycleEnd !== '') {
$parts[] = 'Zeitraum ' . $formatDateShort($cycleStart) . '' . $formatDateShort($cycleEnd);
}
return implode(' · ', $parts);
};
$isAssignmentOverdueByDate = static function (array $assignment, DateTimeImmutable $now): bool {
$status = (string) ($assignment['status'] ?? '');
if ($status === 'completed') {
return false;
}
$dueAt = trim((string) ($assignment['due_at'] ?? ''));
if ($dueAt === '') {
return false;
}
try {
return (new DateTimeImmutable($dueAt)) < $now;
} catch (Throwable $throwable) {
return false;
}
};
$groupedAssignments = [];
$categoryOrder = [];
foreach ($assignments as $assignment) {
$categoryName = trim((string) ($assignment['task_category_name'] ?? ''));
if ($categoryName === '') {
$categoryName = 'Allgemein';
}
if (!array_key_exists($categoryName, $groupedAssignments)) {
$groupedAssignments[$categoryName] = [];
$categoryOrder[] = $categoryName;
}
$groupedAssignments[$categoryName][] = $assignment;
}
?>
<div class="task-cert task-cert-user-my-tasks">
<?php if ($error): ?>
<div class="task-cert-error"><?php echo TaskCertView::e($error); ?></div>
<?php endif; ?>
<form method="get" action="<?php echo TaskCertView::e($myTasksUrl); ?>" class="task-cert-user-filter-bar">
<label for="task-cert-user-status-filter" class="task-cert-sr-only">Status filtern</label>
<select name="status" id="task-cert-user-status-filter" aria-label="Status filtern" onchange="this.form.submit()">
<option value="">Alle Status</option>
<?php foreach ($statusLabels as $key => $label): ?>
<option value="<?php echo TaskCertView::e($key); ?>" <?php echo $statusFilter === $key ? 'selected' : ''; ?>>
<?php echo TaskCertView::e($label); ?>
</option>
<?php endforeach; ?>
</select>
<?php if ($statusFilter !== ''): ?>
<a href="<?php echo TaskCertView::e($myTasksUrl); ?>" class="task-cert-user-filter-reset">Zurücksetzen</a>
<?php endif; ?>
</form>
<?php if ($assignments === []): ?>
<div class="task-cert-block">
<?php if ($statusFilter !== ''): ?>
Keine Aufgaben mit Status &bdquo;<?php echo TaskCertView::e($statusLabels[$statusFilter] ?? $statusFilter); ?>&ldquo; vorhanden.
<?php else: ?>
Aktuell sind keine Aufgaben vorhanden.
<?php endif; ?>
</div>
<?php else: ?>
<?php foreach ($categoryOrder as $categoryName): ?>
<?php
$categoryAssignments = $groupedAssignments[$categoryName] ?? [];
if ($categoryAssignments === []) { continue; }
$activeAssignments = [];
$completedAssignments = [];
foreach ($categoryAssignments as $a) {
if (in_array($a['status'] ?? '', $completedStatuses, true)) {
$completedAssignments[] = $a;
} else {
$activeAssignments[] = $a;
}
}
usort($completedAssignments, static function (array $a, array $b): int {
return strtotime((string) ($b['completed_at'] ?? '0')) - strtotime((string) ($a['completed_at'] ?? '0'));
});
$activeCount = count($activeAssignments);
$completedCount = count($completedAssignments);
?>
<section class="task-cert-user-category-group">
<header class="task-cert-user-category-head">
<h3><?php echo TaskCertView::e($categoryName); ?></h3>
<span><?php echo $activeCount; ?> offen<?php echo $completedCount > 0 ? ', ' . $completedCount . ' abgeschlossen' : ''; ?></span>
</header>
<?php if ($activeAssignments !== []): ?>
<div class="task-cert-user-task-cards">
<?php foreach ($activeAssignments as $assignment): ?>
<?php
$status = (string) ($assignment['status'] ?? '');
$title = (string) ($assignment['title'] ?? 'Aufgabe');
$metaText = $getCardMeta($assignment);
$isOverdueByDate = $isAssignmentOverdueByDate($assignment, $now);
$isEscalated = (int) ($assignment['escalation_level'] ?? 0) > 0;
$cardClasses = [
'task-cert-user-task-card',
'status-' . $status,
];
if ($isOverdueByDate) {
$cardClasses[] = 'is-overdue-date';
}
if ($isEscalated) {
$cardClasses[] = 'is-escalated';
}
?>
<a
href="<?php echo TaskCertView::e($taskDetailUrl . '?assignment_id=' . (int) $assignment['id']); ?>"
class="<?php echo TaskCertView::e(implode(' ', $cardClasses)); ?>"
>
<div class="task-cert-user-task-card-head">
<strong><?php echo TaskCertView::e($title); ?></strong>
<span class="task-cert-user-status-badge status-<?php echo TaskCertView::e($status); ?>">
<?php echo TaskCertView::e($statusLabels[$status] ?? $status); ?>
</span>
</div>
<div class="task-cert-user-task-card-meta">
<?php echo TaskCertView::e($metaText); ?>
</div>
</a>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if ($completedAssignments !== []): ?>
<details class="task-cert-user-completed-group">
<summary>
<?php echo $completedCount; ?> abgeschlossene Aufgabe<?php echo $completedCount === 1 ? '' : 'n'; ?> anzeigen
</summary>
<div class="task-cert-user-task-cards">
<?php foreach ($completedAssignments as $assignment): ?>
<?php
$status = (string) ($assignment['status'] ?? '');
$title = (string) ($assignment['title'] ?? 'Aufgabe');
$metaText = $getCardMeta($assignment);
$cardClasses = ['task-cert-user-task-card', 'status-' . $status];
?>
<a
href="<?php echo TaskCertView::e($taskDetailUrl . '?assignment_id=' . (int) $assignment['id']); ?>"
class="<?php echo TaskCertView::e(implode(' ', $cardClasses)); ?>"
>
<div class="task-cert-user-task-card-head">
<strong><?php echo TaskCertView::e($title); ?></strong>
<span class="task-cert-user-status-badge status-<?php echo TaskCertView::e($status); ?>">
<?php echo TaskCertView::e($statusLabels[$status] ?? $status); ?>
</span>
</div>
<div class="task-cert-user-task-card-meta">
<?php echo TaskCertView::e($metaText); ?>
</div>
</a>
<?php endforeach; ?>
</div>
</details>
<?php endif; ?>
<?php if ($activeAssignments === [] && $completedAssignments === []): ?>
<div class="task-cert-block">Keine Aufgaben in dieser Kategorie.</div>
<?php endif; ?>
</section>
<?php endforeach; ?>
<?php endif; ?>
</div>