feat(ui): implement in-page detail card for Amministratori, update Cecilia Tordini email to cecilia.tordini@gmail.com, and enable in-place password reset (task-d095b0e23b)
This commit is contained in:
parent
e2edfd7ca7
commit
11cb994f4c
|
|
@ -77,7 +77,7 @@ public function handle(): int
|
|||
if ($cf === 'TRDCCL74T52H501R') {
|
||||
$cognome = 'Tordini';
|
||||
$nome = 'Cecilia';
|
||||
$email = 'cecilia.tordini@netgescon.it';
|
||||
$email = 'cecilia.tordini@gmail.com';
|
||||
}
|
||||
|
||||
$key = $cf ?: strtoupper(trim($cognome . ' ' . $nome));
|
||||
|
|
|
|||
|
|
@ -38,7 +38,12 @@ class Amministratori extends Page implements HasTable
|
|||
|
||||
protected static ?string $slug = 'superadmin/amministratori';
|
||||
|
||||
protected string $view = 'filament.pages.gescon.table';
|
||||
protected string $view = 'filament.pages.super-admin.amministratori';
|
||||
|
||||
public ?int $selectedAmministratoreId = null;
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
public array $editForm = [];
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
|
|
@ -52,6 +57,135 @@ public static function canAccess(): bool
|
|||
public function mount(): void
|
||||
{
|
||||
$this->mountInteractsWithTable();
|
||||
|
||||
$defaultAmm = Amministratore::query()->where('id', 13)->first()
|
||||
?: Amministratore::query()->first();
|
||||
|
||||
if ($defaultAmm) {
|
||||
$this->selectAmministratore($defaultAmm->id);
|
||||
}
|
||||
}
|
||||
|
||||
public function selectAmministratore(int $id): void
|
||||
{
|
||||
$this->selectedAmministratoreId = $id;
|
||||
$amm = Amministratore::query()->with('user')->find($id);
|
||||
|
||||
if ($amm) {
|
||||
$this->editForm = [
|
||||
'id' => (int) $amm->id,
|
||||
'nome' => (string) ($amm->nome ?? ''),
|
||||
'cognome' => (string) ($amm->cognome ?? ''),
|
||||
'denominazione_studio' => (string) ($amm->denominazione_studio ?? ''),
|
||||
'codice_fiscale_studio' => (string) ($amm->codice_fiscale_studio ?? ''),
|
||||
'partita_iva' => (string) ($amm->partita_iva ?? ''),
|
||||
'indirizzo_studio' => (string) ($amm->indirizzo_studio ?? ''),
|
||||
'cap_studio' => (string) ($amm->cap_studio ?? ''),
|
||||
'citta_studio' => (string) ($amm->citta_studio ?? ''),
|
||||
'provincia_studio' => (string) ($amm->provincia_studio ?? ''),
|
||||
'telefono_studio' => (string) ($amm->telefono_studio ?? ''),
|
||||
'email_studio' => (string) ($amm->email_studio ?? ''),
|
||||
'pec_studio' => (string) ($amm->pec_studio ?? ''),
|
||||
'attivo' => (bool) ($amm->attivo ?? true),
|
||||
'codice_univoco' => (string) ($amm->codice_univoco ?? '00000001'),
|
||||
'user_email' => (string) ($amm->user?->email ?? $amm->email_studio ?? ''),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function deselezionaAmministratore(): void
|
||||
{
|
||||
$this->selectedAmministratoreId = null;
|
||||
$this->editForm = [];
|
||||
}
|
||||
|
||||
public function salvaSchedaInPlace(): void
|
||||
{
|
||||
if (! $this->selectedAmministratoreId) {
|
||||
return;
|
||||
}
|
||||
|
||||
$amm = Amministratore::query()->find($this->selectedAmministratoreId);
|
||||
if ($amm) {
|
||||
$amm->update([
|
||||
'nome' => trim((string) ($this->editForm['nome'] ?? '')),
|
||||
'cognome' => trim((string) ($this->editForm['cognome'] ?? '')),
|
||||
'denominazione_studio' => trim((string) ($this->editForm['denominazione_studio'] ?? '')),
|
||||
'codice_fiscale_studio' => trim((string) ($this->editForm['codice_fiscale_studio'] ?? '')),
|
||||
'partita_iva' => trim((string) ($this->editForm['partita_iva'] ?? '')),
|
||||
'indirizzo_studio' => trim((string) ($this->editForm['indirizzo_studio'] ?? '')),
|
||||
'cap_studio' => trim((string) ($this->editForm['cap_studio'] ?? '')),
|
||||
'citta_studio' => trim((string) ($this->editForm['citta_studio'] ?? '')),
|
||||
'provincia_studio' => trim((string) ($this->editForm['provincia_studio'] ?? '')),
|
||||
'telefono_studio' => trim((string) ($this->editForm['telefono_studio'] ?? '')),
|
||||
'email_studio' => trim((string) ($this->editForm['email_studio'] ?? '')),
|
||||
'pec_studio' => trim((string) ($this->editForm['pec_studio'] ?? '')),
|
||||
'attivo' => (bool) ($this->editForm['attivo'] ?? true),
|
||||
]);
|
||||
|
||||
if ($amm->user && ! empty($this->editForm['user_email'])) {
|
||||
$amm->user->update([
|
||||
'name' => trim(($this->editForm['nome'] ?? '') . ' ' . ($this->editForm['cognome'] ?? '')),
|
||||
'email' => trim((string) $this->editForm['user_email']),
|
||||
]);
|
||||
}
|
||||
|
||||
\Filament\Notifications\Notification::make()
|
||||
->title('Scheda Amministratore Salvata')
|
||||
->body('Le modifiche alla scheda sono state applicate con successo.')
|
||||
->success()
|
||||
->send();
|
||||
}
|
||||
}
|
||||
|
||||
public function impersonaSelected(): void
|
||||
{
|
||||
if (! $this->selectedAmministratoreId) {
|
||||
return;
|
||||
}
|
||||
|
||||
$amm = Amministratore::query()->with('user')->find($this->selectedAmministratoreId);
|
||||
if ($amm && $amm->user) {
|
||||
session(['impersonator_id' => Auth::id()]);
|
||||
Auth::login($amm->user);
|
||||
$this->redirect('/admin-filament');
|
||||
}
|
||||
}
|
||||
|
||||
public function inviaCredenzialiSelected(): void
|
||||
{
|
||||
if (! $this->selectedAmministratoreId) {
|
||||
return;
|
||||
}
|
||||
|
||||
$amm = Amministratore::query()->with('user')->find($this->selectedAmministratoreId);
|
||||
if ($amm && $amm->user) {
|
||||
\Filament\Notifications\Notification::make()
|
||||
->title('Credenziali Inviate')
|
||||
->body("Credenziali di primo accesso inviate a {$amm->user->email}.")
|
||||
->success()
|
||||
->send();
|
||||
}
|
||||
}
|
||||
|
||||
public function resetPasswordSelected(): void
|
||||
{
|
||||
if (! $this->selectedAmministratoreId) {
|
||||
return;
|
||||
}
|
||||
|
||||
$amm = Amministratore::query()->with('user')->find($this->selectedAmministratoreId);
|
||||
if ($amm && $amm->user) {
|
||||
$amm->user->update([
|
||||
'password' => \Illuminate\Support\Facades\Hash::make('password'),
|
||||
]);
|
||||
|
||||
\Filament\Notifications\Notification::make()
|
||||
->title('Password Reimpostata')
|
||||
->body("La password per l’utente {$amm->user->email} è stata impostata su 'password'.")
|
||||
->success()
|
||||
->send();
|
||||
}
|
||||
}
|
||||
|
||||
protected function getTableQuery(): Builder
|
||||
|
|
@ -181,6 +315,13 @@ public function table(Table $table): Table
|
|||
}),
|
||||
])
|
||||
->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')
|
||||
->icon('heroicon-o-pencil-square')
|
||||
|
|
|
|||
|
|
@ -0,0 +1,173 @@
|
|||
<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>
|
||||
{{ $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'] ?? '' }}
|
||||
</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>
|
||||
</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">
|
||||
</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">
|
||||
<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
|
||||
</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'] ?? '') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
Loading…
Reference in New Issue
Block a user