307 lines
9.4 KiB
PHP
307 lines
9.4 KiB
PHP
{{--
|
|
========================================
|
|
MENU UTENTE HEADER
|
|
========================================
|
|
Dropdown menu utente con profile, impostazioni, logout.
|
|
|
|
Props:
|
|
- $showAvatar (bool): Mostra avatar utente
|
|
- $showStatus (bool): Mostra stato online/offline
|
|
- $avatarSize (string): Dimensione avatar (sm, md, lg)
|
|
|
|
Autore: NetGesCon Development Team
|
|
Data: 2024
|
|
========================================
|
|
--}}
|
|
|
|
@props([
|
|
'showAvatar' => true,
|
|
'showStatus' => true,
|
|
'avatarSize' => 'md'
|
|
])
|
|
|
|
@php
|
|
$user = Auth::user();
|
|
$avatarSizes = [
|
|
'sm' => '32px',
|
|
'md' => '40px',
|
|
'lg' => '48px'
|
|
];
|
|
$currentSize = $avatarSizes[$avatarSize] ?? $avatarSizes['md'];
|
|
@endphp
|
|
|
|
<div class="netgescon-user-menu dropdown">
|
|
|
|
{{-- Trigger utente --}}
|
|
<button class="btn btn-outline-secondary d-flex align-items-center"
|
|
type="button"
|
|
data-bs-toggle="dropdown"
|
|
aria-expanded="false"
|
|
aria-label="Menu utente">
|
|
|
|
{{-- Avatar --}}
|
|
@if($showAvatar)
|
|
<div class="user-avatar me-2 position-relative" style="width: {{ $currentSize }}; height: {{ $currentSize }};">
|
|
@if($user->avatar)
|
|
<img src="{{ asset('storage/' . $user->avatar) }}"
|
|
alt="Avatar {{ $user->name }}"
|
|
class="rounded-circle w-100 h-100 object-fit-cover">
|
|
@else
|
|
<div class="avatar-placeholder rounded-circle w-100 h-100 d-flex align-items-center justify-content-center bg-primary text-white">
|
|
{{ strtoupper(substr($user->name, 0, 1)) }}
|
|
</div>
|
|
@endif
|
|
|
|
{{-- Status indicator --}}
|
|
@if($showStatus)
|
|
<span class="position-absolute bottom-0 end-0 status-indicator bg-success border border-white rounded-circle"
|
|
title="Online"></span>
|
|
@endif
|
|
</div>
|
|
@endif
|
|
|
|
{{-- Nome utente (nascosto su mobile) --}}
|
|
<span class="d-none d-md-inline">{{ $user->name }}</span>
|
|
|
|
{{-- Freccia dropdown --}}
|
|
<i class="fas fa-chevron-down ms-2 small"></i>
|
|
|
|
</button>
|
|
|
|
{{-- Dropdown menu --}}
|
|
<ul class="dropdown-menu dropdown-menu-end user-dropdown">
|
|
|
|
{{-- Header utente --}}
|
|
<li class="dropdown-header user-info">
|
|
<div class="d-flex align-items-center">
|
|
@if($showAvatar)
|
|
<div class="user-avatar-large me-3">
|
|
@if($user->avatar)
|
|
<img src="{{ asset('storage/' . $user->avatar) }}"
|
|
alt="Avatar {{ $user->name }}"
|
|
class="rounded-circle" style="width: 50px; height: 50px;">
|
|
@else
|
|
<div class="avatar-placeholder rounded-circle bg-primary text-white d-flex align-items-center justify-content-center"
|
|
style="width: 50px; height: 50px; font-size: 1.25rem;">
|
|
{{ strtoupper(substr($user->name, 0, 1)) }}
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endif
|
|
<div>
|
|
<div class="fw-semibold">{{ $user->name }}</div>
|
|
<small class="text-muted">{{ $user->email }}</small>
|
|
@if($user->roles->isNotEmpty())
|
|
<div>
|
|
<span class="badge bg-secondary small">{{ $user->roles->first()->name }}</span>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</li>
|
|
|
|
<li><hr class="dropdown-divider"></li>
|
|
|
|
{{-- Menu items --}}
|
|
<li>
|
|
<a class="dropdown-item" href="{{ route('profile.edit') }}">
|
|
<i class="fas fa-user me-2"></i>Il mio profilo
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a class="dropdown-item" href="{{ route('profile.edit') }}" title="Impostazioni profilo">
|
|
<i class="fas fa-cog me-2"></i>Impostazioni
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a class="dropdown-item" href="#" title="Notifiche (in sviluppo)">
|
|
<i class="fas fa-bell me-2"></i>Notifiche
|
|
@php $unreadNotifications = 0; /* TODO: implementare conteggio */ @endphp
|
|
@if($unreadNotifications > 0)
|
|
<span class="badge bg-danger ms-auto">{{ $unreadNotifications }}</span>
|
|
@endif
|
|
</a>
|
|
</li>
|
|
|
|
{{-- Separatore --}}
|
|
<li><hr class="dropdown-divider"></li>
|
|
|
|
{{-- Azioni admin (solo per ruoli appropriati) --}}
|
|
@if($user->hasRole(['super-admin', 'admin']))
|
|
<li>
|
|
<a class="dropdown-item" href="{{ route('admin.dashboard') }}">
|
|
<i class="fas fa-tachometer-alt me-2"></i>Pannello Admin
|
|
</a>
|
|
</li>
|
|
|
|
@if($user->hasRole('super-admin'))
|
|
<li>
|
|
<a class="dropdown-item" href="{{ route('superadmin.dashboard') }}">
|
|
<i class="fas fa-crown me-2 text-warning"></i>Super Admin
|
|
</a>
|
|
</li>
|
|
@endif
|
|
|
|
<li><hr class="dropdown-divider"></li>
|
|
@endif
|
|
|
|
{{-- Cambio tema --}}
|
|
<li>
|
|
<button type="button" class="dropdown-item" id="themeToggle">
|
|
<i class="fas fa-moon me-2" id="themeIcon"></i>
|
|
<span id="themeText">Tema scuro</span>
|
|
</button>
|
|
</li>
|
|
|
|
{{-- Aiuto --}}
|
|
<li>
|
|
<a class="dropdown-item" href="#" title="Centro aiuto (in sviluppo)">
|
|
<i class="fas fa-question-circle me-2"></i>Aiuto
|
|
</a>
|
|
</li>
|
|
|
|
{{-- Logout --}}
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li>
|
|
<form method="POST" action="{{ route('logout') }}" class="d-inline">
|
|
@csrf
|
|
<button type="submit" class="dropdown-item text-danger">
|
|
<i class="fas fa-sign-out-alt me-2"></i>Logout
|
|
</button>
|
|
</form>
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
{{-- CSS per menu utente --}}
|
|
@push('styles')
|
|
<style>
|
|
.user-dropdown {
|
|
width: 280px;
|
|
border: none;
|
|
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
|
}
|
|
|
|
.user-info {
|
|
padding: 1rem;
|
|
background: linear-gradient(135deg, var(--bs-primary), var(--bs-info));
|
|
color: white;
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.user-info .text-muted {
|
|
color: rgba(255, 255, 255, 0.8) !important;
|
|
}
|
|
|
|
.user-info .badge {
|
|
background-color: rgba(255, 255, 255, 0.2) !important;
|
|
}
|
|
|
|
.status-indicator {
|
|
width: 12px;
|
|
height: 12px;
|
|
}
|
|
|
|
.avatar-placeholder {
|
|
font-weight: 600;
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.dropdown-item {
|
|
padding: 0.75rem 1rem;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.dropdown-item:hover {
|
|
background-color: var(--bs-light);
|
|
}
|
|
|
|
.dropdown-item.text-danger:hover {
|
|
background-color: var(--bs-danger);
|
|
color: white !important;
|
|
}
|
|
|
|
/* Tema scuro */
|
|
.dark .user-dropdown {
|
|
background-color: var(--bs-dark);
|
|
border-color: var(--bs-gray-700);
|
|
}
|
|
|
|
.dark .dropdown-item:hover {
|
|
background-color: var(--bs-gray-800);
|
|
}
|
|
|
|
.dark .user-info {
|
|
background: linear-gradient(135deg, var(--bs-primary), var(--bs-secondary));
|
|
}
|
|
|
|
/* Responsive */
|
|
@media (max-width: 768px) {
|
|
.user-dropdown {
|
|
width: 250px;
|
|
}
|
|
}
|
|
</style>
|
|
@endpush
|
|
|
|
{{-- JavaScript per menu utente --}}
|
|
@push('scripts')
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Toggle tema
|
|
const themeToggle = document.getElementById('themeToggle');
|
|
const themeIcon = document.getElementById('themeIcon');
|
|
const themeText = document.getElementById('themeText');
|
|
|
|
if (themeToggle) {
|
|
// Stato iniziale
|
|
const isDark = document.documentElement.classList.contains('dark') ||
|
|
localStorage.getItem('theme') === 'dark';
|
|
|
|
updateThemeButton(isDark);
|
|
|
|
themeToggle.addEventListener('click', function() {
|
|
const currentTheme = localStorage.getItem('theme');
|
|
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
|
|
|
localStorage.setItem('theme', newTheme);
|
|
document.documentElement.classList.toggle('dark', newTheme === 'dark');
|
|
|
|
updateThemeButton(newTheme === 'dark');
|
|
|
|
// Notifica cambio tema
|
|
if (typeof window.updateTheme === 'function') {
|
|
window.updateTheme(newTheme);
|
|
}
|
|
});
|
|
}
|
|
|
|
function updateThemeButton(isDark) {
|
|
if (themeIcon && themeText) {
|
|
if (isDark) {
|
|
themeIcon.className = 'fas fa-sun me-2';
|
|
themeText.textContent = 'Tema chiaro';
|
|
} else {
|
|
themeIcon.className = 'fas fa-moon me-2';
|
|
themeText.textContent = 'Tema scuro';
|
|
}
|
|
}
|
|
}
|
|
|
|
// Conferma logout
|
|
const logoutForm = document.querySelector('form[action*="logout"]');
|
|
if (logoutForm) {
|
|
logoutForm.addEventListener('submit', function(e) {
|
|
if (!confirm('Sei sicuro di voler uscire?')) {
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
}
|
|
});
|
|
</script>
|
|
@endpush
|