diff --git a/HANDOFF.md b/HANDOFF.md index 9e11a9b..af85aaa 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -162,6 +162,25 @@ regola è un no-op (nessun territorio assegnato è prioritario); su backup vecch con stato contraddittorio l'import normalizza il flag anziché riprodurlo tale e quale. +### Profilo utente, viewer PDF, privacy admin-only + +Tre ritocchi minori ma con qualche implicazione: + +- **Pagina profilo** (`Profile` → rotta `profilo`, nome `profile`) accessibile a + ogni utente loggato (nel gruppo `auth`, nessun permesso): mostra nome, email e + qualifica del solo utente corrente (sola lettura). Nell'header il blocco utente + è ora un link a questa pagina, con nome in evidenza ed `email · qualifica` + sotto. Non esiste un campo "username": l'email fa da identificativo. +- **Viewer PDF pubblico**: oltre a territorio/proclamatore/data mostra ora + *giorni assegnato*, *consegna prevista* e *scadenza*. Sono attributi calcolati + su `Assegnazione` (`data_consegna_presunta`, `giorni_alla_scadenza`) basati + sulla soglia `giorni_per_smarrito` — la stessa oltre cui `Territorio::stato` + diventa `da_rientrare`. Il viewer è servito solo per assegnazioni aperte, ma + gli accessor gestiscono comunque il caso `returned_at` (ritornano null). +- **Privacy solo admin**: la rotta `privacy` è passata dal solo `auth` al gruppo + `permission:settings.manage` e il link in sidebar è sotto + `@can('settings.manage')`. + ### Export/Import XML: backup completo e round-trip `Livewire/Settings/XmlExchange` esporta e reimporta **tutti** i dati gestionali, diff --git a/app/Livewire/Profile.php b/app/Livewire/Profile.php new file mode 100644 index 0000000..88a802e --- /dev/null +++ b/app/Livewire/Profile.php @@ -0,0 +1,15 @@ + auth()->user(), + ]); + } +} diff --git a/app/Models/Assegnazione.php b/app/Models/Assegnazione.php index 2dd0846..01e99d6 100644 --- a/app/Models/Assegnazione.php +++ b/app/Models/Assegnazione.php @@ -103,6 +103,40 @@ class Assegnazione extends Model return is_null($this->returned_at); } + /** + * Scadenza dell'assegnazione: data entro cui il territorio andrebbe + * riconsegnato, cioè assigned_at + la soglia "giorni_per_smarrito" (la + * stessa oltre cui Territorio::stato diventa "da_rientrare"). Null per le + * assegnazioni già rientrate. + */ + public function getDataConsegnaPresuntaAttribute(): ?Carbon + { + if ($this->returned_at !== null) { + return null; + } + + $soglia = (int) Setting::getValue('giorni_per_smarrito', 120); + + return Carbon::parse($this->assigned_at)->addDays($soglia); + } + + /** + * Giorni che mancano alla scadenza: positivo se ancora entro i termini, + * negativo (giorni di ritardo) se già scaduta. Null se rientrata. + */ + public function getGiorniAllaScadenzaAttribute(): ?int + { + $scadenza = $this->data_consegna_presunta?->copy()->startOfDay(); + if (! $scadenza) { + return null; + } + + $oggi = Carbon::today(); + $giorni = (int) $oggi->diffInDays($scadenza); + + return $oggi->lessThanOrEqualTo($scadenza) ? $giorni : -$giorni; + } + public function ensurePdfAccessCode(): string { if ($this->pdf_access_code) { diff --git a/resources/views/assignments/pdf-viewer.blade.php b/resources/views/assignments/pdf-viewer.blade.php index 1fc0323..9e2476c 100644 --- a/resources/views/assignments/pdf-viewer.blade.php +++ b/resources/views/assignments/pdf-viewer.blade.php @@ -215,6 +215,27 @@ Data {{ $assignment->assigned_at->format('d/m/Y') }} +
+ {{ $user->email }} + + {{ ucfirst($user->roles->first()?->name ?? 'utente') }} + +
+