Quelltext des aktuellen Standes
<?php
$this->layout('layouts/main', [
'page_title' => $page_title ?? 'Antrag',
'current_route' => 'workflows',
'full_width' => true,
'extra_css' => ['/assets/css/workflows.css'],
]);
$req = $request;
$fields = $fields ?? [];
$steps = $steps ?? [];
$approvers = $approvers ?? [];
$decisions = $decisions ?? [];
$links = $links ?? [];
$actionable = $actionable ?? [];
$isRequester = $is_requester ?? false;
$actionableIds = array_map(fn($s) => (int)$s['id'], $actionable);
$statusMap = [
'draft' => ['Entwurf', ''],
'pending' => ['In Bearbeitung', 'status-pill--info'],
'waiting_requester' => ['Rückfrage offen', 'status-pill--warning'],
'approved' => ['Genehmigt', 'status-pill--success'],
'rejected' => ['Abgelehnt', 'status-pill--danger'],
'cancelled' => ['Zurückgezogen', ''],
'expired' => ['Abgelaufen', 'status-pill--danger'],
];
$st = $statusMap[$req['status']] ?? [$req['status'], ''];
// Stationen nach Stage gruppieren
$stages = [];
foreach ($steps as $s) { $stages[(int)$s['stage_no']][] = $s; }
ksort($stages);
$stepStatusIcon = [
'pending' => ['fa-clock', ''],
'active' => ['fa-hourglass-half', 'is-active'],
'approved' => ['fa-check', 'is-approved'],
'done' => ['fa-check', 'is-done'],
'rejected' => ['fa-times', 'is-rejected'],
'skipped' => ['fa-forward', 'is-skipped'],
'waiting' => ['fa-comment', 'is-active'],
];
$openQuestion = false;
foreach (array_reverse($decisions) as $d) {
if ($d['decision'] === 'question') { $openQuestion = true; break; }
if ($d['decision'] === 'answer') { break; }
}
?>
<div class="content-header">
<div>
<h1><?= $this->e($req['title']) ?></h1>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/antraege"><?= $this->te('Anträge') ?></a></li>
<li class="breadcrumb-item active"><?= $this->e($req['workflow_name']) ?></li>
</ol>
</div>
<div style="display:flex;gap:.5rem;align-items:center;">
<span class="status-pill <?= $st[1] ?>"><?= $this->e($st[0]) ?></span>
<a class="btn btn-sm btn-secondary" href="/antraege/<?= (int)$req['id'] ?>/pdf" title="<?= $this->te('Als PDF') ?>"><i class="fas fa-file-pdf"></i> PDF</a>
</div>
</div>
<?php
// Fortschritts-Leiste: Status je Stufe aggregieren
// (fertig = alle Stationen abgeschlossen, aktiv = mind. eine aktiv/wartend)
$stageStates = [];
foreach ($stages as $no => $sts) {
$state = 'done';
foreach ($sts as $x) {
if (in_array($x['status'], ['active', 'waiting'], true)) { $state = 'active'; break; }
if ($x['status'] === 'rejected') { $state = 'rejected'; break; }
if ($x['status'] === 'pending') { $state = 'pending'; }
}
$stageStates[$no] = $state;
}
$reqFinished = in_array($req['status'], ['approved', 'rejected', 'cancelled', 'expired'], true);
?>
<?php if (!empty($stageStates)): ?>
<div class="page-body" style="padding-bottom:0;">
<div class="wf-progress">
<div class="wf-progress-step <?= 'is-done' ?>">
<span class="wf-progress-dot"><i class="fas fa-play"></i></span>
<span class="wf-progress-label"><?= $this->te('Eingereicht') ?></span>
</div>
<?php foreach ($stageStates as $no => $state):
$names = implode(', ', array_map(fn($x) => $x['name'], $stages[$no]));
?>
<div class="wf-progress-line <?= $state === 'done' ? 'is-done' : '' ?>"></div>
<div class="wf-progress-step is-<?= $state ?>" title="<?= $this->e($names) ?>">
<span class="wf-progress-dot"><?php
echo match ($state) {
'done' => '<i class="fas fa-check"></i>',
'rejected' => '<i class="fas fa-times"></i>',
'active' => '<i class="fas fa-hourglass-half"></i>',
default => (int)$no,
};
?></span>
<span class="wf-progress-label"><?= $this->te('Stufe {nummer}', ['nummer' => (int)$no]) ?><small><?= $this->e(mb_substr($names, 0, 34)) ?><?= mb_strlen($names) > 34 ? '…' : '' ?></small></span>
</div>
<?php endforeach; ?>
<div class="wf-progress-line <?= $reqFinished && $req['status'] === 'approved' ? 'is-done' : '' ?>"></div>
<div class="wf-progress-step <?= $req['status'] === 'approved' ? 'is-done' : ($req['status'] === 'rejected' ? 'is-rejected' : '') ?>">
<span class="wf-progress-dot"><i class="fas fa-flag-checkered"></i></span>
<span class="wf-progress-label"><?= $req['status'] === 'rejected' ? 'Abgelehnt' : 'Abgeschlossen' ?></span>
</div>
</div>
</div>
<?php endif; ?>
<div class="page-body wf-detail-grid">
<div>
<!-- Stammdaten + Felder -->
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Antragsdaten') ?></span></div>
<div class="detail-card-body">
<table class="wf-kv">
<tr><th scope="col"><?= $this->te('Antragsteller') ?></th><td><?= $this->e($req['requester_name']) ?></td></tr>
<?php if ($req['subject_type'] === 'person' && !empty($req['subject_person_name'])): ?>
<tr><th scope="row"><?= $this->te('Betroffene Person') ?></th><td><?= $this->e($req['subject_person_name']) ?></td></tr>
<?php elseif ($req['subject_type'] === 'free' && !empty($req['subject_text'])): ?>
<tr><th scope="row"><?= $this->te('Betroffene Person') ?></th><td><?= $this->e($req['subject_text']) ?></td></tr>
<?php elseif ($req['subject_type'] === 'self'): ?>
<tr><th scope="row"><?= $this->te('Betroffene Person') ?></th><td><?= $this->e($req['requester_name']) ?></td></tr>
<?php endif; ?>
<tr><th scope="row"><?= $this->te('Eingereicht') ?></th><td><?= $this->date($req['submitted_at'] ?? $req['created_at'], 'd.m.Y H:i') ?></td></tr>
<?php foreach ($fields as $f): ?>
<tr>
<th scope="row"><?= $this->e($f['field_label']) ?></th>
<td>
<?php $v = (string)($f['field_value'] ?? ''); ?>
<?php if ($f['field_type'] === 'file' && str_starts_with($v, '/uploads/')): ?>
<a class="table-link" href="<?= $this->e($v) ?>" target="_blank"><i class="fas fa-paperclip"></i> <?= $this->te('Datei öffnen') ?></a>
<?php else: ?>
<?= $v !== '' ? nl2br($this->e($v)) : '<span class="text-muted">–</span>' ?>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</table>
</div>
</div>
<!-- Stationsverlauf -->
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Stationsverlauf') ?></span></div>
<div class="detail-card-body">
<?php foreach ($stages as $stageNo => $stageSteps): ?>
<div class="wf-stage">
<div class="wf-stage-title"><?= $this->t('Stufe') ?> <?= (int)$stageNo ?><?= count($stageSteps) > 1 ? ' (parallel)' : '' ?></div>
<?php foreach ($stageSteps as $s):
$ic = $stepStatusIcon[$s['status']] ?? ['fa-circle', ''];
$sApprovers = $approvers[(int)$s['id']] ?? [];
?>
<div class="wf-step">
<div class="wf-step-icon <?= $ic[1] ?>"><i class="fas <?= $ic[0] ?>"></i></div>
<div class="wf-step-body">
<div class="wf-step-name"><?= $this->e($s['name']) ?></div>
<div class="wf-step-meta">
<?php
$typeLabel = ['approval'=>'Genehmigung','task'=>'Aufgabe','condition'=>'Bedingung','info'=>'Info'][$s['step_type']] ?? $s['step_type'];
echo $this->e($typeLabel);
if (!empty($sApprovers)) {
$names = array_map(fn($a) => $a['name'] ?: $a['email'], $sApprovers);
echo ' · ' . $this->e(implode(', ', array_filter($names)));
}
if (!empty($s['deadline_at']) && $s['status'] === 'active') {
echo ' · Frist: ' . $this->date($s['deadline_at'], 'd.m.Y H:i');
}
?>
</div>
<?php if (($can_manage ?? false) && $s['status'] === 'active'): ?>
<div style="margin-top:.4rem;display:flex;gap:.4rem;flex-wrap:wrap;">
<form method="post" action="/antraege/<?= (int)$req['id'] ?>/steps/<?= (int)$s['id'] ?>/reassign">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<button class="btn btn-xs btn-secondary" type="submit" title="<?= $this->te('Genehmiger neu auflösen') ?>"><i class="fas fa-sync-alt"></i> <?= $this->te('Neu zuweisen') ?></button>
</form>
<form method="post" action="/antraege/<?= (int)$req['id'] ?>/steps/<?= (int)$s['id'] ?>/remind">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<button class="btn btn-xs btn-secondary" type="submit" title="<?= $this->te('Offene Genehmiger jetzt erneut erinnern') ?>"><i class="fas fa-bell"></i> <?= $this->te('Jetzt erinnern') ?></button>
</form>
<form method="post" action="/antraege/<?= (int)$req['id'] ?>/steps/<?= (int)$s['id'] ?>/skip" onsubmit="return confirm('Diese Station überspringen und den Antrag weiterschalten?');">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<button class="btn btn-xs btn-secondary" type="submit" title="<?= $this->te('Station überspringen') ?>"><i class="fas fa-forward"></i> <?= $this->te('Überspringen') ?></button>
</form>
</div>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
</div>
</div>
<!-- Notiz-Faden / Entscheidungen -->
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Verlauf & Diskussion') ?></span></div>
<div class="detail-card-body">
<?php if (!empty($decisions)): ?>
<ul class="wf-thread">
<?php foreach ($decisions as $d):
$dl = ['approve'=>'genehmigt','reject'=>'abgelehnt','question'=>'Rückfrage','answer'=>'Antwort','done'=>'erledigt','cancel'=>'abgebrochen','forward'=>'weitergeleitet','comment'=>'kommentiert'][$d['decision']] ?? $d['decision'];
?>
<li class="wf-d-<?= $this->e($d['decision']) ?>">
<div class="wf-thread-meta">
<strong><?= $this->e($d['approver_name'] ?: 'System') ?></strong> · <?= $this->e($dl) ?>
· <?= $this->date($d['created_at'], 'd.m.Y H:i') ?>
</div>
<?php if (!empty($d['reason'])): ?><div class="wf-thread-note"><?= nl2br($this->e($d['reason'])) ?></div><?php endif; ?>
<?php if (!empty($d['note'])): ?><div class="wf-thread-note"><em><?= nl2br($this->e($d['note'])) ?></em></div><?php endif; ?>
<?php if (!empty($d['attachment_path'])): ?><div class="wf-thread-note"><a class="table-link" href="<?= $this->e($d['attachment_path']) ?>" target="_blank"><i class="fas fa-paperclip"></i> <?= $this->te('Anhang öffnen') ?></a></div><?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p class="text-muted"><?= $this->te('Noch keine Einträge.') ?></p>
<?php endif; ?>
<?php if (empty($req['anonymized_at'])): ?>
<hr>
<form method="post" action="/antraege/<?= (int)$req['id'] ?>/comment" enctype="multipart/form-data">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<div class="form-group" style="margin-bottom:.5rem;">
<label><?= $this->te('Kommentar hinzufügen') ?></label>
<textarea class="form-control form-control-sm" name="text" rows="2" placeholder="<?= $this->te('Sichtbar für alle Beteiligten') ?>"></textarea>
</div>
<div style="display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;">
<input class="form-control form-control-sm" type="file" name="attachment" style="flex:1;min-width:160px;">
<button class="btn btn-secondary btn-sm" type="submit"><i class="fas fa-comment-dots"></i> <?= $this->te('Kommentieren') ?></button>
</div>
</form>
<?php endif; ?>
</div>
</div>
</div>
<!-- Aktionsspalte -->
<div>
<?php if ($isRequester && $req['status'] === 'draft'):
$valMap = [];
foreach ($fields as $fv) { $valMap[$fv['field_key']] = $fv['field_value']; }
?>
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Entwurf bearbeiten & einreichen') ?></span></div>
<div class="detail-card-body">
<form method="post" action="/antraege/<?= (int)$req['id'] ?>/submit" enctype="multipart/form-data">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<?php foreach (($wf_fields ?? []) as $f):
$name = 'field_' . $f['field_key']; $cur = $valMap[$f['field_key']] ?? '';
$req2 = (int)$f['is_required'] === 1; ?>
<div class="form-group">
<label><?= $this->e($f['label']) ?><?php if ($req2): ?> <span class="text-danger">*</span><?php endif; ?></label>
<?php if ($f['field_type'] === 'textarea'): ?>
<textarea class="form-control form-control-sm" name="<?= $this->e($name) ?>" rows="2"><?= $this->e($cur) ?></textarea>
<?php elseif ($f['field_type'] === 'file'): ?>
<input class="form-control form-control-sm" type="file" name="<?= $this->e($name) ?>">
<?php if ($cur !== ''): ?><small class="text-muted"><?= $this->te('Datei bereits hochgeladen') ?></small><?php endif; ?>
<?php else: ?>
<input class="form-control form-control-sm" type="text" name="<?= $this->e($name) ?>" value="<?= $this->e($cur) ?>">
<?php endif; ?>
</div>
<?php endforeach; ?>
<button class="btn btn-primary" type="submit"><i class="fas fa-paper-plane"></i> <?= $this->te('Antrag einreichen') ?></button>
</form>
</div>
</div>
<?php endif; ?>
<?php if (!empty($actionable)): ?>
<?php foreach ($actionable as $s): ?>
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->e($s['name']) ?></span></div>
<div class="detail-card-body">
<?php if (!empty($s['decision_instructions'])): ?>
<div class="wf-instructions"><i class="fas fa-info-circle"></i> <?= nl2br($this->e($s['decision_instructions'])) ?></div>
<?php endif; ?>
<?php if ($s['step_type'] === 'task'): ?>
<?php
// Checkliste: Teilaufgaben einzeln abhaken; die Station schließt
// automatisch, sobald alle Punkte erledigt sind.
$clCfg = !empty($s['fulfillment_config_json']) ? (json_decode($s['fulfillment_config_json'], true) ?: []) : [];
$clItems = array_values((array)($clCfg['items'] ?? []));
$clState = !empty($s['checklist_state_json']) ? (json_decode($s['checklist_state_json'], true) ?: []) : [];
?>
<?php if (($s['fulfillment_type'] ?? 'none') === 'checklist' && !empty($clItems)): ?>
<?php $clDone = count(array_filter($clState, fn($e) => !empty($e['at']))); ?>
<div style="font-size:.8rem;color:var(--gray-500);margin-bottom:.5rem;">
<?= $this->t('<strong>{erledigt} von {gesamt}</strong> Teilaufgaben erledigt – die Aufgabe schließt automatisch, sobald alles abgehakt ist.', ['erledigt' => $clDone, 'gesamt' => count($clItems)]) ?>
</div>
<div style="display:flex;flex-direction:column;gap:.35rem;">
<?php foreach ($clItems as $ci => $item):
$st = (array)($clState[(string)$ci] ?? []);
$done = !empty($st['at']);
$claimed = (string)($st['claimed_name'] ?? '');
?>
<div style="display:flex;gap:.5rem;align-items:stretch;">
<form method="post" action="/antraege/<?= (int)$req['id'] ?>/checklist" style="margin:0;flex:1;min-width:0;">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<input type="hidden" name="step_state_id" value="<?= (int)$s['id'] ?>">
<input type="hidden" name="item" value="<?= (int)$ci ?>">
<input type="hidden" name="op" value="<?= $done ? 'uncheck' : 'check' ?>">
<label style="display:flex;gap:.55rem;align-items:flex-start;cursor:pointer;padding:.4rem .6rem;border:1px solid var(--gray-200);border-radius:.4rem;background:<?= $done ? 'var(--green-50)' : 'var(--color-bg)' ?>;height:100%;box-sizing:border-box;">
<input type="checkbox" <?= $done ? 'checked' : '' ?> onchange="this.form.submit()" style="margin-top:.2rem;flex:0 0 auto;">
<span style="<?= $done ? 'text-decoration:line-through;color:var(--gray-500);' : '' ?>"><?= $this->e($item) ?>
<?php if ($done): ?><small style="display:block;color:var(--gray-400);text-decoration:none;">✓ <?= $this->e($st['name'] ?? '') ?> · <?= $this->e(date('d.m.Y H:i', strtotime((string)($st['at'] ?? 'now')))) ?></small>
<?php elseif ($claimed !== ''): ?><small style="display:block;color:var(--violet-700);"><?= $this->t('→ übernommen von') ?> <?= $this->e($claimed) ?></small><?php endif; ?>
</span>
</label>
</form>
<?php if (!$done): ?>
<form method="post" action="/antraege/<?= (int)$req['id'] ?>/checklist" style="margin:0;flex:0 0 auto;display:flex;">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<input type="hidden" name="step_state_id" value="<?= (int)$s['id'] ?>">
<input type="hidden" name="item" value="<?= (int)$ci ?>">
<input type="hidden" name="op" value="<?= $claimed !== '' ? 'unclaim' : 'claim' ?>">
<button class="btn btn-xs btn-secondary" type="submit" style="align-self:center;white-space:nowrap;" title="<?= $claimed !== '' ? 'Übernahme freigeben (nur durch die übernehmende Person)' : 'Ich kümmere mich um diese Teilaufgabe' ?>">
<?= $claimed !== '' ? 'freigeben' : 'übernehmen' ?>
</button>
</form>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<?php else: ?>
<form method="post" action="/antraege/<?= (int)$req['id'] ?>/done">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<input type="hidden" name="step_state_id" value="<?= (int)$s['id'] ?>">
<div class="form-group">
<label><?= $this->te('Notiz (optional)') ?></label>
<textarea class="form-control form-control-sm" name="note" rows="2"></textarea>
</div>
<button class="btn btn-success" type="submit"><i class="fas fa-check"></i> <?= $this->te('Als erledigt markieren') ?></button>
</form>
<?php endif; ?>
<?php else: ?>
<?php $noteReq = (int)($s['require_note'] ?? 0) === 1; ?>
<form method="post" action="/antraege/<?= (int)$req['id'] ?>/decide">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<input type="hidden" name="step_state_id" value="<?= (int)$s['id'] ?>">
<div class="form-group">
<label for="note_ "><?= $this->t('Notiz für Folgestationen') ?> <?= $noteReq ? '(bei Zustimmung erforderlich) <span class="text-danger">*</span>' : '(optional)' ?></label>
<textarea class="form-control form-control-sm" name="note" id="note_<?= (int)$s['id'] ?>" rows="2"></textarea>
</div>
<div class="form-group">
<label><?= $this->te('Begründung (bei Ablehnung erforderlich)') ?></label>
<textarea class="form-control form-control-sm" name="reason" rows="2"></textarea>
</div>
<div class="form-actions" style="display:flex;gap:.5rem;">
<button class="btn btn-success" type="submit" name="decision" value="approve"
<?php if ($noteReq): ?>onclick="var n=document.getElementById('note_<?= (int)$s['id'] ?>'); if(!n.value.trim()){alert('Für diese Station ist eine Notiz auch bei Zustimmung erforderlich.');n.focus();return false;}"<?php endif; ?>>
<i class="fas fa-check"></i> <?= $this->te('Genehmigen') ?></button>
<button class="btn btn-danger" type="submit" name="decision" value="reject"><i class="fas fa-times"></i> <?= $this->te('Ablehnen') ?></button>
</div>
</form>
<?php endif; ?>
<hr>
<form method="post" action="/antraege/<?= (int)$req['id'] ?>/question">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<div class="form-group">
<label><?= $this->te('Rückfrage an Antragsteller') ?></label>
<textarea class="form-control form-control-sm" name="text" rows="2" placeholder="<?= $this->te('Stellt den Antrag auf \'Rückfrage offen\'') ?>"></textarea>
</div>
<button class="btn btn-secondary btn-sm" type="submit"><i class="fas fa-comment"></i> <?= $this->te('Rückfrage senden') ?></button>
</form>
<?php if ($s['step_type'] !== 'task'): ?>
<hr>
<form method="post" action="/antraege/<?= (int)$req['id'] ?>/steps/<?= (int)$s['id'] ?>/forward" style="display:flex;gap:.5rem;align-items:flex-end;flex-wrap:wrap;">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<div class="form-group" style="margin:0;flex:1;min-width:200px;">
<label><?= $this->te('Nicht zuständig? An andere Person weiterleiten') ?></label>
<select class="form-control form-control-sm" name="to_user" required>
<option value=""><?= $this->te('– Person wählen –') ?></option>
<?php foreach (($forward_users ?? []) as $u): ?>
<?php if ((int)$u['id'] === ($current_user->id ?? 0)) continue; ?>
<option value="<?= (int)$u['id'] ?>"><?= $this->e($u['display_name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<input class="form-control form-control-sm" type="text" name="note" placeholder="<?= $this->te('Notiz (optional)') ?>" style="flex:1;min-width:160px;">
<button class="btn btn-secondary btn-sm" type="submit"><i class="fas fa-share"></i> <?= $this->te('Weiterleiten') ?></button>
</form>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
<?php if ($isRequester && $req['status'] === 'waiting_requester' && $openQuestion): ?>
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Rückfrage beantworten') ?></span></div>
<div class="detail-card-body">
<form method="post" action="/antraege/<?= (int)$req['id'] ?>/answer">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<div class="form-group">
<textarea class="form-control form-control-sm" name="text" rows="3" required></textarea>
</div>
<button class="btn btn-primary" type="submit"><i class="fas fa-reply"></i> <?= $this->te('Antwort senden') ?></button>
</form>
</div>
</div>
<?php endif; ?>
<?php if ($isRequester && in_array($req['status'], ['rejected', 'waiting_requester'], true)): ?>
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Korrigieren & erneut einreichen') ?></span></div>
<div class="detail-card-body">
<form method="post" action="/antraege/<?= (int)$req['id'] ?>/resubmit">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<?php foreach ($fields as $f): if ($f['field_type'] === 'file') continue; ?>
<div class="form-group">
<label><?= $this->e($f['field_label']) ?></label>
<?php if ($f['field_type'] === 'textarea'): ?>
<textarea class="form-control form-control-sm" name="<?= $this->e($f['field_key']) ?>" rows="2"><?= $this->e($f['field_value']) ?></textarea>
<?php else: ?>
<input class="form-control form-control-sm" type="text" name="<?= $this->e($f['field_key']) ?>" value="<?= $this->e($f['field_value']) ?>">
<?php endif; ?>
</div>
<?php endforeach; ?>
<button class="btn btn-primary" type="submit"><i class="fas fa-redo"></i> <?= $this->te('Erneut einreichen') ?></button>
</form>
</div>
</div>
<?php endif; ?>
<?php if (!empty($links)): ?>
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Verknüpfte Aufgaben') ?></span></div>
<div class="detail-card-body">
<ul style="margin:0;padding-left:1.1rem;">
<?php foreach ($links as $l): ?>
<li>
<?php if ($l['link_type'] === 'ticket'): ?>
<a class="table-link" href="/tickets/<?= (int)$l['object_id'] ?>"><?= $this->te('Ticket #{nummer}', ['nummer' => (int)$l['object_id']]) ?></a>
<?php else: ?>
<a class="table-link" href="/kanban"><?= $this->t('Kanban-Aufgabe #') ?><?= (int)$l['object_id'] ?></a>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
</div>
</div>
<?php endif; ?>
<?php if ($isRequester && in_array($req['status'], ['pending', 'waiting_requester', 'draft'], true)): ?>
<form method="post" action="/antraege/<?= (int)$req['id'] ?>/cancel" onsubmit="return confirm('Antrag wirklich zurückziehen?');">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<button class="btn btn-secondary btn-sm" type="submit"><i class="fas fa-ban"></i> <?= $this->te('Antrag zurückziehen') ?></button>
</form>
<?php endif; ?>
<?php if (($can_manage ?? false) && in_array($req['status'], ['approved','rejected','cancelled','expired'], true) && empty($req['anonymized_at'])): ?>
<form method="post" action="/antraege/<?= (int)$req['id'] ?>/anonymize" onsubmit="return confirm('Personenbezogene Daten dieses Antrags unwiderruflich anonymisieren?');" style="margin-top:.75rem;">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<button class="btn btn-sm btn-danger" type="submit"><i class="fas fa-user-slash"></i> <?= $this->te('Anonymisieren (DSGVO)') ?></button>
</form>
<?php endif; ?>
</div>
</div>