- 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>
128 lines
8.9 KiB
PHP
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>
|