++ gruppi: il gruppo sciolto si elimina; il sorvegliante entra con un nome utente dal nome del gruppo

- Sciolto, il gruppo non resta nello storico: si elimina (via sciolto_at;
  la migrazione elimina anche quelli gia' sciolti). I territori solo nel
  pacchetto tornano in reparto; quelli gia' dati restano ai membri, e
  l'assegnazione conserva il nome del gruppo (assegnazioni.gruppo_nome).
- Creando il gruppo non si chiede l'email: users.username dal nome del
  gruppo ("Gruppo Zisa" -> gruppo.zisa), users.email facoltativa. Login con
  "Email o nome utente". Nome del gruppo unico.
- Sciolto il gruppo il nome utente si libera (l'utenza disattivata prende
  ex.sorvegliante.<id>). XML: nome utente e gruppo_nome.
- Profilo, testata, cambio password e Utenti mostrano il nome utente dove
  manca l'email. Informativa privacy, README, HANDOFF e test aggiornati.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Francesco Picone
2026-10-20 11:45:00 +02:00
parent a93539242a
commit aaffeb7de7
29 changed files with 408 additions and 199 deletions

View File

@@ -12,9 +12,10 @@ use Livewire\Component;
/**
* Gruppi di servizio (solo amministratore): elenco e creazione. Creando un
* gruppo si sceglie il sorvegliante, che riceve un'utenza con l'email
* indicata e una password temporanea, mostrata qui una volta sola.
* Membri e pacchetto si gestiscono nella pagina del gruppo (GruppoShow).
* gruppo si sceglie il sorvegliante, che riceve un'utenza con un nome utente
* ricavato dal nome del gruppo (niente email) e una password temporanea,
* mostrati qui una volta sola. Membri e pacchetto si gestiscono nella pagina
* del gruppo (GruppoShow).
*/
class GruppiIndex extends Component
{
@@ -24,8 +25,6 @@ class GruppiIndex extends Component
public ?int $sorveglianteId = null;
public string $email = '';
/** Gruppo appena creato e password temporanea del sorvegliante, da consegnare. */
#[Locked]
public ?int $creatoId = null;
@@ -38,19 +37,17 @@ class GruppiIndex extends Component
$this->authorize('settings.manage');
$this->validate([
'nome' => 'required|string|max:100',
'nome' => 'required|string|max:100|unique:gruppi_servizio,nome',
'sorveglianteId' => 'required|integer|exists:proclamatori,id',
'email' => 'required|email|max:255',
], [
'nome.unique' => 'Esiste già un gruppo con questo nome.',
'sorveglianteId.required' => 'Scegli il sorvegliante.',
'email.required' => "Serve l'email con cui il sorvegliante entrerà.",
]);
try {
[$gruppo, $password] = app(GruppiServizio::class)->crea(
$this->nome,
Proclamatore::findOrFail($this->sorveglianteId),
trim($this->email),
);
} catch (InvalidArgumentException $e) {
$this->addError('sorveglianteId', $e->getMessage());
@@ -58,7 +55,7 @@ class GruppiIndex extends Component
return;
}
$this->reset(['nome', 'sorveglianteId', 'email']);
$this->reset(['nome', 'sorveglianteId']);
$this->creatoId = $gruppo->id;
$this->passwordTemporanea = $password;
}
@@ -72,7 +69,6 @@ class GruppiIndex extends Component
{
$gruppi = GruppoServizio::with('sorvegliante')
->withCount(['membri', 'territori'])
->orderByRaw('sciolto_at IS NOT NULL')
->orderBy('nome')
->get();