dashboard and menu layouts
This commit is contained in:
@@ -4,6 +4,8 @@ namespace Modules\Administration\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Modules\Audit\Models\AuditLog;
|
||||
use Modules\Media\Models\Media;
|
||||
@@ -18,21 +20,63 @@ final class DashboardController extends Controller
|
||||
'roleCount' => Schema::hasTable('roles') ? Role::count() : 0,
|
||||
'mediaCount' => Schema::hasTable('media') ? Media::count() : 0,
|
||||
'auditCount' => Schema::hasTable('audit_logs') ? AuditLog::count() : 0,
|
||||
'recentAudit' => Schema::hasTable('audit_logs') ? AuditLog::query()->latest('created_at')->limit(8)->get() : collect(),
|
||||
'recentAudit' => $this->recentAudit(),
|
||||
'modules' => $this->modules(),
|
||||
]);
|
||||
}
|
||||
|
||||
private function modules(): array
|
||||
private function recentAudit(): LengthAwarePaginator
|
||||
{
|
||||
if (! Schema::hasTable('audit_logs')) {
|
||||
return new LengthAwarePaginator(
|
||||
items: [],
|
||||
total: 0,
|
||||
perPage: 8,
|
||||
currentPage: Paginator::resolveCurrentPage('audit_page'),
|
||||
options: [
|
||||
'path' => request()->url(),
|
||||
'pageName' => 'audit_page',
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return AuditLog::query()
|
||||
->latest('created_at')
|
||||
->paginate(8, ['*'], 'audit_page')
|
||||
->withQueryString();
|
||||
}
|
||||
|
||||
private function modules(): LengthAwarePaginator
|
||||
{
|
||||
$statuses = json_decode((string) file_get_contents(base_path('modules_statuses.json')), true) ?: [];
|
||||
$modules = [];
|
||||
|
||||
foreach (glob(base_path('Modules/*/module.json')) ?: [] as $manifest) {
|
||||
$data = json_decode((string) file_get_contents($manifest), true) ?: [];
|
||||
$name = $data['name'] ?? basename(dirname($manifest));
|
||||
$modules[] = ['name' => $name, 'version' => $data['version'] ?? '1.0.0', 'enabled' => (bool) ($statuses[$name] ?? false)];
|
||||
|
||||
$modules[] = [
|
||||
'name' => $name,
|
||||
'version' => $data['version'] ?? '1.0.0',
|
||||
'enabled' => (bool) ($statuses[$name] ?? false),
|
||||
];
|
||||
}
|
||||
usort($modules, fn ($a, $b) => strcasecmp($a['name'], $b['name']));
|
||||
return $modules;
|
||||
|
||||
usort($modules, fn (array $a, array $b): int => strcasecmp($a['name'], $b['name']));
|
||||
|
||||
$pageName = 'modules_page';
|
||||
$perPage = 8;
|
||||
$currentPage = Paginator::resolveCurrentPage($pageName);
|
||||
|
||||
return (new LengthAwarePaginator(
|
||||
items: array_slice($modules, ($currentPage - 1) * $perPage, $perPage),
|
||||
total: count($modules),
|
||||
perPage: $perPage,
|
||||
currentPage: $currentPage,
|
||||
options: [
|
||||
'path' => request()->url(),
|
||||
'pageName' => $pageName,
|
||||
],
|
||||
))->withQueryString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,60 +1,76 @@
|
||||
<x-layouts.app :title="__('Dashboard')">
|
||||
<div class="flex h-full w-full flex-1 flex-col gap-6 rounded-xl">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold text-zinc-950 dark:text-zinc-100">Dashboard</h1>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">Platform health and recent activity.</p>
|
||||
</div>
|
||||
<div class="relative flex h-full w-full flex-1 flex-col overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700">
|
||||
<x-stylist-theme-admin::placeholder-pattern class="pointer-events-none absolute inset-0 size-full stroke-gray-900/20 dark:stroke-neutral-100/20" />
|
||||
|
||||
<div class="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
|
||||
@foreach([
|
||||
['Users', $userCount, 'users'],
|
||||
['Roles', $roleCount, 'shield-check'],
|
||||
['Media', $mediaCount, 'photo'],
|
||||
['Audit events', $auditCount, 'clipboard-document-list'],
|
||||
] as [$label, $count, $icon])
|
||||
<div class="rounded-xl border border-zinc-200 bg-white p-5 shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<flux:icon :name="$icon" class="size-5 text-zinc-500" />
|
||||
<div class="mt-4 text-3xl font-semibold text-zinc-950 dark:text-zinc-100">{{ $count }}</div>
|
||||
<div class="text-sm text-zinc-500">{{ $label }}</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="relative z-10 flex h-full flex-1 flex-col gap-6 overflow-auto p-4 sm:p-6">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold text-zinc-950 dark:text-zinc-100">Dashboard</h1>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">Platform health and recent activity.</p>
|
||||
</div>
|
||||
|
||||
<div class="grid flex-1 gap-6 xl:grid-cols-2">
|
||||
<section class="overflow-hidden rounded-xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<div class="border-b border-zinc-200 px-5 py-4 font-semibold text-zinc-950 dark:border-zinc-700 dark:text-zinc-100">
|
||||
Modules
|
||||
</div>
|
||||
<div class="divide-y divide-zinc-200 dark:divide-zinc-800">
|
||||
@foreach($modules as $module)
|
||||
<div class="flex items-center justify-between px-5 py-3">
|
||||
<div>
|
||||
<div class="font-medium text-zinc-950 dark:text-zinc-100">{{ $module['name'] }}</div>
|
||||
<div class="text-xs text-zinc-500">v{{ $module['version'] }}</div>
|
||||
<div class="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
|
||||
@foreach([
|
||||
['Users', $userCount, 'users'],
|
||||
['Roles', $roleCount, 'shield-check'],
|
||||
['Media', $mediaCount, 'photo'],
|
||||
['Audit events', $auditCount, 'clipboard-document-list'],
|
||||
] as [$label, $count, $icon])
|
||||
<div class="rounded-xl border border-zinc-200/90 bg-white/90 p-5 shadow-sm backdrop-blur dark:border-zinc-700/90 dark:bg-zinc-900/90">
|
||||
<flux:icon :name="$icon" class="size-5 text-zinc-500" />
|
||||
<div class="mt-4 text-3xl font-semibold text-zinc-950 dark:text-zinc-100">{{ $count }}</div>
|
||||
<div class="text-sm text-zinc-500">{{ $label }}</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="grid flex-1 items-start gap-6 xl:grid-cols-2">
|
||||
<section class="overflow-hidden rounded-xl border border-zinc-200/90 bg-white/90 shadow-sm backdrop-blur dark:border-zinc-700/90 dark:bg-zinc-900/90">
|
||||
<div class="border-b border-zinc-200 px-5 py-4 font-semibold text-zinc-950 dark:border-zinc-700 dark:text-zinc-100">
|
||||
Modules
|
||||
</div>
|
||||
<div class="divide-y divide-zinc-200 dark:divide-zinc-800">
|
||||
@forelse($modules as $module)
|
||||
<div class="flex items-center justify-between px-5 py-3">
|
||||
<div>
|
||||
<div class="font-medium text-zinc-950 dark:text-zinc-100">{{ $module['name'] }}</div>
|
||||
<div class="text-xs text-zinc-500">v{{ $module['version'] }}</div>
|
||||
</div>
|
||||
<span class="rounded-full px-2.5 py-1 text-xs {{ $module['enabled'] ? 'bg-emerald-100 text-emerald-800 dark:bg-emerald-950 dark:text-emerald-200' : 'bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300' }}">
|
||||
{{ $module['enabled'] ? 'Enabled' : 'Disabled' }}
|
||||
</span>
|
||||
</div>
|
||||
<span class="rounded-full px-2.5 py-1 text-xs {{ $module['enabled'] ? 'bg-emerald-100 text-emerald-800 dark:bg-emerald-950 dark:text-emerald-200' : 'bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300' }}">
|
||||
{{ $module['enabled'] ? 'Enabled' : 'Disabled' }}
|
||||
</span>
|
||||
@empty
|
||||
<div class="px-5 py-8 text-center text-sm text-zinc-500">No modules found.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
@if($modules->hasPages())
|
||||
<div class="border-t border-zinc-200 px-5 py-4 dark:border-zinc-700">
|
||||
{{ $modules->onEachSide(1)->links() }}
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</section>
|
||||
@endif
|
||||
</section>
|
||||
|
||||
<section class="overflow-hidden rounded-xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<div class="border-b border-zinc-200 px-5 py-4 font-semibold text-zinc-950 dark:border-zinc-700 dark:text-zinc-100">
|
||||
Recent audit activity
|
||||
</div>
|
||||
<div class="divide-y divide-zinc-200 dark:divide-zinc-800">
|
||||
@forelse($recentAudit as $log)
|
||||
<div class="px-5 py-3">
|
||||
<div class="font-medium text-zinc-950 dark:text-zinc-100">{{ $log->event }}</div>
|
||||
<div class="text-xs text-zinc-500">{{ optional($log->created_at)->diffForHumans() }}</div>
|
||||
<section class="overflow-hidden rounded-xl border border-zinc-200/90 bg-white/90 shadow-sm backdrop-blur dark:border-zinc-700/90 dark:bg-zinc-900/90">
|
||||
<div class="border-b border-zinc-200 px-5 py-4 font-semibold text-zinc-950 dark:border-zinc-700 dark:text-zinc-100">
|
||||
Recent audit activity
|
||||
</div>
|
||||
<div class="divide-y divide-zinc-200 dark:divide-zinc-800">
|
||||
@forelse($recentAudit as $log)
|
||||
<div class="px-5 py-3">
|
||||
<div class="font-medium text-zinc-950 dark:text-zinc-100">{{ $log->event }}</div>
|
||||
<div class="text-xs text-zinc-500">{{ optional($log->created_at)->diffForHumans() }}</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="px-5 py-8 text-center text-sm text-zinc-500">No audit events yet.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
@if($recentAudit->hasPages())
|
||||
<div class="border-t border-zinc-200 px-5 py-4 dark:border-zinc-700">
|
||||
{{ $recentAudit->onEachSide(1)->links() }}
|
||||
</div>
|
||||
@empty
|
||||
<div class="px-5 py-8 text-center text-sm text-zinc-500">No audit events yet.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</section>
|
||||
@endif
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-layouts.app>
|
||||
|
||||
@@ -3,49 +3,123 @@
|
||||
<head>@include('stylist-theme-common::partials.head')</head>
|
||||
<body class="min-h-screen bg-white dark:bg-zinc-800">
|
||||
<flux:sidebar sticky collapsible="mobile" class="border-e border-zinc-200 bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<flux:sidebar.header><x-stylist-theme-common::app-logo :sidebar="true" href="{{ route('dashboard') }}" wire:navigate /><flux:sidebar.collapse class="lg:hidden" /></flux:sidebar.header>
|
||||
<flux:sidebar.nav>
|
||||
<flux:sidebar.group :heading="__('Security')" class="grid">
|
||||
<flux:sidebar.item icon="shield-check" :href="route('administration.security.index')" :current="request()->routeIs('administration.security.*')" wire:navigate>{{ __('Security Centre') }}</flux:sidebar.item>
|
||||
</flux:sidebar.group>
|
||||
<flux:sidebar.group :heading="__('Business')" class="grid">
|
||||
<flux:sidebar.item icon="shopping-bag" :href="route('administration.commerce.index')" :current="request()->routeIs('administration.commerce.*')" wire:navigate>{{ __('Commerce') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="building-office-2" :href="route('administration.crm.index')" :current="request()->routeIs('administration.crm.*')" wire:navigate>{{ __('CRM') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="envelope" :href="route('administration.newsletter.index')" :current="request()->routeIs('administration.newsletter.*')" wire:navigate>{{ __('Newsletter') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="calendar-days" :href="route('administration.events.index')" :current="request()->routeIs('administration.events.*')" wire:navigate>{{ __('Events') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="briefcase" :href="route('administration.careers.index')" :current="request()->routeIs('administration.careers.*')" wire:navigate>{{ __('Careers') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="map-pin" :href="route('administration.locations.index')" :current="request()->routeIs('administration.locations.*')" wire:navigate>{{ __('Locations') }}</flux:sidebar.item>
|
||||
</flux:sidebar.group>
|
||||
<flux:sidebar.group :heading="__('Publishing')" class="grid">
|
||||
<flux:sidebar.item icon="newspaper" :href="route('administration.blog.index')" :current="request()->routeIs('administration.blog.*')" wire:navigate>{{ __('Blog') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="megaphone" :href="route('administration.news.index')" :current="request()->routeIs('administration.news.*')" wire:navigate>{{ __('News') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="folder" :href="route('administration.categories.index')" :current="request()->routeIs('administration.categories.*')" wire:navigate>{{ __('Categories') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="tag" :href="route('administration.tags.index')" :current="request()->routeIs('administration.tags.*')" wire:navigate>{{ __('Tags') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="pencil-square" :href="route('administration.authors.index')" :current="request()->routeIs('administration.authors.*')" wire:navigate>{{ __('Authors') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="chat-bubble-oval-left" :href="route('administration.comments.index')" :current="request()->routeIs('administration.comments.*')" wire:navigate>{{ __('Comments') }}</flux:sidebar.item>
|
||||
</flux:sidebar.group>
|
||||
<flux:sidebar.group :heading="__('Content')" class="grid">
|
||||
<flux:sidebar.item icon="document-text" :href="route('administration.pages.index')" :current="request()->routeIs('administration.pages.*')" wire:navigate>{{ __('Pages') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="bars-3-bottom-left" :href="route('administration.menus.index')" :current="request()->routeIs('administration.menus.*')" wire:navigate>{{ __('Menus') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="arrow-uturn-right" :href="route('administration.redirects.index')" :current="request()->routeIs('administration.redirects.*')" wire:navigate>{{ __('Redirects') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="rectangle-stack" :href="route('administration.forms.index')" :current="request()->routeIs('administration.forms.*')" wire:navigate>{{ __('Forms') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="folder" :href="route('administration.documents.index')" :current="request()->routeIs('administration.documents.*')" wire:navigate>{{ __('Documents') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="megaphone" :href="route('administration.banners.index')" :current="request()->routeIs('administration.banners.*')" wire:navigate>{{ __('Banners') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="question-mark-circle" :href="route('administration.faq.index')" :current="request()->routeIs('administration.faq.*')" wire:navigate>{{ __('FAQ') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="user-group" :href="route('administration.team.index')" :current="request()->routeIs('administration.team.*')" wire:navigate>{{ __('Team') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="chat-bubble-left-right" :href="route('administration.testimonials.index')" :current="request()->routeIs('administration.testimonials.*')" wire:navigate>{{ __('Testimonials') }}</flux:sidebar.item>
|
||||
</flux:sidebar.group>
|
||||
<flux:sidebar.group :heading="__('Platform')" class="grid"><flux:sidebar.item icon="server-stack" :href="route('administration.enterprise.index')" :current="request()->routeIs('administration.enterprise.*')" wire:navigate>{{ __('Enterprise Services') }}</flux:sidebar.item><flux:sidebar.item icon="globe-alt" :href="route('administration.sites.index')" :current="request()->routeIs('administration.sites.*')" wire:navigate>{{ __('Sites') }}</flux:sidebar.item><flux:sidebar.item icon="home" :href="route('dashboard')" :current="request()->routeIs('dashboard')" wire:navigate>{{ __('Dashboard') }}</flux:sidebar.item></flux:sidebar.group>
|
||||
<flux:sidebar.group :heading="__('Developer')" class="grid"><flux:sidebar.item icon="code-bracket" :href="route('administration.api.index')" :current="request()->routeIs('administration.api.*')" wire:navigate>{{ __('API & Webhooks') }}</flux:sidebar.item><flux:sidebar.item icon="command-line" href="{{ route('administration.developer.index') }}" :current="request()->routeIs('administration.developer.*')" wire:navigate>{{ __('Developer Tools') }}</flux:sidebar.item></flux:sidebar.group>
|
||||
<flux:sidebar.group :heading="__('Artificial Intelligence')" class="grid"><flux:sidebar.item icon="sparkles" :href="route('administration.ai.index')" :current="request()->routeIs('administration.ai.*')" wire:navigate>{{ __('AI Platform') }}</flux:sidebar.item></flux:sidebar.group>
|
||||
<flux:sidebar.group :heading="__('Automation')" class="grid"><flux:sidebar.item icon="bolt" :href="route('administration.automation.index')" :current="request()->routeIs('administration.automation.*')" wire:navigate>{{ __('Automation') }}</flux:sidebar.item></flux:sidebar.group>
|
||||
<flux:sidebar.group :heading="__('Workflow')" class="grid"><flux:sidebar.item icon="arrows-right-left" :href="route('administration.workflows.index')" :current="request()->routeIs('administration.workflows.*')" wire:navigate>{{ __('Review Queue') }}</flux:sidebar.item></flux:sidebar.group>
|
||||
<flux:sidebar.group :heading="__('Management')" class="grid"><flux:sidebar.item icon="users" :href="route('administration.users.index')" :current="request()->routeIs('administration.users.*')" wire:navigate>{{ __('Users') }}</flux:sidebar.item><flux:sidebar.item icon="shield-check" :href="route('administration.roles.index')" :current="request()->routeIs('administration.roles.*')" wire:navigate>{{ __('Roles & Permissions') }}</flux:sidebar.item><flux:sidebar.item icon="photo" :href="route('administration.media.index')" :current="request()->routeIs('administration.media.*')" wire:navigate>{{ __('Media') }}</flux:sidebar.item><flux:sidebar.item icon="magnifying-glass" :href="route('administration.search.index')" :current="request()->routeIs('administration.search.*')" wire:navigate>{{ __('Search') }}</flux:sidebar.item></flux:sidebar.group>
|
||||
<flux:sidebar.group :heading="__('Configuration')" class="grid"><flux:sidebar.item icon="language" :href="route('administration.localization.index')" :current="request()->routeIs('administration.localization.*')" wire:navigate>{{ __('Localisation') }}</flux:sidebar.item><flux:sidebar.item icon="globe-alt" :href="route('administration.seo.index')" :current="request()->routeIs('administration.seo.*')" wire:navigate>{{ __('SEO') }}</flux:sidebar.item><flux:sidebar.item icon="cog-6-tooth" :href="route('administration.settings.index')" :current="request()->routeIs('administration.settings.*')" wire:navigate>{{ __('Settings') }}</flux:sidebar.item><flux:sidebar.item icon="cube" :href="route('administration.modules.index')" :current="request()->routeIs('administration.modules.*')" wire:navigate>{{ __('Modules') }}</flux:sidebar.item><flux:sidebar.item icon="clipboard-document-list" :href="route('administration.audit.index')" :current="request()->routeIs('administration.audit.*')" wire:navigate>{{ __('Audit Log') }}</flux:sidebar.item></flux:sidebar.group>
|
||||
<flux:sidebar.group :heading="__('Operations')" class="grid"><flux:sidebar.item icon="cloud-arrow-up" :href="route('administration.cloud-devops.index')" :current="request()->routeIs('administration.cloud-devops.*')" wire:navigate>{{ __('Cloud & DevOps') }}</flux:sidebar.item></flux:sidebar.group>
|
||||
</flux:sidebar.nav><flux:spacer /><x-stylist-theme-common::desktop-user-menu class="hidden lg:block" :name="auth()->user()->name" /></flux:sidebar>
|
||||
<flux:header class="lg:hidden"><flux:sidebar.toggle class="lg:hidden" icon="bars-2" inset="left" /><flux:spacer /><flux:dropdown position="top" align="end"><flux:profile :initials="auth()->user()->initials()" icon-trailing="chevron-down" /><flux:menu><flux:menu.radio.group><div class="p-0 text-sm font-normal"><div class="flex items-center gap-2 px-1 py-1.5 text-start text-sm"><flux:avatar :name="auth()->user()->name" :initials="auth()->user()->initials()" /><div class="grid flex-1 text-start text-sm leading-tight"><flux:heading class="truncate">{{ auth()->user()->name }}</flux:heading><flux:text class="truncate">{{ auth()->user()->email }}</flux:text></div></div></div></flux:menu.radio.group><flux:menu.separator /><flux:menu.radio.group><flux:menu.item :href="route('profile.edit')" icon="cog" wire:navigate>{{ __('Settings') }}</flux:menu.item></flux:menu.radio.group><flux:menu.separator /><form method="POST" action="{{ route('logout') }}" class="w-full">@csrf<flux:menu.item as="button" type="submit" icon="arrow-right-start-on-rectangle" class="w-full cursor-pointer" data-test="logout-button">{{ __('Log out') }}</flux:menu.item></form></flux:menu></flux:dropdown></flux:header>
|
||||
<flux:sidebar.header>
|
||||
<x-stylist-theme-common::app-logo :sidebar="true" href="{{ route('dashboard') }}" wire:navigate />
|
||||
<flux:sidebar.collapse class="lg:hidden" />
|
||||
</flux:sidebar.header>
|
||||
|
||||
<flux:sidebar.nav>
|
||||
<flux:sidebar.group :heading="__('Platform')" expandable :expanded="request()->routeIs('dashboard', 'administration.enterprise.*', 'administration.sites.*')" class="grid">
|
||||
<flux:sidebar.item icon="home" :href="route('dashboard')" :current="request()->routeIs('dashboard')" wire:navigate>{{ __('Dashboard') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="server-stack" :href="route('administration.enterprise.index')" :current="request()->routeIs('administration.enterprise.*')" wire:navigate>{{ __('Enterprise Services') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="globe-alt" :href="route('administration.sites.index')" :current="request()->routeIs('administration.sites.*')" wire:navigate>{{ __('Sites') }}</flux:sidebar.item>
|
||||
</flux:sidebar.group>
|
||||
|
||||
<flux:sidebar.group :heading="__('Publishing')" expandable :expanded="request()->routeIs('administration.blog.*', 'administration.news.*', 'administration.categories.*', 'administration.tags.*', 'administration.authors.*', 'administration.comments.*')" class="grid">
|
||||
<flux:sidebar.item icon="newspaper" :href="route('administration.blog.index')" :current="request()->routeIs('administration.blog.*')" wire:navigate>{{ __('Blog') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="megaphone" :href="route('administration.news.index')" :current="request()->routeIs('administration.news.*')" wire:navigate>{{ __('News') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="folder" :href="route('administration.categories.index')" :current="request()->routeIs('administration.categories.*')" wire:navigate>{{ __('Categories') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="tag" :href="route('administration.tags.index')" :current="request()->routeIs('administration.tags.*')" wire:navigate>{{ __('Tags') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="pencil-square" :href="route('administration.authors.index')" :current="request()->routeIs('administration.authors.*')" wire:navigate>{{ __('Authors') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="chat-bubble-oval-left" :href="route('administration.comments.index')" :current="request()->routeIs('administration.comments.*')" wire:navigate>{{ __('Comments') }}</flux:sidebar.item>
|
||||
</flux:sidebar.group>
|
||||
|
||||
<flux:sidebar.group :heading="__('Content')" expandable :expanded="request()->routeIs('administration.pages.*', 'administration.menus.*', 'administration.redirects.*', 'administration.forms.*', 'administration.documents.*', 'administration.banners.*', 'administration.faq.*', 'administration.team.*', 'administration.testimonials.*')" class="grid">
|
||||
<flux:sidebar.item icon="document-text" :href="route('administration.pages.index')" :current="request()->routeIs('administration.pages.*')" wire:navigate>{{ __('Pages') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="bars-3-bottom-left" :href="route('administration.menus.index')" :current="request()->routeIs('administration.menus.*')" wire:navigate>{{ __('Menus') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="arrow-uturn-right" :href="route('administration.redirects.index')" :current="request()->routeIs('administration.redirects.*')" wire:navigate>{{ __('Redirects') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="rectangle-stack" :href="route('administration.forms.index')" :current="request()->routeIs('administration.forms.*')" wire:navigate>{{ __('Forms') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="folder" :href="route('administration.documents.index')" :current="request()->routeIs('administration.documents.*')" wire:navigate>{{ __('Documents') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="megaphone" :href="route('administration.banners.index')" :current="request()->routeIs('administration.banners.*')" wire:navigate>{{ __('Banners') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="question-mark-circle" :href="route('administration.faq.index')" :current="request()->routeIs('administration.faq.*')" wire:navigate>{{ __('FAQ') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="user-group" :href="route('administration.team.index')" :current="request()->routeIs('administration.team.*')" wire:navigate>{{ __('Team') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="chat-bubble-left-right" :href="route('administration.testimonials.index')" :current="request()->routeIs('administration.testimonials.*')" wire:navigate>{{ __('Testimonials') }}</flux:sidebar.item>
|
||||
</flux:sidebar.group>
|
||||
|
||||
<flux:sidebar.group :heading="__('Business')" expandable :expanded="request()->routeIs('administration.commerce.*', 'administration.crm.*', 'administration.newsletter.*', 'administration.events.*', 'administration.careers.*', 'administration.locations.*')" class="grid">
|
||||
<flux:sidebar.item icon="shopping-bag" :href="route('administration.commerce.index')" :current="request()->routeIs('administration.commerce.*')" wire:navigate>{{ __('Commerce') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="building-office-2" :href="route('administration.crm.index')" :current="request()->routeIs('administration.crm.*')" wire:navigate>{{ __('CRM') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="envelope" :href="route('administration.newsletter.index')" :current="request()->routeIs('administration.newsletter.*')" wire:navigate>{{ __('Newsletter') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="calendar-days" :href="route('administration.events.index')" :current="request()->routeIs('administration.events.*')" wire:navigate>{{ __('Events') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="briefcase" :href="route('administration.careers.index')" :current="request()->routeIs('administration.careers.*')" wire:navigate>{{ __('Careers') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="map-pin" :href="route('administration.locations.index')" :current="request()->routeIs('administration.locations.*')" wire:navigate>{{ __('Locations') }}</flux:sidebar.item>
|
||||
</flux:sidebar.group>
|
||||
|
||||
<flux:sidebar.group :heading="__('Management')" expandable :expanded="request()->routeIs('administration.users.*', 'administration.roles.*', 'administration.media.*', 'administration.search.*')" class="grid">
|
||||
<flux:sidebar.item icon="users" :href="route('administration.users.index')" :current="request()->routeIs('administration.users.*')" wire:navigate>{{ __('Users') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="shield-check" :href="route('administration.roles.index')" :current="request()->routeIs('administration.roles.*')" wire:navigate>{{ __('Roles & Permissions') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="photo" :href="route('administration.media.index')" :current="request()->routeIs('administration.media.*')" wire:navigate>{{ __('Media') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="magnifying-glass" :href="route('administration.search.index')" :current="request()->routeIs('administration.search.*')" wire:navigate>{{ __('Search') }}</flux:sidebar.item>
|
||||
</flux:sidebar.group>
|
||||
|
||||
<flux:sidebar.group :heading="__('Workflow & Automation')" expandable :expanded="request()->routeIs('administration.workflows.*', 'administration.automation.*', 'administration.ai.*')" class="grid">
|
||||
<flux:sidebar.item icon="arrows-right-left" :href="route('administration.workflows.index')" :current="request()->routeIs('administration.workflows.*')" wire:navigate>{{ __('Review Queue') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="bolt" :href="route('administration.automation.index')" :current="request()->routeIs('administration.automation.*')" wire:navigate>{{ __('Automation') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="sparkles" :href="route('administration.ai.index')" :current="request()->routeIs('administration.ai.*')" wire:navigate>{{ __('AI Platform') }}</flux:sidebar.item>
|
||||
</flux:sidebar.group>
|
||||
|
||||
<flux:sidebar.group :heading="__('Security')" expandable :expanded="request()->routeIs('administration.security.*')" class="grid">
|
||||
<flux:sidebar.item icon="shield-check" :href="route('administration.security.index')" :current="request()->routeIs('administration.security.*')" wire:navigate>{{ __('Security Centre') }}</flux:sidebar.item>
|
||||
</flux:sidebar.group>
|
||||
|
||||
<flux:sidebar.group :heading="__('Developer')" expandable :expanded="request()->routeIs('administration.api.*', 'administration.developer.*')" class="grid">
|
||||
<flux:sidebar.item icon="code-bracket" :href="route('administration.api.index')" :current="request()->routeIs('administration.api.*')" wire:navigate>{{ __('API & Webhooks') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="command-line" :href="route('administration.developer.index')" :current="request()->routeIs('administration.developer.*')" wire:navigate>{{ __('Developer Tools') }}</flux:sidebar.item>
|
||||
</flux:sidebar.group>
|
||||
|
||||
<flux:sidebar.group :heading="__('Configuration')" expandable :expanded="request()->routeIs('administration.localization.*', 'administration.seo.*', 'administration.settings.*', 'administration.modules.*', 'administration.audit.*')" class="grid">
|
||||
<flux:sidebar.item icon="language" :href="route('administration.localization.index')" :current="request()->routeIs('administration.localization.*')" wire:navigate>{{ __('Localisation') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="globe-alt" :href="route('administration.seo.index')" :current="request()->routeIs('administration.seo.*')" wire:navigate>{{ __('SEO') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="cog-6-tooth" :href="route('administration.settings.index')" :current="request()->routeIs('administration.settings.*')" wire:navigate>{{ __('Settings') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="cube" :href="route('administration.modules.index')" :current="request()->routeIs('administration.modules.*')" wire:navigate>{{ __('Modules') }}</flux:sidebar.item>
|
||||
<flux:sidebar.item icon="clipboard-document-list" :href="route('administration.audit.index')" :current="request()->routeIs('administration.audit.*')" wire:navigate>{{ __('Audit Log') }}</flux:sidebar.item>
|
||||
</flux:sidebar.group>
|
||||
|
||||
<flux:sidebar.group :heading="__('Operations')" expandable :expanded="request()->routeIs('administration.cloud-devops.*')" class="grid">
|
||||
<flux:sidebar.item icon="cloud-arrow-up" :href="route('administration.cloud-devops.index')" :current="request()->routeIs('administration.cloud-devops.*')" wire:navigate>{{ __('Cloud & DevOps') }}</flux:sidebar.item>
|
||||
</flux:sidebar.group>
|
||||
</flux:sidebar.nav>
|
||||
|
||||
<flux:spacer />
|
||||
<x-stylist-theme-common::desktop-user-menu class="hidden lg:block" :name="auth()->user()->name" />
|
||||
</flux:sidebar>
|
||||
|
||||
<flux:header class="lg:hidden">
|
||||
<flux:sidebar.toggle class="lg:hidden" icon="bars-2" inset="left" />
|
||||
<flux:spacer />
|
||||
<flux:dropdown position="top" align="end">
|
||||
<flux:profile :initials="auth()->user()->initials()" icon-trailing="chevron-down" />
|
||||
<flux:menu>
|
||||
<flux:menu.radio.group>
|
||||
<div class="p-0 text-sm font-normal">
|
||||
<div class="flex items-center gap-2 px-1 py-1.5 text-start text-sm">
|
||||
<flux:avatar :name="auth()->user()->name" :initials="auth()->user()->initials()" />
|
||||
<div class="grid flex-1 text-start text-sm leading-tight">
|
||||
<flux:heading class="truncate">{{ auth()->user()->name }}</flux:heading>
|
||||
<flux:text class="truncate">{{ auth()->user()->email }}</flux:text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</flux:menu.radio.group>
|
||||
<flux:menu.separator />
|
||||
<flux:menu.radio.group>
|
||||
<flux:menu.item :href="route('profile.edit')" icon="cog" wire:navigate>{{ __('Settings') }}</flux:menu.item>
|
||||
</flux:menu.radio.group>
|
||||
<flux:menu.separator />
|
||||
<form method="POST" action="{{ route('logout') }}" class="w-full">
|
||||
@csrf
|
||||
<flux:menu.item as="button" type="submit" icon="arrow-right-start-on-rectangle" class="w-full cursor-pointer" data-test="logout-button">{{ __('Log out') }}</flux:menu.item>
|
||||
</form>
|
||||
</flux:menu>
|
||||
</flux:dropdown>
|
||||
</flux:header>
|
||||
|
||||
{{ $slot }}
|
||||
@persist('toast')<flux:toast.group><flux:toast /></flux:toast.group>@endpersist
|
||||
|
||||
@persist('toast')
|
||||
<flux:toast.group><flux:toast /></flux:toast.group>
|
||||
@endpersist
|
||||
|
||||
@fluxScripts
|
||||
</body></html>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user