80 lines
3.3 KiB
PHP
80 lines
3.3 KiB
PHP
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title><?= \Steuerkram\View::h($pageTitle ?? 'Steuerkram') ?> – Steuerkram</title>
|
||
<link rel="stylesheet" href="/static/css/app.css?v=<?= defined('ASSET_VERSION') ? ASSET_VERSION : 'dev' ?>">
|
||
<style>:root { --color-nav-bg: <?= \Steuerkram\View::h(\Steuerkram\Config::get('sidebar_bg_color', '#1e293b')) ?>; }</style>
|
||
<link rel="icon" type="image/png" href="/static/favicon/favicon-96x96.png" sizes="96x96" />
|
||
<link rel="icon" type="image/svg+xml" href="/static/favicon/favicon.svg" />
|
||
<link rel="shortcut icon" href="/static/favicon/favicon.ico" />
|
||
<link rel="apple-touch-icon" sizes="180x180" href="/static/favicon/apple-touch-icon.png" />
|
||
<meta name="apple-mobile-web-app-title" content="Steuerkram" />
|
||
<link rel="manifest" href="/static/favicon/site.webmanifest" />
|
||
<meta name="csrf-token" content="<?= \Steuerkram\View::h(\Steuerkram\Auth::generateCsrfToken()) ?>">
|
||
</head>
|
||
<body>
|
||
<div class="app-layout">
|
||
|
||
<?php include __DIR__ . '/nav.php'; ?>
|
||
|
||
<div class="main-content">
|
||
<div class="topbar">
|
||
<div class="topbar-title">
|
||
<?= \Steuerkram\View::h($pageTitle ?? '') ?>
|
||
<?php if (!empty($version)): ?>
|
||
<span style="font-size:0.9rem;font-weight:normal;opacity:0.65;margin-left:.4rem"><?= \Steuerkram\View::h($version) ?></span>
|
||
<?php endif; ?>
|
||
</div>
|
||
<div style="display:flex;gap:.5rem;align-items:center;">
|
||
<?php if (!empty($topbarActions)) echo $topbarActions; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="page-body">
|
||
|
||
<?php if (!empty($flash)): ?>
|
||
<div class="flash-list">
|
||
<?php foreach ($flash as $f): ?>
|
||
<div class="flash flash-<?= \Steuerkram\View::h($f['type']) ?>">
|
||
<?= \Steuerkram\View::h($f['message']) ?>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?= $content ?? '' ?>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<script src="/static/js/app.js?v=<?= defined('ASSET_VERSION') ? ASSET_VERSION : 'dev' ?>"></script>
|
||
<script>
|
||
(function() {
|
||
var token = (document.querySelector('meta[name="csrf-token"]') || {}).content || '';
|
||
if (!token) return;
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
document.querySelectorAll('form').forEach(function(form) {
|
||
var m = (form.getAttribute('method') || '').toUpperCase();
|
||
if (m !== 'POST' && m !== 'PUT' && m !== 'DELETE') return;
|
||
if (!form.querySelector('[name="csrf_token"]')) {
|
||
var inp = document.createElement('input');
|
||
inp.type = 'hidden'; inp.name = 'csrf_token'; inp.value = token;
|
||
form.appendChild(inp);
|
||
}
|
||
});
|
||
});
|
||
var _fetch = window.fetch;
|
||
window.fetch = function(url, opts) {
|
||
opts = opts || {};
|
||
var method = (opts.method || 'GET').toUpperCase();
|
||
if (method !== 'GET' && method !== 'HEAD') {
|
||
opts.headers = Object.assign({'X-CSRF-Token': token}, opts.headers || {});
|
||
}
|
||
return _fetch(url, opts);
|
||
};
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|