glastree_on_gitea

This commit is contained in:
2026-05-26 08:14:29 +02:00
commit 0bed099d05
9556 changed files with 1186307 additions and 0 deletions
@@ -0,0 +1,97 @@
@extends('admin.layout')
@section('title', 'Log Attività')
@section('page_title', 'Log Attività')
@section('breadcrumbs')
<li class="breadcrumb-item active">Admin</li>
<li class="breadcrumb-item active">Log Attività</li>
@endsection
@section('content')
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Attività di Sistema</h3>
</div>
<div class="card-body">
<form method="GET" class="mb-3">
<div class="row">
<div class="col-md-2">
<select name="user_id" class="form-control">
<option value="">Tutti gli utenti</option>
@foreach($users as $u)
<option value="{{ $u->id }}" {{ request('user_id') == $u->id ? 'selected' : '' }}>{{ $u->name }}</option>
@endforeach
</select>
</div>
<div class="col-md-2">
<select name="module" class="form-control">
<option value="">Tutti i moduli</option>
@foreach($modules as $module)
<option value="{{ $module }}" {{ request('module') == $module ? 'selected' : '' }}>{{ $module }}</option>
@endforeach
</select>
</div>
<div class="col-md-2">
<select name="action" class="form-control">
<option value="">Tutte le azioni</option>
<option value="create" {{ request('action') == 'create' ? 'selected' : '' }}>Create</option>
<option value="update" {{ request('action') == 'update' ? 'selected' : '' }}>Update</option>
<option value="delete" {{ request('action') == 'delete' ? 'selected' : '' }}>Delete</option>
<option value="login" {{ request('action') == 'login' ? 'selected' : '' }}>Login</option>
</select>
</div>
<div class="col-md-2">
<input type="date" name="from" class="form-control" value="{{ request('from') }}" placeholder="Da">
</div>
<div class="col-md-2">
<input type="date" name="to" class="form-control" value="{{ request('to') }}" placeholder="A">
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-primary">Filtra</button>
<a href="/admin/activity-logs" class="btn btn-secondary">Reset</a>
</div>
</div>
</form>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Data/Ora</th>
<th>Utente</th>
<th>Azione</th>
<th>Modulo</th>
<th>Descrizione</th>
<th>IP</th>
</tr>
</thead>
<tbody>
@forelse($logs as $log)
<tr>
<td><small>{{ $log->created_at->format('d/m/Y H:i:s') }}</small></td>
<td>{{ $log->user->name ?? 'Sistema' }}</td>
<td>
<span class="badge badge-{{ $log->action == 'delete' ? 'danger' : ($log->action == 'create' ? 'success' : ($log->action == 'login' ? 'info' : 'warning')) }}">
{{ $log->action }}
</span>
</td>
<td>{{ $log->module }}</td>
<td>{{ $log->description }}</td>
<td><small>{{ $log->ip_address }}</small></td>
</tr>
@empty
<tr>
<td colspan="6" class="text-center">Nessun log presente</td>
</tr>
@endforelse
</tbody>
</table>
{{ $logs->links() }}
</div>
</div>
</div>
</div>
@endsection
@@ -0,0 +1,443 @@
@extends('layouts.adminlte')
@section('title', 'Impostazioni Email')
@section('page_title', 'Configurazione Email')
@section('breadcrumbs')
<li class="breadcrumb-item"><a href="{{ route('dashboard') }}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="/impostazioni">Impostazioni</a></li>
<li class="breadcrumb-item active">Email Settings</li>
@endsection
@section('content')
<div class="row">
<div class="col-md-3">
<div class="card card-secondary">
<div class="card-header">
<h3 class="card-title">Sezioni</h3>
</div>
<div class="list-group list-group-flush">
<a href="#imap" class="list-group-item list-group-item-action active" data-toggle="tab">
<i class="nav-icon fas fa-server"></i> Server IMAP
</a>
<a href="#smtp" class="list-group-item list-group-item-action" data-toggle="tab">
<i class="nav-icon fas fa-paper-plane"></i> Server SMTP (Invio)
</a>
<a href="#account" class="list-group-item list-group-item-action" data-toggle="tab">
<i class="nav-icon fas fa-user"></i> Account
</a>
<a href="#sync" class="list-group-item list-group-item-action" data-toggle="tab">
<i class="nav-icon fas fa-sync"></i> Sincronizzazione
</a>
<a href="#signature" class="list-group-item list-group-item-action" data-toggle="tab">
<i class="nav-icon fas fa-signature"></i> Firma
</a>
</div>
</div>
</div>
<div class="col-md-9">
<form method="POST" action="{{ route('impostazioni.email.save') }}">
@csrf
<input type="hidden" name="id" value="{{ $settings->id ?? 1 }}">
<div class="tab-content">
<div class="tab-pane active" id="imap">
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">Configurazione Server IMAP</h3>
</div>
<div class="card-body">
@if(session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if(session('error'))
<div class="alert alert-danger">{{ session('error') }}</div>
@endif
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="imap_host">Host IMAP</label>
<input type="text" name="imap_host" id="imap_host" class="form-control"
value="{{ $settings->imap_host ?? 'imap.gmail.com' }}"
placeholder="es. imap.gmail.com">
<small class="text-muted">Gmail: imap.gmail.com | Outlook: outlook.office365.com</small>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="imap_port">Porta</label>
<input type="number" name="imap_port" id="imap_port" class="form-control"
value="{{ $settings->imap_port ?? 993 }}">
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="imap_encryption">Crittografia</label>
<select name="imap_encryption" id="imap_encryption" class="form-control">
<option value="ssl" {{ ($settings->imap_encryption ?? 'ssl') == 'ssl' ? 'selected' : '' }}>SSL</option>
<option value="tls" {{ ($settings->imap_encryption ?? '') == 'tls' ? 'selected' : '' }}>TLS</option>
<option value="none" {{ ($settings->imap_encryption ?? '') == 'none' ? 'selected' : '' }}>Nessuna</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="smtp">
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">Configurazione Server SMTP (per invio email)</h3>
</div>
<div class="card-body">
<div class="alert alert-info">
<i class="fas fa-info-circle"></i>
<strong>Nota:</strong> Per inviare email devi configurare il server SMTP.
Per Gmail, usa <code>smtp.gmail.com</code> sulla porta <code>587</code> con TLS
e genera una <a href="https://support.google.com/accounts/answer/185833" target="_blank">App Password</a>.
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="smtp_host">Host SMTP</label>
<input type="text" name="smtp_host" id="smtp_host" class="form-control"
value="{{ $settings->smtp_host ?? 'smtp.gmail.com' }}"
placeholder="es. smtp.gmail.com">
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="smtp_port">Porta</label>
<input type="number" name="smtp_port" id="smtp_port" class="form-control"
value="{{ $settings->smtp_port ?? 587 }}">
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="smtp_encryption">Crittografia</label>
<select name="smtp_encryption" id="smtp_encryption" class="form-control">
<option value="tls" {{ ($settings->smtp_encryption ?? 'tls') == 'tls' ? 'selected' : '' }}>TLS</option>
<option value="ssl" {{ ($settings->smtp_encryption ?? '') == 'ssl' ? 'selected' : '' }}>SSL</option>
<option value="none" {{ ($settings->smtp_encryption ?? '') == 'none' ? 'selected' : '' }}>Nessuna</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="smtp_username">Username SMTP</label>
<input type="text" name="smtp_username" id="smtp_username" class="form-control"
value="{{ $settings->smtp_username ?? '' }}"
placeholder="lascia vuoto per usare l'account IMAP">
<small class="text-muted">Generalmente uguale all'account email</small>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="smtp_password">Password SMTP / App Password</label>
<input type="password" name="smtp_password" id="smtp_password" class="form-control"
placeholder="{{ $settings->smtp_password ? '••••••••' : '' }}">
<small class="text-muted">Lascia vuoto per usare la password IMAP</small>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="account">
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">Credenziali Account</h3>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="imap_username">Username/Email</label>
<input type="text" name="imap_username" id="imap_username" class="form-control"
value="{{ $settings->imap_username ?? '' }}"
placeholder="es. tuo@gmail.com">
<small class="text-muted">Per Gmail usa l'indirizzo completo</small>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="imap_password">Password / App Password</label>
<input type="password" name="imap_password" id="imap_password" class="form-control"
placeholder="">
<small class="text-muted">
<a href="https://support.google.com/accounts/answer/185833" target="_blank">
Per Gmail: genera una App Password
</a>
</small>
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="email_address">Email Indirizzo</label>
<input type="email" name="email_address" id="email_address" class="form-control"
value="{{ $settings->email_address ?? '' }}">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="email_name">Nome Visualizzato</label>
<input type="text" name="email_name" id="email_name" class="form-control"
value="{{ $settings->email_name ?? '' }}"
placeholder="es. Nome Cognome">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="reply_to">Email Risposta (Reply-To)</label>
<input type="email" name="reply_to" id="reply_to" class="form-control"
value="{{ $settings->reply_to ?? '' }}">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="sync">
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">Sincronizzazione</h3>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="sync_interval_minutes">Intervallo Sync (minuti)</label>
<select name="sync_interval_minutes" id="sync_interval_minutes" class="form-control">
<option value="1" {{ ($settings->sync_interval_minutes ?? 5) == 1 ? 'selected' : '' }}>1 minuto</option>
<option value="5" {{ ($settings->sync_interval_minutes ?? 5) == 5 ? 'selected' : '' }}>5 minuti</option>
<option value="15" {{ ($settings->sync_interval_minutes ?? 5) == 15 ? 'selected' : '' }}>15 minuti</option>
<option value="30" {{ ($settings->sync_interval_minutes ?? 5) == 30 ? 'selected' : '' }}>30 minuti</option>
<option value="60" {{ ($settings->sync_interval_minutes ?? 5) == 60 ? 'selected' : '' }}>1 ora</option>
</select>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Stato Connessione</label>
<div class="mt-2">
@if($settings->last_sync_at)
<span class="badge badge-success">
<i class="fas fa-check-circle"></i> Ultimo sync: {{ $settings->last_sync_at->format('d/m/Y H:i') }}
</span>
@else
<span class="badge badge-secondary">
<i class="fas fa-clock"></i> Mai sincronizzato
</span>
@endif
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="is_active"
name="is_active" value="1" {{ ($settings->is_active ?? false) ? 'checked' : '' }}>
<label class="custom-control-label" for="is_active">Account Email Attivo</label>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="signature">
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">Firma Email</h3>
</div>
<div class="card-body">
<div class="form-group">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="signature_enabled"
name="signature_enabled" value="1" {{ ($settings->signature_enabled ?? true) ? 'checked' : '' }}>
<label class="custom-control-label" for="signature_enabled">Attiva firma automatica</label>
</div>
<small class="text-muted">Quando attivo, la firma verrà aggiunta in fondo a ogni email inviata</small>
</div>
<hr>
<div class="form-group">
<label for="signature">Testo Firma (formato HTML)</label>
<div id="signature-editor" style="height: 200px;"></div>
<input type="hidden" name="signature" id="signature_input" value="{{ $settings->signature ?? '' }}">
<small class="text-muted">Usa il riquadro sopra per comporre la tua firma. HTML supportato.</small>
</div>
</div>
</div>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary">
<i class="fas fa-save mr-1"></i> Salva Impostazioni
</button>
<button type="button" class="btn btn-info ml-2" onclick="testConnection()">
<i class="fas fa-plug mr-1"></i> Test Connessione IMAP
</button>
<button type="button" class="btn btn-success ml-2" onclick="testSmtp()">
<i class="fas fa-paper-plane mr-1"></i> Test Invio Email (SMTP)
</button>
<a href="{{ route('impostazioni.email.sync') }}" class="btn btn-warning ml-2">
<i class="fas fa-sync mr-1"></i> Sincronizza Ora
</a>
</div>
</form>
</div>
</div>
@endsection
@section('scripts')
<script>
function testConnection() {
$.ajax({
url: '{{ route('impostazioni.email.test') }}',
method: 'POST',
headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}' },
success: function(response) {
if (response.success) {
alert('✅ ' + response.message);
} else {
alert('❌ ' + response.message);
}
},
error: function() {
alert('❌ Errore nella richiesta');
}
});
}
function testSmtp() {
var email = prompt('Inserisci l\'indirizzo email a cui inviare il test:');
if (!email) return;
if (!email.includes('@')) {
alert('⚠️ Indirizzo email non valido');
return;
}
var btn = event.target;
btn.disabled = true;
btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Invio...';
$.ajax({
url: '{{ route('impostazioni.email.testSmtp') }}',
method: 'POST',
headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}' },
data: { email: email },
timeout: 30000,
success: function(response) {
btn.disabled = false;
btn.innerHTML = '<i class="fas fa-paper-plane mr-1"></i> Test Invio Email (SMTP)';
if (response.success) {
alert('✅ ' + response.message);
} else {
alert('❌ ' + response.message);
}
},
error: function(xhr, status, error) {
btn.disabled = false;
btn.innerHTML = '<i class="fas fa-paper-plane mr-1"></i> Test Invio Email (SMTP)';
if (xhr.responseJSON && xhr.responseJSON.message) {
alert('❌ ' + xhr.responseJSON.message);
} else {
alert('❌ Errore: ' + status + ' - ' + error);
}
}
});
}
function createEditor() {
var container = document.querySelector('#signature-editor');
if (!container || container.querySelector('.ql-toolbar')) return;
var quill = new Quill('#signature-editor', {
theme: 'snow',
modules: {
toolbar: [
['bold', 'italic', 'underline'],
[{ 'color': [] }, { 'background': [] }],
[{ 'header': 1 }, { 'header': 2 }, { 'header': 3 }],
[{ 'align': [] }],
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
['link', 'image'],
['clean', 'code']
]
}
});
var signatureInput = document.getElementById('signature_input');
var isEditingHtml = false;
quill.getModule('toolbar').addHandler('code', function() {
if (!isEditingHtml) {
var textarea = document.createElement('textarea');
textarea.className = 'ql-editor';
textarea.style.cssText = 'font-family: monospace; min-height: 150px; width: 100%;';
textarea.value = signatureInput.value;
quill.root.innerHTML = '';
quill.root.appendChild(textarea);
textarea.focus();
isEditingHtml = true;
} else {
var textarea = quill.root.querySelector('textarea');
if (textarea) {
signatureInput.value = textarea.value;
quill.root.innerHTML = textarea.value;
}
isEditingHtml = false;
}
});
if (signatureInput.value) {
quill.root.innerHTML = signatureInput.value;
}
quill.on('text-change', function() {
if (!isEditingHtml) {
signatureInput.value = quill.root.innerHTML;
}
});
}
function initSignatureEditor() {
if (document.querySelector('#signature-editor .ql-toolbar')) return;
if (typeof Quill === 'undefined') {
var script = document.createElement('script');
script.src = 'https://cdn.quilljs.com/1.3.7/quill.min.js';
script.onload = createEditor;
document.head.appendChild(script);
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://cdn.quilljs.com/1.3.7/quill.snow.css';
document.head.appendChild(link);
} else {
createEditor();
}
}
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
if ($(e.target).attr('href') === '#signature') {
setTimeout(initSignatureEditor, 100);
}
});
if ($('#signature').hasClass('active')) {
initSignatureEditor();
}
</script>
@endsection
+116
View File
@@ -0,0 +1,116 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>@yield('title', 'Admin') - Glastree</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/css/adminlte.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
@yield('styles')
</head>
<body class="hold-transition sidebar-mini layout-fixed">
<div class="wrapper">
<nav class="main-header navbar navbar-expand navbar-white navbar-light">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" data-widget="pushmenu" href="#"><i class="fas fa-bars"></i></a>
</li>
</ul>
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="{{ route('dashboard') }}">
<i class="fas fa-home"></i> Torna al Sito
</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link" data-toggle="dropdown" href="#">
<i class="fas fa-user"></i> {{ Auth::user()->name }}
</a>
<div class="dropdown-menu dropdown-menu-right">
<form method="POST" action="{{ route('logout') }}">
@csrf
<button type="submit" class="dropdown-item">
<i class="fas fa-sign-out-alt mr-2"></i> Esci
</button>
</form>
</div>
</li>
</ul>
</nav>
<aside class="main-sidebar sidebar-dark-primary elevation-4">
<a href="{{ route('dashboard') }}" class="brand-link">
<i class="fas fa-shield-alt brand-image ml-3 mr-2"></i>
<span class="brand-text font-weight-light">Admin</span>
</a>
<div class="sidebar">
<nav class="mt-2">
<ul class="nav nav-pills nav-sidebar flex-column">
<li class="nav-item">
<a href="/admin/utenti" class="nav-link {{ request()->is('admin/utenti*') ? 'active' : '' }}">
<i class="nav-icon fas fa-users"></i>
<p>Utenti</p>
</a>
</li>
<li class="nav-item">
<a href="/admin/ruoli" class="nav-link {{ request()->is('admin/ruoli*') ? 'active' : '' }}">
<i class="nav-icon fas fa-user-tag"></i>
<p>Ruoli</p>
</a>
</li>
<li class="nav-item">
<a href="/admin/activity-logs" class="nav-link {{ request()->is('admin/activity-logs*') ? 'active' : '' }}">
<i class="nav-icon fas fa-history"></i>
<p>Log Attività</p>
</a>
</li>
</ul>
</nav>
</div>
</aside>
<div class="content-wrapper">
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1 class="m-0">@yield('page_title', 'Admin')</h1>
</div>
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="{{ route('dashboard') }}">Dashboard</a></li>
@yield('breadcrumbs')
</ol>
</div>
</div>
</div>
</div>
<div class="content">
<div class="container-fluid">
@if(session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if(session('error'))
<div class="alert alert-danger">{{ session('error') }}</div>
@endif
@yield('content')
</div>
</div>
</div>
<footer class="main-footer">
<strong>{{ \App\Models\AppSetting::getFooterText() }}</strong>
@if(\App\Models\AppSetting::shouldShowVersion() && \App\Models\AppSetting::getAppVersion())
<span class="ml-2">v{{ \App\Models\AppSetting::getAppVersion() }}</span>
@endif
</footer>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/js/adminlte.min.js"></script>
@yield('scripts')
</body>
</html>
@@ -0,0 +1,64 @@
@extends('admin.layout')
@section('title', 'Crea Ruolo')
@section('page_title', 'Crea Nuovo Ruolo')
@section('breadcrumbs')
<li class="breadcrumb-item"><a href="/admin/ruoli">Admin</a></li>
<li class="breadcrumb-item"><a href="/admin/ruoli">Ruoli</a></li>
<li class="breadcrumb-item active">Nuovo</li>
@endsection
@section('content')
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h3 class="card-title">Nuovo Ruolo</h3>
</div>
<div class="card-body">
<form method="POST" action="/admin/ruoli">
@csrf
<div class="form-group">
<label>Nome *</label>
<input type="text" name="name" class="form-control" required maxlength="50" placeholder="es. Segretario">
</div>
<div class="form-group">
<label>Descrizione</label>
<input type="text" name="description" class="form-control" maxlength="255" placeholder="es. Accesso per segretari">
</div>
<h5 class="mt-4">Permessi</h5>
<table class="table table-sm">
<thead>
<tr>
<th>Modulo</th>
<th>Nessuno</th>
<th>Lettura</th>
<th>Completo</th>
</tr>
</thead>
<tbody>
@foreach(['individui', 'gruppi', 'eventi', 'documenti', 'mailing', 'viste'] as $module)
<tr>
<td><strong>{{ ucfirst($module) }}</strong></td>
<td class="text-center"><input type="radio" name="permissions[{{ $module }}]" value="0" checked></td>
<td class="text-center"><input type="radio" name="permissions[{{ $module }}]" value="1"></td>
<td class="text-center"><input type="radio" name="permissions[{{ $module }}]" value="2"></td>
</tr>
@endforeach
</tbody>
</table>
<div class="mt-4">
<button type="submit" class="btn btn-primary">
<i class="fas fa-save"></i> Salva
</button>
<a href="/admin/ruoli" class="btn btn-secondary">Annulla</a>
</div>
</form>
</div>
</div>
</div>
</div>
@endsection
@@ -0,0 +1,83 @@
@extends('admin.layout')
@section('title', 'Modifica Ruolo')
@section('page_title', 'Modifica Ruolo: ' . $ruolo->name)
@section('breadcrumbs')
<li class="breadcrumb-item"><a href="/admin/ruoli">Admin</a></li>
<li class="breadcrumb-item"><a href="/admin/ruoli">Ruoli</a></li>
<li class="breadcrumb-item active">{{ $ruolo->name }}</li>
@endsection
@section('content')
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h3 class="card-title">Modifica Ruolo: {{ $ruolo->name }}</h3>
@if($usersCount > 0)
<span class="badge badge-info ml-2">{{ $usersCount }} utenti</span>
@endif
</div>
<div class="card-body">
@if(session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
<form method="POST" action="{{ url('/admin/ruoli/' . $ruolo->id) }}">
@csrf @method('PUT')
<div class="form-group">
<label>Nome</label>
<input type="text" class="form-control" value="{{ $ruolo->name }}" disabled>
<small class="text-muted">Il nome del ruolo non può essere modificato</small>
</div>
<div class="form-group">
<label>Descrizione</label>
<input type="text" name="description" class="form-control" value="{{ old('description', $ruolo->description) }}">
</div>
<h5 class="mt-4">Permessi</h5>
<table class="table table-sm">
<thead>
<tr>
<th>Modulo</th>
<th>Nessuno</th>
<th>Lettura</th>
<th>Completo</th>
</tr>
</thead>
<tbody>
@foreach(['individui', 'gruppi', 'eventi', 'documenti', 'mailing', 'viste'] as $module)
<tr>
<td><strong>{{ ucfirst($module) }}</strong></td>
<td><input type="radio" name="permissions[{{ $module }}]" value="0" {{ ($ruolo->permissions[$module] ?? 0) == 0 ? 'checked' : '' }}></td>
<td><input type="radio" name="permissions[{{ $module }}]" value="1" {{ ($ruolo->permissions[$module] ?? 0) == 1 ? 'checked' : '' }}></td>
<td><input type="radio" name="permissions[{{ $module }}]" value="2" {{ ($ruolo->permissions[$module] ?? 0) == 2 ? 'checked' : '' }}></td>
</tr>
@endforeach
</tbody>
</table>
@if($usersCount > 0)
<div class="form-group mt-3">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="updateUsers" name="update_users" value="1">
<label class="custom-control-label" for="updateUsers">
Applica queste modifiche a tutti i {{ $usersCount }} utenti con questo ruolo
</label>
</div>
</div>
@endif
<div class="mt-4">
<button type="submit" class="btn btn-primary">
<i class="fas fa-save"></i> Salva
</button>
<a href="/admin/ruoli" class="btn btn-secondary">Annulla</a>
</div>
</form>
</div>
</div>
</div>
</div>
@endsection
@@ -0,0 +1,70 @@
@extends('admin.layout')
@section('title', 'Gestione Ruoli')
@section('page_title', 'Gestione Ruoli')
@section('breadcrumbs')
<li class="breadcrumb-item active">Admin</li>
<li class="breadcrumb-item active">Ruoli</li>
@endsection
@section('content')
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Ruoli Predefiniti</h3>
<a href="/admin/ruoli/create" class="btn btn-success btn-sm float-right">
<i class="fas fa-plus"></i> Nuovo Ruolo
</a>
</div>
<div class="card-body">
<table class="table table-bordered">
<thead>
<tr>
<th>Nome</th>
<th>Descrizione</th>
<th>Utenti</th>
<th>Permessi</th>
<th style="width: 100px;">Azioni</th>
</tr>
</thead>
<tbody>
@foreach($ruoli as $ruolo)
<tr>
<td><strong>{{ $ruolo->name }}</strong></td>
<td>{{ $ruolo->description }}</td>
<td><span class="badge badge-info">{{ $ruolo->users_count }}</span></td>
<td>
@foreach($ruolo->permissions as $module => $level)
<span class="badge badge-{{ $level == 2 ? 'success' : ($level == 1 ? 'info' : 'secondary') }}">
{{ ucfirst($module) }}: {{ $level == 2 ? 'Full' : ($level == 1 ? 'Read' : 'None') }}
</span>
@endforeach
</td>
<td>
<a href="{{ url('/admin/ruoli/' . $ruolo->id . '/edit') }}" class="btn btn-xs btn-warning">
<i class="fas fa-edit"></i>
</a>
@if($ruolo->users_count == 0)
<form method="POST" action="{{ url('/admin/ruoli/' . $ruolo->id) }}" style="display: inline;">
@csrf @method('DELETE')
<button type="submit" class="btn btn-xs btn-danger" onclick="return confirm('Eliminare questo ruolo?')">
<i class="fas fa-trash"></i>
</button>
</form>
@else
<button type="button" class="btn btn-xs btn-secondary" disabled title="Utenti associati: {{ $ruolo->users_count }}">
<i class="fas fa-trash"></i>
</button>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
@endsection
@@ -0,0 +1,101 @@
@extends('admin.layout')
@section('title', 'Crea Utente')
@section('page_title', 'Crea Nuovo Utente')
@section('breadcrumbs')
<li class="breadcrumb-item"><a href="/admin/utenti">Admin</a></li>
<li class="breadcrumb-item"><a href="/admin/utenti">Utenti</a></li>
<li class="breadcrumb-item active">Nuovo</li>
@endsection
@section('content')
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h3 class="card-title">Dati Utente</h3>
</div>
<div class="card-body">
<form method="POST" action="/admin/utenti">
@csrf
<div class="form-group">
<label>Nome *</label>
<input type="text" name="name" class="form-control" required value="{{ old('name') }}">
</div>
<div class="form-group">
<label>Email *</label>
<input type="email" name="email" class="form-control" required value="{{ old('email') }}">
</div>
<div class="form-group">
<label>Password *</label>
<input type="password" name="password" class="form-control" required minlength="8">
</div>
<div class="form-group">
<label>Conferma Password *</label>
<input type="password" name="password_confirmation" class="form-control" required minlength="8">
</div>
<div class="form-group">
<label>Ruolo Predefinito</label>
<select name="role_preset_id" class="form-control" id="rolePresetSelect">
<option value="">Personalizzato</option>
@foreach($rolePresets as $preset)
<option value="{{ $preset->id }}">{{ $preset->name }} - {{ $preset->description }}</option>
@endforeach
</select>
</div>
<div class="form-group">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="isAdmin" name="is_admin" value="1">
<label class="custom-control-label" for="isAdmin">Superadmin (bypass ACL)</label>
</div>
</div>
<div id="permissionsSection" class="mt-4">
<h5>Permessi Granulari</h5>
<table class="table table-sm">
<thead>
<tr>
<th>Modulo</th>
<th>Nessuno</th>
<th>Lettura</th>
<th>Completo</th>
</tr>
</thead>
<tbody>
@foreach(['individui', 'gruppi', 'eventi', 'documenti', 'mailing', 'viste'] as $module)
<tr>
<td><strong>{{ ucfirst($module) }}</strong></td>
<td><input type="radio" name="permissions[{{ $module }}]" value="0" {{ old('permissions.' . $module, '1') == '0' ? 'checked' : '' }}></td>
<td><input type="radio" name="permissions[{{ $module }}]" value="1" {{ old('permissions.' . $module, '1') == '1' ? 'checked' : '' }}></td>
<td><input type="radio" name="permissions[{{ $module }}]" value="2" {{ old('permissions.' . $module, '1') == '2' ? 'checked' : '' }}></td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div class="mt-4">
<button type="submit" class="btn btn-primary">
<i class="fas fa-save"></i> Salva
</button>
<a href="/admin/utenti" class="btn btn-secondary">Annulla</a>
</div>
</form>
</div>
</div>
</div>
</div>
@endsection
@section('scripts')
<script>
$('#rolePresetSelect').change(function() {
if ($(this).val()) {
$('#permissionsSection').hide();
} else {
$('#permissionsSection').show();
}
});
</script>
@endsection
+111
View File
@@ -0,0 +1,111 @@
@extends('admin.layout')
@section('title', 'Modifica Utente')
@section('page_title', 'Modifica Utente: ' . $user->name)
@section('breadcrumbs')
<li class="breadcrumb-item"><a href="/admin/utenti">Admin</a></li>
<li class="breadcrumb-item"><a href="/admin/utenti">Utenti</a></li>
<li class="breadcrumb-item active">{{ $user->name }}</li>
@endsection
@section('content')
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h3 class="card-title">Dati Utente</h3>
</div>
<div class="card-body">
<form method="POST" action="{{ url('/admin/utenti/' . $user->id) }}">
@csrf @method('PUT')
<div class="form-group">
<label>Nome *</label>
<input type="text" name="name" class="form-control" required value="{{ old('name', $user->name) }}">
</div>
<div class="form-group">
<label>Email *</label>
<input type="email" name="email" class="form-control" required value="{{ old('email', $user->email) }}">
</div>
<div class="form-group">
<label>Nuova Password <small>(lascia vuoto per non cambiare)</small></label>
<input type="password" name="password" class="form-control" minlength="8">
</div>
<div class="form-group">
<label>Conferma Password</label>
<input type="password" name="password_confirmation" class="form-control" minlength="8">
</div>
<div class="form-group">
<label>Stato</label>
<select name="status" class="form-control" required>
<option value="active" {{ $user->status === 'active' ? 'selected' : '' }}>Attivo</option>
<option value="suspended" {{ $user->status === 'suspended' ? 'selected' : '' }}>Sospeso</option>
<option value="pending" {{ $user->status === 'pending' ? 'selected' : '' }}>In attesa</option>
</select>
</div>
<div class="form-group">
<label>Ruolo Predefinito</label>
<select name="role_preset_id" class="form-control" id="rolePresetSelect">
<option value="">Personalizzato</option>
@foreach($rolePresets as $preset)
<option value="{{ $preset->id }}" {{ $user->role_preset_id == $preset->id ? 'selected' : '' }}>
{{ $preset->name }} - {{ $preset->description }}
</option>
@endforeach
</select>
</div>
<div class="form-group">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="isAdmin" name="is_admin" value="1" {{ $user->isSuperAdmin() ? 'checked' : '' }}>
<label class="custom-control-label" for="isAdmin">Superadmin (bypass ACL)</label>
</div>
</div>
<div id="permissionsSection" class="mt-4">
<h5>Permessi Granulari</h5>
<table class="table table-sm">
<thead>
<tr>
<th>Modulo</th>
<th>Nessuno</th>
<th>Lettura</th>
<th>Completo</th>
</tr>
</thead>
<tbody>
@foreach(['individui', 'gruppi', 'eventi', 'documenti', 'mailing', 'viste'] as $module)
<tr>
<td><strong>{{ ucfirst($module) }}</strong></td>
<td><input type="radio" name="permissions[{{ $module }}]" value="0" {{ ($user->permissions[$module] ?? 0) == 0 ? 'checked' : '' }}></td>
<td><input type="radio" name="permissions[{{ $module }}]" value="1" {{ ($user->permissions[$module] ?? 0) == 1 ? 'checked' : '' }}></td>
<td><input type="radio" name="permissions[{{ $module }}]" value="2" {{ ($user->permissions[$module] ?? 0) == 2 ? 'checked' : '' }}></td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div class="mt-4">
<button type="submit" class="btn btn-primary">
<i class="fas fa-save"></i> Salva
</button>
<a href="/admin/utenti" class="btn btn-secondary">Annulla</a>
</div>
</form>
</div>
</div>
</div>
</div>
@endsection
@section('scripts')
<script>
$('#rolePresetSelect').change(function() {
if ($(this).val()) {
$('#permissionsSection').hide();
} else {
$('#permissionsSection').show();
}
}).trigger('change');
</script>
@endsection
@@ -0,0 +1,109 @@
@extends('admin.layout')
@section('title', 'Gestione Utenti')
@section('page_title', 'Gestione Utenti')
@section('breadcrumbs')
<li class="breadcrumb-item active">Admin</li>
<li class="breadcrumb-item active">Utenti</li>
@endsection
@section('content')
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Utenti Registrati</h3>
<a href="/admin/utenti/create" class="btn btn-success btn-sm float-right">
<i class="fas fa-plus"></i> Nuovo Utente
</a>
</div>
<div class="card-body">
<form method="GET" class="mb-3">
<div class="row">
<div class="col-md-4">
<input type="text" name="search" class="form-control" placeholder="Cerca nome o email..." value="{{ request('search') }}">
</div>
<div class="col-md-3">
<select name="status" class="form-control">
<option value="">Tutti gli stati</option>
<option value="active" {{ request('status') == 'active' ? 'selected' : '' }}>Attivo</option>
<option value="suspended" {{ request('status') == 'suspended' ? 'selected' : '' }}>Sospeso</option>
<option value="pending" {{ request('status') == 'pending' ? 'selected' : '' }}>In attesa</option>
</select>
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-primary">Filtra</button>
</div>
</div>
</form>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Nome</th>
<th>Email</th>
<th>Stato</th>
<th>Permessi</th>
<th>Creato</th>
<th style="width: 150px;">Azioni</th>
</tr>
</thead>
<tbody>
@foreach($utenti as $utente)
<tr>
<td>
<strong>{{ $utente->name }}</strong>
@if($utente->isSuperAdmin())
<span class="badge badge-danger ml-1">Admin</span>
@endif
</td>
<td>{{ $utente->email }}</td>
<td>
@switch($utente->status)
@case('active')
<span class="badge badge-success">Attivo</span>
@break
@case('suspended')
<span class="badge badge-secondary">Sospeso</span>
@break
@case('pending')
<span class="badge badge-warning">In attesa</span>
@break
@endswitch
</td>
<td>
@php $summary = $utente->getPermissionsSummary(); @endphp
<small>
@foreach($summary as $module => $level)
@if($level !== 'Nessuno')
<span class="text-{{ $level === 'Completo' ? 'success' : 'info' }}">{{ ucfirst($module) }}: {{ $level }}</span><br>
@endif
@endforeach
</small>
</td>
<td>{{ $utente->created_at->format('d/m/Y') }}</td>
<td>
<a href="{{ url('/admin/utenti/' . $utente->id . '/edit') }}" class="btn btn-xs btn-warning">
<i class="fas fa-edit"></i>
</a>
@if($utente->id !== auth()->id())
<form method="POST" action="{{ url('/admin/utenti/' . $utente->id) }}" style="display: inline;">
@csrf @method('DELETE')
<button type="submit" class="btn btn-xs btn-danger" onclick="return confirm('Eliminare questo utente?')">
<i class="fas fa-trash"></i>
</button>
</form>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
{{ $utenti->links() }}
</div>
</div>
</div>
</div>
@endsection