Files
omsorg/omsorgWeb/mitarbeiter-app-legacy/pages/urlaubsantrag.php
T
Felix KemmlerandClaude Sonnet 5 b6c1389c55 Reorganize into monorepo layout, move mitarbeiter-app to legacy reference
Consolidates the previously separate omsorgapp and omsorgCore repos
(each had their own nested .git with GitHub history) plus the old
root-level website/mitarbeiter-app into a single monorepo, matching
the structure already documented in the root CLAUDE.md. Also moves
the PHP employee app aside as omsorgWeb/mitarbeiter-app-legacy/ to
serve as a template for a ground-up rewrite.

Fixes .gitignore in the same pass: the config-secrets/uploads/data
patterns were unanchored (relative to repo root, not depth-agnostic),
so they silently stopped matching once the app moved under omsorgWeb/.
Patterns are now **/-prefixed and cover both mitarbeiter-app and
mitarbeiter-app-legacy, keeping DB/SMTP credentials and uploaded
employee documents out of version control.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-07 14:21:37 +02:00

148 lines
6.3 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__ . '/../lib/auth.php';
require_once __DIR__ . '/../lib/db.php';
require_once __DIR__ . '/../lib/layout.php';
require_login();
$user_id = current_user()['id'];
$stmt = db()->prepare('SELECT * FROM requests_urlaubsantrag WHERE user_id = ? ORDER BY created_at DESC');
$stmt->execute([$user_id]);
$requests = $stmt->fetchAll();
$status_labels = ['pending' => 'Ausstehend', 'accepted' => 'Akzeptiert', 'rejected' => 'Abgelehnt'];
layout_start('OMSORG Urlaubsantrag', 'urlaubsantrag');
?>
<style>
.modal-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.55);display:none;align-items:center;justify-content:center;z-index:1000}
.modal-box{background:var(--glass-bg,#1e2235);border:1px solid var(--border,rgba(255,255,255,.1));border-radius:14px;padding:28px 32px;max-width:480px;width:90%;position:relative}
.modal-box h3{margin:0 0 20px;font-family:'KindelSerif',Georgia,serif;font-size:1.3rem}
.modal-close{position:absolute;top:12px;right:16px;background:none;border:none;font-size:1.5rem;cursor:pointer;color:var(--muted,#888);line-height:1}
.modal-dl{display:grid;grid-template-columns:auto 1fr;gap:8px 16px;font-size:.95rem}
.modal-dl dt{color:var(--muted,#888);white-space:nowrap}
.modal-dl dd{margin:0;font-weight:500}
.btn-sm{display:inline-flex;align-items:center;gap:6px;padding:7px 13px;border-radius:9px;border:1px solid rgba(255,255,255,.2);background:rgba(255,255,255,.08);color:#fff;font-weight:600;font-size:.82rem;cursor:pointer;font:inherit;transition:background .15s}
.btn-sm:hover{background:rgba(255,255,255,.15)}
</style>
<h1 class="main-title">🌴 Urlaubsantrag</h1>
<p class="main-sub">Beantrage deinen Urlaub. Das Startdatum muss vor dem Enddatum liegen.</p>
<?php if (isset($_GET['success'])): ?>
<div class="success" style="margin-top:16px">Antrag erfolgreich eingereicht.</div>
<?php elseif (isset($_GET['error'])): ?>
<div class="error" style="margin-top:16px"><?= e(urldecode($_GET['error'])) ?></div>
<?php endif; ?>
<!-- Details-Modal -->
<div id="urlaub-modal" class="modal-backdrop" onclick="if(event.target===this)this.style.display='none'">
<div class="modal-box glass">
<button class="modal-close" onclick="document.getElementById('urlaub-modal').style.display='none'">&times;</button>
<h3>Antrag Details</h3>
<dl class="modal-dl">
<dt>Von</dt> <dd id="md-von"></dd>
<dt>Bis</dt> <dd id="md-bis"></dd>
<dt>Vertretung</dt><dd id="md-vertretung"></dd>
<dt>Nachricht</dt> <dd id="md-nachricht"></dd>
<dt>Eingereicht</dt><dd id="md-eingereicht"></dd>
<dt>Status</dt> <dd id="md-status"></dd>
<dt>Admin-Notiz</dt><dd id="md-note"></dd>
</dl>
</div>
</div>
<div class="page-split">
<div class="page-split-list">
<h2>Meine Anträge</h2>
<?php if (empty($requests)): ?>
<p style="color:var(--muted)">Noch keine Anträge gestellt.</p>
<?php else: ?>
<table class="requests-table">
<thead>
<tr>
<th>Von</th>
<th>Bis</th>
<th>Status</th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach ($requests as $r): ?>
<tr>
<td><?= e(date('d.m.Y', strtotime($r['von']))) ?></td>
<td><?= e(date('d.m.Y', strtotime($r['bis']))) ?></td>
<td><span class="badge badge-<?= e($r['status']) ?>"><?= e($status_labels[$r['status']] ?? $r['status']) ?></span></td>
<td>
<button class="btn-sm js-urlaub-details"
data-von="<?= e(date('d.m.Y', strtotime($r['von']))) ?>"
data-bis="<?= e(date('d.m.Y', strtotime($r['bis']))) ?>"
data-vertretung="<?= e($r['vertretung'] !== '' ? $r['vertretung'] : '') ?>"
data-nachricht="<?= e($r['nachricht'] !== '' ? $r['nachricht'] : '') ?>"
data-eingereicht="<?= e(date('d.m.Y', strtotime($r['created_at']))) ?>"
data-status-label="<?= e($status_labels[$r['status']] ?? $r['status']) ?>"
data-status-key="<?= e($r['status']) ?>"
data-note="<?= e($r['admin_note'] !== '' ? $r['admin_note'] : '') ?>"
>Details</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
<div class="page-split-form">
<div class="glass detail-card">
<h2>Neuer Urlaubsantrag</h2>
<form action="../actions/submit-urlaubsantrag.php" method="post" enctype="multipart/form-data">
<?= csrf_field() ?>
<label>
<span>Von <span style="color:#ff8080">*</span></span>
<input type="date" name="von" required>
</label>
<label>
<span>Bis <span style="color:#ff8080">*</span></span>
<input type="date" name="bis" required>
</label>
<label>
Vertretung
<input type="text" name="vertretung" placeholder="Name der Vertretung">
</label>
<label>
Nachricht
<textarea name="nachricht" rows="4" placeholder="Optionale Anmerkungen"></textarea>
</label>
<label>
Anhang
<input type="file" name="datei" accept=".pdf,.doc,.docx,.jpg,.jpeg,.png">
<span class="hint">PDF, Word, JPG, PNG &mdash; max. 12 MB (optional)</span>
</label>
<button type="submit" class="btn" style="margin-top:6px">Antrag einreichen</button>
</form>
</div>
</div>
</div>
<script>
document.addEventListener('click', function(e) {
var btn = e.target.closest('.js-urlaub-details');
if (!btn) return;
var d = btn.dataset;
document.getElementById('md-von').textContent = d.von;
document.getElementById('md-bis').textContent = d.bis;
document.getElementById('md-vertretung').textContent = d.vertretung;
document.getElementById('md-nachricht').textContent = d.nachricht;
document.getElementById('md-eingereicht').textContent = d.eingereicht;
document.getElementById('md-status').innerHTML =
'<span class="badge badge-' + d.statusKey + '">' + d.statusLabel + '</span>';
document.getElementById('md-note').textContent = d.note;
document.getElementById('urlaub-modal').style.display = 'flex';
});
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') document.getElementById('urlaub-modal').style.display = 'none';
});
</script>
<?php layout_end(); ?>