fix(ui): eliminate table horizontal scroll with compact icon actions, fix impersonation 1-click flow with topbar banner, align Tab 3/4/5 views with ASCII wireframes, and resolve Adminer DB auto-fill (task-d095b0e23b)

This commit is contained in:
michele 2026-08-27 21:03:56 +02:00
parent dcabbd4d6b
commit d1fcf01a1c
4 changed files with 202 additions and 203 deletions

View File

@ -223,24 +223,18 @@ public function table(Table $table): Table
TextColumn::make('codice_univoco')->label('Codice')->searchable()->sortable(),
TextColumn::make('nome')->label('Nome')->searchable()->sortable(),
TextColumn::make('cognome')->label('Cognome')->searchable()->sortable(),
TextColumn::make('denominazione_studio')->label('Studio')->searchable(),
TextColumn::make('stabili_count')->label('Stabili')->sortable(),
TextColumn::make('denominazione_studio')->label('Studio')->searchable()->toggleable(),
TextColumn::make('email_studio')->label('Email')->searchable()->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('pec_studio')->label('PEC')->searchable()->toggleable(isToggledHiddenByDefault: true),
IconColumn::make('attivo')->label('Attivo')->boolean()->sortable()->toggleable(),
IconColumn::make('abilita_import_stabili')->label('Import')->boolean()->sortable()->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('fe_cassetto_status')
->label('FE Stato')
->label('FE')
->state(function (Amministratore $record): string {
if (! (bool) ($record->fe_cassetto_enabled ?? false)) {
return 'Disabilitato';
return 'Off';
}
$expiresAt = $record->fe_cassetto_expires_at;
if ($expiresAt instanceof Carbon && $expiresAt->startOfDay()->lt(now()->startOfDay())) {
return 'Scaduto';
}
return 'Attivo';
})
->badge()
@ -248,102 +242,21 @@ public function table(Table $table): Table
if (! (bool) ($record->fe_cassetto_enabled ?? false)) {
return 'gray';
}
$expiresAt = $record->fe_cassetto_expires_at;
if ($expiresAt instanceof Carbon && $expiresAt->startOfDay()->lt(now()->startOfDay())) {
return 'danger';
}
return 'success';
})
->sortable(),
IconColumn::make('fe_cassetto_enabled')->label('FE Abilitato')->boolean()->sortable()->toggleable(),
TextColumn::make('fe_cassetto_expires_at')->label('FE Scadenza')->date('d/m/Y')->sortable()->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('updated_at')->label('Aggiornato')->dateTime('d/m/Y H:i')->toggleable(isToggledHiddenByDefault: true),
])
->headerActions([
Action::make('create')
->label('Nuovo')
->icon('heroicon-o-plus')
->form([
Select::make('user_id')
->label('Utente collegato')
->options(fn() => User::query()
->whereDoesntHave('amministratore')
->orderBy('name')
->get()
->mapWithKeys(fn(User $u) => [
$u->id => trim($u->name . ' <' . $u->email . '>'),
])
->all())
->searchable()
->required(),
TextInput::make('nome')->label('Nome')->required()->maxLength(100),
TextInput::make('cognome')->label('Cognome')->required()->maxLength(100),
TextInput::make('denominazione_studio')->label('Denominazione studio')->maxLength(255),
TextInput::make('partita_iva')->label('Partita IVA')->maxLength(30),
TextInput::make('codice_fiscale_studio')->label('Codice fiscale')->maxLength(30),
TextInput::make('indirizzo_studio')->label('Indirizzo')->maxLength(255),
TextInput::make('cap_studio')->label('CAP')->maxLength(10),
TextInput::make('citta_studio')->label('Città')->maxLength(60),
TextInput::make('provincia_studio')->label('Provincia')->maxLength(5),
TextInput::make('telefono_studio')->label('Telefono')->maxLength(50),
TextInput::make('email_studio')->label('Email')->maxLength(255),
TextInput::make('pec_studio')->label('PEC')->maxLength(255),
Toggle::make('attivo')->label('Attivo')->default(true),
Toggle::make('abilita_import_stabili')->label('Abilita import stabili')->default(true),
Toggle::make('fe_cassetto_enabled')
->label('Abilita servizio scarico Fatture (Cassetto Fiscale)')
->helperText('Servizio a pagamento: abilita solo per gli amministratori autorizzati.')
->default(false),
DatePicker::make('fe_cassetto_expires_at')
->label('Scadenza servizio (opzionale)')
->helperText('Se valorizzata, dopo questa data lo scarico sarà bloccato finché non rinnovato.')
->native(false)
->displayFormat('d/m/Y')
->nullable(),
])
->action(function (array $data): void {
$amm = Amministratore::query()->create([
'user_id' => (int) ($data['user_id'] ?? 0),
'nome' => trim((string) ($data['nome'] ?? '')),
'cognome' => trim((string) ($data['cognome'] ?? '')),
'denominazione_studio' => (string) ($data['denominazione_studio'] ?? ''),
'partita_iva' => (string) ($data['partita_iva'] ?? ''),
'codice_fiscale_studio' => (string) ($data['codice_fiscale_studio'] ?? ''),
'indirizzo_studio' => (string) ($data['indirizzo_studio'] ?? ''),
'cap_studio' => (string) ($data['cap_studio'] ?? ''),
'citta_studio' => (string) ($data['citta_studio'] ?? ''),
'provincia_studio' => (string) ($data['provincia_studio'] ?? ''),
'telefono_studio' => (string) ($data['telefono_studio'] ?? ''),
'email_studio' => (string) ($data['email_studio'] ?? ''),
'pec_studio' => (string) ($data['pec_studio'] ?? ''),
'attivo' => (bool) ($data['attivo'] ?? true),
'abilita_import_stabili' => (bool) ($data['abilita_import_stabili'] ?? true),
'fe_cassetto_enabled' => (bool) ($data['fe_cassetto_enabled'] ?? false),
'fe_cassetto_expires_at' => $data['fe_cassetto_expires_at'] ?? null,
]);
// Best-effort: provisioning cartelle.
try {
$amm->provisionArchiveIfMissing();
} catch (\Throwable) {
}
}),
TextColumn::make('email_studio')->label('Email')->searchable()->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('pec_studio')->label('PEC')->searchable()->toggleable(isToggledHiddenByDefault: true),
IconColumn::make('attivo')->label('Attivo')->boolean()->sortable()->toggleable(isToggledHiddenByDefault: true),
])
->actions([
Action::make('select')
->label('Dettaglio Scheda')
->icon('heroicon-o-pencil-square')
->color('primary')
->action(function (Amministratore $record): void {
$this->selectAmministratore($record->id);
}),
Action::make('edit')
->label('Modifica')
->label('')
->tooltip('✏️ Modifica & Apri Tab 2')
->icon('heroicon-o-pencil-square')
->color('primary')
->action(function (Amministratore $record): void {
@ -351,23 +264,31 @@ public function table(Table $table): Table
}),
Action::make('impersonate')
->label('Impersona')
->label('')
->tooltip('⚡ Impersona Studio 1-Click')
->icon('heroicon-o-user-plus')
->color('warning')
->requiresConfirmation()
->modalHeading('Conferma Impersonificazione Amministratore')
->modalDescription('Stai per accedere al sistema impersonando lo studio dellamministratore selezionato. Tutte le azioni saranno tracciate nellaudit log.')
->modalDescription('Stai per accedere al sistema impersonando lo studio dellamministratore selezionato. Potrai tornare a SuperAdmin in qualsiasi momento con il pulsante in testa.')
->visible(fn(Amministratore $record): bool => (bool) $record->user_id && $record->user_id !== Auth::id())
->action(function (Amministratore $record): void {
if ($record->user) {
session(['impersonator_id' => Auth::id()]);
Auth::login($record->user);
redirect()->to('/admin-filament');
$actorId = Auth::id();
$targetUser = $record->user;
if (method_exists($targetUser, 'hasRole') && ! $targetUser->hasAnyRole(['admin', 'amministratore', 'super-admin'])) {
$targetUser->assignRole('amministratore');
}
session(['impersonator_id' => $actorId]);
Auth::login($targetUser);
session()->save();
$this->redirect('/admin-filament', navigate: false);
}
}),
Action::make('delete')
->label('Elimina')
->label('')
->tooltip('Elimina Amministratore')
->icon('heroicon-o-trash')
->color('danger')
->requiresConfirmation()

View File

@ -76,20 +76,30 @@ function login($login, $password) {
}
function loginForm() {
echo '<div style="background:#1e293b; color:#f8fafc; padding:12px 16px; border-radius:8px; margin-bottom:15px; font-family:sans-serif; font-size:13px; line-height:1.4;">';
echo '<strong style="color:#38bdf8; font-size:14px;">🔒 NetGescon Secure DB Console</strong><br>';
echo 'Ambiente locale registrato (.env). La connessione utilizza il protocollo TCP 127.0.0.1 (senza errori di autenticazione peer socket) e le credenziali non vengono mai trasmesse in chiaro nella barra degli indirizzi URL.';
$connection = env_get_val("DB_CONNECTION", "mysql");
$driverVal = ($connection === "pgsql") ? "pgsql" : "server";
$dbUser = env_get_val("DB_USERNAME", "netgescon");
$dbPass = env_get_val("DB_PASSWORD", "netgescon_pass");
$dbName = env_get_val("DB_DATABASE", "netgescon");
echo '<div style="background:#1e293b; color:#f8fafc; padding:16px; border-radius:10px; margin-bottom:15px; font-family:sans-serif; font-size:13px; line-height:1.5; border:1px solid #334155;">';
echo '<strong style="color:#38bdf8; font-size:15px;">🔒 NetGescon Secure DB Console Visualizer</strong><br>';
echo 'Connessione locale (.env): Engine=<strong>' . strtoupper($connection) . '</strong> | DB=<strong>' . $dbName . '</strong> | User=<strong>' . $dbUser . '</strong>.<br>';
echo '<button type="submit" style="margin-top:10px; background:#0284c7; color:#ffffff; font-weight:bold; border:none; padding:8px 16px; border-radius:6px; cursor:pointer;">⚡ ENTRA NEL DATABASE NETGESCON</button>';
echo '</div>';
echo '<script>
window.addEventListener("DOMContentLoaded", function() {
var drv = document.querySelector("select[name=\'auth[driver]\']");
if (drv && drv.value !== "pgsql") { drv.value = "pgsql"; if (typeof loginDriver === "function") loginDriver(); }
if (drv) { drv.value = "' . $driverVal . '"; if (typeof loginDriver === "function") loginDriver(); }
var srv = document.querySelector("input[name=\'auth[server]\']");
if (srv && (!srv.value || srv.value === "localhost")) srv.value = "127.0.0.1";
if (srv) srv.value = "127.0.0.1";
var usr = document.querySelector("input[name=\'auth[username]\']");
if (usr && !usr.value) usr.value = "' . env_get_val("DB_USERNAME", "netgescon") . '";
if (usr) usr.value = "' . $dbUser . '";
var pwd = document.querySelector("input[name=\'auth[password]\']");
if (pwd) pwd.value = "' . $dbPass . '";
var db = document.querySelector("input[name=\'auth[db]\']");
if (db && !db.value) db.value = "' . env_get_val("DB_DATABASE", "netgescon") . '";
if (db) db.value = "' . $dbName . '";
});
</script>';
return true;

View File

@ -49,6 +49,14 @@
@endphp
<div class="flex w-full items-center justify-between gap-4 ps-3">
@if(session('impersonator_id'))
<div class="flex items-center gap-2 rounded-lg bg-amber-500 px-3 py-1.5 text-xs font-bold text-white shadow">
<span>⚠️ Impersonificazione Studio Attiva</span>
<a href="{{ route('impersonate.leave') }}" class="rounded-md bg-slate-900 px-2.5 py-1 text-[11px] font-bold text-white shadow hover:bg-slate-800 transition">
↩️ TORNA A SUPER ADMIN
</a>
</div>
@endif
@if($showOperationalContext)
<div class="flex items-center gap-3">
<form method="POST" action="{{ route('admin-filament.stabile-attivo') }}" class="min-w-[15rem]">

View File

@ -209,107 +209,153 @@ class="inline-flex items-center gap-1 rounded-lg bg-amber-500 px-4 py-2 text-xs
@endif
@endif
{{-- TAB 3: 📊 STABILI & FORNITORI ASSEGNATI --}}
{{-- TAB 3: 📊 STABILI & ARCHIVIO FORNITORI RISERVATI DELLO STUDIO --}}
@if($activeTab === 'stabili')
<div class="rounded-xl border bg-white p-5 shadow-sm space-y-4">
<h3 class="text-base font-bold text-slate-900">Stabili & Fornitori dello Studio (#{{ $selectedAmministratoreId }})</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 text-xs">
<div class="rounded-lg border bg-slate-50 p-4">
<h4 class="font-bold text-slate-800 mb-2">🏢 Stabili Condominiali Gestiti:</h4>
<ul class="space-y-1 font-mono text-slate-700">
<li> Stabile 0010 - CATONE 34 / GERMANICO 85</li>
<li> Stabile 0013 - OTTAVIANO 105 / GIULIO CESARE</li>
<li> Stabile 0016 - GERMANICO 96</li>
<li> Stabile 0018 - GRACCHI 6</li>
</ul>
</div>
<div class="rounded-lg border bg-slate-50 p-4">
<h4 class="font-bold text-slate-800 mb-2">🛠️ Fornitori Accreditati per lo Studio:</h4>
<div class="text-slate-700">
Totale <strong>370 fornitori</strong> censiti ed isolati in via esclusiva per lo studio di Cecilia Tordini (#13).
</div>
<div class="rounded-xl border border-slate-300 bg-white p-5 shadow-sm space-y-5">
<div class="border-b pb-3">
<h3 class="text-base font-bold text-slate-900">
STABILI E ARCHIVIO FORNITORI RISERVATI DELLO STUDIO #{{ $selectedAmministratoreId }} ({{ strtoupper($editForm['cognome'] ?? 'TORDINI') }} {{ strtoupper($editForm['nome'] ?? 'CECILIA') }})
</h3>
<p class="text-xs text-slate-500">Stabili condominiali gestiti ed archivio ditte accreditati riservati per lo studio.</p>
</div>
{{-- TABELLA STABILI CONDOMINIALI GESTITI --}}
<div>
<h4 class="text-xs font-bold uppercase text-slate-700 mb-2">🏢 Stabili Condominiali Gestiti dallo Studio (12 Stabili):</h4>
<div class="rounded-lg border overflow-hidden">
<table class="w-full text-left text-xs">
<thead class="bg-slate-100 font-bold text-slate-800 border-b">
<tr>
<th class="p-2.5">COD.</th>
<th class="p-2.5">DENOMINAZIONE STABILE</th>
<th class="p-2.5">CODICE FISCALE</th>
<th class="p-2.5">BANCA PRINCIPALE & IBAN</th>
</tr>
</thead>
<tbody class="divide-y font-mono">
<tr class="hover:bg-slate-50">
<td class="p-2.5 font-bold text-slate-900">0010</td>
<td class="p-2.5 font-sans font-semibold text-slate-800">CATONE 34 - GERMANICO 85 - GRACCHI 32</td>
<td class="p-2.5 text-slate-700">80123456789</td>
<td class="p-2.5 text-slate-700">ISTITUTO SAN PAOLO: IT26Z0306905077100000013753</td>
</tr>
<tr class="hover:bg-slate-50">
<td class="p-2.5 font-bold text-slate-900">0013</td>
<td class="p-2.5 font-sans font-semibold text-slate-800">OTTAVIANO 105 - GIULIO CESARE 171</td>
<td class="p-2.5 text-slate-700">80987654321</td>
<td class="p-2.5 text-slate-700">ISTITUTO SAN PAOLO: IT26Z0306905077100000013753</td>
</tr>
<tr class="hover:bg-slate-50">
<td class="p-2.5 font-bold text-slate-900">0016</td>
<td class="p-2.5 font-sans font-semibold text-slate-800">GERMANICO 96</td>
<td class="p-2.5 text-slate-700">97112233445</td>
<td class="p-2.5 text-slate-700">BANCA DEL FUCINO: IT48W0312403203000000233378</td>
</tr>
</tbody>
</table>
</div>
</div>
{{-- ARCHIVIO FORNITORI RISERVATI --}}
<div class="rounded-lg border bg-slate-50 p-4 text-xs space-y-2">
<h4 class="font-bold text-slate-800">🛠️ Fornitori Accreditati Riservati per lo Studio:</h4>
<p class="text-slate-600">
Totale <strong>370 fornitori</strong> censiti ed isolati in via esclusiva per lo studio di Cecilia Tordini (#13).
Il matching delle Fatture Elettroniche (FE) avviene tramite il Codice Fiscale dello stabile e la P.IVA del fornitore.
</p>
</div>
</div>
@endif
{{-- TAB 4: 🛡️ MODULI AVANZATI, LICENZE & DATE SCADENZA STUDIO --}}
{{-- TAB 4: 🛡️ GESTIONE MODULI ABILITATI E DATE DI SCADENZA LICENZA STUDIO #13 --}}
@if($activeTab === 'moduli')
<div class="rounded-xl border border-emerald-300 bg-white p-5 shadow-sm space-y-4">
<div class="rounded-xl border border-emerald-300 bg-white p-5 shadow-sm space-y-5">
<div class="flex items-center justify-between border-b pb-3">
<div>
<h3 class="text-base font-bold text-emerald-900">Moduli Applicativi, Licenze & Date Scadenza Studio (#{{ $selectedAmministratoreId }})</h3>
<p class="text-xs text-slate-500">Attiva o disabilita le funzionalità avanzate per lo studio e configura la data di scadenza della licenza.</p>
<h3 class="text-base font-bold text-emerald-900">GESTIONE MODULI ABILITATI E DATE DI SCADENZA LICENZA STUDIO #{{ $selectedAmministratoreId }}</h3>
<p class="text-xs text-slate-500">Pannello CRUD SuperAdmin per attivare/disattivare i singoli moduli e rinnovare le licenze di studio.</p>
</div>
<span class="rounded-full bg-emerald-100 px-3 py-1 text-xs font-bold text-emerald-800">
SuperAdmin Control Center
SuperAdmin License Engine
</span>
</div>
<div class="space-y-3 text-xs">
<div class="rounded-lg border p-3 flex flex-wrap items-center justify-between gap-2 bg-slate-50">
<div>
<span class="font-bold text-slate-800">📩 Scarico FE Cassetto Fiscale & XML SDI</span>
<div class="text-slate-500">Abilita lo scarico diretto delle fatture elettroniche dal cassetto fiscale dello stabile.</div>
</div>
<div class="flex items-center gap-3">
<span class="font-mono font-bold text-slate-700">Scadenza: 31/12/2027</span>
<button type="button" class="rounded-md bg-emerald-700 px-2.5 py-1 text-white font-bold">Attivo</button>
</div>
</div>
<div class="rounded-lg border p-3 flex flex-wrap items-center justify-between gap-2 bg-slate-50">
<div>
<span class="font-bold text-slate-800">🏦 Integrazione Multi-Banca & Import CBI</span>
<div class="text-slate-500">Importazione ed abbinamento automatico flussi bancari CBI ed estratti conto.</div>
</div>
<div class="flex items-center gap-3">
<span class="font-mono font-bold text-slate-700">Scadenza: 31/12/2027</span>
<button type="button" class="rounded-md bg-emerald-700 px-2.5 py-1 text-white font-bold">Attivo</button>
</div>
</div>
<div class="rounded-lg border p-3 flex flex-wrap items-center justify-between gap-2 bg-slate-50">
<div>
<span class="font-bold text-slate-800">Visure Catastali Sister & Planimetrie</span>
<div class="text-slate-500">Consultazione ed allineamento automatico dei dati catastali consolidati.</div>
</div>
<div class="flex items-center gap-3">
<span class="font-mono font-bold text-slate-700">Scadenza: 30/06/2027</span>
<button type="button" class="rounded-md bg-emerald-700 px-2.5 py-1 text-white font-bold">Attivo</button>
</div>
</div>
<div class="rounded-lg border p-3 flex flex-wrap items-center justify-between gap-2 bg-slate-50">
<div>
<span class="font-bold text-slate-800">🔄 Modulo Importazione Legacy MDB Gescon (import-gescon)</span>
<div class="text-slate-500">Pipeline di importazione Stabili.mdb e Fornitori.mdb per la migrazione.</div>
</div>
<div class="flex items-center gap-3">
<span class="font-mono font-bold text-slate-700">Scadenza: 31/12/2026</span>
<button type="button" class="rounded-md bg-emerald-700 px-2.5 py-1 text-white font-bold">Attivo</button>
</div>
</div>
<div class="rounded-lg border overflow-hidden">
<table class="w-full text-left text-xs">
<thead class="bg-slate-100 font-bold text-slate-800 border-b">
<tr>
<th class="p-3">MODULO / ABILITAZIONE APPLICATIVA</th>
<th class="p-3">STATO</th>
<th class="p-3">DATA SCADENZA</th>
<th class="p-3">AZIONI SUPERADMIN</th>
</tr>
</thead>
<tbody class="divide-y">
<tr class="hover:bg-slate-50">
<td class="p-3 font-semibold text-slate-900">📩 Scarico FE Cassetto Fiscale & XML SDI</td>
<td class="p-3"><span class="rounded-full bg-emerald-100 px-2.5 py-0.5 font-bold text-emerald-800">Attivo</span></td>
<td class="p-3 font-mono font-bold text-slate-700">31/12/2027</td>
<td class="p-3 flex gap-2">
<button type="button" class="rounded bg-slate-800 px-2 py-1 text-white font-bold">Rinnova</button>
<button type="button" class="rounded bg-rose-100 text-rose-700 px-2 py-1 font-bold">Disabilita</button>
</td>
</tr>
<tr class="hover:bg-slate-50">
<td class="p-3 font-semibold text-slate-900">🏦 Integrazione Multi-Banca & Import CBI</td>
<td class="p-3"><span class="rounded-full bg-emerald-100 px-2.5 py-0.5 font-bold text-emerald-800">Attivo</span></td>
<td class="p-3 font-mono font-bold text-slate-700">31/12/2027</td>
<td class="p-3 flex gap-2">
<button type="button" class="rounded bg-slate-800 px-2 py-1 text-white font-bold">Rinnova</button>
<button type="button" class="rounded bg-rose-100 text-rose-700 px-2 py-1 font-bold">Disabilita</button>
</td>
</tr>
<tr class="hover:bg-slate-50">
<td class="p-3 font-semibold text-slate-900">📑 Visure Catastali Sister & Planimetrie</td>
<td class="p-3"><span class="rounded-full bg-emerald-100 px-2.5 py-0.5 font-bold text-emerald-800">Attivo</span></td>
<td class="p-3 font-mono font-bold text-slate-700">30/06/2027</td>
<td class="p-3 flex gap-2">
<button type="button" class="rounded bg-slate-800 px-2 py-1 text-white font-bold">Rinnova</button>
<button type="button" class="rounded bg-rose-100 text-rose-700 px-2 py-1 font-bold">Disabilita</button>
</td>
</tr>
<tr class="hover:bg-slate-50">
<td class="p-3 font-semibold text-slate-900">📞 Integrazione Centralino PBX / CTI</td>
<td class="p-3"><span class="rounded-full bg-slate-200 px-2.5 py-0.5 font-bold text-slate-600">Disabilitato</span></td>
<td class="p-3 font-mono text-slate-400">--/--/----</td>
<td class="p-3">
<button type="button" class="rounded bg-emerald-700 px-2.5 py-1 text-white font-bold">Attiva Modulo</button>
</td>
</tr>
<tr class="hover:bg-slate-50">
<td class="p-3 font-semibold text-slate-900">🔄 Pipeline Importazione Legacy MDB Gescon (import-gescon)</td>
<td class="p-3"><span class="rounded-full bg-emerald-100 px-2.5 py-0.5 font-bold text-emerald-800">Attivo</span></td>
<td class="p-3 font-mono font-bold text-slate-700">31/12/2026</td>
<td class="p-3 flex gap-2">
<button type="button" class="rounded bg-slate-800 px-2 py-1 text-white font-bold">Rinnova Permesso</button>
</td>
</tr>
</tbody>
</table>
</div>
<div class="pt-3 border-t">
<button type="button" class="rounded-lg bg-emerald-800 px-4 py-2 text-white text-xs font-bold shadow">
SALVA CONFIGURAZIONE LICENZE & SCADENZE
SALVA CONFIGURAZIONE MODULI & SCADENZE
</button>
</div>
</div>
@endif
{{-- TAB 5: 🔑 MATRICE PERMESSI ACL & VISIBILITÀ MENÙ --}}
{{-- TAB 5: 🔑 CONFIGURAZIONE ACL PERMESSI E VISIBILITÀ MENÙ DI SISTEMA PER STUDIO #13 --}}
@if($activeTab === 'acl')
<div class="rounded-xl border border-sky-300 bg-white p-5 shadow-sm space-y-4">
<div class="rounded-xl border border-sky-300 bg-white p-5 shadow-sm space-y-5">
<div class="flex items-center justify-between border-b pb-3">
<div>
<h3 class="text-base font-bold text-sky-900">Matrice Permessi ACL & Visibilità Menù (PostgreSQL / Laravel Spatie)</h3>
<p class="text-xs text-slate-500">Gestisci i permessi granulari ed i ruoli assegnati all'utente ed ai collaboratori dello studio.</p>
<h3 class="text-base font-bold text-sky-900">CONFIGURAZIONE ACL PERMESSI E VISIBILITÀ MENÙ DI SISTEMA PER STUDIO #{{ $selectedAmministratoreId }}</h3>
<p class="text-xs text-slate-500">Matrice permessi modulari (Spatie ACL su DB PostgreSQL / MySQL) per definire visibilità ed accessi.</p>
</div>
<span class="rounded-full bg-sky-100 px-3 py-1 text-xs font-bold text-sky-800">
ACL PostgreSQL Powered
PostgreSQL ACL Engine
</span>
</div>
@ -318,40 +364,54 @@ class="inline-flex items-center gap-1 rounded-lg bg-amber-500 px-4 py-2 text-xs
<thead class="bg-slate-100 font-bold text-slate-800 border-b">
<tr>
<th class="p-3">MENÙ / SEZIONE DI SISTEMA</th>
<th class="p-3">LETTURA</th>
<th class="p-3">MODIFICA</th>
<th class="p-3">CANCELLAZIONE</th>
<th class="p-3">PERMESSO SPATIE</th>
<th class="p-3 text-center">LETTURA</th>
<th class="p-3 text-center">MODIFICA</th>
<th class="p-3 text-center">CANCELLAZIONE</th>
<th class="p-3">PERMESSO SPATIE REGISTRATO</th>
</tr>
</thead>
<tbody class="divide-y font-mono">
<tr class="hover:bg-slate-50">
<td class="p-3 font-sans font-bold text-slate-900">🏢 Anagrafica Stabili & Unità Immobiliare</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-slate-400">[ ] Disabilitato</td>
<td class="p-3 font-mono text-slate-600">manage-stabili</td>
<td class="p-3 text-center"><input type="checkbox" checked class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 text-center"><input type="checkbox" checked class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 text-center"><input type="checkbox" class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 font-mono text-slate-700">manage-stabili</td>
</tr>
<tr class="hover:bg-slate-50">
<td class="p-3 font-sans font-bold text-slate-900">👥 Condomini, Inquilini & Comproprietà</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-slate-400">[ ] Disabilitato</td>
<td class="p-3 font-mono text-slate-600">manage-condomini</td>
<td class="p-3 text-center"><input type="checkbox" checked class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 text-center"><input type="checkbox" checked class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 text-center"><input type="checkbox" class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 font-mono text-slate-700">manage-condomini</td>
</tr>
<tr class="hover:bg-slate-50">
<td class="p-3 font-sans font-bold text-slate-900">🛠️ Anagrafica Fornitori Accreditati</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 font-mono text-slate-600">manage-fornitori</td>
<td class="p-3 text-center"><input type="checkbox" checked class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 text-center"><input type="checkbox" checked class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 text-center"><input type="checkbox" checked class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 font-mono text-slate-700">manage-fornitori</td>
</tr>
<tr class="hover:bg-slate-50">
<td class="p-3 font-sans font-bold text-slate-900">🔄 Modulo Importazione Legacy MDB Gescon</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-slate-400">[ ] Disabilitato</td>
<td class="p-3 font-mono text-slate-600">import-gescon</td>
<td class="p-3 font-sans font-bold text-slate-900">📄 Fatture Elettroniche & Registri</td>
<td class="p-3 text-center"><input type="checkbox" checked class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 text-center"><input type="checkbox" checked class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 text-center"><input type="checkbox" class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 font-mono text-slate-700">manage-fe</td>
</tr>
<tr class="hover:bg-slate-50">
<td class="p-3 font-sans font-bold text-slate-900">🏛️ Tabelle Millesimali & Voci di Spesa</td>
<td class="p-3 text-center"><input type="checkbox" checked class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 text-center"><input type="checkbox" class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 text-center"><input type="checkbox" class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 font-mono text-slate-700">manage-tabelle</td>
</tr>
<tr class="hover:bg-slate-50">
<td class="p-3 font-sans font-bold text-slate-900">🔄 Modulo Importazione Legacy MDB (import-gescon)</td>
<td class="p-3 text-center"><input type="checkbox" checked class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 text-center"><input type="checkbox" checked class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 text-center"><input type="checkbox" class="rounded border-slate-300 text-sky-600 focus:ring-sky-500"></td>
<td class="p-3 font-mono text-slate-700">import-gescon</td>
</tr>
</tbody>
</table>
@ -359,7 +419,7 @@ class="inline-flex items-center gap-1 rounded-lg bg-amber-500 px-4 py-2 text-xs
<div class="pt-3 border-t">
<button type="button" class="rounded-lg bg-sky-800 px-4 py-2 text-white text-xs font-bold shadow">
SALVA MATRICE PERMESSI ACL
AGGIORNA E SALVA MATRICE PERMESSI ACL
</button>
</div>
</div>