Files
termanager2/resources/views/livewire/gruppi/gruppo-show.blade.php
Francesco Picone ec2e7bd7e9 ++ gruppi: email fittizia iniziale+cognome per il sorvegliante; sciolto il gruppo l'utenza si elimina
- L'utenza del sorvegliante ha un'email fittizia creata dall'app:
  iniziale del nome e cognome @termanager.it (ffontana@termanager.it),
  come gli altri utenti. Via il nome utente: login di nuovo per email.
- Sciolto il gruppo l'utenza si elimina, il sorvegliante torna un
  proclamatore come gli altri: assegnazioni a chi scioglie, registro a nome
  "Sorvegliante del gruppo ...". Via le utenze disattivate.
- User::eliminaConservandoStorico(): l'eliminazione della pagina Utenti in
  un metodo solo, usato anche dallo scioglimento.
- Migrazione 000030: elimina le utenze gia' disattivate, toglie
  users.username e users.disattivato_at, email di nuovo obbligatoria.
- XML, informativa privacy, README, HANDOFF e test aggiornati.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 12:09:15 +02:00

128 lines
8.9 KiB
PHP

<div>
<div class="mb-6">
<a href="{{ $ritorno ?? route('gruppi.index') }}" class="inline-flex items-center gap-1 text-sm text-gray-500 hover:text-indigo-600 transition-colors mb-1">
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/></svg>
{{ $ritorno ? 'Torna indietro' : 'Gruppi di servizio' }}
</a>
<h1 class="text-2xl font-bold text-gray-900">Gruppo {{ $gruppo->nome }}</h1>
<p class="text-sm text-gray-500 mt-1">
Sorvegliante: <strong>{{ $gruppo->sorvegliante?->nome_completo ?? '—' }}</strong>
@if($gruppo->sorvegliante?->utente)
· accede con <code class="select-all">{{ $gruppo->sorvegliante->utente->email }}</code>
@endif
</p>
</div>
@if($passwordTemporanea)
<div class="mb-6 rounded-xl border-2 border-green-200 bg-green-50 p-4 text-sm text-green-900" role="status">
<p>Nuova password temporanea per {{ $gruppo->sorvegliante?->nome_completo }}, da cambiare al primo accesso. Si vede <strong>solo ora</strong>:</p>
<p class="mt-2"><code class="select-all text-base">{{ $passwordTemporanea }}</code></p>
</div>
@endif
{{-- ─── Pacchetto ─────────────────────────────────────────── --}}
<section class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden mb-6" aria-labelledby="titolo-pacchetto">
<h2 id="titolo-pacchetto" class="px-4 py-3 border-b border-gray-100 text-sm font-semibold text-gray-800">
Pacchetto ({{ $territori->count() }} territori)
</h2>
<ul class="divide-y divide-gray-100">
@forelse($territori as $t)
@php($a = $t->assegnazioneCorrente)
<li class="px-4 py-3 flex flex-wrap items-center justify-between gap-2" wire:key="pacchetto-{{ $t->id }}">
<span class="text-sm">
<a data-ritorno href="{{ route('territori.show', $t) }}" class="font-semibold text-indigo-600 hover:underline">N° {{ $t->numero }}</a>
<span class="text-gray-500">{{ $t->zona?->nome }}</span>
—
@if($a)
<span class="text-gray-700">a {{ $a->proclamatore?->nome_completo }} dal {{ $a->assigned_at->format('d/m/Y') }}</span>
@else
<span class="text-gray-700">da dare</span>
@endif
</span>
@unless($a)
<x-btn variante="secondary" tono="tenue" dimensione="sm" wire:click="rimanda({{ $t->id }})"
wire:confirm="Rimandare in reparto il territorio {{ $t->numero }}?">Rimanda in reparto</x-btn>
@endunless
</li>
@empty
<li class="px-4 py-6 text-center text-sm text-gray-500">Il pacchetto è vuoto.</li>
@endforelse
</ul>
{{-- Assegnazione in blocco: si spuntano i territori in reparto --}}
<div class="border-t border-gray-100 bg-gray-50 p-4" x-data="elencoCercabile">
<h3 class="text-sm font-semibold text-gray-700 mb-2">Aggiungi territori al pacchetto</h3>
@if($candidatiTerritori->isEmpty())
<p class="text-sm text-gray-500">Non ci sono territori in reparto da aggiungere.</p>
@else
<input x-model="q" type="search" inputmode="search" autocomplete="off" aria-label="Filtra i territori in reparto"
placeholder="Filtra per numero o zona…"
class="mb-2 block w-full rounded-lg border-gray-300 text-base sm:text-sm focus:ring-indigo-500 focus:border-indigo-500">
<div class="max-h-72 overflow-y-auto rounded-lg border border-gray-200 bg-white divide-y divide-gray-100">
@foreach($candidatiTerritori as $c)
<label class="flex items-center gap-3 px-3 py-2.5 text-sm cursor-pointer hover:bg-indigo-50/40"
data-cerca="{{ \Illuminate\Support\Str::lower(\Illuminate\Support\Str::ascii($c->numero . ' ' . $c->zona?->nome)) }}"
x-show="corrisponde($el.dataset.cerca)" wire:key="candidato-t-{{ $c->id }}">
<input type="checkbox" value="{{ $c->id }}" wire:model="nuoviTerritori" class="h-5 w-5 rounded border-gray-300 text-indigo-600">
<span><strong>N° {{ $c->numero }}</strong> <span class="text-gray-500">{{ $c->zona?->nome }}</span></span>
</label>
@endforeach
</div>
<div class="mt-3">
<x-btn variante="primary" wire:click="aggiungiTerritori">Aggiungi i territori selezionati</x-btn>
</div>
@endif
</div>
</section>
{{-- ─── Membri ───────────────────────────────────────────── --}}
<section class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden mb-6" aria-labelledby="titolo-membri">
<h2 id="titolo-membri" class="px-4 py-3 border-b border-gray-100 text-sm font-semibold text-gray-800">Membri ({{ $membri->count() }})</h2>
<ul class="divide-y divide-gray-100">
@foreach($membri as $m)
<li class="px-4 py-2.5 flex items-center justify-between gap-2 text-sm" wire:key="membro-{{ $m->id }}">
<span>{{ $m->nome_completo }} @if($m->id === $gruppo->sorvegliante_id)<span class="text-xs text-gray-500">(sorvegliante)</span>@endif</span>
@if($m->id !== $gruppo->sorvegliante_id)
<x-btn variante="secondary" tono="tenue" dimensione="sm" wire:click="togliMembro({{ $m->id }})">Togli</x-btn>
@endif
</li>
@endforeach
</ul>
<div class="border-t border-gray-100 bg-gray-50 p-4" x-data="elencoCercabile">
<h3 class="text-sm font-semibold text-gray-700 mb-2">Aggiungi membri</h3>
@if($candidatiMembri->isEmpty())
<p class="text-sm text-gray-500">Tutti i proclamatori attivi fanno già parte di un gruppo.</p>
@else
<input x-model="q" type="search" inputmode="search" autocomplete="off" aria-label="Filtra i proclamatori"
placeholder="Filtra per nome…"
class="mb-2 block w-full rounded-lg border-gray-300 text-base sm:text-sm focus:ring-indigo-500 focus:border-indigo-500">
<div class="max-h-72 overflow-y-auto rounded-lg border border-gray-200 bg-white divide-y divide-gray-100">
@foreach($candidatiMembri as $c)
<label class="flex items-center gap-3 px-3 py-2.5 text-sm cursor-pointer hover:bg-indigo-50/40"
data-cerca="{{ \Illuminate\Support\Str::lower(\Illuminate\Support\Str::ascii($c->nome_completo)) }}"
x-show="corrisponde($el.dataset.cerca)" wire:key="candidato-p-{{ $c->id }}">
<input type="checkbox" value="{{ $c->id }}" wire:model="nuoviMembri" class="h-5 w-5 rounded border-gray-300 text-indigo-600">
<span>{{ $c->nome_completo }}</span>
</label>
@endforeach
</div>
<div class="mt-3">
<x-btn variante="primary" wire:click="aggiungiMembri">Aggiungi i membri selezionati</x-btn>
</div>
@endif
</div>
</section>
{{-- ─── Sorvegliante ─────────────────────────────────────── --}}
<section class="bg-white rounded-xl shadow-sm border border-gray-200 p-4" aria-labelledby="titolo-sorvegliante">
<h2 id="titolo-sorvegliante" class="text-sm font-semibold text-gray-800 mb-2">Sorvegliante</h2>
<div class="flex flex-wrap gap-2">
<x-btn variante="secondary" wire:click="nuovaPassword"
wire:confirm="Generare una nuova password temporanea per {{ $gruppo->sorvegliante?->nome_completo }}? Quella attuale smette di funzionare.">Nuova password temporanea</x-btn>
<x-btn variante="danger" wire:click="sciogli"
wire:confirm="Togliere il ruolo di sorvegliante a {{ $gruppo->sorvegliante?->nome_completo }}? Il gruppo si scioglie e viene eliminato: i territori non ancora dati tornano in reparto, i membri restano senza gruppo e l'utenza del sorvegliante viene eliminata. Le assegnazioni già fatte restano ai membri.">Togli il ruolo e sciogli il gruppo</x-btn>
</div>
</section>
</div>