Phase 11: Receipt preview, print & PDF via dompdf. Phase 12: Accounting section with receipt list, filters, pagination, selectable checkboxes and XLSX export via PhpSpreadsheet. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
159 lines
8.3 KiB
PHP
159 lines
8.3 KiB
PHP
<!doctype html>
|
|
<html lang="pl">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title><?= $e($t('meta.title_pattern', ['title' => (string) ($title ?? $t('meta.default_panel_title'))])) ?></title>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="/assets/css/app.css?ver=<?= filemtime(dirname(__DIR__, 3) . '/public/assets/css/app.css') ?: 0 ?>">
|
|
<link rel="stylesheet" href="/assets/css/modules/jquery-alerts.css?ver=<?= filemtime(dirname(__DIR__, 3) . '/public/assets/css/modules/jquery-alerts.css') ?: 0 ?>">
|
|
</head>
|
|
<body>
|
|
<?php $currentMenu = (string) ($activeMenu ?? ''); ?>
|
|
<?php $currentSettings = (string) ($activeSettings ?? ''); ?>
|
|
<?php $currentOrders = (string) ($activeOrders ?? ''); ?>
|
|
<div class="app-shell" id="js-app-shell">
|
|
<aside class="sidebar" id="js-sidebar">
|
|
<div class="sidebar__brand">
|
|
<span class="sidebar__brand-text"><?= $e($t('brand.name_prefix')) ?><strong><?= $e($t('brand.name_suffix')) ?></strong></span>
|
|
<button class="sidebar__collapse-btn" id="js-sidebar-collapse" title="Zwiń menu" aria-label="Zwiń menu">
|
|
<svg class="sidebar__collapse-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M15 18l-6-6 6-6"/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
<nav class="sidebar__nav" aria-label="<?= $e($t('navigation.main_menu')) ?>">
|
|
<details class="sidebar__group<?= $currentMenu === 'orders' ? ' is-active' : '' ?>"<?= $currentMenu === 'orders' ? ' open' : '' ?>>
|
|
<summary class="sidebar__group-toggle">
|
|
<span class="sidebar__icon">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M9 5H7a2 2 0 00-2 2v13a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2"/>
|
|
<rect x="9" y="3" width="6" height="4" rx="1"/>
|
|
<path d="M9 12h6M9 16h4"/>
|
|
</svg>
|
|
</span>
|
|
<span class="sidebar__label"><?= $e($t('navigation.orders')) ?></span>
|
|
<svg class="sidebar__toggle-arrow" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M6 9l6 6 6-6"/>
|
|
</svg>
|
|
</summary>
|
|
<div class="sidebar__group-links">
|
|
<a class="sidebar__sublink<?= $currentMenu === 'orders' && $currentOrders === 'list' ? ' is-active' : '' ?>" href="/orders/list">
|
|
<?= $e($t('navigation.orders_list')) ?>
|
|
</a>
|
|
</div>
|
|
</details>
|
|
|
|
<a class="sidebar__link<?= ($currentMenu ?? '') === 'accounting' ? ' is-active' : '' ?>" href="/accounting">
|
|
<span class="sidebar__icon">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
|
|
<polyline points="14 2 14 8 20 8"/>
|
|
<line x1="16" y1="13" x2="8" y2="13"/>
|
|
<line x1="16" y1="17" x2="8" y2="17"/>
|
|
<polyline points="10 9 9 9 8 9"/>
|
|
</svg>
|
|
</span>
|
|
<span class="sidebar__label"><?= $e($t('navigation.accounting_section')) ?></span>
|
|
</a>
|
|
|
|
<details class="sidebar__group<?= $currentMenu === 'settings' ? ' is-active' : '' ?>"<?= $currentMenu === 'settings' ? ' open' : '' ?>>
|
|
<summary class="sidebar__group-toggle">
|
|
<span class="sidebar__icon">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
|
<circle cx="12" cy="12" r="3"/>
|
|
<path d="M12 2v2M12 20v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M2 12h2M20 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>
|
|
</svg>
|
|
</span>
|
|
<span class="sidebar__label"><?= $e($t('navigation.settings')) ?></span>
|
|
<svg class="sidebar__toggle-arrow" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M6 9l6 6 6-6"/>
|
|
</svg>
|
|
</summary>
|
|
<div class="sidebar__group-links">
|
|
<a class="sidebar__sublink<?= $currentMenu === 'settings' && $currentSettings === 'users' ? ' is-active' : '' ?>" href="/settings/users">
|
|
<?= $e($t('navigation.users')) ?>
|
|
</a>
|
|
<a class="sidebar__sublink<?= $currentMenu === 'settings' && $currentSettings === 'database' ? ' is-active' : '' ?>" href="/settings/database">
|
|
<?= $e($t('navigation.database')) ?>
|
|
</a>
|
|
<a class="sidebar__sublink<?= $currentMenu === 'settings' && $currentSettings === 'statuses' ? ' is-active' : '' ?>" href="/settings/statuses">
|
|
<?= $e($t('navigation.statuses')) ?>
|
|
</a>
|
|
<a class="sidebar__sublink<?= $currentMenu === 'settings' && $currentSettings === 'cron' ? ' is-active' : '' ?>" href="/settings/cron">
|
|
<?= $e($t('navigation.cron')) ?>
|
|
</a>
|
|
<a class="sidebar__sublink<?= $currentMenu === 'settings' && in_array($currentSettings, ['integrations', 'allegro', 'apaczka', 'inpost', 'shoppro'], true) ? ' is-active' : '' ?>" href="/settings/integrations">
|
|
<?= $e($t('navigation.integrations')) ?>
|
|
</a>
|
|
<a class="sidebar__sublink<?= $currentMenu === 'settings' && $currentSettings === 'company' ? ' is-active' : '' ?>" href="/settings/company">
|
|
<?= $e($t('navigation.company')) ?>
|
|
</a>
|
|
<a class="sidebar__sublink<?= $currentMenu === 'settings' && $currentSettings === 'accounting' ? ' is-active' : '' ?>" href="/settings/accounting">
|
|
<?= $e($t('navigation.accounting')) ?>
|
|
</a>
|
|
</div>
|
|
</details>
|
|
</nav>
|
|
</aside>
|
|
|
|
<div class="app-main">
|
|
<header class="topbar">
|
|
<div>
|
|
<strong><?= $e((string) (($user['name'] ?? '') !== '' ? $user['name'] : ($user['email'] ?? ''))) ?></strong>
|
|
</div>
|
|
<form action="/logout" method="post">
|
|
<input type="hidden" name="_token" value="<?= $e($csrfToken ?? '') ?>">
|
|
<button type="submit" class="btn btn--secondary"><?= $e($t('actions.logout')) ?></button>
|
|
</form>
|
|
</header>
|
|
|
|
<main class="container">
|
|
<?= $content ?>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
<script src="/assets/js/modules/jquery-alerts.js?ver=<?= filemtime(dirname(__DIR__, 3) . '/public/assets/js/modules/jquery-alerts.js') ?: 0 ?>"></script>
|
|
<script>
|
|
(function () {
|
|
var STORAGE_KEY = 'sidebarCollapsed';
|
|
var sidebar = document.getElementById('js-sidebar');
|
|
var collapseBtn = document.getElementById('js-sidebar-collapse');
|
|
if (!sidebar || !collapseBtn) return;
|
|
|
|
function setCollapsed(collapsed) {
|
|
sidebar.classList.toggle('is-collapsed', collapsed);
|
|
collapseBtn.setAttribute('title', collapsed ? 'Rozwiń menu' : 'Zwiń menu');
|
|
collapseBtn.setAttribute('aria-label', collapsed ? 'Rozwiń menu' : 'Zwiń menu');
|
|
if (collapsed) {
|
|
sidebar.querySelectorAll('details[open]').forEach(function (det) {
|
|
det.removeAttribute('open');
|
|
});
|
|
}
|
|
try { localStorage.setItem(STORAGE_KEY, collapsed ? '1' : '0'); } catch (e) {}
|
|
}
|
|
|
|
try {
|
|
if (localStorage.getItem(STORAGE_KEY) === '1') setCollapsed(true);
|
|
} catch (e) {}
|
|
|
|
collapseBtn.addEventListener('click', function () {
|
|
setCollapsed(!sidebar.classList.contains('is-collapsed'));
|
|
});
|
|
|
|
sidebar.querySelectorAll('details > summary').forEach(function (summary) {
|
|
summary.addEventListener('click', function (e) {
|
|
if (sidebar.classList.contains('is-collapsed')) {
|
|
e.preventDefault();
|
|
setCollapsed(false);
|
|
}
|
|
});
|
|
});
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|