Initial commit: OMSORG website + Mitarbeiter-App

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Felix Kemmler
2026-06-13 20:03:22 +02:00
co-authored by Claude Sonnet 4.6
commit 8beb0fcf52
103 changed files with 7384 additions and 0 deletions
+110
View File
@@ -0,0 +1,110 @@
<?php
function layout_start(string $title, string $current_page, string $extra_head = ''): void {
$name = current_name();
$admin = is_admin();
$user = current_user();
$nav = [
'dashboard' => ['href' => 'dashboard.php', 'icon' => '⊞', 'label' => 'Dashboard'],
'stundennachweis' => ['href' => 'stundennachweis.php', 'icon' => '🕐', 'label' => 'Stundennachweis'],
'urlaubsantrag' => ['href' => 'urlaubsantrag.php', 'icon' => '🌴', 'label' => 'Urlaubsantrag'],
'dienstplan' => ['href' => 'dienstplan.php', 'icon' => '📋', 'label' => 'Dienstplan'],
'downloads' => ['href' => 'downloads.php', 'icon' => '📥', 'label' => 'Downloads'],
'einsatzanweisung' => ['href' => 'einsatzanweisung.php', 'icon' => '📄', 'label' => 'Einsatzanweisung'],
'benefitsantrag' => ['href' => 'benefitsantrag.php', 'icon' => '🎁', 'label' => 'Benefitsantrag'],
'abwesenheitsantrag' => ['href' => 'abwesenheitsantrag.php', 'icon' => '📅', 'label' => 'Abwesenheitsantrag'],
'fortbildungsantrag' => ['href' => 'fortbildungsantrag.php', 'icon' => '🎓', 'label' => 'Fortbildungsantrag'],
'dokumentenarchiv' => ['href' => 'dokumentenarchiv.php', 'icon' => '🗂', 'label' => 'Dokumentenarchiv'],
'einsatzbewertung' => ['href' => 'einsatzbewertung.php', 'icon' => '⭐', 'label' => 'Einsatzbewertung'],
'werben' => ['href' => 'werben.php', 'icon' => '🤝', 'label' => 'Mitarbeiter werben'],
'settings' => ['href' => 'settings.php', 'icon' => '⚙', 'label' => 'Einstellungen'],
];
if ($admin) {
$nav['admin'] = ['href' => 'admin.php', 'icon' => '🛡', 'label' => 'Verwaltung'];
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title><?= e($title) ?></title>
<link rel="stylesheet" href="../app.css">
<link rel="manifest" href="../manifest.webmanifest">
<meta name="theme-color" content="#1a3a5c">
<meta name="csrf-token" content="<?= csrf_token() ?>">
<?= $extra_head ?>
</head>
<body>
<div class="dashboard-layout">
<aside class="sidebar glass">
<div class="sidebar-brand">
<img src="../assets/omsorg-wordmark-new.png" alt="OMSORG">
<span class="sidebar-app-name">Mitarbeiter-App</span>
<button class="nav-toggle" type="button" aria-label="Menü öffnen" aria-expanded="false">☰</button>
</div>
<div class="sidebar-user">
<div class="sidebar-avatar">
<?php if (!empty($user['avatar'])): ?>
<img src="../assets/avatars/<?= e($user['avatar']) ?>" alt="<?= e($name) ?>">
<?php else: ?>
<?= e(mb_substr($name, 0, 1)) ?>
<?php endif; ?>
</div>
<div>
<b><?= e($name) ?></b>
<small><?= $admin ? 'Admin' : 'Mitarbeiter' ?></small>
</div>
</div>
<nav class="sidebar-nav">
<p class="sidebar-nav-label">Navigation</p>
<?php foreach ($nav as $key => $item): ?>
<a href="<?= e($item['href']) ?>"<?= $current_page === $key ? ' class="active"' : '' ?>>
<span class="nav-icon"><?= $item['icon'] ?></span><span class="nav-label"> <?= e($item['label']) ?></span>
</a>
<?php endforeach; ?>
</nav>
<div class="sidebar-footer">
<a href="../actions/logout.php" class="sidebar-logout">Abmelden</a>
</div>
</aside>
<div class="nav-backdrop" onclick="closeNav()"></div>
<main class="main-content">
<div class="main-inner">
<?php
}
function layout_end(): void {
?>
</div>
</main>
</div>
<script>
if ('serviceWorker' in navigator) navigator.serviceWorker.register('../service-worker.js');
function closeNav(){
document.body.classList.remove('nav-open');
const btn=document.querySelector('.nav-toggle');
if(btn){btn.textContent='☰';btn.setAttribute('aria-expanded','false');}
}
const navToggle=document.querySelector('.nav-toggle');
if(navToggle){
navToggle.addEventListener('click',function(){
const open=document.body.classList.toggle('nav-open');
this.textContent=open?'✕':'☰';
this.setAttribute('aria-expanded',open);
});
}
document.addEventListener('keydown',e=>{if(e.key==='Escape')closeNav();});
</script>
</body>
</html>
<?php
}