Files
omsorg/mitarbeiter-app/pages/dashboard.php
T
2026-06-13 20:03:22 +02:00

190 lines
8.7 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();
$name = current_name();
$user_id = current_user()['id'];
$news_items = db()->query('SELECT * FROM news ORDER BY date DESC, id DESC')->fetchAll();
$grund_labels = [
'arztbesuch' => 'Arztbesuch',
'behoerdengang' => 'Behördengang',
'sonderurlaub' => 'Sonderurlaub',
'elternzeit_pflegezeit' => 'Elternzeit / Pflegezeit',
'sonstiges' => 'Sonstiges',
];
$benefit_labels = [
'massage' => 'Massage',
'fitnessstudio' => 'Fitnessstudio',
'tankgutschein' => 'Tankgutschein',
'fortbildung' => 'Fortbildung',
];
$rows = [];
$stmt = db()->prepare('SELECT id, status, created_at, von, bis, vertretung, nachricht FROM requests_urlaubsantrag WHERE user_id=? ORDER BY created_at DESC');
$stmt->execute([$user_id]);
foreach ($stmt->fetchAll() as $r) {
$rows[] = ['type' => 'urlaub', 'type_label' => 'Urlaubsantrag', 'icon' => '🌴'] + $r + ['detail' => $r['von'] . ' ' . $r['bis']];
}
$stmt = db()->prepare('SELECT id, status, created_at, von, bis, grund, vertretung, nachricht FROM requests_abwesenheitsantrag WHERE user_id=? ORDER BY created_at DESC');
$stmt->execute([$user_id]);
foreach ($stmt->fetchAll() as $r) {
$rows[] = ['type' => 'abwesenheit', 'type_label' => 'Abwesenheitsantrag', 'icon' => '📅'] + $r + ['detail' => ($grund_labels[$r['grund']] ?? $r['grund']) . ': ' . $r['von'] . ' ' . $r['bis']];
}
$stmt = db()->prepare('SELECT id, status, created_at, benefit, nachricht FROM requests_benefitsantrag WHERE user_id=? ORDER BY created_at DESC');
$stmt->execute([$user_id]);
foreach ($stmt->fetchAll() as $r) {
$rows[] = ['type' => 'benefits', 'type_label' => 'Benefitsantrag', 'icon' => '🎁'] + $r + ['detail' => $benefit_labels[$r['benefit']] ?? $r['benefit']];
}
$stmt = db()->prepare('SELECT id, status, created_at, name, email, qualifikation, nachricht FROM requests_werben WHERE user_id=? ORDER BY created_at DESC');
$stmt->execute([$user_id]);
foreach ($stmt->fetchAll() as $r) {
$rows[] = ['type' => 'werben', 'type_label' => 'Mitarbeiter werben', 'icon' => '🤝'] + $r + ['detail' => $r['name'] . ($r['qualifikation'] ? ' (' . $r['qualifikation'] . ')' : '')];
}
usort($rows, fn($a, $b) => strcmp($b['created_at'], $a['created_at']));
$pending_count = count(array_filter($rows, fn($r) => $r['status'] === 'pending'));
$status_map = ['pending' => 'Ausstehend', 'accepted' => 'Angenommen', 'rejected' => 'Abgelehnt'];
layout_start('OMSORG Felix Dashboard', 'dashboard');
?>
<h1 class="main-title">Willkommen, <span><?= e($name) ?></span>!</h1>
<p class="main-sub">Hier siehst du alle deine Anträge auf einen Blick.</p>
<?php if (!empty($news_items)): ?>
<div style="margin:28px 0 8px">
<h2 style="font-family:'KindelSerif',Georgia,serif;font-size:1.5rem;margin:0 0 14px">📢 News & Ankündigungen</h2>
<?php foreach ($news_items as $n): ?>
<div class="glass" style="padding:20px 24px;border-radius:18px;margin-bottom:12px">
<div style="color:var(--cyan2);font-size:.82rem;font-weight:900;margin-bottom:5px">
<?= e(date('d.m.Y', strtotime($n['date']))) ?>
</div>
<strong style="font-size:1.05rem;display:block;margin-bottom:6px"><?= e($n['title']) ?></strong>
<p style="margin:0;color:var(--muted);line-height:1.6;font-size:.95rem"><?= nl2br(e($n['text'])) ?></p>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if ($pending_count > 0): ?>
<p style="margin:18px 0 0;color:var(--muted)">
<?= $pending_count === 1 ? '1 Antrag ist noch' : $pending_count . ' Anträge sind noch' ?> <strong style="color:#ffe566">ausstehend</strong>.
</p>
<?php endif; ?>
<?php if (empty($rows)): ?>
<p style="margin-top:32px;color:var(--muted)">Du hast noch keine Anträge gestellt.</p>
<?php else: ?>
<div class="type-tabs" id="type-tabs">
<button class="type-tab active" data-type="all">Alle (<?= count($rows) ?>)</button>
<?php
$types = [];
foreach ($rows as $r) {
$types[$r['type']] = ['label' => $r['type_label'], 'icon' => $r['icon'], 'count' => ($types[$r['type']]['count'] ?? 0) + 1];
}
foreach ($types as $type => $info): ?>
<button class="type-tab" data-type="<?= e($type) ?>"><?= $info['icon'] ?> <?= e($info['label']) ?> (<?= $info['count'] ?>)</button>
<?php endforeach; ?>
</div>
<table class="requests-table" style="margin-top:16px">
<thead>
<tr>
<th>Art</th>
<th>Details</th>
<th>Eingereicht</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<?php foreach ($rows as $r): ?>
<tr data-type="<?= e($r['type']) ?>">
<td><?= $r['icon'] ?> <?= e($r['type_label']) ?></td>
<td style="color:var(--muted);font-size:.93rem"><?= e($r['detail']) ?></td>
<td style="color:var(--muted);font-size:.88rem;white-space:nowrap"><?= e(date('d.m.Y', strtotime($r['created_at']))) ?></td>
<td><span class="badge badge-<?= e($r['status']) ?>"><?= e($status_map[$r['status']] ?? $r['status']) ?></span></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<script>
document.getElementById('type-tabs').addEventListener('click', function(e) {
const btn = e.target.closest('.type-tab');
if (!btn) return;
this.querySelectorAll('.type-tab').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
const type = btn.dataset.type;
document.querySelectorAll('.requests-table tbody tr').forEach(row => {
row.style.display = (type === 'all' || row.dataset.type === type) ? '' : 'none';
});
});
</script>
<?php endif; ?>
<?php layout_end(); ?>
<div id="pwa-install-banner" style="display:none;position:fixed;bottom:0;left:0;right:0;background:#1a3a5c;color:#fff;padding:.85rem 1rem;z-index:8000;align-items:center;gap:.75rem;box-shadow:0 -2px 12px rgba(0,0,0,.25);">
<span style="flex:1;font-size:.95rem;">📲 <strong>OMSORG App</strong> zum Home-Bildschirm hinzufügen</span>
<button id="pwa-install-confirm" type="button" style="background:#fff;color:#1a3a5c;border:none;border-radius:8px;padding:.45rem 1rem;font-weight:700;cursor:pointer;white-space:nowrap;">Installieren</button>
<button id="pwa-install-dismiss" type="button" style="background:transparent;color:#fff;border:none;font-size:1.2rem;cursor:pointer;padding:0 .25rem;line-height:1;">✕</button>
</div>
<div id="pwa-install-modal" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.55);z-index:9000;align-items:flex-end;justify-content:center;padding:1rem;" role="dialog" aria-modal="true">
<div style="background:#fff;border-radius:16px;padding:1.5rem;width:100%;max-width:440px;color:#1a3a5c;">
<p style="margin:0 0 1.25rem;font-weight:700;font-size:1.1rem;text-align:center;">📲 App installieren</p>
<div style="background:#f0f4ff;border-radius:12px;padding:1rem 1.1rem;margin-bottom:.75rem;">
<p style="margin:0 0 .4rem;font-weight:700;font-size:.95rem;">🤖 Android (Chrome)</p>
<p style="margin:0;font-size:.9rem;line-height:1.6;color:#444;">Tippe oben rechts auf das <strong>Menü ⋮</strong> und dann auf<br><strong>„App installieren"</strong> oder <strong>„Zum Startbildschirm hinzufügen"</strong>.</p>
</div>
<div style="background:#f0f4ff;border-radius:12px;padding:1rem 1.1rem;margin-bottom:1.25rem;">
<p style="margin:0 0 .4rem;font-weight:700;font-size:.95rem;">🍎 iPhone / iPad (Safari)</p>
<p style="margin:0;font-size:.9rem;line-height:1.6;color:#444;">Tippe unten auf das <strong>Teilen-Symbol ⬆</strong> und dann auf<br><strong>„Zum Home-Bildschirm"</strong>.</p>
</div>
<button id="pwa-modal-close" style="display:block;width:100%;background:#1a3a5c;color:#fff;border:none;border-radius:8px;padding:.65rem;cursor:pointer;font-size:.95rem;font-weight:600;">Schließen</button>
</div>
</div>
<script>
(function(){
if(window.matchMedia('(display-mode: standalone)').matches)return;
if(document.cookie.split(';').some(c=>c.trim()==='pwa_dismissed=1'))return;
const banner=document.getElementById('pwa-install-banner');
const modal=document.getElementById('pwa-install-modal');
let deferred=null;
window.addEventListener('beforeinstallprompt',function(e){
e.preventDefault();
deferred=e;
});
banner.style.display='flex';
document.getElementById('pwa-install-confirm').addEventListener('click',function(){
if(deferred){
deferred.prompt();
banner.style.display='none';
} else {
banner.style.display='none';
modal.style.display='flex';
}
});
function dismiss(){
banner.style.display='none';
document.cookie='pwa_dismissed=1;path=/;max-age='+60*60*24*365;
}
document.getElementById('pwa-install-dismiss').addEventListener('click',dismiss);
document.getElementById('pwa-modal-close').addEventListener('click',function(){
modal.style.display='none';
dismiss();
});
})();
</script>