tinyqc/app/Views/layout/main_layout.php

243 lines
13 KiB
PHP
Raw Normal View History

<!DOCTYPE html>
<html lang="en" class="h-full bg-slate-50">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $page_title ?? 'QC Application' ?></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=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/toastify-js/src/toastify.min.css">
<script defer src="https://cdn.jsdelivr.net/npm/@alpinejs/collapse@3.x.x/dist/cdn.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/toastify-js"></script>
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'sans-serif'],
},
colors: {
primary: {
50: '#eef2ff',
100: '#e0e7ff',
200: '#c7d2fe',
300: '#a5b4fc',
400: '#818cf8',
500: '#6366f1',
600: '#4f46e5',
700: '#4338ca',
800: '#3730a3',
900: '#312e81',
950: '#1e1b4b',
},
surface: {
50: '#f8fafc',
100: '#f1f5f9',
200: '#e2e8f0',
300: '#cbd5e1',
400: '#94a3b8',
500: '#64748b',
600: '#475569',
700: '#334155',
800: '#1e293b',
900: '#0f172a',
950: '#020617',
}
},
boxShadow: {
'glass': '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(255, 255, 255, 0.5) inset',
'card': '0 0 0 1px rgba(226, 232, 240, 1), 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
}
}
}
};
const baseUrl = '<?= base_url() ?>';
window.BASEURL = '<?= base_url() ?>';
</script>
<style>
[x-cloak] {
display: none !important;
}
.glass-panel {
background-color: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
}
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: #94a3b8;
}
</style>
</head>
<body class="bg-gray-50 h-full overflow-hidden text-slate-800 antialiased">
<div x-cloak x-show="App.loading" x-transition.opacity
class="fixed inset-0 z-[100] flex items-center justify-center bg-white/80 backdrop-blur-sm">
<div class="bg-white shadow-xl rounded-2xl p-6 flex items-center space-x-4 border border-slate-100">
<div class="animate-spin h-6 w-6 border-[3px] border-primary-600 border-t-transparent rounded-full"></div>
<span class="text-slate-600 font-medium">Loading application...</span>
</div>
</div>
<div class="flex h-screen bg-slate-50">
<div id="sidebar-backdrop" x-show="App.sidebarOpen" @click="App.sidebarOpen = false" x-transition.opacity aria-hidden="true"
class="fixed inset-0 z-40 bg-slate-900/50 backdrop-blur-sm lg:hidden"></div>
<aside id="sidebar"
x-data="{
resultsOpen: <?= in_array($active_menu, ['entry', 'entry_daily']) ? 'true' : 'false' ?>,
masterOpen: <?= in_array($active_menu, ['test', 'control', 'dept']) ? 'true' : 'false' ?>
}"
:class="App.sidebarOpen ? 'translate-x-0' : '-translate-x-full'"
class="fixed inset-y-0 left-0 z-50 w-72 bg-white border-r border-slate-200 transition-transform duration-300 ease-in-out lg:static lg:translate-x-0 flex flex-col shadow-lg lg:shadow-none">
<div class="flex h-16 items-center px-6 border-b border-slate-100 bg-white/50">
<div class="flex items-center space-x-3">
<div class="h-8 w-8 rounded-lg bg-gradient-to-br from-primary-600 to-primary-700 flex items-center justify-center shadow-lg shadow-primary-500/30">
<i class="fa-solid fa-flask text-white text-sm"></i>
</div>
<div>
<h1 class="text-lg font-bold text-slate-800 tracking-tight">TinyQC</h1>
<p class="text-xs text-slate-500 font-medium tracking-wide">LABORATORY</p>
</div>
</div>
</div>
<nav class="flex-1 overflow-y-auto px-4 py-4 space-y-1">
<p class="px-2 text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2">Main Menu</p>
<?php $active_menu = $active_menu ?? ''; ?>
<?php $navClass = 'group flex items-center px-3 py-2 text-sm font-medium rounded-xl transition-all duration-200 w-full'; ?>
<?php $activeClass = 'bg-primary-50 text-primary-700 shadow-sm ring-1 ring-primary-100'; ?>
<?php $inactiveClass = 'text-slate-600 hover:bg-slate-50 hover:text-slate-900'; ?>
<?php $subActiveClass = 'text-primary-700 font-semibold bg-primary-50/50'; ?>
<?php $subInactiveClass = 'text-slate-500 hover:text-slate-800 hover:bg-slate-50'; ?>
<a href="<?= base_url('/') ?>"
class="<?= $navClass ?> <?= $active_menu == 'dashboard' ? $activeClass : $inactiveClass ?>">
<i class="fa-solid fa-house h-5 w-5 mr-3 flex items-center justify-center <?= $active_menu == 'dashboard' ? 'text-primary-600' : 'text-slate-400 group-hover:text-slate-600' ?> transition-colors"></i>
Dashboard
</a>
<!-- Results Dropdown -->
<div class="space-y-1">
<button @click="resultsOpen = !resultsOpen"
class="<?= $navClass ?> <?= in_array($active_menu, ['entry', 'entry_daily']) ? 'text-primary-700' : 'text-slate-600 hover:bg-slate-50' ?>">
<i class="fa-solid fa-square-poll-vertical h-5 w-5 mr-3 flex items-center justify-center <?= in_array($active_menu, ['entry', 'entry_daily']) ? 'text-primary-600' : 'text-slate-400' ?>"></i>
<span class="flex-1 text-left">Results</span>
<i class="fa-solid fa-chevron-right text-[10px] transition-transform duration-200" :class="resultsOpen ? 'rotate-90' : ''"></i>
</button>
<div x-show="resultsOpen" x-cloak x-collapse class="pl-11 space-y-1">
<a href="<?= base_url('/entry') ?>" class="block px-3 py-1.5 text-sm rounded-lg transition-colors <?= $active_menu == 'entry' ? $subActiveClass : $subInactiveClass ?>">
Monthly Entry
</a>
<a href="<?= base_url('/entry/daily') ?>" class="block px-3 py-1.5 text-sm rounded-lg transition-colors <?= $active_menu == 'entry_daily' ? $subActiveClass : $subInactiveClass ?>">
Daily Entry
</a>
</div>
</div>
<a href="<?= base_url('/report') ?>"
class="<?= $navClass ?> <?= $active_menu == 'report' ? $activeClass : $inactiveClass ?>">
<i class="fa-solid fa-chart-column h-5 w-5 mr-3 flex items-center justify-center <?= $active_menu == 'report' ? 'text-primary-600' : 'text-slate-400 group-hover:text-slate-600' ?> transition-colors"></i>
Reports
</a>
<p class="px-2 text-xs font-semibold text-slate-400 uppercase tracking-wider mt-6 mb-2">Settings</p>
<!-- Master Data Dropdown -->
<div class="space-y-1">
<button @click="masterOpen = !masterOpen"
class="<?= $navClass ?> <?= in_array($active_menu, ['test', 'control', 'dept']) ? 'text-primary-700' : 'text-slate-600 hover:bg-slate-50' ?>">
<i class="fa-solid fa-database h-5 w-5 mr-3 flex items-center justify-center <?= in_array($active_menu, ['test', 'control', 'dept']) ? 'text-primary-600' : 'text-slate-400' ?>"></i>
<span class="flex-1 text-left">Master Data</span>
<i class="fa-solid fa-chevron-right text-[10px] transition-transform duration-200" :class="masterOpen ? 'rotate-90' : ''"></i>
</button>
<div x-show="masterOpen" x-cloak x-collapse class="pl-11 space-y-1">
<a href="<?= base_url('/test') ?>" class="block px-3 py-1.5 text-sm rounded-lg transition-colors <?= $active_menu == 'test' ? $subActiveClass : $subInactiveClass ?>">
Test Definitions
</a>
<a href="<?= base_url('/control') ?>" class="block px-3 py-1.5 text-sm rounded-lg transition-colors <?= $active_menu == 'control' ? $subActiveClass : $subInactiveClass ?>">
Control Dictionary
</a>
<a href="<?= base_url('/dept') ?>" class="block px-3 py-1.5 text-sm rounded-lg transition-colors <?= $active_menu == 'dept' ? $subActiveClass : $subInactiveClass ?>">
Department Dictionary
</a>
</div>
</div>
</nav>
<div class="px-6 py-4 border-t border-slate-100">
<div class="bg-gradient-to-br from-primary-800 to-indigo-900 rounded-xl p-4 text-white shadow-lg overflow-hidden relative">
<div class="absolute -right-4 -top-4 bg-white/10 w-24 h-24 rounded-full blur-xl"></div>
<h4 class="font-medium text-sm relative z-10">Need Help?</h4>
<p class="text-primary-200 text-xs mt-1 relative z-10">Check the documentation or contact support.</p>
</div>
</div>
</aside>
<div class="flex-1 flex flex-col overflow-hidden bg-slate-50/50">
<header class="bg-white/80 backdrop-blur-md sticky top-0 z-30 border-b border-slate-200/60 supports-backdrop-blur:bg-white/60">
<div class="flex items-center justify-between h-16 px-8">
<div class="flex items-center">
<button id="sidebar-toggle" @click="App.sidebarOpen = !App.sidebarOpen" class="lg:hidden p-2 -ml-2 text-slate-500 hover:text-slate-700 hover:bg-slate-100 rounded-lg">
<i class="fa-solid fa-bars h-6 w-6 flex items-center justify-center"></i>
</button>
<h2 class="ml-2 lg:ml-0 text-xl font-bold text-slate-800 tracking-tight"><?= $page_title ?? 'Dashboard' ?></h2>
</div>
<div class="flex items-center space-x-4">
<div class="hidden md:flex items-center px-3 py-1 bg-slate-100 rounded-full border border-slate-200">
<i class="fa-solid fa-calendar-days text-slate-400 mr-2 text-xs"></i>
<span class="text-sm font-medium text-slate-600"><?= date('F d, Y') ?></span>
</div>
<div class="h-8 w-8 rounded-full bg-primary-100 border border-primary-200 flex items-center justify-center text-primary-700 font-bold text-sm">AD</div>
</div>
</div>
</header>
<main class="flex-1 overflow-y-auto p-4 md:p-6">
<div class="w-full">
<?= $this->renderSection("content"); ?>
</div>
</main>
</div>
</div>
<script src="<?= base_url('js/app.js') ?>"></script>
<script src="<?= base_url('js/tables.js') ?>"></script>
<script src="<?= base_url('js/charts.js') ?>"></script>
<?= $this->renderSection("script"); ?>
</body>
</html>