= 0ca7361a22 Feat: user dashboard with active services
- Added `UserAppAccessService` for retrieving active services by user with detailed role and permission validation.
- Created `ServiceAppDto` to standardize service data for UI rendering.
- Enhanced user dashboard layout and Livewire component with computed services, role-based restricted access, and expiring service warnings.
- Updated dashboard blade views for improved user experience and dynamic active services display.
2026-05-21 11:44:57 +00:00

141 lines
5.7 KiB
PHP

<?php
use App\Services\UserAppAccessService;
use Illuminate\Support\Collection;
use Livewire\Attributes\{Computed, Layout, Title};
use Livewire\Component;
new
#[Layout('layouts.app.sidebar')]
#[Title('Dashboard')]
class extends Component {
private UserAppAccessService $service;
public function boot(UserAppAccessService $service): void
{
$this->service = $service;
}
public function mount(): void
{
$user = auth()->user();
// Using spatie/laravel-activitylog v5 to log dashboard access
if ($user) {
activity()
->causedBy($user)
->event('dashboard_access')
->log('User accessed their assigned services dashboard.');
}
}
#[Computed]
public function services(): Collection
{
$user = auth()->user();
if (!$user) {
return collect();
}
return $this->service->getActiveServices($user);
}
};
?>
<div class="space-y-6">
<x-shared.card class="p-4 flex items-center justify-between">
<x-mary-avatar
:placeholder="auth()->user()->initials()"
:title="'Welcome back, ' . auth()->user()->name . '!'"
>
<x-slot:subtitle>
<p class="text-sm text-gray-500 dark:text-gray-400 mt-0.5">
Manage and access your authenticated single sign-on services.
</p>
</x-slot:subtitle>
</x-mary-avatar>
<div class="flex items-center gap-4">
<x-mary-badge class="badge-soft badge-primary font-semibold text-xs px-3 py-1.5">
Active Account
</x-mary-badge>
<span class="text-xs text-gray-400 dark:text-gray-500 flex items-center gap-1">
<x-mary-icon name="lucide.calendar" class="w-3.5 h-3.5"/>
{{ now()->format('F j, Y') }}
</span>
</div>
</x-shared.card>
@if($this->services->isEmpty())
<x-shared.card
class="flex flex-col items-center justify-center text-center p-12 min-h-100">
<div class="p-4 bg-gray-50 rounded-full mb-4">
<x-mary-icon
name="lucide.shield-alert"
class="w-12 h-12 text-gray-600 animate-pulse"
/>
</div>
<h3 class="text-lg font-semibold text-gray-900 mb-2">No Active Services Assigned</h3>
<p class="text-sm text-gray-500 max-w-md mb-6">
Your account does not currently have any active or visible services assigned by your role, or your
access duration has expired.
</p>
<x-mary-alert icon="lucide.info" class="alert-soft alert-info">
To request access to specific applications, please contact your system administrator or IT helpdesk with
your account details
</x-mary-alert>
</x-shared.card>
@else
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
@foreach($this->services as $service)
<x-shared.card
:title="$service->name"
icon="lucide-key-round"
class="group relative {{ $service->is_warning ? 'border-amber-300 dark:border-amber-900/40 bg-amber-50/10' :'' }} rounded-2xl shadow-xs flex flex-col justify-between"
>
<x-slot:actions>
@if($service->is_warning)
<x-mary-badge
class="badge-soft badge-warning font-semibold text-xs px-2.5 py-1 flex items-center gap-1.5">
<x-mary-icon name="lucide.alert-triangle"
class="w-3.5 h-3.5 inline animate-pulse text-amber-600 dark:text-amber-400"/>
<span>Expiring Soon</span>
</x-mary-badge>
@else
<x-mary-badge class="badge-soft badge-success text-xs font-semibold px-2.5 py-1">
Active
</x-mary-badge>
@endif
</x-slot:actions>
<div class="p-4 flex-1 flex flex-col justify-between gap-4">
<div>
<p class="text-xs text-gray-400 dark:text-gray-500 font-mono tracking-wider uppercase">
{{ $service->slug }}
</p>
</div>
<div class="pt-4 border-t border-gray-200 flex items-center justify-between gap-4">
<div class="flex items-center gap-2">
<x-mary-icon name="lucide.clock"
class="w-4 h-4 {{ $service->is_warning ? 'text-amber-500 animate-pulse' : 'text-gray-400 dark:text-gray-500' }}"/>
<span
class="text-sm font-medium {{ $service->is_warning ? 'text-amber-600 dark:text-amber-400 font-semibold' : 'text-gray-600 dark:text-gray-400' }}">
{{ $service->days_remaining }} {{ Str::plural('day', $service->days_remaining) }} left
</span>
</div>
<x-mary-button
icon="lucide.external-link"
class="btn-sm btn-circle btn-soft btn-primary"
tooltip="Launch Service"
/>
</div>
</div>
</x-shared.card>
@endforeach
</div>
@endif
</div>