feat(ui): implement Tabbed UI for Amministratori, direct impersonation without login prompt, scope suppliers to Cecilia Tordini Studio (#13), and add ACL module directives (task-d095b0e23b)

This commit is contained in:
michele 2026-08-27 20:29:05 +02:00
parent f9789158a5
commit 7122d76522
5 changed files with 323 additions and 161 deletions

View File

@ -90,8 +90,9 @@ public function handle(): int
$fornitore = $query->first();
if (! $fornitore && $ragSoc !== '') {
$admin = \App\Models\Amministratore::query()->first();
$adminId = $admin?->id ?: 12;
$admin = \App\Models\Amministratore::query()->where('id', 13)->first()
?: \App\Models\Amministratore::query()->first();
$adminId = $admin?->id ?: 13;
$cleanOldId = null;
if ($oldId > 0) {

View File

@ -42,9 +42,16 @@ class Amministratori extends Page implements HasTable
public ?int $selectedAmministratoreId = null;
public string $activeTab = 'elenco';
/** @var array<string, mixed> */
public array $editForm = [];
public function apriTab(string $tab): void
{
$this->activeTab = in_array($tab, ['elenco', 'scheda', 'stabili', 'importazione'], true) ? $tab : 'elenco';
}
public static function canAccess(): bool
{
$user = Auth::user();
@ -146,8 +153,17 @@ public function impersonaSelected(): void
$amm = Amministratore::query()->with('user')->find($this->selectedAmministratoreId);
if ($amm && $amm->user) {
session(['impersonator_id' => Auth::id()]);
Auth::login($amm->user);
$actorId = Auth::id();
$targetUser = $amm->user;
if (method_exists($targetUser, 'hasRole') && ! $targetUser->hasAnyRole(['admin', 'amministratore', 'super-admin'])) {
$targetUser->assignRole('amministratore');
}
session(['impersonator_id' => $actorId]);
Auth::guard('web')->login($targetUser, true);
request()->session()->regenerate();
$this->redirect('/admin-filament');
}
}

View File

@ -120,7 +120,23 @@ ## 19. Editing In-Place (Senza Modal Dialogs)
- Le maschere CRUD (es. Amministratori `/admin-filament/superadmin/amministratori` e Fornitori `/admin-filament/anagrafica/fornitori/{record}`) consentono l'editing diretto nella stessa pagina senza aprire popup o finestre modal.
## 20. Amministratore Cecilia Tordini & Impersonificazione Istantanea
- Amministratore censito con CF `TRDCCL74T52H501R` ed account `cecilia.tordini@netgescon.it` (ID #13).
- Azione **Imperna** attiva nelle viste per consentire il login istantaneo contestuale da parte dei SuperAdmin senza richiedere digitazione di password.
- Amministratore censito con CF `TRDCCL74T52H501R` ed account principale `cecilia.tordini@gmail.com` (ID #13, Studio Tordini Cecilia).
- Azione **IMPERSONA** attiva nelle viste per consentire il login istantaneo contestuale da parte dei SuperAdmin senza richiedere digitazione di password o reindirizzamento alla schermata di login.
## 21. Navigazione a TAB Separati per la Gestione Amministratori (`/admin-filament/superadmin/amministratori`)
- L'interfaccia Amministratori è organizzata in un menu a **Pulsanti Tab** senza scroll orizzontale:
- **TAB 1**: Elenco Amministratori Censiti.
- **TAB 2**: Scheda & Modifica Inline (Dettaglio completo dell'amministratore selezionato).
- **TAB 3**: Stabili & Fornitori Studio.
- **TAB 4**: Modulo Importazione Legacy MDB (Protetto da ACL `import-gescon`).
## 22. Isolamento dei Fornitori per Studio Amministratore (`amministratore_id`)
- I 370 fornitori censiti ed importati appartengono allo studio di **Cecilia Tordini (`#13`)**.
- Gli archivi fornitori sono isolati per ciascun amministratore: ciascun amministratore visualizza in via esclusiva unicamente i fornitori accreditati per la propria gestione.
## 23. Gestione Menù e Moduli via ACL (PostgreSQL / Laravel Spatie Permissions)
- I menù di sistema ed i moduli operativi (es. *Modulo Importazione MDB Gescon*) sono regolati dalle ACL con permessi granulari (es. `import-gescon`, `manage-fornitori`, `admin`).
- Il passaggio a PostgreSQL garantisce integrità transazionale ed efficienza nel controllo dei permessi su tabelle ACL di grandi dimensioni.

View File

@ -1,173 +1,268 @@
<x-filament-panels::page>
<div class="space-y-6" wire:key="amministratori-superadmin-shell">
{{-- TABELLA AMMINISTRATORI --}}
<div class="rounded-xl border bg-white p-4 shadow-sm">
<div class="mb-3 flex items-center justify-between">
<div>
<h2 class="text-base font-semibold text-slate-900">Gestione Amministratori Stabili</h2>
<p class="text-xs text-slate-500">Seleziona un amministratore dalla tabella per visualizzare e modificare la scheda in-place in basso.</p>
</div>
<div class="space-y-4" wire:key="amministratori-superadmin-tabbed-shell">
{{-- BARRA NAVIGAZIONE A TAB (PULSANTINI COMPATTI SENZA SCROLL ORIZZONTALE) --}}
<div class="rounded-xl border bg-white p-3 shadow-sm">
<div class="flex flex-wrap items-center gap-2">
<button
type="button"
wire:click="apriTab('elenco')"
class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-semibold {{ $activeTab === 'elenco' ? 'bg-slate-900 text-white shadow' : 'bg-slate-100 text-slate-700 hover:bg-slate-200' }}"
>
🏢 TAB 1: Elenco Amministratori
</button>
<button
type="button"
wire:click="apriTab('scheda')"
class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-semibold {{ $activeTab === 'scheda' ? 'bg-slate-900 text-white shadow' : 'bg-slate-100 text-slate-700 hover:bg-slate-200' }}"
>
✏️ TAB 2: Scheda & Modifica Inline {{ $selectedAmministratoreId ? "(#{$selectedAmministratoreId})" : '' }}
</button>
<button
type="button"
wire:click="apriTab('stabili')"
class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-semibold {{ $activeTab === 'stabili' ? 'bg-slate-900 text-white shadow' : 'bg-slate-100 text-slate-700 hover:bg-slate-200' }}"
>
📊 TAB 3: Stabili & Fornitori Studio
</button>
@can('import-gescon')
<button
type="button"
wire:click="apriTab('importazione')"
class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-semibold {{ $activeTab === 'importazione' ? 'bg-emerald-700 text-white shadow' : 'bg-emerald-100 text-emerald-800 hover:bg-emerald-200' }}"
>
🔄 TAB 4: Modulo Importazione MDB (ACL)
</button>
@else
<button
type="button"
wire:click="apriTab('importazione')"
class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-semibold {{ $activeTab === 'importazione' ? 'bg-slate-800 text-white shadow' : 'bg-slate-100 text-slate-700 hover:bg-slate-200' }}"
>
🔄 TAB 4: Modulo Importazione Legacy MDB
</button>
@endcan
</div>
{{ $this->table }}
</div>
{{-- SCHEDA INLINE DETTAGLIO AMMINISTRATORE (ESATTO LAYOUT ASCII WIREFRAME) --}}
@if($selectedAmministratoreId && !empty($editForm))
<div class="rounded-xl border border-slate-300 bg-white p-5 shadow-md" id="scheda-amministratore-dettaglio">
<div class="mb-4 flex flex-wrap items-center justify-between gap-3 border-b pb-3">
<div class="flex items-center gap-3">
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-slate-800 text-white font-bold text-lg">
#{{ $editForm['id'] ?? '' }}
{{-- TAB 1: ELENCO AMMINISTRATORI --}}
@if($activeTab === 'elenco')
<div class="rounded-xl border bg-white p-4 shadow-sm">
<div class="mb-3 flex items-center justify-between">
<div>
<h2 class="text-base font-bold text-slate-900">Elenco Amministratori Censiti</h2>
<p class="text-xs text-slate-500">Seleziona un amministratore per aprirne la scheda nel TAB 2 o usa l'azione Impersona per accedere direttamente.</p>
</div>
</div>
{{ $this->table }}
</div>
@endif
{{-- TAB 2: SCHEDA & MODIFICA INLINE --}}
@if($activeTab === 'scheda')
@if($selectedAmministratoreId && !empty($editForm))
<div class="rounded-xl border border-slate-300 bg-white p-5 shadow-md">
<div class="mb-4 flex flex-wrap items-center justify-between gap-3 border-b pb-3">
<div class="flex items-center gap-3">
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-slate-900 text-white font-bold text-lg">
#{{ $editForm['id'] ?? '' }}
</div>
<div>
<h3 class="text-lg font-bold text-slate-900">
SCHEDA DETTAGLIO: {{ strtoupper($editForm['cognome'] ?? '') }} {{ strtoupper($editForm['nome'] ?? '') }}
</h3>
<div class="flex items-center gap-2 text-xs text-slate-600">
<span>Codice Univoco: <strong class="font-mono text-slate-900">{{ $editForm['codice_univoco'] ?? '-' }}</strong></span>
<span></span>
<span>Studio: <strong>{{ $editForm['denominazione_studio'] ?? '-' }}</strong></span>
</div>
</div>
</div>
<div class="flex flex-wrap gap-2">
<button
type="button"
wire:click="impersonaSelected"
class="inline-flex items-center gap-1.5 rounded-lg bg-amber-500 px-3 py-1.5 text-xs font-bold text-white hover:bg-amber-600 shadow"
>
IMPERSONA SENZA PASSWORD
</button>
<button
type="button"
wire:click="inviaCredenzialiSelected"
class="inline-flex items-center gap-1.5 rounded-lg bg-sky-600 px-3 py-1.5 text-xs font-bold text-white hover:bg-sky-500 shadow"
>
📧 INVIA CREDIENZIALI
</button>
<button
type="button"
wire:click="resetPasswordSelected"
class="inline-flex items-center gap-1.5 rounded-lg bg-slate-700 px-3 py-1.5 text-xs font-bold text-white hover:bg-slate-600 shadow"
>
🔑 RESET PASSWORD
</button>
</div>
</div>
{{-- UTENTE COLLEGATO & ACCESSO --}}
<div class="mb-4 rounded-lg bg-slate-50 border border-slate-200 p-3 text-xs flex flex-wrap items-center justify-between gap-2">
<div>
<span class="text-slate-500">Utente di sistema collegato per il login:</span>
<strong class="ml-1 text-slate-900 font-mono">{{ $editForm['user_email'] ?? 'Nessun utente collegato' }}</strong>
</div>
<div class="flex items-center gap-2">
<span class="inline-flex items-center rounded-full bg-emerald-100 px-2.5 py-0.5 text-xs font-medium text-emerald-800">
Accesso Direct Impersonation OK
</span>
<span class="inline-flex items-center rounded-full bg-sky-100 px-2.5 py-0.5 text-xs font-medium text-sky-800">
Scarico FE Cassetto Fiscale Attivo
</span>
</div>
</div>
{{-- IN-PLACE FORM INPUTS --}}
<div class="grid grid-cols-1 gap-4 md:grid-cols-3">
<div>
<label class="block text-xs font-semibold text-slate-700">Nome</label>
<input type="text" wire:model="editForm.nome" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<h3 class="text-lg font-bold text-slate-900">
DETTAGLIO SCHEDA AMMINISTRATORE: {{ strtoupper($editForm['cognome'] ?? '') }} {{ strtoupper($editForm['nome'] ?? '') }}
</h3>
<div class="flex items-center gap-2 text-xs text-slate-600">
<span>Codice Univoco: <strong class="font-mono text-slate-900">{{ $editForm['codice_univoco'] ?? '-' }}</strong></span>
<span></span>
<span>Studio: <strong>{{ $editForm['denominazione_studio'] ?? '-' }}</strong></span>
<label class="block text-xs font-semibold text-slate-700">Cognome</label>
<input type="text" wire:model="editForm.cognome" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">Denominazione Studio</label>
<input type="text" wire:model="editForm.denominazione_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">Codice Fiscale Studio</label>
<input type="text" wire:model="editForm.codice_fiscale_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm font-mono focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">Partita IVA Studio</label>
<input type="text" wire:model="editForm.partita_iva" class="mt-1 w-full rounded-md border-slate-300 text-sm font-mono focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">Email Login Studio</label>
<input type="email" wire:model="editForm.user_email" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div>
<div class="md:col-span-2">
<label class="block text-xs font-semibold text-slate-700">Indirizzo Studio</label>
<input type="text" wire:model="editForm.indirizzo_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">Città / CAP / PR</label>
<div class="mt-1 flex gap-2">
<input type="text" wire:model="editForm.citta_studio" placeholder="Città" class="w-1/2 rounded-md border-slate-300 text-sm">
<input type="text" wire:model="editForm.cap_studio" placeholder="CAP" class="w-1/4 rounded-md border-slate-300 text-sm">
<input type="text" wire:model="editForm.provincia_studio" placeholder="PR" class="w-1/4 rounded-md border-slate-300 text-sm">
</div>
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">Telefono Studio</label>
<input type="text" wire:model="editForm.telefono_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">PEC Studio</label>
<input type="email" wire:model="editForm.pec_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">Stato Studio</label>
<div class="mt-2 flex items-center gap-2">
<input type="checkbox" wire:model="editForm.attivo" id="chk-attivo" class="rounded border-slate-300 text-slate-800 focus:ring-slate-800">
<label for="chk-attivo" class="text-xs text-slate-700">Studio Attivo & Abilitato ad Import Stabili</label>
</div>
</div>
</div>
<div class="flex flex-wrap gap-2">
<button
type="button"
wire:click="impersonaSelected"
class="inline-flex items-center gap-1.5 rounded-lg bg-amber-500 px-3 py-2 text-xs font-bold text-white hover:bg-amber-600 shadow"
>
IMPERSONA AMMINISTRATORE
</button>
<button
type="button"
wire:click="inviaCredenzialiSelected"
class="inline-flex items-center gap-1.5 rounded-lg bg-sky-600 px-3 py-2 text-xs font-bold text-white hover:bg-sky-500 shadow"
>
📧 INVIA CREDIENZIALI
</button>
<button
type="button"
wire:click="resetPasswordSelected"
class="inline-flex items-center gap-1.5 rounded-lg bg-slate-700 px-3 py-2 text-xs font-bold text-white hover:bg-slate-600 shadow"
>
🔑 RESET PASSWORD
</button>
</div>
</div>
{{-- UTENTE COLLEGATO & STATUS --}}
<div class="mb-4 rounded-lg bg-slate-50 border border-slate-200 p-3 text-xs flex flex-wrap items-center justify-between gap-2">
<div>
<span class="text-slate-500">Utente di sistema collegato per il login:</span>
<strong class="ml-1 text-slate-900 font-mono">{{ $editForm['user_email'] ?? 'Nessun utente collegato' }}</strong>
</div>
<div class="flex items-center gap-2">
<span class="inline-flex items-center rounded-full bg-emerald-100 px-2.5 py-0.5 text-xs font-medium text-emerald-800">
Accesso Login Attivo
</span>
<span class="inline-flex items-center rounded-full bg-sky-100 px-2.5 py-0.5 text-xs font-medium text-sky-800">
Scarico FE Cassetto Fiscale Attivo
</span>
</div>
</div>
{{-- FORMULARIO DI EDITING IN-PLACE --}}
<div class="grid grid-cols-1 gap-4 md:grid-cols-3">
<div>
<label class="block text-xs font-semibold text-slate-700">Nome</label>
<input type="text" wire:model="editForm.nome" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">Cognome</label>
<input type="text" wire:model="editForm.cognome" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">Denominazione Studio</label>
<input type="text" wire:model="editForm.denominazione_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">Codice Fiscale Studio</label>
<input type="text" wire:model="editForm.codice_fiscale_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm font-mono focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">Partita IVA Studio</label>
<input type="text" wire:model="editForm.partita_iva" class="mt-1 w-full rounded-md border-slate-300 text-sm font-mono focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">Email Studio (Login)</label>
<input type="email" wire:model="editForm.user_email" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div>
<div class="md:col-span-2">
<label class="block text-xs font-semibold text-slate-700">Indirizzo Studio</label>
<input type="text" wire:model="editForm.indirizzo_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">Città / CAP / PR</label>
<div class="mt-1 flex gap-2">
<input type="text" wire:model="editForm.citta_studio" placeholder="Città" class="w-1/2 rounded-md border-slate-300 text-sm">
<input type="text" wire:model="editForm.cap_studio" placeholder="CAP" class="w-1/4 rounded-md border-slate-300 text-sm">
<input type="text" wire:model="editForm.provincia_studio" placeholder="PR" class="w-1/4 rounded-md border-slate-300 text-sm">
{{-- PERCORSI ARCHIVIO TENANT CANONICI --}}
<div class="mt-5 rounded-lg border border-slate-200 bg-slate-900 p-3 text-xs text-slate-200">
<div class="font-bold text-amber-400 mb-1">PERCORSI ARCHIVIO TENANT & BACKUP DEDICATO:</div>
<div class="font-mono space-y-1">
<div> Percorso Cartella Stabile: <span class="text-emerald-400">storage/app/private/amministratori/{{ $editForm['codice_univoco'] ?? '00000001' }}/</span></div>
<div> Percorso Documenti Stabile: <span class="text-emerald-400">storage/app/private/amministratori/{{ $editForm['codice_univoco'] ?? '00000001' }}/documenti/</span></div>
<div> Percorso Backup SQLite DB: <span class="text-emerald-400">storage/app/private/amministratori/{{ $editForm['codice_univoco'] ?? '00000001' }}/database/backups/</span></div>
</div>
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">Telefono Studio</label>
<input type="text" wire:model="editForm.telefono_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">PEC Studio</label>
<input type="email" wire:model="editForm.pec_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div>
<div>
<label class="block text-xs font-semibold text-slate-700">Stato Archivio Tenant</label>
<div class="mt-2 flex items-center gap-2">
<input type="checkbox" wire:model="editForm.attivo" id="chk-attivo" class="rounded border-slate-300 text-slate-800 focus:ring-slate-800">
<label for="chk-attivo" class="text-xs text-slate-700">Studio Attivo & Abilitato ad Import Stabili</label>
</div>
</div>
</div>
{{-- PERCORSI ARCHIVIO TENANT CANONICI --}}
<div class="mt-5 rounded-lg border border-slate-200 bg-slate-900 p-3 text-xs text-slate-200">
<div class="font-bold text-amber-400 mb-1">PERCORSI ARCHIVIO TENANT & BACKUP DEDICATO (CANONICO SYSTEM HASH):</div>
<div class="font-mono space-y-1">
<div> Percorso Cartella Stabile: <span class="text-emerald-400">storage/app/private/amministratori/{{ $editForm['codice_univoco'] ?? '00000001' }}/</span></div>
<div> Percorso Documenti Stabile: <span class="text-emerald-400">storage/app/private/amministratori/{{ $editForm['codice_univoco'] ?? '00000001' }}/documenti/</span></div>
<div> Percorso Backup SQLite DB: <span class="text-emerald-400">storage/app/private/amministratori/{{ $editForm['codice_univoco'] ?? '00000001' }}/database/backups/</span></div>
</div>
</div>
{{-- PULSANTI DI SALVATAGGIO E AZIONE --}}
<div class="mt-5 flex flex-wrap items-center justify-between gap-3 border-t pt-4">
<div class="flex gap-2">
{{-- SALVATAGGIO IN-PLACE --}}
<div class="mt-5 flex flex-wrap items-center justify-between gap-3 border-t pt-4">
<button
type="button"
wire:click="salvaSchedaInPlace"
class="inline-flex items-center rounded-lg bg-emerald-700 px-4 py-2 text-xs font-bold text-white hover:bg-emerald-600 shadow"
>
SALVA MODIFICHE SCHEDA
SALVA SCHEDA AMMINISTRATORE
</button>
<button
type="button"
wire:click="deselezionaAmministratore"
class="inline-flex items-center rounded-lg bg-slate-200 px-4 py-2 text-xs font-medium text-slate-700 hover:bg-slate-300"
>
ANNULLA / CHIUDI DETTAGLIO
</button>
</div>
<div>
<button
type="button"
wire:click="impersonaSelected"
class="inline-flex items-center gap-1 rounded-lg bg-amber-500 px-4 py-2 text-xs font-bold text-white hover:bg-amber-600 shadow"
>
IMPERSONA STUDIO {{ strtoupper($editForm['cognome'] ?? '') }}
IMPERSONA SENZA PASSWORD
</button>
</div>
</div>
@else
<div class="rounded-xl border bg-white p-8 text-center text-slate-500">
Nessun amministratore selezionato. Torna al TAB 1 per selezionare una scheda.
</div>
@endif
@endif
{{-- TAB 3: STABILI & FORNITORI 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 Amministrati dallo Studio:</h4>
<ul class="space-y-1 font-mono text-slate-700">
<li> Stabile 0013 - CATONE 34 / GERMANICO 85</li>
<li> Stabile 0017 - OTTAVIANO 105 / GIULIO CESARE</li>
<li> Stabile 0018 - GRACCHI 6</li>
<li> Stabile 0016 - GERMANICO 96</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 (#13 Cecilia Tordini):</h4>
<div class="text-slate-700">
Totale <strong>370 fornitori</strong> censiti ed isolati in via esclusiva per lo studio di Cecilia Tordini.
</div>
</div>
</div>
</div>
@endif
{{-- TAB 4: MODULO IMPORTAZIONE MDB (ACL: import-gescon) --}}
@if($activeTab === 'importazione')
<div class="rounded-xl border border-emerald-300 bg-white p-5 shadow-sm space-y-4">
<div class="flex items-center justify-between border-b pb-3">
<div>
<h3 class="text-base font-bold text-emerald-900">Modulo Importazione MDB Gescon (Autorizzato ACL: import-gescon)</h3>
<p class="text-xs text-slate-500">Seleziona e carica gli archivi MDB per la sincronizzazione differenziale dello studio selezionato.</p>
</div>
<span class="rounded-full bg-emerald-100 px-3 py-1 text-xs font-bold text-emerald-800">
Modulo ACL Attivo
</span>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 text-xs">
<div class="rounded-lg border bg-emerald-50/50 p-4 space-y-2">
<label class="block font-bold text-slate-800">1. File Archivio Stabili MDB:</label>
<input type="text" readonly value="/mnt/gescon-archives/gescon/dbc/Stabili.mdb" class="w-full rounded-md border-slate-300 text-xs font-mono bg-slate-100">
<button type="button" class="rounded-md bg-slate-800 px-3 py-1.5 text-white font-semibold">🔄 Sincronizza Stabili MDB</button>
</div>
<div class="rounded-lg border bg-emerald-50/50 p-4 space-y-2">
<label class="block font-bold text-slate-800">2. File Archivio Fornitori MDB:</label>
<input type="text" readonly value="/mnt/gescon-archives/gescon/dbc/Fornitori.mdb" class="w-full rounded-md border-slate-300 text-xs font-mono bg-slate-100">
<button type="button" class="rounded-md bg-slate-800 px-3 py-1.5 text-white font-semibold">🔄 Sincronizza Fornitori MDB</button>
</div>
</div>
</div>
@endif
</div>
</x-filament-panels::page>

View File

@ -1,4 +1,6 @@
# ASCII Wireframe - Gestione Amministratori Stabili (/admin-filament/superadmin/amministratori)
# ASCII Wireframe - Gestione Amministratori Stabili con Menu a Tab (/admin-filament/superadmin/amministratori)
## 1. TAB 1: ELENCO AMMINISTRATORI CENSITI
```text
+-------------------------------------------------------------------------------------------------------------------+
@ -6,38 +8,70 @@ # ASCII Wireframe - Gestione Amministratori Stabili (/admin-filament/superadmin/
+-------------------------------------------------------------------------------------------------------------------+
| PATH: Home > Super Admin > Gestione Amministratori Stabili |
+-------------------------------------------------------------------------------------------------------------------+
| NAVIGAZIONE A TAB SEPARATI: |
| [ TAB 1: ELENCO AMMINISTRATORI (Attivo) ] [ TAB 2: SCHEDA & MODIFICA ] [ TAB 3: STABILI & FORNITORI ] |
| [ TAB 4: MODULO IMPORTAZIONE MDB (ACL: import-gescon) ] |
+-------------------------------------------------------------------------------------------------------------------+
| |
| [ + NUOVO AMMINISTRATORE ] [ 🔄 IMPORTA DA STABILI.MDB ] [ 🔍 Cerca per Nome, Cognome, CF, Studio... ] |
| |
| +----+----------+---------------------------+---------------------------------+---------+------------+------------+
| | ID | CODICE | NOMINATIVO AMMINISTRATORE | STUDIO / INTESTAZIONE | STABILI | FE CASSETTO| AZIONI |
| +----+----------+---------------------------+---------------------------------+---------+------------+------------+
| | 13 | 00000001 | Tordini Cecilia | Studio Tordini Cecilia | 12 | [Attivo] | [Modifica] |
| | | | | | | | [⚡Impersona|
| | 14 | 00000002 | BARONE MICHELE | Studio BARONE MICHELE | 8 | [Attivo] | [Modifica] |
| | | | | | | | [⚡Impersona|
| | 15 | 00000003 | Conforti Ignazio Vittorio | Studio Conforti Ignazio | 14 | [Attivo] | [Modifica] |
| | | | | | | | [⚡Impersona|
| | 16 | 00000004 | Roscioli Anna Maria | Studio Roscioli Anna Maria | 6 | [Attivo] | [Modifica] |
| | 13 | 00000001 | Tordini Cecilia | Studio Tordini Cecilia | 12 | [Attivo] | [Apri Tab2]|
| | | | (cecilia.tordini@gmail.com)| | | | [⚡Impersona|
| | 14 | 00000002 | BARONE MICHELE | Studio BARONE MICHELE | 8 | [Attivo] | [Apri Tab2]|
| | | | | | | | [⚡Impersona|
| | 15 | 00000003 | Conforti Ignazio Vittorio | Studio Conforti Ignazio | 14 | [Attivo] | [Apri Tab2]|
| | 16 | 00000004 | Roscioli Anna Maria | Studio Roscioli Anna Maria | 6 | [Attivo] | [Apri Tab2]|
| +----+----------+---------------------------+---------------------------------+---------+------------+------------+
| Mostrati 4 di 4 amministratori censiti negli archivi di sistema |
+-------------------------------------------------------------------------------------------------------------------+
| DETTAGLIO ED EDITING SCHEDA AMMINISTRATORE (#13 TORDINI CECILIA) |
```
## 2. TAB 2: SCHEDA DETTAGLIO & EDITING IN-PLACE (AMMINISTRATORE SELEZIONATO: #13 TORDINI CECILIA)
```text
+-------------------------------------------------------------------------------------------------------------------+
| NAVIGAZIONE A TAB SEPARATI: |
| [ TAB 1: ELENCO AMMINISTRATORI ] [ TAB 2: SCHEDA & MODIFICA (Attivo: #13) ] [ TAB 3: STABILI & FORNITORI ] |
+-------------------------------------------------------------------------------------------------------------------+
| DETTAGLIO SCHEDA AMMINISTRATORE (#13 TORDINI CECILIA) |
| |
| UTENTE DI SISTEMA COLLEGATO: cecilia.tordini@gmail.com (Ruoli: Amministratore, Admin) |
| |
| [ Utente Collegato: cecilia.tordini@netgescon.it ] |
| [ Nome: Cecilia ] [ Cognome: Tordini ] |
| [ Denominazione Studio: Studio Tordini Cecilia ] |
| [ Codice Fiscale Studio: TRDCCL74T52H501R ] [ Partita IVA: 01234567890 ] |
| [ Indirizzo Studio: Viale delle Milizie 9a ] [ Città: ROMA ] [ CAP: 00192] |
| [ Email: cecilia.tordini@netgescon.it ] [ PEC: cecilia.tordini@pec.it ] |
| [ Telefono: 06-12345678 ] [ Cellulare: 335-1234567 ] |
| [ Email Login: cecilia.tordini@gmail.com ] [ PEC: cecilia.tordini@pec.it ] |
| [ Telefono Studio: 06-12345678 ] [ Cellulare Studio: 335-1234567 ] |
| |
| PERCORSI ARCHIVIO TENANT & BACKUP DEDICATO (CANONICO SYSTEM HASH): |
| • Percorso Cartella Stabile: storage/app/private/amministratori/00000001/ |
| • Percorso Documenti Stabile: storage/app/private/amministratori/00000001/documenti/ |
| • Percorso Backup SQLite DB: storage/app/private/amministratori/00000001/database/backups/ |
| |
| [ SALVA MODIFICHE ] [ ANNULLA ] [ ⚡ IMPERSONA AMMINISTRATORE ] |
| PULSANTI DI AZIONE COMPATTI (SENZA SCROLL ORIZZONTALE): |
| [ ✓ SALVA SCHEDA ] [ ⚡ IMPERSONA SENZA PASSWORD ] [ 📧 INVIA CREDIENZIALI ] [ 🔑 RESET PASSWORD ] |
+-------------------------------------------------------------------------------------------------------------------+
```
## 3. TAB 4: MODULO IMPORTAZIONE LEGACY MDB (SCOPED ALL'AMMINISTRATORE - ACL: import-gescon)
```text
+-------------------------------------------------------------------------------------------------------------------+
| NAVIGAZIONE A TAB SEPARATI: |
| [ TAB 1: ELENCO ] [ TAB 2: SCHEDA ] [ TAB 3: STABILI & FORNITORI ] [ TAB 4: MODULO IMPORTAZIONE MDB (Attivo) ]|
+-------------------------------------------------------------------------------------------------------------------+
| SELEZIONE E CARICAMENTO ARCHIVI LEGACY MDB PER LO STUDIO: TORDINI CECILIA (#13) |
| |
| 1. FILE ARCHIVIO STABILI: [ /mnt/gescon-archives/gescon/dbc/Stabili.mdb ▾ ] [ 🔄 AVVIA IMPORT STABILI ] |
| 2. FILE ARCHIVIO FORNITORI: [ /mnt/gescon-archives/gescon/dbc/Fornitori.mdb ▾ ] [ 🔄 AVVIA IMPORT FORNITORI ] |
| |
| STATO IMPORTAZIONE ARCHIVIO STUDIO TORDINI CECILIA: |
| • Stabili importati e collegati: 12 stabili condominiali |
| • Fornitori accreditati per lo studio: 387 ditte/professionisti (Trib 1019/1020 ok) |
| • Modalità Coesistenza: Dual-Run Incrementale (Sorgente autoritativa: Legacy MDB -> NetGescon DB) |
+-------------------------------------------------------------------------------------------------------------------+
```