mirror of
https://github.com/twinpath/app-beta.git
synced 2026-01-26 13:51:52 +07:00
first commit
This commit is contained in:
138
resources/views/layouts/app.blade.php
Normal file
138
resources/views/layouts/app.blade.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="h-full">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
|
||||
<title>{{ $title ?? 'Dashboard' }} | {{ config('app.name') }}</title>
|
||||
|
||||
<!-- Scripts -->
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||
|
||||
<!-- Alpine.js -->
|
||||
{{-- <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script> --}}
|
||||
|
||||
<!-- Theme Store -->
|
||||
<script>
|
||||
document.addEventListener('alpine:init', () => {
|
||||
Alpine.store('theme', {
|
||||
init() {
|
||||
const savedTheme = localStorage.getItem('theme');
|
||||
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' :
|
||||
'light';
|
||||
this.theme = savedTheme || systemTheme;
|
||||
this.updateTheme();
|
||||
},
|
||||
theme: 'light',
|
||||
toggle() {
|
||||
this.theme = this.theme === 'light' ? 'dark' : 'light';
|
||||
localStorage.setItem('theme', this.theme);
|
||||
this.updateTheme();
|
||||
},
|
||||
updateTheme() {
|
||||
const html = document.documentElement;
|
||||
const body = document.body;
|
||||
if (this.theme === 'dark') {
|
||||
html.classList.add('dark');
|
||||
body.classList.add('dark', 'bg-gray-900');
|
||||
} else {
|
||||
html.classList.remove('dark');
|
||||
body.classList.remove('dark', 'bg-gray-900');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Alpine.store('sidebar', {
|
||||
// Initialize based on screen size
|
||||
isExpanded: window.innerWidth >= 1280, // true for desktop, false for mobile
|
||||
isMobileOpen: false,
|
||||
isHovered: false,
|
||||
|
||||
toggleExpanded() {
|
||||
this.isExpanded = !this.isExpanded;
|
||||
// When toggling desktop sidebar, ensure mobile menu is closed
|
||||
this.isMobileOpen = false;
|
||||
},
|
||||
|
||||
toggleMobileOpen() {
|
||||
this.isMobileOpen = !this.isMobileOpen;
|
||||
// Don't modify isExpanded when toggling mobile menu
|
||||
},
|
||||
|
||||
setMobileOpen(val) {
|
||||
this.isMobileOpen = val;
|
||||
},
|
||||
|
||||
setHovered(val) {
|
||||
// Only allow hover effects on desktop when sidebar is collapsed
|
||||
if (window.innerWidth >= 1280 && !this.isExpanded) {
|
||||
this.isHovered = val;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Apply dark mode immediately to prevent flash -->
|
||||
<script>
|
||||
(function() {
|
||||
const savedTheme = localStorage.getItem('theme');
|
||||
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
const theme = savedTheme || systemTheme;
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.classList.add('dark');
|
||||
document.body.classList.add('dark', 'bg-gray-900');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
document.body.classList.remove('dark', 'bg-gray-900');
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body
|
||||
x-data="{ 'loaded': true}"
|
||||
x-init="$store.sidebar.isExpanded = window.innerWidth >= 1280;
|
||||
const checkMobile = () => {
|
||||
if (window.innerWidth < 1280) {
|
||||
$store.sidebar.setMobileOpen(false);
|
||||
$store.sidebar.isExpanded = false;
|
||||
} else {
|
||||
$store.sidebar.isMobileOpen = false;
|
||||
$store.sidebar.isExpanded = true;
|
||||
}
|
||||
};
|
||||
window.addEventListener('resize', checkMobile);">
|
||||
|
||||
{{-- preloader --}}
|
||||
<x-common.preloader/>
|
||||
{{-- preloader end --}}
|
||||
|
||||
<div class="min-h-screen xl:flex">
|
||||
@include('layouts.backdrop')
|
||||
@include('layouts.sidebar')
|
||||
|
||||
<div class="flex-1 transition-all duration-300 ease-in-out"
|
||||
:class="{
|
||||
'xl:ml-[290px]': $store.sidebar.isExpanded || $store.sidebar.isHovered,
|
||||
'xl:ml-[90px]': !$store.sidebar.isExpanded && !$store.sidebar.isHovered,
|
||||
'ml-0': $store.sidebar.isMobileOpen
|
||||
}">
|
||||
<!-- app header start -->
|
||||
@include('layouts.app-header')
|
||||
<!-- app header end -->
|
||||
<div class="p-4 mx-auto max-w-(--breakpoint-2xl) md:p-6">
|
||||
@yield('content')
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
@stack('scripts')
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user