- Consolidate page controllers into unified PagesController - Remove deprecated V2 pages, layouts, and controllers (AuthPage, DashboardPage, V2Page) - Add Edge resource with migration and model (EdgeResModel) - Implement new main_layout.php for consistent page structure - Reorganize patient views into dedicated module with dialog form - Update routing configuration in Routes.php - Enhance AuthFilter for improved authentication handling - Clean up unused V2 assets (CSS, JS) and legacy images - Update README.md with latest project information This refactoring improves code organization, removes technical debt, and establishes a cleaner foundation for future development.
189 lines
7.1 KiB
PHP
189 lines
7.1 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="en" data-theme="business">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title><?= esc($pageTitle ?? 'CLQMS') ?> - CLQMS</title>
|
|
|
|
<!-- TailwindCSS + DaisyUI CDN -->
|
|
<link href="https://cdn.jsdelivr.net/npm/daisyui@5.0.0-beta.9/daisyui.css" rel="stylesheet" type="text/css" />
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
|
|
<!-- FontAwesome -->
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/js/all.min.js"></script>
|
|
|
|
<!-- Alpine.js -->
|
|
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
|
|
|
<style>
|
|
[x-cloak] { display: none !important; }
|
|
|
|
/* Custom scrollbar for dark theme */
|
|
::-webkit-scrollbar { width: 8px; height: 8px; }
|
|
::-webkit-scrollbar-track { background: rgba(0,0,0,0.1); }
|
|
::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.2); border-radius: 4px; }
|
|
::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.3); }
|
|
|
|
/* Sidebar transition */
|
|
.sidebar-transition { transition: width 0.3s ease, transform 0.3s ease; }
|
|
</style>
|
|
</head>
|
|
<body class="min-h-screen flex bg-base-200" x-data="layout()">
|
|
|
|
<!-- Sidebar -->
|
|
<aside
|
|
class="sidebar-transition fixed lg:relative z-40 h-screen bg-base-300 flex flex-col shadow-xl"
|
|
:class="sidebarOpen ? 'w-56' : 'w-0 lg:w-16'"
|
|
>
|
|
<!-- Sidebar Header -->
|
|
<div class="h-16 flex items-center justify-between px-4 border-b border-base-content/10" x-show="sidebarOpen" x-cloak>
|
|
<span class="text-xl font-bold text-primary">CLQMS</span>
|
|
</div>
|
|
|
|
<!-- Navigation -->
|
|
<nav class="flex-1 py-4 overflow-y-auto" :class="sidebarOpen ? 'px-3' : 'px-1'">
|
|
<ul class="menu space-y-1">
|
|
<!-- Dashboard -->
|
|
<li>
|
|
<a href="<?= base_url('/') ?>"
|
|
class="flex items-center gap-3 rounded-lg"
|
|
:class="'<?= $activePage ?? '' ?>' === 'dashboard' ? 'bg-primary text-primary-content' : 'hover:bg-base-content/10'">
|
|
<i class="fa-solid fa-th-large w-5 text-center"></i>
|
|
<span x-show="sidebarOpen" x-cloak>Dashboard</span>
|
|
</a>
|
|
</li>
|
|
|
|
<!-- Patients -->
|
|
<li>
|
|
<a href="<?= base_url('/patients') ?>"
|
|
class="flex items-center gap-3 rounded-lg"
|
|
:class="'<?= $activePage ?? '' ?>' === 'patients' ? 'bg-primary text-primary-content' : 'hover:bg-base-content/10'">
|
|
<i class="fa-solid fa-users w-5 text-center"></i>
|
|
<span x-show="sidebarOpen" x-cloak>Patients</span>
|
|
</a>
|
|
</li>
|
|
|
|
<!-- Lab Requests -->
|
|
<li>
|
|
<a href="<?= base_url('/requests') ?>"
|
|
class="flex items-center gap-3 rounded-lg"
|
|
:class="'<?= $activePage ?? '' ?>' === 'requests' ? 'bg-primary text-primary-content' : 'hover:bg-base-content/10'">
|
|
<i class="fa-solid fa-flask w-5 text-center"></i>
|
|
<span x-show="sidebarOpen" x-cloak>Lab Requests</span>
|
|
</a>
|
|
</li>
|
|
|
|
<!-- Settings -->
|
|
<li>
|
|
<a href="<?= base_url('/settings') ?>"
|
|
class="flex items-center gap-3 rounded-lg"
|
|
:class="'<?= $activePage ?? '' ?>' === 'settings' ? 'bg-primary text-primary-content' : 'hover:bg-base-content/10'">
|
|
<i class="fa-solid fa-cog w-5 text-center"></i>
|
|
<span x-show="sidebarOpen" x-cloak>Settings</span>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
</aside>
|
|
|
|
<!-- Overlay for mobile -->
|
|
<div
|
|
x-show="sidebarOpen"
|
|
@click="sidebarOpen = false"
|
|
class="fixed inset-0 bg-black/50 z-30 lg:hidden"
|
|
x-cloak
|
|
></div>
|
|
|
|
<!-- Main Content Wrapper -->
|
|
<div class="flex-1 flex flex-col min-h-screen">
|
|
|
|
<!-- Top Navbar -->
|
|
<nav class="h-16 bg-base-100 border-b border-base-content/10 flex items-center justify-between px-4 sticky top-0 z-20">
|
|
<!-- Left: Burger Menu -->
|
|
<div class="flex items-center gap-4">
|
|
<button @click="sidebarOpen = !sidebarOpen" class="btn btn-ghost btn-sm btn-square">
|
|
<i class="fa-solid fa-bars text-lg"></i>
|
|
</button>
|
|
<h1 class="text-lg font-semibold"><?= esc($pageTitle ?? 'Dashboard') ?></h1>
|
|
</div>
|
|
|
|
<!-- Right: Theme Toggle & User -->
|
|
<div class="flex items-center gap-2">
|
|
<!-- Theme Toggle -->
|
|
<label class="swap swap-rotate btn btn-ghost btn-sm btn-square">
|
|
<input type="checkbox" class="theme-controller" value="corporate" @change="toggleTheme($event)" :checked="lightMode" />
|
|
<i class="swap-off fa-solid fa-moon text-lg"></i>
|
|
<i class="swap-on fa-solid fa-sun text-lg"></i>
|
|
</label>
|
|
|
|
<!-- User Dropdown -->
|
|
<div class="dropdown dropdown-end">
|
|
<div tabindex="0" role="button" class="btn btn-ghost btn-circle avatar placeholder">
|
|
<div class="bg-primary text-primary-content rounded-full w-10">
|
|
<span class="text-sm">U</span>
|
|
</div>
|
|
</div>
|
|
<ul tabindex="0" class="dropdown-content menu bg-base-100 rounded-box z-50 w-52 p-2 shadow-lg border border-base-content/10">
|
|
<li><a href="#"><i class="fa-solid fa-user mr-2"></i> Profile</a></li>
|
|
<li><a href="#"><i class="fa-solid fa-cog mr-2"></i> Settings</a></li>
|
|
<li class="border-t border-base-content/10 mt-1 pt-1">
|
|
<a href="<?= base_url('/logout') ?>" class="text-error">
|
|
<i class="fa-solid fa-sign-out-alt mr-2"></i> Logout
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- Page Content -->
|
|
<main class="flex-1 p-4 lg:p-6 overflow-auto">
|
|
<?= $this->renderSection('content') ?>
|
|
</main>
|
|
|
|
<!-- Footer -->
|
|
<footer class="bg-base-100 border-t border-base-content/10 py-4 px-6">
|
|
<div class="flex flex-col sm:flex-row items-center justify-between gap-2 text-sm text-base-content/60">
|
|
<span>© 2025 5panda. All rights reserved.</span>
|
|
<span>CLQMS v1.0.0</span>
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
|
|
<!-- Global Scripts -->
|
|
<script>
|
|
window.BASEURL = "<?= base_url() ?>";
|
|
|
|
function layout() {
|
|
return {
|
|
sidebarOpen: window.innerWidth >= 1024,
|
|
lightMode: localStorage.getItem('theme') === 'corporate',
|
|
|
|
init() {
|
|
// Apply saved theme
|
|
const savedTheme = localStorage.getItem('theme') || 'business';
|
|
document.documentElement.setAttribute('data-theme', savedTheme);
|
|
this.lightMode = savedTheme === 'corporate';
|
|
|
|
// Handle resize
|
|
window.addEventListener('resize', () => {
|
|
if (window.innerWidth >= 1024) {
|
|
this.sidebarOpen = true;
|
|
}
|
|
});
|
|
},
|
|
|
|
toggleTheme(event) {
|
|
const theme = event.target.checked ? 'corporate' : 'business';
|
|
document.documentElement.setAttribute('data-theme', theme);
|
|
localStorage.setItem('theme', theme);
|
|
this.lightMode = event.target.checked;
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<?= $this->renderSection('script') ?>
|
|
</body>
|
|
</html>
|