structure updates
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
@import 'tailwindcss';
|
||||||
|
@import '@fortawesome/fontawesome-free/css/all.min.css';
|
||||||
|
@import '../../../../../vendor/livewire/flux/dist/flux.css';
|
||||||
|
@import './helpdesk.css';
|
||||||
|
|
||||||
|
@source '../../views/**/*.blade.php';
|
||||||
|
@source '../../../../../Modules/**/*.php';
|
||||||
|
@source '../../../../../Modules/*/Resources/views/**/*.blade.php';
|
||||||
|
@source '../../../../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php';
|
||||||
|
@source '../../../../../vendor/livewire/flux/stubs/**/*.blade.php';
|
||||||
|
@source '../../../../../vendor/livewire/flux-pro/stubs/**/*.blade.php';
|
||||||
|
|
||||||
|
@custom-variant dark (&:where(.dark, .dark *));
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif,
|
||||||
|
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||||
|
}
|
||||||
@@ -1547,3 +1547,42 @@ span.flatpickr-weekday {
|
|||||||
width: min(310px, calc(100vw - 20px));
|
width: min(310px, calc(100vw - 20px));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Dark authentication + account settings controls */
|
||||||
|
:is(.hd-auth-surface, .hd-account-settings) input:not([type="checkbox"]):not([type="radio"]):not([type="color"]):not([type="file"]),
|
||||||
|
:is(.hd-auth-surface, .hd-account-settings) textarea,
|
||||||
|
:is(.hd-auth-surface, .hd-account-settings) select,
|
||||||
|
:is(.hd-auth-surface, .hd-account-settings) [data-flux-input],
|
||||||
|
:is(.hd-auth-surface, .hd-account-settings) [data-flux-control],
|
||||||
|
:is(.hd-auth-surface, .hd-account-settings) [data-flux-field-control],
|
||||||
|
:is(.hd-auth-surface, .hd-account-settings) [data-flux-select] {
|
||||||
|
background: #252a31 !important;
|
||||||
|
border-color: #424a56 !important;
|
||||||
|
color: #f3f4f6 !important;
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255,255,255,.025) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.hd-auth-surface, .hd-account-settings) input::placeholder,
|
||||||
|
:is(.hd-auth-surface, .hd-account-settings) textarea::placeholder {
|
||||||
|
color: #8f96a3 !important;
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.hd-auth-surface, .hd-account-settings) input:not([type="checkbox"]):not([type="radio"]):focus,
|
||||||
|
:is(.hd-auth-surface, .hd-account-settings) textarea:focus,
|
||||||
|
:is(.hd-auth-surface, .hd-account-settings) select:focus {
|
||||||
|
border-color: #3b82f6 !important;
|
||||||
|
outline: none !important;
|
||||||
|
box-shadow: 0 0 0 3px rgba(59,130,246,.16) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hd-account-settings,
|
||||||
|
.hd-account-settings label {
|
||||||
|
color: #e5e7eb !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hd-account-settings [data-flux-subheading],
|
||||||
|
.hd-account-settings [data-flux-text] {
|
||||||
|
color: #9ca3af !important;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,158 @@
|
|||||||
@props(['title' => null])
|
@props([
|
||||||
|
'title' => null,
|
||||||
|
])
|
||||||
|
|
||||||
{{--
|
<!DOCTYPE html>
|
||||||
Helpdesk compatibility component.
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark">
|
||||||
|
<head>
|
||||||
|
@include('partials.head')
|
||||||
|
@if(!empty($title))
|
||||||
|
<title>{{ $title }} · {{ config('app.name', 'Laravel') }}</title>
|
||||||
|
@endif
|
||||||
|
</head>
|
||||||
|
<body class="hd-app-body">
|
||||||
|
@php
|
||||||
|
$user = auth()->user();
|
||||||
|
$isAdmin = $user !== null && (
|
||||||
|
(bool) ($user->helpdesk_admin ?? false)
|
||||||
|
|| (method_exists($user, 'isHelpdeskAdmin') && $user->isHelpdeskAdmin())
|
||||||
|
);
|
||||||
|
$roleLabel = $isAdmin ? 'Administrator' : ((method_exists($user, 'isHelpdeskAgent') && $user->isHelpdeskAgent()) || (bool) ($user->helpdesk_agent ?? false) ? 'Agent' : 'User');
|
||||||
|
@endphp
|
||||||
|
<div class="hd-app-shell" data-hd-shell>
|
||||||
|
<header class="hd-topbar">
|
||||||
|
<div class="hd-topbar-brand">
|
||||||
|
<button class="hd-icon-button hd-mobile-menu-button" type="button" data-hd-sidebar-toggle aria-label="Toggle navigation"><i class="fa-solid fa-bars"></i></button>
|
||||||
|
<a href="{{ route('dashboard') }}" wire:navigate class="hd-brand-name">{{ config('app.name', 'Laravel') }}</a>
|
||||||
|
</div>
|
||||||
|
<div class="hd-topbar-main">
|
||||||
|
@if(Route::has('helpdesk.tickets.index'))
|
||||||
|
<form method="GET" action="{{ route('helpdesk.tickets.index') }}" class="hd-top-search">
|
||||||
|
<i class="fa-solid fa-magnifying-glass"></i><input name="search" placeholder="Search tickets" aria-label="Search tickets">
|
||||||
|
</form>
|
||||||
|
@endif
|
||||||
|
<div class="hd-topbar-spacer"></div>
|
||||||
|
<details class="hd-account-menu">
|
||||||
|
<summary class="hd-account-button">
|
||||||
|
<span class="hd-user-avatar hd-user-avatar--gravatar">
|
||||||
|
<span class="hd-user-avatar-fallback">{{ $user->initials() }}</span>
|
||||||
|
<img
|
||||||
|
src="{{ $user->gravatarUrl(160) }}"
|
||||||
|
alt="{{ $user->name }}"
|
||||||
|
loading="lazy"
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
|
onerror="this.style.display='none'"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
|
||||||
Do not call <x-layouts.app> from here: when Laravel resolves this component path first,
|
<span class="hd-account-copy">
|
||||||
that creates an infinite component loop. Delegate directly to the central WMS layout instead.
|
<strong>{{ $user->name }}</strong>
|
||||||
--}}
|
<small>{{ $roleLabel }}</small>
|
||||||
@include('layouts.app.sidebar')
|
</span>
|
||||||
|
|
||||||
|
<i class="fa-solid fa-chevron-down hd-account-chevron"></i>
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
<div class="hd-account-dropdown" role="menu">
|
||||||
|
<div class="hd-account-dropdown-user">
|
||||||
|
<span class="hd-user-avatar hd-user-avatar--gravatar hd-user-avatar--large">
|
||||||
|
<span class="hd-user-avatar-fallback">{{ $user->initials() }}</span>
|
||||||
|
<img
|
||||||
|
src="{{ $user->gravatarUrl(160) }}"
|
||||||
|
alt="{{ $user->name }}"
|
||||||
|
loading="lazy"
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
|
onerror="this.style.display='none'"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="hd-account-dropdown-copy">
|
||||||
|
<strong>{{ $user->name }}</strong>
|
||||||
|
<span>{{ $user->email }}</span>
|
||||||
|
<small>{{ $roleLabel }}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hd-account-dropdown-divider"></div>
|
||||||
|
|
||||||
|
<nav class="hd-account-dropdown-nav" aria-label="Account">
|
||||||
|
@if(Route::has('profile.edit'))
|
||||||
|
<a href="{{ route('profile.edit') }}" wire:navigate role="menuitem">
|
||||||
|
<i class="fa-regular fa-user"></i>
|
||||||
|
<span>Profile</span>
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if(Route::has('helpdesk.settings'))
|
||||||
|
<a href="{{ route('helpdesk.settings') }}" wire:navigate role="menuitem">
|
||||||
|
<i class="fa-solid fa-gear"></i>
|
||||||
|
<span>Helpdesk Settings</span>
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if($isAdmin)
|
||||||
|
<a href="{{ url('/admin/users') }}" wire:navigate role="menuitem">
|
||||||
|
<i class="fa-solid fa-users"></i>
|
||||||
|
<span>User Management</span>
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="hd-account-dropdown-divider"></div>
|
||||||
|
|
||||||
|
<form method="POST" action="{{ route('logout') }}">
|
||||||
|
@csrf
|
||||||
|
<button class="hd-account-logout" type="submit" role="menuitem">
|
||||||
|
<i class="fa-solid fa-arrow-right-from-bracket"></i>
|
||||||
|
<span>Log out</span>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<aside class="hd-shell-sidebar" data-hd-sidebar>
|
||||||
|
<nav class="hd-shell-nav" aria-label="Primary navigation">
|
||||||
|
<div class="hd-nav-section">
|
||||||
|
<div class="hd-nav-heading">Platform</div>
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="hd-nav-link {{ request()->routeIs('dashboard') ? 'is-active' : '' }}"
|
||||||
|
href="{{ route('dashboard') }}"
|
||||||
|
wire:navigate
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-house"></i>
|
||||||
|
<span>Dashboard</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hd-nav-section"><div class="hd-nav-heading">Helpdesk</div>
|
||||||
|
@if(Route::has('helpdesk.tickets.index'))<a class="hd-nav-link {{ request()->routeIs('helpdesk.tickets.*') ? 'is-active' : '' }}" href="{{ route('helpdesk.tickets.index') }}" wire:navigate><i class="fa-solid fa-ticket"></i><span>Tickets</span></a>@endif
|
||||||
|
@if(Route::has('helpdesk.kanban'))<a class="hd-nav-link {{ request()->routeIs('helpdesk.kanban') ? 'is-active' : '' }}" href="{{ route('helpdesk.kanban') }}" wire:navigate><i class="fa-solid fa-table-columns"></i><span>Kanban</span></a>@endif
|
||||||
|
@if(Route::has('helpdesk.settings'))<a class="hd-nav-link {{ request()->routeIs('helpdesk.settings*') ? 'is-active' : '' }}" href="{{ route('helpdesk.settings') }}" wire:navigate><i class="fa-solid fa-gear"></i><span>Settings</span></a>@endif
|
||||||
|
</div>
|
||||||
|
@if(Route::has('documentation.index') || Route::has('documentation.documents.index'))
|
||||||
|
<div class="hd-nav-section"><div class="hd-nav-heading">Documentation</div>
|
||||||
|
<a class="hd-nav-link {{ request()->routeIs('documentation.documents.*') || request()->routeIs('documentation.index') ? 'is-active' : '' }}" href="{{ Route::has('documentation.documents.index') ? route('documentation.documents.index') : route('documentation.index') }}" wire:navigate><i class="fa-regular fa-file-lines"></i><span>Documents</span></a>
|
||||||
|
@if(Route::has('documentation.categories.index'))<a class="hd-nav-link {{ request()->routeIs('documentation.categories.*') ? 'is-active' : '' }}" href="{{ route('documentation.categories.index') }}" wire:navigate><i class="fa-regular fa-folder"></i><span>Categories</span></a>@endif
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@if($isAdmin && Route::has('user-management.index'))
|
||||||
|
<div class="hd-nav-section"><div class="hd-nav-heading">Users</div>
|
||||||
|
<a class="hd-nav-link {{ request()->routeIs('user-management.index') || request()->routeIs('user-management.create') || request()->routeIs('user-management.edit') ? 'is-active' : '' }}" href="{{ route('user-management.index') }}" wire:navigate><i class="fa-solid fa-users"></i><span>Users</span></a>
|
||||||
|
<a class="hd-nav-link {{ request()->routeIs('user-management.roles') ? 'is-active' : '' }}" href="{{ route('user-management.roles') }}" wire:navigate><i class="fa-solid fa-shield-halved"></i><span>Roles & Permissions</span></a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</nav>
|
||||||
|
<div class="hd-sidebar-resizer" data-hd-sidebar-resizer title="Drag to resize sidebar"><span></span></div>
|
||||||
|
</aside>
|
||||||
|
<button type="button" class="hd-sidebar-backdrop" data-hd-sidebar-toggle aria-label="Close navigation"></button>
|
||||||
|
|
||||||
|
<main class="hd-shell-main">{{ $slot }}</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@persist('toast')<flux:toast.group><flux:toast /></flux:toast.group>@endpersist
|
||||||
|
@fluxScripts
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|||||||
@@ -2,6 +2,157 @@
|
|||||||
'title' => null,
|
'title' => null,
|
||||||
])
|
])
|
||||||
|
|
||||||
<x-layouts::app :title="$title" {{ $attributes }}>
|
<!DOCTYPE html>
|
||||||
{{ $slot }}
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark">
|
||||||
</x-layouts::app>
|
<head>
|
||||||
|
@include('partials.head')
|
||||||
|
@if(!empty($title))
|
||||||
|
<title>{{ $title }} · {{ config('app.name', 'Laravel') }}</title>
|
||||||
|
@endif
|
||||||
|
</head>
|
||||||
|
<body class="hd-app-body">
|
||||||
|
@php
|
||||||
|
$user = auth()->user();
|
||||||
|
$isAdmin = $user !== null && (
|
||||||
|
(bool) ($user->helpdesk_admin ?? false)
|
||||||
|
|| (method_exists($user, 'isHelpdeskAdmin') && $user->isHelpdeskAdmin())
|
||||||
|
);
|
||||||
|
$roleLabel = $isAdmin ? 'Administrator' : ((method_exists($user, 'isHelpdeskAgent') && $user->isHelpdeskAgent()) || (bool) ($user->helpdesk_agent ?? false) ? 'Agent' : 'User');
|
||||||
|
@endphp
|
||||||
|
<div class="hd-app-shell" data-hd-shell>
|
||||||
|
<header class="hd-topbar">
|
||||||
|
<div class="hd-topbar-brand">
|
||||||
|
<button class="hd-icon-button hd-mobile-menu-button" type="button" data-hd-sidebar-toggle aria-label="Toggle navigation"><i class="fa-solid fa-bars"></i></button>
|
||||||
|
<a href="{{ route('dashboard') }}" wire:navigate class="hd-brand-name">{{ config('app.name', 'Laravel') }}</a>
|
||||||
|
</div>
|
||||||
|
<div class="hd-topbar-main">
|
||||||
|
@if(Route::has('helpdesk.tickets.index'))
|
||||||
|
<form method="GET" action="{{ route('helpdesk.tickets.index') }}" class="hd-top-search">
|
||||||
|
<i class="fa-solid fa-magnifying-glass"></i><input name="search" placeholder="Search tickets" aria-label="Search tickets">
|
||||||
|
</form>
|
||||||
|
@endif
|
||||||
|
<div class="hd-topbar-spacer"></div>
|
||||||
|
<details class="hd-account-menu">
|
||||||
|
<summary class="hd-account-button">
|
||||||
|
<span class="hd-user-avatar hd-user-avatar--gravatar">
|
||||||
|
<span class="hd-user-avatar-fallback">{{ $user->initials() }}</span>
|
||||||
|
<img
|
||||||
|
src="{{ $user->gravatarUrl(160) }}"
|
||||||
|
alt="{{ $user->name }}"
|
||||||
|
loading="lazy"
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
|
onerror="this.style.display='none'"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="hd-account-copy">
|
||||||
|
<strong>{{ $user->name }}</strong>
|
||||||
|
<small>{{ $roleLabel }}</small>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<i class="fa-solid fa-chevron-down hd-account-chevron"></i>
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
<div class="hd-account-dropdown" role="menu">
|
||||||
|
<div class="hd-account-dropdown-user">
|
||||||
|
<span class="hd-user-avatar hd-user-avatar--gravatar hd-user-avatar--large">
|
||||||
|
<span class="hd-user-avatar-fallback">{{ $user->initials() }}</span>
|
||||||
|
<img
|
||||||
|
src="{{ $user->gravatarUrl(160) }}"
|
||||||
|
alt="{{ $user->name }}"
|
||||||
|
loading="lazy"
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
|
onerror="this.style.display='none'"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="hd-account-dropdown-copy">
|
||||||
|
<strong>{{ $user->name }}</strong>
|
||||||
|
<span>{{ $user->email }}</span>
|
||||||
|
<small>{{ $roleLabel }}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hd-account-dropdown-divider"></div>
|
||||||
|
|
||||||
|
<nav class="hd-account-dropdown-nav" aria-label="Account">
|
||||||
|
@if(Route::has('profile.edit'))
|
||||||
|
<a href="{{ route('profile.edit') }}" wire:navigate role="menuitem">
|
||||||
|
<i class="fa-regular fa-user"></i>
|
||||||
|
<span>Profile</span>
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if(Route::has('helpdesk.settings'))
|
||||||
|
<a href="{{ route('helpdesk.settings') }}" wire:navigate role="menuitem">
|
||||||
|
<i class="fa-solid fa-gear"></i>
|
||||||
|
<span>Helpdesk Settings</span>
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if($isAdmin)
|
||||||
|
<a href="{{ url('/admin/users') }}" wire:navigate role="menuitem">
|
||||||
|
<i class="fa-solid fa-users"></i>
|
||||||
|
<span>User Management</span>
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="hd-account-dropdown-divider"></div>
|
||||||
|
|
||||||
|
<form method="POST" action="{{ route('logout') }}">
|
||||||
|
@csrf
|
||||||
|
<button class="hd-account-logout" type="submit" role="menuitem">
|
||||||
|
<i class="fa-solid fa-arrow-right-from-bracket"></i>
|
||||||
|
<span>Log out</span>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<aside class="hd-shell-sidebar" data-hd-sidebar>
|
||||||
|
<nav class="hd-shell-nav" aria-label="Primary navigation">
|
||||||
|
<div class="hd-nav-section">
|
||||||
|
<div class="hd-nav-heading">Platform</div>
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="hd-nav-link {{ request()->routeIs('dashboard') ? 'is-active' : '' }}"
|
||||||
|
href="{{ route('dashboard') }}"
|
||||||
|
wire:navigate
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-house"></i>
|
||||||
|
<span>Dashboard</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hd-nav-section"><div class="hd-nav-heading">Helpdesk</div>
|
||||||
|
@if(Route::has('helpdesk.tickets.index'))<a class="hd-nav-link {{ request()->routeIs('helpdesk.tickets.*') ? 'is-active' : '' }}" href="{{ route('helpdesk.tickets.index') }}" wire:navigate><i class="fa-solid fa-ticket"></i><span>Tickets</span></a>@endif
|
||||||
|
@if(Route::has('helpdesk.kanban'))<a class="hd-nav-link {{ request()->routeIs('helpdesk.kanban') ? 'is-active' : '' }}" href="{{ route('helpdesk.kanban') }}" wire:navigate><i class="fa-solid fa-table-columns"></i><span>Kanban</span></a>@endif
|
||||||
|
@if(Route::has('helpdesk.settings'))<a class="hd-nav-link {{ request()->routeIs('helpdesk.settings*') ? 'is-active' : '' }}" href="{{ route('helpdesk.settings') }}" wire:navigate><i class="fa-solid fa-gear"></i><span>Settings</span></a>@endif
|
||||||
|
</div>
|
||||||
|
@if(Route::has('documentation.index') || Route::has('documentation.documents.index'))
|
||||||
|
<div class="hd-nav-section"><div class="hd-nav-heading">Documentation</div>
|
||||||
|
<a class="hd-nav-link {{ request()->routeIs('documentation.documents.*') || request()->routeIs('documentation.index') ? 'is-active' : '' }}" href="{{ Route::has('documentation.documents.index') ? route('documentation.documents.index') : route('documentation.index') }}" wire:navigate><i class="fa-regular fa-file-lines"></i><span>Documents</span></a>
|
||||||
|
@if(Route::has('documentation.categories.index'))<a class="hd-nav-link {{ request()->routeIs('documentation.categories.*') ? 'is-active' : '' }}" href="{{ route('documentation.categories.index') }}" wire:navigate><i class="fa-regular fa-folder"></i><span>Categories</span></a>@endif
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@if($isAdmin && Route::has('user-management.index'))
|
||||||
|
<div class="hd-nav-section"><div class="hd-nav-heading">Users</div>
|
||||||
|
<a class="hd-nav-link {{ request()->routeIs('user-management.index') || request()->routeIs('user-management.create') || request()->routeIs('user-management.edit') ? 'is-active' : '' }}" href="{{ route('user-management.index') }}" wire:navigate><i class="fa-solid fa-users"></i><span>Users</span></a>
|
||||||
|
<a class="hd-nav-link {{ request()->routeIs('user-management.roles') ? 'is-active' : '' }}" href="{{ route('user-management.roles') }}" wire:navigate><i class="fa-solid fa-shield-halved"></i><span>Roles & Permissions</span></a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</nav>
|
||||||
|
<div class="hd-sidebar-resizer" data-hd-sidebar-resizer title="Drag to resize sidebar"><span></span></div>
|
||||||
|
</aside>
|
||||||
|
<button type="button" class="hd-sidebar-backdrop" data-hd-sidebar-toggle aria-label="Close navigation"></button>
|
||||||
|
|
||||||
|
<main class="hd-shell-main">{{ $slot }}</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@persist('toast')<flux:toast.group><flux:toast /></flux:toast.group>@endpersist
|
||||||
|
@fluxScripts
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|||||||
@@ -1,4 +1,158 @@
|
|||||||
@include('layouts.app.sidebar', [
|
@php
|
||||||
'slot' => $slot,
|
$title = $title ?? null;
|
||||||
'title' => $title ?? null,
|
@endphp
|
||||||
])
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark">
|
||||||
|
<head>
|
||||||
|
@include('partials.head')
|
||||||
|
@if(!empty($title))
|
||||||
|
<title>{{ $title }} · {{ config('app.name', 'Laravel') }}</title>
|
||||||
|
@endif
|
||||||
|
</head>
|
||||||
|
<body class="hd-app-body">
|
||||||
|
@php
|
||||||
|
$user = auth()->user();
|
||||||
|
$isAdmin = $user !== null && (
|
||||||
|
(bool) ($user->helpdesk_admin ?? false)
|
||||||
|
|| (method_exists($user, 'isHelpdeskAdmin') && $user->isHelpdeskAdmin())
|
||||||
|
);
|
||||||
|
$roleLabel = $isAdmin ? 'Administrator' : ((method_exists($user, 'isHelpdeskAgent') && $user->isHelpdeskAgent()) || (bool) ($user->helpdesk_agent ?? false) ? 'Agent' : 'User');
|
||||||
|
@endphp
|
||||||
|
<div class="hd-app-shell" data-hd-shell>
|
||||||
|
<header class="hd-topbar">
|
||||||
|
<div class="hd-topbar-brand">
|
||||||
|
<button class="hd-icon-button hd-mobile-menu-button" type="button" data-hd-sidebar-toggle aria-label="Toggle navigation"><i class="fa-solid fa-bars"></i></button>
|
||||||
|
<a href="{{ route('dashboard') }}" wire:navigate class="hd-brand-name">{{ config('app.name', 'Laravel') }}</a>
|
||||||
|
</div>
|
||||||
|
<div class="hd-topbar-main">
|
||||||
|
@if(Route::has('helpdesk.tickets.index'))
|
||||||
|
<form method="GET" action="{{ route('helpdesk.tickets.index') }}" class="hd-top-search">
|
||||||
|
<i class="fa-solid fa-magnifying-glass"></i><input name="search" placeholder="Search tickets" aria-label="Search tickets">
|
||||||
|
</form>
|
||||||
|
@endif
|
||||||
|
<div class="hd-topbar-spacer"></div>
|
||||||
|
<details class="hd-account-menu">
|
||||||
|
<summary class="hd-account-button">
|
||||||
|
<span class="hd-user-avatar hd-user-avatar--gravatar">
|
||||||
|
<span class="hd-user-avatar-fallback">{{ $user->initials() }}</span>
|
||||||
|
<img
|
||||||
|
src="{{ $user->gravatarUrl(160) }}"
|
||||||
|
alt="{{ $user->name }}"
|
||||||
|
loading="lazy"
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
|
onerror="this.style.display='none'"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="hd-account-copy">
|
||||||
|
<strong>{{ $user->name }}</strong>
|
||||||
|
<small>{{ $roleLabel }}</small>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<i class="fa-solid fa-chevron-down hd-account-chevron"></i>
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
<div class="hd-account-dropdown" role="menu">
|
||||||
|
<div class="hd-account-dropdown-user">
|
||||||
|
<span class="hd-user-avatar hd-user-avatar--gravatar hd-user-avatar--large">
|
||||||
|
<span class="hd-user-avatar-fallback">{{ $user->initials() }}</span>
|
||||||
|
<img
|
||||||
|
src="{{ $user->gravatarUrl(160) }}"
|
||||||
|
alt="{{ $user->name }}"
|
||||||
|
loading="lazy"
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
|
onerror="this.style.display='none'"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="hd-account-dropdown-copy">
|
||||||
|
<strong>{{ $user->name }}</strong>
|
||||||
|
<span>{{ $user->email }}</span>
|
||||||
|
<small>{{ $roleLabel }}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hd-account-dropdown-divider"></div>
|
||||||
|
|
||||||
|
<nav class="hd-account-dropdown-nav" aria-label="Account">
|
||||||
|
@if(Route::has('profile.edit'))
|
||||||
|
<a href="{{ route('profile.edit') }}" wire:navigate role="menuitem">
|
||||||
|
<i class="fa-regular fa-user"></i>
|
||||||
|
<span>Profile</span>
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if(Route::has('helpdesk.settings'))
|
||||||
|
<a href="{{ route('helpdesk.settings') }}" wire:navigate role="menuitem">
|
||||||
|
<i class="fa-solid fa-gear"></i>
|
||||||
|
<span>Helpdesk Settings</span>
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if($isAdmin)
|
||||||
|
<a href="{{ url('/admin/users') }}" wire:navigate role="menuitem">
|
||||||
|
<i class="fa-solid fa-users"></i>
|
||||||
|
<span>User Management</span>
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="hd-account-dropdown-divider"></div>
|
||||||
|
|
||||||
|
<form method="POST" action="{{ route('logout') }}">
|
||||||
|
@csrf
|
||||||
|
<button class="hd-account-logout" type="submit" role="menuitem">
|
||||||
|
<i class="fa-solid fa-arrow-right-from-bracket"></i>
|
||||||
|
<span>Log out</span>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<aside class="hd-shell-sidebar" data-hd-sidebar>
|
||||||
|
<nav class="hd-shell-nav" aria-label="Primary navigation">
|
||||||
|
<div class="hd-nav-section">
|
||||||
|
<div class="hd-nav-heading">Platform</div>
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="hd-nav-link {{ request()->routeIs('dashboard') ? 'is-active' : '' }}"
|
||||||
|
href="{{ route('dashboard') }}"
|
||||||
|
wire:navigate
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-house"></i>
|
||||||
|
<span>Dashboard</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hd-nav-section"><div class="hd-nav-heading">Helpdesk</div>
|
||||||
|
@if(Route::has('helpdesk.tickets.index'))<a class="hd-nav-link {{ request()->routeIs('helpdesk.tickets.*') ? 'is-active' : '' }}" href="{{ route('helpdesk.tickets.index') }}" wire:navigate><i class="fa-solid fa-ticket"></i><span>Tickets</span></a>@endif
|
||||||
|
@if(Route::has('helpdesk.kanban'))<a class="hd-nav-link {{ request()->routeIs('helpdesk.kanban') ? 'is-active' : '' }}" href="{{ route('helpdesk.kanban') }}" wire:navigate><i class="fa-solid fa-table-columns"></i><span>Kanban</span></a>@endif
|
||||||
|
@if(Route::has('helpdesk.settings'))<a class="hd-nav-link {{ request()->routeIs('helpdesk.settings*') ? 'is-active' : '' }}" href="{{ route('helpdesk.settings') }}" wire:navigate><i class="fa-solid fa-gear"></i><span>Settings</span></a>@endif
|
||||||
|
</div>
|
||||||
|
@if(Route::has('documentation.index') || Route::has('documentation.documents.index'))
|
||||||
|
<div class="hd-nav-section"><div class="hd-nav-heading">Documentation</div>
|
||||||
|
<a class="hd-nav-link {{ request()->routeIs('documentation.documents.*') || request()->routeIs('documentation.index') ? 'is-active' : '' }}" href="{{ Route::has('documentation.documents.index') ? route('documentation.documents.index') : route('documentation.index') }}" wire:navigate><i class="fa-regular fa-file-lines"></i><span>Documents</span></a>
|
||||||
|
@if(Route::has('documentation.categories.index'))<a class="hd-nav-link {{ request()->routeIs('documentation.categories.*') ? 'is-active' : '' }}" href="{{ route('documentation.categories.index') }}" wire:navigate><i class="fa-regular fa-folder"></i><span>Categories</span></a>@endif
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@if($isAdmin && Route::has('user-management.index'))
|
||||||
|
<div class="hd-nav-section"><div class="hd-nav-heading">Users</div>
|
||||||
|
<a class="hd-nav-link {{ request()->routeIs('user-management.index') || request()->routeIs('user-management.create') || request()->routeIs('user-management.edit') ? 'is-active' : '' }}" href="{{ route('user-management.index') }}" wire:navigate><i class="fa-solid fa-users"></i><span>Users</span></a>
|
||||||
|
<a class="hd-nav-link {{ request()->routeIs('user-management.roles') ? 'is-active' : '' }}" href="{{ route('user-management.roles') }}" wire:navigate><i class="fa-solid fa-shield-halved"></i><span>Roles & Permissions</span></a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</nav>
|
||||||
|
<div class="hd-sidebar-resizer" data-hd-sidebar-resizer title="Drag to resize sidebar"><span></span></div>
|
||||||
|
</aside>
|
||||||
|
<button type="button" class="hd-sidebar-backdrop" data-hd-sidebar-toggle aria-label="Close navigation"></button>
|
||||||
|
|
||||||
|
<main class="hd-shell-main">{{ $slot }}</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@persist('toast')<flux:toast.group><flux:toast /></flux:toast.group>@endpersist
|
||||||
|
@fluxScripts
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|||||||
@@ -4,8 +4,12 @@
|
|||||||
<link rel="icon" href="/favicon.ico" sizes="any"><link rel="icon" href="/favicon.svg" type="image/svg+xml"><link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
<link rel="icon" href="/favicon.ico" sizes="any"><link rel="icon" href="/favicon.svg" type="image/svg+xml"><link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
||||||
@fonts
|
@fonts
|
||||||
@php
|
@php
|
||||||
|
$backendCssEntry = is_file(resource_path('themes/backend/assets/css/app.css'))
|
||||||
|
? 'resources/themes/backend/assets/css/app.css'
|
||||||
|
: 'resources/themes/backend/assets/css/helpdesk.css';
|
||||||
|
|
||||||
$viteAssets = [
|
$viteAssets = [
|
||||||
'resources/themes/backend/assets/css/app.css',
|
$backendCssEntry,
|
||||||
'resources/themes/backend/assets/js/passkeys.js',
|
'resources/themes/backend/assets/js/passkeys.js',
|
||||||
'resources/themes/backend/assets/js/layout.js',
|
'resources/themes/backend/assets/js/layout.js',
|
||||||
];
|
];
|
||||||
|
|||||||
+7
-1
@@ -6,6 +6,12 @@ import { existsSync, readdirSync, statSync } from 'node:fs';
|
|||||||
import { join, relative } from 'node:path';
|
import { join, relative } from 'node:path';
|
||||||
|
|
||||||
const projectRoot = process.cwd();
|
const projectRoot = process.cwd();
|
||||||
|
|
||||||
|
const backendCssEntry = existsSync(
|
||||||
|
join(projectRoot, 'resources/themes/backend/assets/css/app.css')
|
||||||
|
)
|
||||||
|
? 'resources/themes/backend/assets/css/app.css'
|
||||||
|
: 'resources/themes/backend/assets/css/helpdesk.css';
|
||||||
function discoverModuleInputs() {
|
function discoverModuleInputs() {
|
||||||
const modulesPath = join(projectRoot, 'Modules');
|
const modulesPath = join(projectRoot, 'Modules');
|
||||||
if (!existsSync(modulesPath)) return [];
|
if (!existsSync(modulesPath)) return [];
|
||||||
@@ -25,7 +31,7 @@ export default defineConfig({
|
|||||||
plugins:[
|
plugins:[
|
||||||
laravel({
|
laravel({
|
||||||
input:[
|
input:[
|
||||||
'resources/themes/backend/assets/css/app.css',
|
backendCssEntry,
|
||||||
'resources/themes/backend/assets/js/passkeys.js',
|
'resources/themes/backend/assets/js/passkeys.js',
|
||||||
'resources/themes/backend/assets/js/layout.js',
|
'resources/themes/backend/assets/js/layout.js',
|
||||||
...moduleInputs,
|
...moduleInputs,
|
||||||
|
|||||||
Reference in New Issue
Block a user