87 lines
2.8 KiB
PHP
87 lines
2.8 KiB
PHP
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="en">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||
|
|
|
||
|
|
<!-- SEO Meta -->
|
||
|
|
<title><?= $title ?? 'CLQMS' ?> - Clinical Laboratory QMS</title>
|
||
|
|
<meta name="description" content="<?= $description ?? 'CLQMS - Modern Clinical Laboratory Quality Management System' ?>">
|
||
|
|
|
||
|
|
<!-- Favicon -->
|
||
|
|
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
||
|
|
|
||
|
|
<!-- Google Fonts - Inter -->
|
||
|
|
<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@400;500;600;700&display=swap" rel="stylesheet">
|
||
|
|
|
||
|
|
<!-- Lucide Icons -->
|
||
|
|
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
|
||
|
|
|
||
|
|
<!-- App Styles -->
|
||
|
|
<link rel="stylesheet" href="/assets/css/app.css">
|
||
|
|
|
||
|
|
<!-- Page-specific styles -->
|
||
|
|
<?= $this->renderSection('styles') ?>
|
||
|
|
</head>
|
||
|
|
<body class="bg-pattern" x-data>
|
||
|
|
|
||
|
|
<!-- Floating Decorative Shapes -->
|
||
|
|
<div class="floating-shapes">
|
||
|
|
<div class="shape shape-1"></div>
|
||
|
|
<div class="shape shape-2"></div>
|
||
|
|
<div class="shape shape-3"></div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Main Content -->
|
||
|
|
<?= $this->renderSection('content') ?>
|
||
|
|
|
||
|
|
<!-- Toast Notifications Container -->
|
||
|
|
<div
|
||
|
|
x-data
|
||
|
|
class="toast-container"
|
||
|
|
style="position: fixed; top: 1rem; right: 1rem; z-index: 9999; display: flex; flex-direction: column; gap: 0.5rem;"
|
||
|
|
>
|
||
|
|
<template x-for="toast in $store.toast.messages" :key="toast.id">
|
||
|
|
<div
|
||
|
|
x-show="true"
|
||
|
|
x-transition:enter="transition ease-out duration-300"
|
||
|
|
x-transition:enter-start="opacity-0 transform translate-x-8"
|
||
|
|
x-transition:enter-end="opacity-100 transform translate-x-0"
|
||
|
|
x-transition:leave="transition ease-in duration-200"
|
||
|
|
x-transition:leave-start="opacity-100"
|
||
|
|
x-transition:leave-end="opacity-0"
|
||
|
|
:class="{
|
||
|
|
'alert': true,
|
||
|
|
'alert-success': toast.type === 'success',
|
||
|
|
'alert-error': toast.type === 'error',
|
||
|
|
'alert-info': toast.type === 'info'
|
||
|
|
}"
|
||
|
|
style="min-width: 280px; cursor: pointer;"
|
||
|
|
@click="$store.toast.dismiss(toast.id)"
|
||
|
|
>
|
||
|
|
<span x-text="toast.message"></span>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Alpine.js 3.x -->
|
||
|
|
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||
|
|
|
||
|
|
<!-- App Scripts (loaded before Alpine) -->
|
||
|
|
<script src="/assets/js/app.js"></script>
|
||
|
|
|
||
|
|
<!-- Initialize Lucide Icons -->
|
||
|
|
<script>
|
||
|
|
document.addEventListener('DOMContentLoaded', () => {
|
||
|
|
lucide.createIcons();
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<!-- Page-specific scripts -->
|
||
|
|
<?= $this->renderSection('scripts') ?>
|
||
|
|
</body>
|
||
|
|
</html>
|