dashboard update
This commit is contained in:
@@ -13,7 +13,7 @@ final class DashboardController extends Controller
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
return view('administration::dashboard', [
|
||||
return view('stylist-theme-admin::dashboard', [
|
||||
'userCount' => User::count(),
|
||||
'roleCount' => Schema::hasTable('roles') ? Role::count() : 0,
|
||||
'mediaCount' => Schema::hasTable('media') ? Media::count() : 0,
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
<x-layouts.app :title="__('Administration')">
|
||||
<div class="space-y-6">
|
||||
<div><h1 class="text-2xl font-semibold text-zinc-950 dark:text-zinc-100">Administration</h1>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">Platform health and recent activity.</p></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 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">{{ $count }}</div>
|
||||
<div class="text-sm text-zinc-500">{{ $label }}</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="grid gap-6 xl:grid-cols-2">
|
||||
<div class="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 dark:border-zinc-700">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">{{ $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>
|
||||
@endforeach</div>
|
||||
</div>
|
||||
<div class="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 dark:border-zinc-700">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">{{ $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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-layouts.app>
|
||||
@@ -1,10 +1,8 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Modules\Administration\Http\Controllers\DashboardController;
|
||||
use Modules\Administration\Http\Controllers\ModuleController;
|
||||
|
||||
Route::middleware(['auth', 'verified'])->prefix('administration')->name('administration.')->group(function (): void {
|
||||
Route::get('/', DashboardController::class)->name('dashboard');
|
||||
Route::get('/modules', [ModuleController::class, 'index'])->name('modules.index');
|
||||
});
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Modules\Administration\Http\Controllers\DashboardController;
|
||||
|
||||
it('boots the Administration module', function (): void {
|
||||
expect(config('administration.name'))->toBe('Administration');
|
||||
});
|
||||
|
||||
it('uses the primary dashboard for administration overview content', function (): void {
|
||||
$dashboard = Route::getRoutes()->getByName('dashboard');
|
||||
|
||||
expect($dashboard)->not->toBeNull()
|
||||
->and($dashboard->getActionName())->toBe(DashboardController::class)
|
||||
->and(view()->exists('stylist-theme-admin::dashboard'))->toBeTrue()
|
||||
->and(Route::has('administration.dashboard'))->toBeFalse();
|
||||
});
|
||||
|
||||
@@ -1,18 +1,60 @@
|
||||
<x-layouts.app :title="__('Dashboard')">
|
||||
<div class="flex h-full w-full flex-1 flex-col gap-4 rounded-xl">
|
||||
<div class="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||
<div class="relative aspect-video overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700">
|
||||
<x-stylist-theme-admin::placeholder-pattern class="absolute inset-0 size-full stroke-gray-900/20 dark:stroke-neutral-100/20" />
|
||||
</div>
|
||||
<div class="relative aspect-video overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700">
|
||||
<x-stylist-theme-admin::placeholder-pattern class="absolute inset-0 size-full stroke-gray-900/20 dark:stroke-neutral-100/20" />
|
||||
</div>
|
||||
<div class="relative aspect-video overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700">
|
||||
<x-stylist-theme-admin::placeholder-pattern class="absolute inset-0 size-full stroke-gray-900/20 dark:stroke-neutral-100/20" />
|
||||
</div>
|
||||
<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 h-full flex-1 overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-700">
|
||||
<x-stylist-theme-admin::placeholder-pattern class="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="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>
|
||||
<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>
|
||||
@endforeach
|
||||
</div>
|
||||
</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>
|
||||
</div>
|
||||
@empty
|
||||
<div class="px-5 py-8 text-center text-sm text-zinc-500">No audit events yet.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</x-layouts.app>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<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.item icon="squares-2x2" :href="route('administration.dashboard')" :current="request()->routeIs('administration.dashboard')" wire:navigate>{{ __('Administration') }}</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>
|
||||
|
||||
+2
-4
@@ -1,16 +1,14 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Modules\Administration\Http\Controllers\DashboardController;
|
||||
|
||||
Route::get('/', function () {
|
||||
return view('stylist-theme-welcome::welcome');
|
||||
})->name('home');
|
||||
|
||||
Route::middleware(['auth', 'verified'])->group(function () {
|
||||
Route::view(
|
||||
'/dashboard',
|
||||
'stylist-theme-admin::dashboard'
|
||||
)->name('dashboard');
|
||||
Route::get('/dashboard', DashboardController::class)->name('dashboard');
|
||||
});
|
||||
|
||||
require __DIR__.'/settings.php';
|
||||
|
||||
Reference in New Issue
Block a user