updates for admin area
This commit is contained in:
@@ -21,3 +21,112 @@
|
||||
|
||||
.crud-heading-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}@media(max-width:640px){.crud-heading-actions{width:100%;align-items:stretch;flex-direction:column}}
|
||||
.legal-shell{max-width:850px}.legal-shell h1{font-size:clamp(38px,6vw,64px);margin:10px 0 8px}.legal-meta{color:var(--muted);font-size:12px;margin-bottom:30px}.legal-copy{color:#cbd5e1;font-size:17px;line-height:1.85;white-space:normal}
|
||||
|
||||
/* Admin appearance */
|
||||
.admin-body{
|
||||
--admin-surface:#fff;
|
||||
--admin-surface-2:#fafbfe;
|
||||
--admin-surface-3:#f0f3f8;
|
||||
--admin-input:#fff;
|
||||
--admin-input-border:#d5dce7;
|
||||
--admin-sidebar:#0b1020;
|
||||
--admin-sidebar-hover:#17203a;
|
||||
--admin-sidebar-line:#202a42;
|
||||
--admin-sidebar-text:#aab7ca;
|
||||
--admin-accent:#6d28d9;
|
||||
--admin-accent-soft:#ede9fe;
|
||||
--admin-accent-text:#6d28d9;
|
||||
--admin-success-bg:#dcfce7;
|
||||
--admin-success-text:#166534;
|
||||
--admin-success-line:#bbf7d0;
|
||||
--admin-danger-bg:#fff1f2;
|
||||
--admin-danger-text:#991b1b;
|
||||
--admin-danger-line:#fecaca;
|
||||
--admin-shadow:0 4px 18px rgba(31,45,75,.04);
|
||||
background:var(--admin-bg);
|
||||
color:var(--admin-ink);
|
||||
color-scheme:light;
|
||||
}
|
||||
html[data-admin-theme="dark"] .admin-body{
|
||||
--admin-bg:#0b1020;
|
||||
--admin-ink:#e8edf6;
|
||||
--admin-muted:#98a6ba;
|
||||
--admin-line:#263149;
|
||||
--admin-surface:#111827;
|
||||
--admin-surface-2:#151e2f;
|
||||
--admin-surface-3:#1b2639;
|
||||
--admin-input:#0f1726;
|
||||
--admin-input-border:#344159;
|
||||
--admin-sidebar:#070b15;
|
||||
--admin-sidebar-hover:#17213a;
|
||||
--admin-sidebar-line:#202b43;
|
||||
--admin-sidebar-text:#aebbd0;
|
||||
--admin-accent:#8b5cf6;
|
||||
--admin-accent-soft:#2b2145;
|
||||
--admin-accent-text:#c4b5fd;
|
||||
--admin-success-bg:#10291d;
|
||||
--admin-success-text:#86efac;
|
||||
--admin-success-line:#1f5138;
|
||||
--admin-danger-bg:#35151d;
|
||||
--admin-danger-text:#fda4af;
|
||||
--admin-danger-line:#642334;
|
||||
--admin-shadow:0 7px 24px rgba(0,0,0,.22);
|
||||
color-scheme:dark;
|
||||
}
|
||||
.admin-sidebar{background:var(--admin-sidebar)}
|
||||
.admin-nav a,.admin-sidebar-foot a,.admin-sidebar-foot button{color:var(--admin-sidebar-text)}
|
||||
.admin-nav a:hover,.admin-nav a.active,.admin-sidebar-foot a:hover,.admin-sidebar-foot button:hover{background:var(--admin-sidebar-hover)}
|
||||
.admin-sidebar-foot{border-color:var(--admin-sidebar-line)}
|
||||
.admin-topbar,.admin-stat,.admin-card{background:var(--admin-surface);box-shadow:var(--admin-shadow)}
|
||||
.admin-topbar{border-color:var(--admin-line)}
|
||||
.admin-card .responsive-table th,.admin-card .responsive-table td{border-color:var(--admin-line);color:var(--admin-ink)}
|
||||
.admin-card .responsive-table th{color:var(--admin-muted)}
|
||||
.toggle-button{background:var(--admin-surface-3);color:var(--admin-ink)}
|
||||
.toggle-button.on{background:var(--admin-success-bg);color:var(--admin-success-text)}
|
||||
.inline-controls select,.crud-search input,.crud-field input,.crud-field select,.crud-field textarea{background:var(--admin-input);border-color:var(--admin-input-border);color:var(--admin-ink)}
|
||||
.crud-field>span,.crud-check strong{color:var(--admin-ink)}
|
||||
.crud-check{background:var(--admin-surface-2);border-color:var(--admin-line)}
|
||||
.admin-flash{background:var(--admin-success-bg);color:var(--admin-success-text);border-color:var(--admin-success-line)}
|
||||
.admin-flash.error,.admin-error{background:var(--admin-danger-bg);color:var(--admin-danger-text);border-color:var(--admin-danger-line)}
|
||||
.danger-button{background:var(--admin-danger-bg);color:var(--admin-danger-text)}
|
||||
.role-badge,.feature-icon{background:var(--admin-accent-soft);color:var(--admin-accent-text)}
|
||||
.action-card:hover{border-color:var(--admin-accent)}
|
||||
.action-card>span{color:var(--admin-accent-text)}
|
||||
.admin-theme-switcher{display:inline-flex;align-items:center;padding:3px;border:1px solid var(--admin-line);border-radius:10px;background:var(--admin-surface-2)}
|
||||
.admin-theme-switcher button{display:grid;place-items:center;width:32px;height:32px;padding:0;border:0;border-radius:7px;background:transparent;color:var(--admin-muted);font:inherit;font-size:15px;cursor:pointer;transition:background .15s ease,color .15s ease,box-shadow .15s ease}
|
||||
.admin-theme-switcher button:hover{color:var(--admin-ink)}
|
||||
.admin-theme-switcher button.active{background:var(--admin-surface);color:var(--admin-accent-text);box-shadow:0 1px 4px rgba(0,0,0,.12)}
|
||||
.admin-topbar-actions{display:flex;align-items:center;gap:10px}
|
||||
html[data-admin-theme="dark"] .admin-button{background:#29354a;color:#f8fafc}
|
||||
html[data-admin-theme="dark"] .admin-button.primary{background:#7c3aed}
|
||||
html[data-admin-theme="dark"] .admin-stat small{color:#c4b5fd}
|
||||
html[data-admin-theme="dark"] .crud-field input:focus,html[data-admin-theme="dark"] .crud-field select:focus,html[data-admin-theme="dark"] .crud-field textarea:focus{border-color:#8b5cf6;box-shadow:0 0 0 3px rgba(139,92,246,.18)}
|
||||
html[data-admin-theme="dark"] input[type="date"],html[data-admin-theme="dark"] input[type="datetime-local"],html[data-admin-theme="dark"] input[type="time"]{color-scheme:dark}
|
||||
@media(max-width:640px){.admin-topbar-actions{margin-left:auto}.admin-theme-switcher button{width:29px;height:29px}.admin-topbar-actions .button{display:none}}
|
||||
|
||||
/* Keep admin appearance controls and Public Site action on one row. */
|
||||
.admin-topbar > .admin-topbar-actions{
|
||||
display:flex;
|
||||
flex-direction:row;
|
||||
flex-wrap:nowrap;
|
||||
align-items:center;
|
||||
justify-content:flex-end;
|
||||
gap:10px;
|
||||
min-width:max-content;
|
||||
margin-left:auto;
|
||||
}
|
||||
.admin-topbar-actions .admin-theme-switcher,
|
||||
.admin-topbar-actions .button{
|
||||
flex:0 0 auto;
|
||||
white-space:nowrap;
|
||||
}
|
||||
@media(max-width:640px){
|
||||
.admin-topbar{padding:0 12px;gap:8px}
|
||||
.admin-topbar > div:not(.admin-topbar-actions){min-width:0;overflow:hidden}
|
||||
.admin-topbar > div:not(.admin-topbar-actions) strong,
|
||||
.admin-topbar > div:not(.admin-topbar-actions) span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||||
.admin-topbar > .admin-topbar-actions{display:flex;gap:6px;margin-left:auto}
|
||||
.admin-theme-switcher{padding:2px}
|
||||
.admin-theme-switcher button{width:28px;height:28px}
|
||||
.admin-topbar-actions .button{display:inline-flex;min-height:32px;padding:0 10px;font-size:11px}
|
||||
}
|
||||
|
||||
@@ -28,3 +28,29 @@ const setAdminMenu = (open) => {
|
||||
document.querySelector('[data-admin-open]')?.addEventListener('click', () => setAdminMenu(true));
|
||||
document.querySelector('[data-admin-close]')?.addEventListener('click', () => setAdminMenu(false));
|
||||
adminOverlay?.addEventListener('click', () => setAdminMenu(false));
|
||||
|
||||
|
||||
const adminThemeButtons = document.querySelectorAll('[data-admin-theme]');
|
||||
const adminThemeMedia = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
|
||||
const applyAdminTheme = (preference, persist = true) => {
|
||||
if (!['light', 'dark', 'system'].includes(preference)) preference = 'system';
|
||||
const resolved = preference === 'system' ? (adminThemeMedia.matches ? 'dark' : 'light') : preference;
|
||||
document.documentElement.dataset.adminTheme = resolved;
|
||||
document.documentElement.dataset.adminThemePreference = preference;
|
||||
if (persist) localStorage.setItem('beatbook-admin-theme', preference);
|
||||
|
||||
adminThemeButtons.forEach((button) => {
|
||||
const active = button.dataset.adminTheme === preference;
|
||||
button.classList.toggle('active', active);
|
||||
button.setAttribute('aria-pressed', String(active));
|
||||
});
|
||||
};
|
||||
|
||||
if (adminThemeButtons.length) {
|
||||
applyAdminTheme(localStorage.getItem('beatbook-admin-theme') || 'system', false);
|
||||
adminThemeButtons.forEach((button) => button.addEventListener('click', () => applyAdminTheme(button.dataset.adminTheme)));
|
||||
adminThemeMedia.addEventListener?.('change', () => {
|
||||
if ((localStorage.getItem('beatbook-admin-theme') || 'system') === 'system') applyAdminTheme('system', false);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5,6 +5,14 @@
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
<title>@yield('title', 'Administration') — BeatBook</title>
|
||||
<script>
|
||||
(() => {
|
||||
const saved = localStorage.getItem('beatbook-admin-theme') || 'system';
|
||||
const dark = saved === 'dark' || (saved === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);
|
||||
document.documentElement.dataset.adminTheme = dark ? 'dark' : 'light';
|
||||
document.documentElement.dataset.adminThemePreference = saved;
|
||||
})();
|
||||
</script>
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||
</head>
|
||||
<body class="admin-body">
|
||||
@@ -37,7 +45,14 @@
|
||||
<header class="admin-topbar">
|
||||
<button class="icon-button admin-menu" type="button" data-admin-open aria-label="Open menu">☰</button>
|
||||
<div><strong>@yield('page-title', 'Administration')</strong><span>{{ auth()->user()->name }}</span></div>
|
||||
<a class="button small" href="{{ route('home') }}">Public site</a>
|
||||
<div class="admin-topbar-actions">
|
||||
<div class="admin-theme-switcher" role="group" aria-label="Appearance">
|
||||
<button type="button" data-admin-theme="light" title="Light mode" aria-label="Use light mode">☀</button>
|
||||
<button type="button" data-admin-theme="system" title="System appearance" aria-label="Use system appearance">◐</button>
|
||||
<button type="button" data-admin-theme="dark" title="Dark mode" aria-label="Use dark mode">☾</button>
|
||||
</div>
|
||||
<a class="button small" href="{{ route('home') }}">Public site</a>
|
||||
</div>
|
||||
</header>
|
||||
@if(session('success'))<div class="admin-flash">{{ session('success') }}</div>@endif
|
||||
@if(session('error'))<div class="admin-flash error">{{ session('error') }}</div>@endif
|
||||
|
||||
Reference in New Issue
Block a user