Primo commit

This commit is contained in:
Francesco Picone
2026-04-05 19:26:04 +02:00
commit 701f479b7f
135 changed files with 21445 additions and 0 deletions

View File

@@ -0,0 +1,160 @@
<!DOCTYPE html>
<html lang="it" class="h-full bg-gray-50">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ $title ?? 'TerManager2' }}</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
@livewireStyles
</head>
<body class="h-full">
<div class="min-h-full">
{{-- Header --}}
<nav class="bg-indigo-700 shadow-lg">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div class="flex h-16 items-center justify-between">
<div class="flex items-center gap-3">
<button @click="sidebarOpen = !sidebarOpen" class="lg:hidden text-white p-2"
x-data x-on:click="$dispatch('toggle-sidebar')">
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
</svg>
</button>
@php $settings = \App\Models\Setting::first(); @endphp
@if($settings && $settings->logo_path)
<img src="{{ asset('storage/' . $settings->logo_path) }}" alt="Logo" class="h-8 w-8 rounded">
@else
<div class="h-8 w-8 bg-indigo-500 rounded flex items-center justify-center text-white font-bold text-sm">T2</div>
@endif
<span class="text-white font-semibold text-lg hidden sm:block">
{{ $settings->congregazione_nome ?? 'TerManager2' }}
</span>
</div>
<div class="flex items-center gap-4">
<span class="text-indigo-200 text-sm hidden sm:block">
{{ auth()->user()->name }}
<span class="text-indigo-300 text-xs">({{ auth()->user()->roles->first()?->name ?? 'utente' }})</span>
</span>
<form method="POST" action="{{ route('logout') }}">
@csrf
<button type="submit" class="text-indigo-200 hover:text-white text-sm font-medium transition">
Esci
</button>
</form>
</div>
</div>
</div>
</nav>
<div class="flex" x-data="{ sidebarOpen: false }" @toggle-sidebar.window="sidebarOpen = !sidebarOpen">
{{-- Sidebar overlay (mobile) --}}
<div x-show="sidebarOpen" x-transition:enter="transition-opacity ease-linear duration-300"
x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100"
x-transition:leave="transition-opacity ease-linear duration-300"
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"
class="fixed inset-0 z-40 bg-gray-600/75 lg:hidden" @click="sidebarOpen = false">
</div>
{{-- Sidebar --}}
<aside :class="sidebarOpen ? 'translate-x-0' : '-translate-x-full'"
class="fixed inset-y-0 left-0 z-50 w-64 bg-white shadow-xl transform transition-transform duration-300 ease-in-out lg:translate-x-0 lg:static lg:inset-0 lg:z-auto lg:shadow-none lg:border-r lg:border-gray-200 pt-16 lg:pt-0">
<nav class="mt-4 px-3 space-y-1">
<a href="{{ route('dashboard') }}"
class="flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg {{ request()->routeIs('dashboard') ? 'bg-indigo-50 text-indigo-700' : 'text-gray-700 hover:bg-gray-100' }}">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0h4"/></svg>
Home
</a>
@can('territori.manage')
<a href="{{ route('territori.index') }}"
class="flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg {{ request()->routeIs('territori.*') ? 'bg-indigo-50 text-indigo-700' : 'text-gray-700 hover:bg-gray-100' }}">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7"/></svg>
Territori
</a>
@endcan
@can('proclamatori.manage')
<a href="{{ route('proclamatori.index') }}"
class="flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg {{ request()->routeIs('proclamatori.*') ? 'bg-indigo-50 text-indigo-700' : 'text-gray-700 hover:bg-gray-100' }}">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
Proclamatori
</a>
@endcan
@can('campagne.manage')
<a href="{{ route('campagne.index') }}"
class="flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg {{ request()->routeIs('campagne.*') ? 'bg-indigo-50 text-indigo-700' : 'text-gray-700 hover:bg-gray-100' }}">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5.882V19.24a1.76 1.76 0 01-3.417.592l-2.147-6.15M18 13a3 3 0 100-6M5.436 13.683A4.001 4.001 0 017 6h1.832c4.1 0 7.625-1.234 9.168-3v14c-1.543-1.766-5.067-3-9.168-3H7a3.988 3.988 0 01-1.564-.317z"/></svg>
Campagne
</a>
@endcan
@can('registro.view')
<a href="{{ route('registro.index') }}"
class="flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg {{ request()->routeIs('registro.*') ? 'bg-indigo-50 text-indigo-700' : 'text-gray-700 hover:bg-gray-100' }}">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/></svg>
Registro
</a>
@endcan
@can('audit.view')
<a href="{{ route('audit.index') }}"
class="flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg {{ request()->routeIs('audit.*') ? 'bg-indigo-50 text-indigo-700' : 'text-gray-700 hover:bg-gray-100' }}">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
Audit Log
</a>
@endcan
@can('settings.manage')
<div class="pt-4 mt-4 border-t border-gray-200">
<p class="px-3 text-xs font-semibold text-gray-400 uppercase tracking-wider">Amministrazione</p>
<a href="{{ route('settings.edit') }}"
class="flex items-center gap-3 px-3 py-2 mt-2 text-sm font-medium rounded-lg {{ request()->routeIs('settings.*') ? 'bg-indigo-50 text-indigo-700' : 'text-gray-700 hover:bg-gray-100' }}">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.066 2.573c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.573 1.066c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.066-2.573c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
Impostazioni
</a>
<a href="{{ route('zone.index') }}"
class="flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg {{ request()->routeIs('zone.*') ? 'bg-indigo-50 text-indigo-700' : 'text-gray-700 hover:bg-gray-100' }}">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
Zone
</a>
<a href="{{ route('tipologie.index') }}"
class="flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg {{ request()->routeIs('tipologie.*') ? 'bg-indigo-50 text-indigo-700' : 'text-gray-700 hover:bg-gray-100' }}">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A2 2 0 013 12V7a4 4 0 014-4z"/></svg>
Tipologie
</a>
</div>
@endcan
<div class="pt-4 mt-4 border-t border-gray-200">
<a href="{{ route('privacy') }}"
class="flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg {{ request()->routeIs('privacy') ? 'bg-indigo-50 text-indigo-700' : 'text-gray-700 hover:bg-gray-100' }}">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/></svg>
Privacy
</a>
</div>
</nav>
</aside>
{{-- Main content --}}
<main class="flex-1 px-4 sm:px-6 lg:px-8 py-6 min-h-screen">
{{-- Flash messages --}}
@if (session()->has('success'))
<div class="mb-4 rounded-lg bg-green-50 p-4 text-sm text-green-700 border border-green-200">
{{ session('success') }}
</div>
@endif
@if (session()->has('error'))
<div class="mb-4 rounded-lg bg-red-50 p-4 text-sm text-red-700 border border-red-200">
{{ session('error') }}
</div>
@endif
{{ $slot }}
</main>
</div>
</div>
@livewireScripts
</body>
</html>

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="it" class="h-full bg-gray-50">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ $title ?? 'TerManager2' }}</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
@livewireStyles
</head>
<body class="h-full flex items-center justify-center">
<div class="w-full max-w-md">
{{ $slot }}
</div>
@livewireScripts
</body>
</html>

View File

@@ -0,0 +1,46 @@
<div>
<div class="mb-6">
<h1 class="text-2xl font-bold text-gray-900">Assegna Territorio</h1>
<a href="{{ route('territori.index') }}" class="text-sm text-indigo-600 hover:text-indigo-800"> Torna ai territori</a>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6 max-w-lg">
<form wire:submit="save" class="space-y-4">
<div>
<label for="territorio_id" class="block text-sm font-medium text-gray-700">Territorio *</label>
<select wire:model="territorio_id" id="territorio_id" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm" @if($preselectedTerritorioId) disabled @endif>
<option value="">Seleziona un territorio</option>
@foreach($territoriDisponibili as $t)
<option value="{{ $t->id }}"> {{ $t->numero }} {{ $t->zona?->nome }} ({{ $t->tipologia?->nome }})</option>
@endforeach
</select>
@if($preselectedTerritorioId)
<input type="hidden" wire:model="territorio_id" value="{{ $preselectedTerritorioId }}">
@endif
@error('territorio_id') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
<div>
<label for="proclamatore_id" class="block text-sm font-medium text-gray-700">Proclamatore *</label>
<select wire:model="proclamatore_id" id="proclamatore_id" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm">
<option value="">Seleziona un proclamatore</option>
@foreach($proclamatoriAttivi as $p)
<option value="{{ $p->id }}">{{ $p->cognome }} {{ $p->nome }}</option>
@endforeach
</select>
@error('proclamatore_id') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
<div>
<label for="assigned_at" class="block text-sm font-medium text-gray-700">Data Assegnazione *</label>
<input wire:model="assigned_at" type="date" id="assigned_at" max="{{ now()->format('Y-m-d') }}" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm">
@error('assigned_at') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
<div class="flex items-center gap-3 pt-4">
<button type="submit" class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">Assegna</button>
<a href="{{ route('territori.index') }}" class="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition">Annulla</a>
</div>
</form>
</div>
</div>

View File

@@ -0,0 +1,60 @@
<div>
<div class="mb-6">
<h1 class="text-2xl font-bold text-gray-900">Rientro Territorio</h1>
<a href="{{ route('territori.show', $assegnazione->territorio) }}" class="text-sm text-indigo-600 hover:text-indigo-800"> Torna al territorio</a>
</div>
{{-- Assignment summary --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 mb-6">
<div class="grid grid-cols-1 sm:grid-cols-3 gap-4">
<div>
<p class="text-xs font-medium text-gray-500 uppercase">Territorio</p>
<p class="mt-1 text-lg font-bold text-gray-900"> {{ $assegnazione->territorio->numero }}</p>
</div>
<div>
<p class="text-xs font-medium text-gray-500 uppercase">Proclamatore</p>
<p class="mt-1 text-sm text-gray-900">{{ $assegnazione->proclamatore->nome_completo }}</p>
</div>
<div>
<p class="text-xs font-medium text-gray-500 uppercase">Assegnato il</p>
<p class="mt-1 text-sm text-gray-900">{{ $assegnazione->assigned_at->format('d/m/Y') }}</p>
</div>
</div>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6 max-w-lg">
<form wire:submit="save" class="space-y-4">
<div>
<label for="returned_at" class="block text-sm font-medium text-gray-700">Data Rientro *</label>
<input wire:model.live="returned_at" type="date" id="returned_at"
min="{{ $assegnazione->assigned_at->format('Y-m-d') }}"
max="{{ now()->format('Y-m-d') }}"
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm">
@error('returned_at') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
{{-- Campaign retroactive prompt --}}
@if($showCampaignPrompt && $campagna)
<div class="bg-amber-50 border border-amber-200 rounded-lg p-4">
<p class="text-sm font-medium text-amber-800 mb-2">
⚠️ Campagna Attiva: <strong>{{ $campagna->descrizione }}</strong>
</p>
<p class="text-xs text-amber-700 mb-3">
Questo territorio è stato assegnato durante la campagna "{{ $campagna->descrizione }}"
({{ $campagna->start_date->format('d/m/Y') }} {{ $campagna->end_date->format('d/m/Y') }}).
Vuoi conteggiarlo nella percentuale di percorrenza?
</p>
<div class="flex items-center gap-2">
<input wire:model="counted_in_campaign" type="checkbox" id="counted_in_campaign" class="rounded border-gray-300 text-amber-600 focus:ring-amber-500">
<label for="counted_in_campaign" class="text-sm text-amber-800">, conteggia in campagna</label>
</div>
</div>
@endif
<div class="flex items-center gap-3 pt-4">
<button type="submit" class="px-4 py-2 text-sm font-medium text-white bg-green-600 rounded-lg hover:bg-green-700 transition">Registra Rientro</button>
<a href="{{ route('territori.show', $assegnazione->territorio) }}" class="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition">Annulla</a>
</div>
</form>
</div>
</div>

View File

@@ -0,0 +1,108 @@
<div>
<div class="mb-6">
<h1 class="text-2xl font-bold text-gray-900">Audit Log</h1>
<p class="text-sm text-gray-500">Registro di tutte le azioni eseguite nel sistema.</p>
</div>
{{-- Filters --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 mb-4">
<div class="grid grid-cols-1 sm:grid-cols-3 gap-3">
<input wire:model.live.debounce.300ms="search" type="text" placeholder="Cerca..." class="rounded-lg border-gray-300 text-sm focus:ring-indigo-500 focus:border-indigo-500">
<select wire:model.live="filterEvent" class="rounded-lg border-gray-300 text-sm focus:ring-indigo-500 focus:border-indigo-500">
<option value="">Tutti gli eventi</option>
@foreach($events as $event)
<option value="{{ $event }}">{{ $event }}</option>
@endforeach
</select>
<select wire:model.live="filterCauser" class="rounded-lg border-gray-300 text-sm focus:ring-indigo-500 focus:border-indigo-500">
<option value="">Tutti gli utenti</option>
@foreach($users as $user)
<option value="{{ $user->id }}">{{ $user->name }}</option>
@endforeach
</select>
</div>
</div>
{{-- Table --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 text-sm">
<thead class="bg-gray-50">
<tr>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase">Data/Ora</th>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase">Utente</th>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase">Evento</th>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase">Soggetto</th>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase">Dettagli</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100">
@forelse($activities as $activity)
<tr class="hover:bg-gray-50">
<td class="px-3 py-2 text-xs text-gray-500 whitespace-nowrap">{{ $activity->created_at->format('d/m/Y H:i:s') }}</td>
<td class="px-3 py-2 text-xs">{{ $activity->causer?->name ?? 'Sistema' }}</td>
<td class="px-3 py-2">
<span class="inline-flex px-2 py-0.5 text-xs font-medium rounded-full
{{ match($activity->description) {
'created' => 'bg-green-100 text-green-800',
'updated' => 'bg-blue-100 text-blue-800',
'deleted' => 'bg-red-100 text-red-800',
'assigned' => 'bg-indigo-100 text-indigo-800',
'returned' => 'bg-amber-100 text-amber-800',
'restored' => 'bg-purple-100 text-purple-800',
'login' => 'bg-cyan-100 text-cyan-800',
default => 'bg-gray-100 text-gray-700',
} }}">
{{ $activity->description }}
</span>
</td>
<td class="px-3 py-2 text-xs text-gray-600">
@if($activity->subject_type)
{{ class_basename($activity->subject_type) }} #{{ $activity->subject_id }}
@else
-
@endif
</td>
<td class="px-3 py-2 text-xs text-gray-500">
@if($activity->properties->isNotEmpty())
<details>
<summary class="cursor-pointer text-indigo-600 hover:text-indigo-800">Mostra</summary>
<div class="mt-1 p-2 bg-gray-50 rounded text-xs font-mono max-w-xs overflow-auto">
@if($activity->properties->has('old'))
<div class="mb-1">
<span class="font-semibold text-red-600">Vecchio:</span>
@foreach($activity->properties['old'] as $k => $v)
<div>{{ $k }}: {{ is_string($v) ? $v : json_encode($v) }}</div>
@endforeach
</div>
<div>
<span class="font-semibold text-green-600">Nuovo:</span>
@foreach($activity->properties['attributes'] ?? [] as $k => $v)
<div>{{ $k }}: {{ is_string($v) ? $v : json_encode($v) }}</div>
@endforeach
</div>
@else
@foreach($activity->properties->toArray() as $k => $v)
<div>{{ $k }}: {{ is_string($v) ? $v : json_encode($v) }}</div>
@endforeach
@endif
</div>
</details>
@else
-
@endif
</td>
</tr>
@empty
<tr>
<td colspan="5" class="px-4 py-8 text-center text-gray-500">Nessuna attività registrata.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="px-4 py-3 border-t border-gray-200">
{{ $activities->links() }}
</div>
</div>
</div>

View File

@@ -0,0 +1,38 @@
<div class="bg-white shadow-xl rounded-2xl p-8">
<div class="text-center mb-8">
<div class="mx-auto h-12 w-12 bg-indigo-600 rounded-xl flex items-center justify-center text-white font-bold text-xl mb-4">T2</div>
<h2 class="text-2xl font-bold text-gray-900">TerManager2</h2>
<p class="text-gray-500 text-sm mt-1">Accedi per continuare</p>
</div>
<form wire:submit="login" class="space-y-5">
<div>
<label for="email" class="block text-sm font-medium text-gray-700">Email</label>
<input wire:model="email" type="email" id="email" autocomplete="email"
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm px-4 py-2.5">
@error('email') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
</div>
<div>
<label for="password" class="block text-sm font-medium text-gray-700">Password</label>
<input wire:model="password" type="password" id="password" autocomplete="current-password"
class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm px-4 py-2.5">
@error('password') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
</div>
<div class="flex items-center">
<input wire:model="remember" type="checkbox" id="remember"
class="h-4 w-4 text-indigo-600 border-gray-300 rounded focus:ring-indigo-500">
<label for="remember" class="ml-2 text-sm text-gray-600">Ricordami</label>
</div>
<button type="submit"
class="w-full flex justify-center py-2.5 px-4 border border-transparent rounded-lg shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition">
<span wire:loading.remove>Accedi</span>
<span wire:loading class="flex items-center gap-2">
<svg class="animate-spin h-4 w-4" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" fill="none"/><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"/></svg>
Accesso in corso...
</span>
</button>
</form>
</div>

View File

@@ -0,0 +1,34 @@
<div>
<div class="mb-6">
<h1 class="text-2xl font-bold text-gray-900">{{ $titolo }}</h1>
<a href="{{ route('campagne.index') }}" class="text-sm text-indigo-600 hover:text-indigo-800"> Torna alla lista</a>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6 max-w-lg">
<form wire:submit="save" class="space-y-4">
<div>
<label for="descrizione" class="block text-sm font-medium text-gray-700">Descrizione *</label>
<input wire:model="descrizione" type="text" id="descrizione" placeholder="es. Campagna della Commemorazione 2025" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm" required>
@error('descrizione') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label for="start_date" class="block text-sm font-medium text-gray-700">Data Inizio *</label>
<input wire:model="start_date" type="date" id="start_date" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm" required>
@error('start_date') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
<div>
<label for="end_date" class="block text-sm font-medium text-gray-700">Data Fine *</label>
<input wire:model="end_date" type="date" id="end_date" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm" required>
@error('end_date') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
</div>
<div class="flex items-center gap-3 pt-4">
<button type="submit" class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">{{ $btnLabel }}</button>
<a href="{{ route('campagne.index') }}" class="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition">Annulla</a>
</div>
</form>
</div>
</div>

View File

@@ -0,0 +1,67 @@
<div>
<div class="mb-6 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
<h1 class="text-2xl font-bold text-gray-900">Campagne</h1>
@can('campagne.manage')
<a href="{{ route('campagne.create') }}" class="inline-flex items-center px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">
+ Nuova Campagna
</a>
@endcan
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Descrizione</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Inizio</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Fine</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Stato</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">% Percorrenza</th>
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase">Azioni</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
@forelse($campagne as $campagna)
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 text-sm font-medium text-gray-900">{{ $campagna->descrizione }}</td>
<td class="px-4 py-3 text-sm text-gray-600">{{ $campagna->start_date->format('d/m/Y') }}</td>
<td class="px-4 py-3 text-sm text-gray-600">{{ $campagna->end_date->format('d/m/Y') }}</td>
<td class="px-4 py-3 text-sm">
@if($campagna->is_attiva)
<span class="inline-flex px-2 py-0.5 text-xs font-medium rounded-full bg-green-100 text-green-800">Attiva</span>
@elseif($campagna->end_date->isPast())
<span class="inline-flex px-2 py-0.5 text-xs font-medium rounded-full bg-gray-100 text-gray-600">Conclusa</span>
@else
<span class="inline-flex px-2 py-0.5 text-xs font-medium rounded-full bg-blue-100 text-blue-800">Futura</span>
@endif
</td>
<td class="px-4 py-3 text-sm">
<div class="flex items-center gap-2">
<div class="w-20 bg-gray-200 rounded-full h-2">
<div class="bg-indigo-500 h-2 rounded-full" style="width:{{ min($campagna->percentuale_percorrenza, 100) }}%"></div>
</div>
<span class="text-xs text-gray-600">{{ $campagna->percentuale_percorrenza }}%</span>
</div>
</td>
<td class="px-4 py-3 text-sm text-right space-x-2">
<a href="{{ route('campagne.show', $campagna) }}" class="text-indigo-600 hover:text-indigo-800 text-xs">Dettaglio</a>
@can('campagne.manage')
<a href="{{ route('campagne.edit', $campagna) }}" class="text-yellow-600 hover:text-yellow-800 text-xs">Modifica</a>
<button wire:click="deleteCampagna({{ $campagna->id }})" wire:confirm="Eliminare la campagna '{{ $campagna->descrizione }}'?" class="text-red-500 hover:text-red-700 text-xs">Elimina</button>
@endcan
</td>
</tr>
@empty
<tr>
<td colspan="6" class="px-4 py-8 text-center text-gray-500 text-sm">Nessuna campagna registrata.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="px-4 py-3 border-t border-gray-200">
{{ $campagne->links() }}
</div>
</div>
</div>

View File

@@ -0,0 +1,75 @@
<div>
<div class="mb-6 flex items-center justify-between">
<div>
<h1 class="text-2xl font-bold text-gray-900">{{ $campagna->descrizione }}</h1>
<a href="{{ route('campagne.index') }}" class="text-sm text-indigo-600 hover:text-indigo-800"> Torna alla lista</a>
</div>
@can('campagne.manage')
<a href="{{ route('campagne.edit', $campagna) }}" class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">Modifica</a>
@endcan
</div>
{{-- Stats --}}
<div class="grid grid-cols-1 sm:grid-cols-4 gap-4 mb-6">
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4">
<p class="text-xs font-medium text-gray-500 uppercase">Periodo</p>
<p class="mt-1 text-sm font-medium text-gray-900">{{ $campagna->start_date->format('d/m/Y') }} {{ $campagna->end_date->format('d/m/Y') }}</p>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4">
<p class="text-xs font-medium text-gray-500 uppercase">Stato</p>
@if($campagna->is_attiva)
<span class="inline-flex mt-1 px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">Attiva</span>
@elseif($campagna->end_date->isPast())
<span class="inline-flex mt-1 px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-600">Conclusa</span>
@else
<span class="inline-flex mt-1 px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">Futura</span>
@endif
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4">
<p class="text-xs font-medium text-gray-500 uppercase">Conteggiati / Assegnati</p>
<p class="mt-1 text-2xl font-bold text-indigo-600">{{ $conteggiate->count() }} / {{ $assegnateNelRange }}</p>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4">
<p class="text-xs font-medium text-gray-500 uppercase">Percentuale</p>
<p class="mt-1 text-2xl font-bold text-gray-900">{{ $campagna->percentuale_percorrenza }}%</p>
<div class="mt-2 w-full bg-gray-200 rounded-full h-2">
<div class="bg-indigo-500 h-2 rounded-full" style="width: {{ min($campagna->percentuale_percorrenza, 100) }}%"></div>
</div>
</div>
</div>
{{-- Counted assignments --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
<div class="px-4 py-3 bg-gray-50 border-b">
<h3 class="text-sm font-semibold text-gray-700">Territori Conteggiati</h3>
</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 text-sm">
<thead class="bg-gray-50">
<tr>
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500">Territorio</th>
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500">Proclamatore</th>
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500">Assegnato</th>
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500">Rientrato</th>
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500">Giorni</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100">
@forelse($conteggiate as $a)
<tr>
<td class="px-4 py-2"><a href="{{ route('territori.show', $a->territorio_id) }}" class="text-indigo-600 hover:underline"> {{ $a->territorio?->numero }}</a></td>
<td class="px-4 py-2">{{ $a->proclamatore?->nome_completo ?? 'N/A' }}</td>
<td class="px-4 py-2">{{ $a->assigned_at->format('d/m/Y') }}</td>
<td class="px-4 py-2">{{ $a->returned_at?->format('d/m/Y') }}</td>
<td class="px-4 py-2">{{ $a->giorni }}</td>
</tr>
@empty
<tr>
<td colspan="5" class="px-4 py-6 text-center text-gray-500">Nessun territorio conteggiato in questa campagna.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>

View File

@@ -0,0 +1,139 @@
<div>
{{-- Header --}}
<div class="mb-6">
<h1 class="text-2xl font-bold text-gray-900">Dashboard</h1>
@if($annoCorrente)
<p class="text-sm text-gray-500">Anno Teocratico {{ $annoCorrente->label }} {{ $annoCorrente->mesi_trascorsi }} mesi trascorsi</p>
@endif
</div>
{{-- Stats cards --}}
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4">
<p class="text-xs font-medium text-gray-500 uppercase">Territori Attivi</p>
<p class="mt-1 text-3xl font-bold text-gray-900">{{ $totTerritoriAttivi }}</p>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4">
<p class="text-xs font-medium text-gray-500 uppercase">Assegnati</p>
<p class="mt-1 text-3xl font-bold text-blue-600">{{ $totAssegnati }}</p>
<p class="text-xs text-gray-500">{{ $totInReparto }} in reparto</p>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4">
<p class="text-xs font-medium text-gray-500 uppercase">Percorsi (anno)</p>
<p class="mt-1 text-3xl font-bold text-green-600">{{ $territoriPercorsi }}</p>
<p class="text-xs text-gray-500">media {{ $mediaPercorrenzaMensile }}/mese</p>
</div>
@if($campagnaStats)
<div class="bg-amber-50 rounded-xl shadow-sm border border-amber-200 p-4">
<p class="text-xs font-medium text-amber-600 uppercase">Campagna</p>
<p class="mt-1 text-lg font-bold text-amber-800">{{ $campagnaStats['descrizione'] }}</p>
<div class="mt-2">
<div class="flex justify-between text-xs text-amber-700 mb-1">
<span>{{ $campagnaStats['percentuale'] }}%</span>
<span>scade {{ $campagnaStats['fine'] }}</span>
</div>
<div class="w-full bg-amber-200 rounded-full h-2">
<div class="bg-amber-500 h-2 rounded-full transition-all" style="width: {{ min($campagnaStats['percentuale'], 100) }}%"></div>
</div>
</div>
</div>
@else
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4">
<p class="text-xs font-medium text-gray-500 uppercase">Campagna</p>
<p class="mt-1 text-sm text-gray-400">Nessuna campagna attiva</p>
</div>
@endif
</div>
{{-- Quick lists --}}
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
{{-- Da assegnare --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
<div class="px-4 py-3 bg-green-50 border-b border-green-100">
<h3 class="text-sm font-semibold text-green-800">Da Assegnare</h3>
</div>
<ul class="divide-y divide-gray-100">
@forelse($daAssegnare as $t)
<li class="px-4 py-2.5 flex items-center justify-between hover:bg-gray-50">
<div>
<a href="{{ route('territori.show', $t) }}" class="text-sm font-semibold text-gray-900 hover:text-indigo-600"> {{ $t->numero }}</a>
<p class="text-xs text-gray-500">{{ $t->zona?->nome }} {{ $t->tipologia?->nome }}</p>
</div>
@can('territori.assign')
<a href="{{ route('assegnazioni.assegna', ['territorioId' => $t->id]) }}" class="text-xs font-medium text-green-600 hover:text-green-800">Assegna </a>
@endcan
</li>
@empty
<li class="px-4 py-4 text-sm text-gray-400 text-center">Tutti assegnati</li>
@endforelse
</ul>
@if($daAssegnare->count() >= 10)
<div class="px-4 py-2 bg-gray-50 border-t text-center">
<a href="{{ route('territori.index') }}?filtroStato=in_reparto" class="text-xs text-indigo-600 hover:text-indigo-800">Vedi tutti </a>
</div>
@endif
</div>
{{-- Prioritari --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
<div class="px-4 py-3 bg-amber-50 border-b border-amber-100">
<h3 class="text-sm font-semibold text-amber-800"> Prioritari</h3>
</div>
<ul class="divide-y divide-gray-100">
@forelse($prioritari as $t)
<li class="px-4 py-2.5 flex items-center justify-between hover:bg-gray-50">
<div>
<a href="{{ route('territori.show', $t) }}" class="text-sm font-semibold text-gray-900 hover:text-indigo-600"> {{ $t->numero }}</a>
<p class="text-xs text-gray-500">
{{ $t->zona?->nome }}
@if($t->ultimaAssegnazione?->returned_at)
ultimo rientro {{ $t->ultimaAssegnazione->returned_at->diffForHumans() }}
@endif
</p>
</div>
<span class="text-xs font-medium text-amber-600">
{{ $t->prioritario ? 'Man' : 'Auto' }}
</span>
</li>
@empty
<li class="px-4 py-4 text-sm text-gray-400 text-center">Nessun territorio prioritario</li>
@endforelse
</ul>
@if($prioritari->count() >= 10)
<div class="px-4 py-2 bg-gray-50 border-t text-center">
<a href="{{ route('territori.index') }}?filtroStato=prioritari" class="text-xs text-indigo-600 hover:text-indigo-800">Vedi tutti </a>
</div>
@endif
</div>
{{-- Da rientrare --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
<div class="px-4 py-3 bg-red-50 border-b border-red-100">
<h3 class="text-sm font-semibold text-red-800">Da Rientrare</h3>
</div>
<ul class="divide-y divide-gray-100">
@forelse($daRientrare as $t)
<li class="px-4 py-2.5 flex items-center justify-between hover:bg-gray-50">
<div>
<a href="{{ route('territori.show', $t) }}" class="text-sm font-semibold text-gray-900 hover:text-indigo-600"> {{ $t->numero }}</a>
<p class="text-xs text-gray-500">
{{ $t->assegnazioneCorrente?->proclamatore?->nome_completo }}
{{ $t->assegnazioneCorrente?->giorni }} giorni
</p>
</div>
@can('territori.return')
<a href="{{ route('assegnazioni.rientra', $t->assegnazioneCorrente) }}" class="text-xs font-medium text-red-600 hover:text-red-800">Rientra </a>
@endcan
</li>
@empty
<li class="px-4 py-4 text-sm text-gray-400 text-center">Nessun territorio da rientrare</li>
@endforelse
</ul>
@if($daRientrare->count() >= 10)
<div class="px-4 py-2 bg-gray-50 border-t text-center">
<a href="{{ route('territori.index') }}?filtroStato=da_rientrare" class="text-xs text-indigo-600 hover:text-indigo-800">Vedi tutti </a>
</div>
@endif
</div>
</div>
</div>

View File

@@ -0,0 +1,72 @@
<div>
<div class="max-w-3xl mx-auto">
<h1 class="text-2xl font-bold text-gray-900 mb-6">Informativa Privacy</h1>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6 md:p-8 space-y-6 text-sm text-gray-700 leading-relaxed">
<section>
<h2 class="text-lg font-semibold text-gray-900 mb-2">Titolare del trattamento</h2>
<p>Congregazione: <strong>{{ $congregazione }}</strong></p>
<p>L'applicazione TerManager2 è utilizzata esclusivamente per la gestione interna dei territori di predicazione.</p>
</section>
<section>
<h2 class="text-lg font-semibold text-gray-900 mb-2">Dati trattati</h2>
<ul class="list-disc list-inside space-y-1">
<li><strong>Proclamatori</strong>: nome e cognome — conservati in forma crittografata (AES-256-CBC) nel database.</li>
<li><strong>Territori</strong>: numero, località, zona, tipologia, mappe PDF — nessun dato personale.</li>
<li><strong>Assegnazioni</strong>: collegamento tra proclamatore e territorio con date di assegnazione e rientro.</li>
<li><strong>Utenti</strong>: nome, email e ruolo per l'accesso all'applicazione.</li>
</ul>
</section>
<section>
<h2 class="text-lg font-semibold text-gray-900 mb-2">Finalità del trattamento</h2>
<p>I dati personali sono trattati esclusivamente per:</p>
<ul class="list-disc list-inside space-y-1">
<li>Organizzare l'assegnazione e il rientro dei territori di predicazione.</li>
<li>Monitorare la copertura territoriale per anno teocratico.</li>
<li>Gestire le campagne speciali di predicazione.</li>
</ul>
</section>
<section>
<h2 class="text-lg font-semibold text-gray-900 mb-2">Base giuridica</h2>
<p>Il trattamento è basato sul legittimo interesse dell'organizzazione religiosa nella gestione delle proprie attività interne (Art. 6(1)(f) GDPR) e sull'appartenenza volontaria dei proclamatori alla congregazione (Art. 9(2)(d) GDPR).</p>
</section>
<section>
<h2 class="text-lg font-semibold text-gray-900 mb-2">Misure di sicurezza</h2>
<ul class="list-disc list-inside space-y-1">
<li><strong>Crittografia</strong>: i dati personali (nome/cognome) sono crittografati con AES-256-CBC prima della memorizzazione.</li>
<li><strong>Controllo accessi</strong>: sistema RBAC con tre ruoli (Admin, Servitore di Territorio, Proclamatore Semplificato).</li>
<li><strong>Audit trail</strong>: tutte le operazioni sono registrate e conservate per {{ $auditRetention }} giorni.</li>
<li><strong>Comunicazioni sicure</strong>: l'accesso avviene tramite HTTPS.</li>
<li><strong>Hosting locale</strong>: i dati risiedono sull'infrastruttura della congregazione, non su servizi cloud di terze parti.</li>
</ul>
</section>
<section>
<h2 class="text-lg font-semibold text-gray-900 mb-2">Conservazione dei dati</h2>
<ul class="list-disc list-inside space-y-1">
<li>I dati dei proclamatori inattivi possono essere anonimizzati su richiesta.</li>
<li>I territori eliminati sono conservati nel cestino (soft-delete) prima dell'eliminazione definitiva.</li>
<li>I log di audit sono conservati per <strong>{{ $auditRetention }} giorni</strong>, configurabili nelle impostazioni.</li>
<li>Lo storico assegnazioni è conservato per la durata necessaria alla gestione territoriale.</li>
</ul>
</section>
<section>
<h2 class="text-lg font-semibold text-gray-900 mb-2">Diritti dell'interessato</h2>
<p>In conformità al GDPR, ogni persona i cui dati sono trattati ha il diritto di:</p>
<ul class="list-disc list-inside space-y-1">
<li><strong>Accesso</strong>: richiedere copia dei propri dati.</li>
<li><strong>Rettifica</strong>: correggere dati inesatti.</li>
<li><strong>Cancellazione</strong>: richiedere l'anonimizzazione o la rimozione dei propri dati.</li>
<li><strong>Portabilità</strong>: richiedere l'esportazione dei propri dati.</li>
</ul>
<p class="mt-2">Le richieste possono essere inoltrate al Servitore di Territorio o all'Amministratore dell'applicazione.</p>
</section>
</div>
</div>
</div>

View File

@@ -0,0 +1,37 @@
<div>
<div class="mb-6">
<h1 class="text-2xl font-bold text-gray-900">Cestino Proclamatori</h1>
<a href="{{ route('proclamatori.index') }}" class="text-sm text-indigo-600 hover:text-indigo-800"> Torna alla lista</a>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Nome Completo</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Eliminato il</th>
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase">Azioni</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
@forelse($proclamatori as $proclamatore)
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 text-sm font-semibold text-gray-900">{{ $proclamatore->nome_completo }}</td>
<td class="px-4 py-3 text-sm text-gray-600">{{ $proclamatore->deleted_at->format('d/m/Y H:i') }}</td>
<td class="px-4 py-3 text-sm text-right space-x-2">
<button wire:click="restore({{ $proclamatore->id }})" class="text-green-600 hover:text-green-800 text-xs font-medium">Ripristina</button>
<button wire:click="forceDelete({{ $proclamatore->id }})" wire:confirm="Eliminare DEFINITIVAMENTE questo proclamatore? Questa azione è irreversibile." class="text-red-600 hover:text-red-800 text-xs font-medium">Elimina definitivamente</button>
</td>
</tr>
@empty
<tr>
<td colspan="3" class="px-4 py-8 text-center text-gray-500 text-sm">Il cestino è vuoto.</td>
</tr>
@endforelse
</tbody>
</table>
<div class="px-4 py-3 border-t border-gray-200">
{{ $proclamatori->links() }}
</div>
</div>
</div>

View File

@@ -0,0 +1,32 @@
<div>
<div class="mb-6">
<h1 class="text-2xl font-bold text-gray-900">{{ $titolo }}</h1>
<a href="{{ route('proclamatori.index') }}" class="text-sm text-indigo-600 hover:text-indigo-800"> Torna alla lista</a>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6 max-w-lg">
<form wire:submit="save" class="space-y-4">
<div>
<label for="cognome" class="block text-sm font-medium text-gray-700">Cognome *</label>
<input wire:model="cognome" type="text" id="cognome" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm" required>
@error('cognome') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
<div>
<label for="nome" class="block text-sm font-medium text-gray-700">Nome *</label>
<input wire:model="nome" type="text" id="nome" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm" required>
@error('nome') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
<div class="flex items-center gap-2">
<input wire:model="attivo" type="checkbox" id="attivo" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500">
<label for="attivo" class="text-sm text-gray-700">Attivo</label>
</div>
<div class="flex items-center gap-3 pt-4">
<button type="submit" class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">{{ $btnLabel }}</button>
<a href="{{ route('proclamatori.index') }}" class="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition">Annulla</a>
</div>
</form>
</div>
</div>

View File

@@ -0,0 +1,81 @@
<div>
<div class="mb-6 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
<h1 class="text-2xl font-bold text-gray-900">Proclamatori</h1>
@can('proclamatori.manage')
<a href="{{ route('proclamatori.create') }}" class="inline-flex items-center px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">
+ Nuovo Proclamatore
</a>
@endcan
</div>
{{-- Filters --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 mb-4">
<div class="grid grid-cols-1 sm:grid-cols-3 gap-3">
<input wire:model.live.debounce.300ms="search" type="text" placeholder="Cerca nome o cognome..." class="rounded-lg border-gray-300 text-sm focus:ring-indigo-500 focus:border-indigo-500">
<select wire:model.live="filtroStato" class="rounded-lg border-gray-300 text-sm focus:ring-indigo-500 focus:border-indigo-500">
<option value="">Tutti</option>
<option value="attivo">Attivi</option>
<option value="inattivo">Inattivi</option>
</select>
<div class="text-xs text-gray-500 flex items-center">
@can('proclamatori.manage')
<a href="{{ route('proclamatori.cestino') }}" class="text-red-500 hover:text-red-700">🗑 Cestino</a>
@endcan
</div>
</div>
</div>
{{-- Table --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th wire:click="sortBy('cognome')" class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase cursor-pointer hover:text-gray-700">
Cognome @if($sortField==='cognome') {{ $sortDirection==='asc'?'↑':'↓' }} @endif
</th>
<th wire:click="sortBy('nome')" class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase cursor-pointer hover:text-gray-700">
Nome @if($sortField==='nome') {{ $sortDirection==='asc'?'↑':'↓' }} @endif
</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Stato</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Territori Assegnati</th>
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase">Azioni</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
@forelse($proclamatori as $proclamatore)
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 text-sm font-medium text-gray-900">{{ $proclamatore->cognome }}</td>
<td class="px-4 py-3 text-sm text-gray-700">{{ $proclamatore->nome }}</td>
<td class="px-4 py-3 text-sm">
@if($proclamatore->attivo)
<span class="inline-flex px-2 py-0.5 text-xs font-medium rounded-full bg-green-100 text-green-800">Attivo</span>
@else
<span class="inline-flex px-2 py-0.5 text-xs font-medium rounded-full bg-gray-100 text-gray-600">Inattivo</span>
@endif
</td>
<td class="px-4 py-3 text-sm text-gray-600">{{ $proclamatore->assegnazioni()->aperte()->count() }}</td>
<td class="px-4 py-3 text-sm text-right space-x-2">
<a href="{{ route('proclamatori.show', $proclamatore) }}" class="text-indigo-600 hover:text-indigo-800 text-xs">Dettaglio</a>
@can('proclamatori.manage')
<a href="{{ route('proclamatori.edit', $proclamatore) }}" class="text-yellow-600 hover:text-yellow-800 text-xs">Modifica</a>
<button wire:click="toggleActive({{ $proclamatore->id }})" class="text-xs {{ $proclamatore->attivo ? 'text-gray-500 hover:text-gray-700' : 'text-green-600 hover:text-green-800' }}">
{{ $proclamatore->attivo ? 'Disattiva' : 'Attiva' }}
</button>
<button wire:click="deleteProclamatore({{ $proclamatore->id }})" wire:confirm="Spostare il proclamatore nel cestino?" class="text-red-500 hover:text-red-700 text-xs">Elimina</button>
@endcan
</td>
</tr>
@empty
<tr>
<td colspan="5" class="px-4 py-8 text-center text-gray-500 text-sm">Nessun proclamatore trovato.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="px-4 py-3 border-t border-gray-200">
{{ $proclamatori->links() }}
</div>
</div>
</div>

View File

@@ -0,0 +1,85 @@
<div>
<div class="mb-6 flex items-center justify-between">
<div>
<h1 class="text-2xl font-bold text-gray-900">{{ $proclamatore->nome_completo }}</h1>
<a href="{{ route('proclamatori.index') }}" class="text-sm text-indigo-600 hover:text-indigo-800"> Torna alla lista</a>
</div>
@can('proclamatori.manage')
<a href="{{ route('proclamatori.edit', $proclamatore) }}" class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">Modifica</a>
@endcan
</div>
{{-- Stats --}}
<div class="grid grid-cols-1 sm:grid-cols-3 gap-4 mb-6">
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4">
<p class="text-xs font-medium text-gray-500 uppercase">Stato</p>
@if($proclamatore->attivo)
<span class="inline-flex mt-1 px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">Attivo</span>
@else
<span class="inline-flex mt-1 px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-600">Inattivo</span>
@endif
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4">
<p class="text-xs font-medium text-gray-500 uppercase">Territori Attualmente</p>
<p class="mt-1 text-2xl font-bold text-indigo-600">{{ $stats['attualmente_assegnati'] }}</p>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4">
<p class="text-xs font-medium text-gray-500 uppercase">Media Giorni Trattenuta</p>
<p class="mt-1 text-2xl font-bold text-gray-900">{{ $stats['media_giorni'] }} gg</p>
<p class="text-xs text-gray-500">su {{ $stats['totale_assegnazioni'] }} assegnazioni totali</p>
</div>
</div>
{{-- Assignment history --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6">
<h3 class="text-lg font-semibold text-gray-900 mb-4">Storico Assegnazioni</h3>
@forelse($assegnazioniPerAnno as $annoLabel => $assegnazioni)
<div class="mb-6">
<h4 class="text-sm font-semibold text-indigo-600 mb-2">Anno Teocratico {{ $annoLabel }}</h4>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 text-sm">
<thead class="bg-gray-50">
<tr>
<th class="px-3 py-2 text-left text-xs font-medium text-gray-500">Territorio</th>
<th class="px-3 py-2 text-left text-xs font-medium text-gray-500">Assegnato</th>
<th class="px-3 py-2 text-left text-xs font-medium text-gray-500">Rientrato</th>
<th class="px-3 py-2 text-left text-xs font-medium text-gray-500">Giorni</th>
<th class="px-3 py-2 text-left text-xs font-medium text-gray-500">Campagna</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100">
@foreach($assegnazioni as $assegnazione)
<tr>
<td class="px-3 py-2">
<a href="{{ route('territori.show', $assegnazione->territorio_id) }}" class="text-indigo-600 hover:underline">
{{ $assegnazione->territorio?->numero ?? 'N/A' }}
</a>
</td>
<td class="px-3 py-2">{{ $assegnazione->assigned_at->format('d/m/Y') }}</td>
<td class="px-3 py-2">
@if($assegnazione->returned_at)
{{ $assegnazione->returned_at->format('d/m/Y') }}
@else
<span class="text-amber-600 font-medium">In corso</span>
@endif
</td>
<td class="px-3 py-2">{{ $assegnazione->giorni }}</td>
<td class="px-3 py-2">
@if($assegnazione->counted_in_campaign)
<span class="text-green-600">{{ $assegnazione->campagna?->descrizione }}</span>
@else
<span class="text-gray-400">-</span>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@empty
<p class="text-gray-500 text-sm">Nessuna assegnazione registrata.</p>
@endforelse
</div>
</div>

View File

@@ -0,0 +1,93 @@
<div>
<div class="mb-6">
<h1 class="text-2xl font-bold text-gray-900">Registro Assegnazioni</h1>
</div>
{{-- Filters --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 mb-4">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3">
<input wire:model.live.debounce.300ms="search" type="text" placeholder="Cerca territorio o proclamatore..." class="rounded-lg border-gray-300 text-sm focus:ring-indigo-500 focus:border-indigo-500">
<select wire:model.live="filtroAnno" class="rounded-lg border-gray-300 text-sm focus:ring-indigo-500 focus:border-indigo-500">
<option value="">Tutti gli anni</option>
@foreach($anni as $anno)
<option value="{{ $anno->id }}">{{ $anno->label }}</option>
@endforeach
</select>
<select wire:model.live="filtroZona" class="rounded-lg border-gray-300 text-sm focus:ring-indigo-500 focus:border-indigo-500">
<option value="">Tutte le zone</option>
@foreach($zone as $zona)
<option value="{{ $zona->id }}">{{ $zona->nome }}</option>
@endforeach
</select>
<select wire:model.live="filtroTipologia" class="rounded-lg border-gray-300 text-sm focus:ring-indigo-500 focus:border-indigo-500">
<option value="">Tutte le tipologie</option>
@foreach($tipologie as $tipologia)
<option value="{{ $tipologia->id }}">{{ $tipologia->nome }}</option>
@endforeach
</select>
<select wire:model.live="filtroStato" class="rounded-lg border-gray-300 text-sm focus:ring-indigo-500 focus:border-indigo-500">
<option value="">Tutte</option>
<option value="aperte">Aperte (in corso)</option>
<option value="chiuse">Chiuse (rientrate)</option>
</select>
</div>
</div>
{{-- Table --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 text-sm">
<thead class="bg-gray-50">
<tr>
<th wire:click="sortBy('territorio_id')" class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase cursor-pointer">Territorio</th>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase">Proclamatore</th>
<th wire:click="sortBy('assigned_at')" class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase cursor-pointer">
Assegnato @if($sortField==='assigned_at') {{ $sortDirection==='asc'?'↑':'↓' }} @endif
</th>
<th wire:click="sortBy('returned_at')" class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase cursor-pointer">
Rientrato @if($sortField==='returned_at') {{ $sortDirection==='asc'?'↑':'↓' }} @endif
</th>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase">Giorni</th>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase">Anno</th>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase">Campagna</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100">
@forelse($assegnazioni as $a)
<tr class="hover:bg-gray-50">
<td class="px-3 py-2">
<a href="{{ route('territori.show', $a->territorio_id) }}" class="text-indigo-600 hover:underline font-medium"> {{ $a->territorio?->numero }}</a>
<span class="text-xs text-gray-400 ml-1">{{ $a->territorio?->zona?->nome }}</span>
</td>
<td class="px-3 py-2">{{ $a->proclamatore?->nome_completo ?? 'N/A' }}</td>
<td class="px-3 py-2">{{ $a->assigned_at->format('d/m/Y') }}</td>
<td class="px-3 py-2">
@if($a->returned_at)
{{ $a->returned_at->format('d/m/Y') }}
@else
<span class="text-amber-600 font-medium text-xs">In corso</span>
@endif
</td>
<td class="px-3 py-2">{{ $a->giorni }}</td>
<td class="px-3 py-2 text-xs text-gray-500">{{ $a->annoTeocratico?->label }}</td>
<td class="px-3 py-2 text-xs">
@if($a->counted_in_campaign)
<span class="text-green-600">{{ $a->campagna?->descrizione }}</span>
@else
<span class="text-gray-300">-</span>
@endif
</td>
</tr>
@empty
<tr>
<td colspan="7" class="px-4 py-8 text-center text-gray-500">Nessuna assegnazione trovata.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="px-4 py-3 border-t border-gray-200">
{{ $assegnazioni->links() }}
</div>
</div>
</div>

View File

@@ -0,0 +1,47 @@
<div>
<div class="mb-6">
<h1 class="text-2xl font-bold text-gray-900">Impostazioni</h1>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6 max-w-lg">
@if (session()->has('success'))
<div x-data="{ show: true }" x-show="show" x-init="setTimeout(() => show = false, 3000)" x-transition.duration.500ms
class="mb-4 rounded-lg bg-green-50 p-4 text-sm text-green-700 border border-green-200">
{{ session('success') }}
</div>
@endif
<form wire:submit="save" class="space-y-5">
<div>
<label for="congregazione_nome" class="block text-sm font-medium text-gray-700">Nome Congregazione *</label>
<input wire:model="congregazione_nome" type="text" id="congregazione_nome" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm" required>
@error('congregazione_nome') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
<div>
<label for="giorni_giacenza_prioritari" class="block text-sm font-medium text-gray-700">Soglia Priorità (giorni)</label>
<p class="text-xs text-gray-500 mb-1">Dopo quanti giorni dal rientro un territorio diventa prioritario automaticamente.</p>
<input wire:model="giorni_giacenza_prioritari" type="number" min="1" max="730" id="giorni_giacenza_prioritari" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm">
@error('giorni_giacenza_prioritari') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
<div>
<label for="giorni_per_smarrito" class="block text-sm font-medium text-gray-700">Soglia Rientro (giorni)</label>
<p class="text-xs text-gray-500 mb-1">Dopo quanti giorni dall'assegnazione un territorio appare nella lista "da rientrare".</p>
<input wire:model="giorni_per_smarrito" type="number" min="30" max="365" id="giorni_per_smarrito" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm">
@error('giorni_per_smarrito') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
<div>
<label for="audit_retention_days" class="block text-sm font-medium text-gray-700">Conservazione Audit (giorni)</label>
<p class="text-xs text-gray-500 mb-1">I log più vecchi di questo periodo verranno cancellati automaticamente.</p>
<input wire:model="audit_retention_days" type="number" min="30" max="3650" id="audit_retention_days" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm">
@error('audit_retention_days') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
<div class="pt-4">
<button type="submit" class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">Salva Impostazioni</button>
</div>
</form>
</div>
</div>

View File

@@ -0,0 +1,49 @@
<div>
<div class="mb-6">
<h1 class="text-2xl font-bold text-gray-900">Gestione Tipologie</h1>
</div>
{{-- Add new --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 mb-4 max-w-lg">
<form wire:submit="addTipologia" class="flex items-end gap-3">
<div class="flex-1">
<label for="nuovaTipologia" class="block text-sm font-medium text-gray-700">Nuova Tipologia</label>
<input wire:model="nuovaTipologia" type="text" id="nuovaTipologia" placeholder="Nome tipologia..." class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm">
@error('nuovaTipologia') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
<button type="submit" class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">Aggiungi</button>
</form>
</div>
{{-- List --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden max-w-lg">
<ul class="divide-y divide-gray-200">
@forelse($tipologie as $tipo)
<li class="px-4 py-3 flex items-center justify-between hover:bg-gray-50">
@if($editingId === $tipo->id)
<form wire:submit="saveEdit" class="flex items-center gap-2 flex-1">
<input wire:model="editingNome" type="text" class="flex-1 rounded-lg border-gray-300 text-sm focus:ring-indigo-500 focus:border-indigo-500">
<button type="submit" class="text-green-600 hover:text-green-800 text-xs font-medium">Salva</button>
<button type="button" wire:click="cancelEdit" class="text-gray-500 hover:text-gray-700 text-xs">Annulla</button>
</form>
@else
<div class="flex items-center gap-2">
<span class="text-sm font-medium {{ $tipo->attivo ? 'text-gray-900' : 'text-gray-400 line-through' }}">{{ $tipo->nome }}</span>
@if(!$tipo->attivo)
<span class="text-xs text-gray-400">(inattiva)</span>
@endif
<span class="text-xs text-gray-400">{{ $tipo->territori()->count() }} territori</span>
</div>
<div class="flex items-center gap-2">
<button wire:click="startEdit({{ $tipo->id }})" class="text-yellow-600 hover:text-yellow-800 text-xs">Rinomina</button>
<button wire:click="toggleActive({{ $tipo->id }})" class="text-xs {{ $tipo->attivo ? 'text-gray-500' : 'text-green-600' }}">{{ $tipo->attivo ? 'Disattiva' : 'Attiva' }}</button>
<button wire:click="deleteTipologia({{ $tipo->id }})" wire:confirm="Eliminare la tipologia '{{ $tipo->nome }}'?" class="text-red-500 hover:text-red-700 text-xs">Elimina</button>
</div>
@endif
</li>
@empty
<li class="px-4 py-6 text-center text-gray-500 text-sm">Nessuna tipologia configurata.</li>
@endforelse
</ul>
</div>
</div>

View File

@@ -0,0 +1,49 @@
<div>
<div class="mb-6">
<h1 class="text-2xl font-bold text-gray-900">Gestione Zone</h1>
</div>
{{-- Add new --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 mb-4 max-w-lg">
<form wire:submit="addZona" class="flex items-end gap-3">
<div class="flex-1">
<label for="nuovaZona" class="block text-sm font-medium text-gray-700">Nuova Zona</label>
<input wire:model="nuovaZona" type="text" id="nuovaZona" placeholder="Nome zona..." class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 text-sm">
@error('nuovaZona') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
<button type="submit" class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">Aggiungi</button>
</form>
</div>
{{-- List --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden max-w-lg">
<ul class="divide-y divide-gray-200">
@forelse($zone as $zona)
<li class="px-4 py-3 flex items-center justify-between hover:bg-gray-50">
@if($editingId === $zona->id)
<form wire:submit="saveEdit" class="flex items-center gap-2 flex-1">
<input wire:model="editingNome" type="text" class="flex-1 rounded-lg border-gray-300 text-sm focus:ring-indigo-500 focus:border-indigo-500">
<button type="submit" class="text-green-600 hover:text-green-800 text-xs font-medium">Salva</button>
<button type="button" wire:click="cancelEdit" class="text-gray-500 hover:text-gray-700 text-xs">Annulla</button>
</form>
@else
<div class="flex items-center gap-2">
<span class="text-sm font-medium {{ $zona->attivo ? 'text-gray-900' : 'text-gray-400 line-through' }}">{{ $zona->nome }}</span>
@if(!$zona->attivo)
<span class="text-xs text-gray-400">(inattiva)</span>
@endif
<span class="text-xs text-gray-400">{{ $zona->territori()->count() }} territori</span>
</div>
<div class="flex items-center gap-2">
<button wire:click="startEdit({{ $zona->id }})" class="text-yellow-600 hover:text-yellow-800 text-xs">Rinomina</button>
<button wire:click="toggleActive({{ $zona->id }})" class="text-xs {{ $zona->attivo ? 'text-gray-500' : 'text-green-600' }}">{{ $zona->attivo ? 'Disattiva' : 'Attiva' }}</button>
<button wire:click="deleteZona({{ $zona->id }})" wire:confirm="Eliminare la zona '{{ $zona->nome }}'?" class="text-red-500 hover:text-red-700 text-xs">Elimina</button>
</div>
@endif
</li>
@empty
<li class="px-4 py-6 text-center text-gray-500 text-sm">Nessuna zona configurata.</li>
@endforelse
</ul>
</div>
</div>

View File

@@ -0,0 +1,105 @@
<div class="bg-white shadow-xl rounded-2xl p-8 w-full max-w-lg mx-auto">
<div class="text-center mb-6">
<h2 class="text-2xl font-bold text-gray-900">Setup iniziale</h2>
<p class="text-gray-500 text-sm mt-1">Passo {{ $step }} di 3</p>
<div class="flex gap-2 justify-center mt-3">
@for($i = 1; $i <= 3; $i++)
<div class="h-2 w-12 rounded-full {{ $i <= $step ? 'bg-indigo-600' : 'bg-gray-200' }}"></div>
@endfor
</div>
</div>
{{-- Step 1: Congregazione --}}
@if($step === 1)
<div class="space-y-4">
<h3 class="text-lg font-semibold text-gray-800">Dati Congregazione</h3>
<div>
<label class="block text-sm font-medium text-gray-700">Nome Congregazione *</label>
<input wire:model="congregazione_nome" type="text" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm px-4 py-2.5" placeholder="Nome della congregazione">
@error('congregazione_nome') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Logo (opzionale)</label>
<input wire:model="logo" type="file" accept="image/*" class="mt-1 block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-lg file:border-0 file:text-sm file:font-semibold file:bg-indigo-50 file:text-indigo-700 hover:file:bg-indigo-100">
@error('logo') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
</div>
<button wire:click="nextStep" class="w-full py-2.5 px-4 rounded-lg text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 transition">Avanti</button>
</div>
@endif
{{-- Step 2: Soglie --}}
@if($step === 2)
<div class="space-y-4">
<h3 class="text-lg font-semibold text-gray-800">Soglie e limiti</h3>
<div>
<label class="block text-sm font-medium text-gray-700">Giorni giacenza per "da assegnare"</label>
<input wire:model="giorni_giacenza_da_assegnare" type="number" min="1" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm px-4 py-2.5">
@error('giorni_giacenza_da_assegnare') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Giorni giacenza per "prioritari"</label>
<input wire:model="giorni_giacenza_prioritari" type="number" min="1" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm px-4 py-2.5">
@error('giorni_giacenza_prioritari') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Giorni per "smarrito / da rientrare"</label>
<input wire:model="giorni_per_smarrito" type="number" min="1" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm px-4 py-2.5">
@error('giorni_per_smarrito') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Limite lista rapida (Home)</label>
<input wire:model="home_limit_list" type="number" min="1" max="100" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm px-4 py-2.5">
@error('home_limit_list') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
</div>
<div class="flex gap-3">
<button wire:click="previousStep" class="flex-1 py-2.5 px-4 rounded-lg text-sm font-medium text-gray-700 bg-gray-100 hover:bg-gray-200 transition">Indietro</button>
<button wire:click="nextStep" class="flex-1 py-2.5 px-4 rounded-lg text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 transition">Avanti</button>
</div>
</div>
@endif
{{-- Step 3: Conferma --}}
@if($step === 3)
<div class="space-y-4">
<h3 class="text-lg font-semibold text-gray-800">Conferma e completa</h3>
<div class="bg-gray-50 rounded-lg p-4 text-sm space-y-2">
<p><span class="font-medium">Congregazione:</span> {{ $congregazione_nome }}</p>
<p><span class="font-medium">Giacenza da assegnare:</span> {{ $giorni_giacenza_da_assegnare }} gg</p>
<p><span class="font-medium">Giacenza prioritari:</span> {{ $giorni_giacenza_prioritari }} gg</p>
<p><span class="font-medium">Soglia smarrito:</span> {{ $giorni_per_smarrito }} gg</p>
<p><span class="font-medium">Limite liste Home:</span> {{ $home_limit_list }}</p>
</div>
@if($needsAdmin)
<div class="border-t pt-4 space-y-4">
<h4 class="text-md font-semibold text-gray-700">Crea account amministratore</h4>
<div>
<label class="block text-sm font-medium text-gray-700">Nome</label>
<input wire:model="admin_name" type="text" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm px-4 py-2.5">
@error('admin_name') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Email</label>
<input wire:model="admin_email" type="email" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm px-4 py-2.5">
@error('admin_email') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Password</label>
<input wire:model="admin_password" type="password" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm px-4 py-2.5">
@error('admin_password') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Conferma Password</label>
<input wire:model="admin_password_confirmation" type="password" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm px-4 py-2.5">
</div>
</div>
@endif
<div class="flex gap-3">
<button wire:click="previousStep" class="flex-1 py-2.5 px-4 rounded-lg text-sm font-medium text-gray-700 bg-gray-100 hover:bg-gray-200 transition">Indietro</button>
<button wire:click="finish" class="flex-1 py-2.5 px-4 rounded-lg text-sm font-medium text-white bg-green-600 hover:bg-green-700 transition">Completa Setup</button>
</div>
</div>
@endif
</div>

View File

@@ -0,0 +1,37 @@
<div>
<div class="mb-6">
<h1 class="text-2xl font-bold text-gray-900">Cestino Territori</h1>
<a href="{{ route('territori.index') }}" class="text-sm text-indigo-600 hover:text-indigo-800"> Torna alla lista</a>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase"></th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Eliminato il</th>
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase">Azioni</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
@forelse($territori as $territorio)
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 text-sm font-semibold text-gray-900">{{ $territorio->numero }}</td>
<td class="px-4 py-3 text-sm text-gray-600">{{ $territorio->deleted_at->format('d/m/Y H:i') }}</td>
<td class="px-4 py-3 text-sm text-right space-x-2">
<button wire:click="restore({{ $territorio->id }})" class="text-green-600 hover:text-green-800 text-xs font-medium">Ripristina</button>
<button wire:click="forceDelete({{ $territorio->id }})" wire:confirm="Eliminare DEFINITIVAMENTE il territorio {{ $territorio->numero }}? Questa azione è irreversibile." class="text-red-600 hover:text-red-800 text-xs font-medium">Elimina definitivamente</button>
</td>
</tr>
@empty
<tr>
<td colspan="3" class="px-4 py-8 text-center text-gray-500 text-sm">Il cestino è vuoto.</td>
</tr>
@endforelse
</tbody>
</table>
<div class="px-4 py-3 border-t border-gray-200">
{{ $territori->links() }}
</div>
</div>
</div>

View File

@@ -0,0 +1,68 @@
<div>
<div class="mb-6">
<h1 class="text-2xl font-bold text-gray-900">{{ $title }}</h1>
<a href="{{ route('territori.index') }}" class="text-sm text-indigo-600 hover:text-indigo-800"> Torna alla lista</a>
</div>
<form wire:submit="save" class="bg-white rounded-xl shadow-sm border border-gray-200 p-6 space-y-5 max-w-2xl">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-5">
<div>
<label class="block text-sm font-medium text-gray-700">Numero *</label>
<input wire:model="numero" type="text" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm">
@error('numero') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Zona</label>
<select wire:model="zona_id" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm">
<option value="">-- Nessuna --</option>
@foreach($zone as $zona)
<option value="{{ $zona->id }}">{{ $zona->nome }}</option>
@endforeach
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Tipologia</label>
<select wire:model="tipologia_id" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm">
<option value="">-- Nessuna --</option>
@foreach($tipologie as $tipologia)
<option value="{{ $tipologia->id }}">{{ $tipologia->nome }}</option>
@endforeach
</select>
</div>
<div class="flex items-center gap-3 pt-6">
<input wire:model="prioritario" type="checkbox" id="prioritario" class="h-4 w-4 text-indigo-600 border-gray-300 rounded">
<label for="prioritario" class="text-sm text-gray-700">Prioritario (manuale)</label>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Note</label>
<textarea wire:model="note" rows="3" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm"></textarea>
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Confini</label>
<textarea wire:model="confini" rows="3" class="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-sm"></textarea>
</div>
<div>
<label class="block text-sm font-medium text-gray-700">PDF Territorio</label>
<input wire:model="pdf" type="file" accept=".pdf" class="mt-1 block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-lg file:border-0 file:text-sm file:font-semibold file:bg-indigo-50 file:text-indigo-700 hover:file:bg-indigo-100">
@error('pdf') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
@if($isEdit && $this->territorio->pdf_path)
<div class="mt-2 flex items-center gap-2 text-sm">
<span class="text-green-600">PDF presente</span>
<button type="button" wire:click="removePdf" wire:confirm="Rimuovere il PDF?" class="text-red-600 hover:text-red-800 text-xs underline">Rimuovi PDF</button>
</div>
@endif
</div>
<div class="flex gap-3 pt-2">
<a href="{{ route('territori.index') }}" class="px-4 py-2.5 rounded-lg text-sm font-medium text-gray-700 bg-gray-100 hover:bg-gray-200 transition">Annulla</a>
<button type="submit" class="px-6 py-2.5 rounded-lg text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 transition">
{{ $isEdit ? 'Aggiorna' : 'Crea' }}
</button>
</div>
</form>
</div>

View File

@@ -0,0 +1,107 @@
<div>
<div class="sm:flex sm:items-center sm:justify-between mb-6">
<div>
<h1 class="text-2xl font-bold text-gray-900">Territori</h1>
<p class="text-sm text-gray-500 mt-1">Gestione dei territori della congregazione</p>
</div>
<div class="mt-4 sm:mt-0 flex gap-2">
<a href="{{ route('territori.cestino') }}" class="inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition">Cestino</a>
<a href="{{ route('territori.create') }}" class="inline-flex items-center px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">+ Nuovo territorio</a>
</div>
</div>
{{-- Filters --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 mb-4">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<input wire:model.live.debounce.300ms="search" type="text" placeholder="Cerca numero..."
class="rounded-lg border-gray-300 text-sm focus:border-indigo-500 focus:ring-indigo-500">
<select wire:model.live="filterZona" class="rounded-lg border-gray-300 text-sm focus:border-indigo-500 focus:ring-indigo-500">
<option value="">Tutte le zone</option>
@foreach($zone as $zona)
<option value="{{ $zona->id }}">{{ $zona->nome }}</option>
@endforeach
</select>
<select wire:model.live="filterTipologia" class="rounded-lg border-gray-300 text-sm focus:border-indigo-500 focus:ring-indigo-500">
<option value="">Tutte le tipologie</option>
@foreach($tipologie as $tipologia)
<option value="{{ $tipologia->id }}">{{ $tipologia->nome }}</option>
@endforeach
</select>
<select wire:model.live="filterStato" class="rounded-lg border-gray-300 text-sm focus:border-indigo-500 focus:ring-indigo-500">
<option value="">Tutti gli stati</option>
<option value="in_reparto">In reparto</option>
<option value="assegnato">Assegnato</option>
<option value="da_rientrare">Da rientrare</option>
<option value="inattivo">Inattivo</option>
</select>
</div>
</div>
{{-- Table --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th wire:click="sortBy('numero')" class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase cursor-pointer hover:text-gray-700">
@if($sortField === 'numero') <span>{{ $sortDirection === 'asc' ? '▲' : '▼' }}</span> @endif
</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Zona</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Tipologia</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Stato</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Assegnatario</th>
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase">Azioni</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
@forelse($territori as $territorio)
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 text-sm font-semibold text-gray-900">
<a href="{{ route('territori.show', $territorio) }}" class="hover:text-indigo-600">{{ $territorio->numero }}</a>
</td>
<td class="px-4 py-3 text-sm text-gray-600">{{ $territorio->zona?->nome ?? '-' }}</td>
<td class="px-4 py-3 text-sm text-gray-600">{{ $territorio->tipologia?->nome ?? '-' }}</td>
<td class="px-4 py-3 text-sm">
@php $stato = $territorio->stato; @endphp
<span class="inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-xs font-medium
{{ match($stato) {
'in_reparto' => 'bg-green-100 text-green-800',
'assegnato' => 'bg-blue-100 text-blue-800',
'da_rientrare' => 'bg-red-100 text-red-800',
'inattivo' => 'bg-gray-100 text-gray-600',
default => 'bg-gray-100 text-gray-600'
} }}">
{{ str_replace('_', ' ', ucfirst($stato)) }}
</span>
@if($territorio->is_prioritario)
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-amber-100 text-amber-800 ml-1"
title="{{ $territorio->prioritario ? 'Prioritario (manuale)' : 'Prioritario (giacenza)' }}">
{{ $territorio->prioritario ? 'Man.' : 'Auto' }}
</span>
@endif
</td>
<td class="px-4 py-3 text-sm text-gray-600">
{{ $territorio->assegnatario?->nome_completo ?? '-' }}
</td>
<td class="px-4 py-3 text-sm text-right space-x-1">
<a href="{{ route('territori.show', $territorio) }}" class="text-indigo-600 hover:text-indigo-800 text-xs font-medium">Dettaglio</a>
<a href="{{ route('territori.edit', $territorio) }}" class="text-gray-600 hover:text-gray-800 text-xs font-medium">Modifica</a>
<button wire:click="toggleActive({{ $territorio->id }})" class="text-xs font-medium {{ $territorio->attivo ? 'text-amber-600 hover:text-amber-800' : 'text-green-600 hover:text-green-800' }}">
{{ $territorio->attivo ? 'Disattiva' : 'Attiva' }}
</button>
<button wire:click="deleteTerritorio({{ $territorio->id }})" wire:confirm="Spostare il territorio {{ $territorio->numero }} nel cestino?" class="text-red-600 hover:text-red-800 text-xs font-medium">Elimina</button>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="px-4 py-8 text-center text-gray-500 text-sm">Nessun territorio trovato.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="px-4 py-3 border-t border-gray-200">
{{ $territori->links() }}
</div>
</div>
</div>

View File

@@ -0,0 +1,123 @@
<div>
<div class="mb-6 flex items-center justify-between">
<div>
<h1 class="text-2xl font-bold text-gray-900">Territorio {{ $territorio->numero }}</h1>
<a href="{{ route('territori.index') }}" class="text-sm text-indigo-600 hover:text-indigo-800"> Torna alla lista</a>
</div>
<a href="{{ route('territori.edit', $territorio) }}" class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">Modifica</a>
</div>
{{-- Info card --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6 mb-6">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div>
<p class="text-xs font-medium text-gray-500 uppercase">Stato</p>
@php $stato = $territorio->stato; @endphp
<span class="inline-flex items-center mt-1 px-2.5 py-0.5 rounded-full text-xs font-medium
{{ match($stato) {
'in_reparto' => 'bg-green-100 text-green-800',
'assegnato' => 'bg-blue-100 text-blue-800',
'da_rientrare' => 'bg-red-100 text-red-800',
'inattivo' => 'bg-gray-100 text-gray-600',
default => 'bg-gray-100 text-gray-600'
} }}">
{{ str_replace('_', ' ', ucfirst($stato)) }}
</span>
@if($territorio->is_prioritario)
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-amber-100 text-amber-800 ml-1"> Prioritario</span>
@endif
</div>
<div>
<p class="text-xs font-medium text-gray-500 uppercase">Zona</p>
<p class="mt-1 text-sm text-gray-900">{{ $territorio->zona?->nome ?? '-' }}</p>
</div>
<div>
<p class="text-xs font-medium text-gray-500 uppercase">Tipologia</p>
<p class="mt-1 text-sm text-gray-900">{{ $territorio->tipologia?->nome ?? '-' }}</p>
</div>
<div>
<p class="text-xs font-medium text-gray-500 uppercase">Assegnatario</p>
<p class="mt-1 text-sm text-gray-900">{{ $territorio->assegnatario?->nome_completo ?? 'Nessuno' }}</p>
</div>
</div>
@if($territorio->note)
<div class="mt-4 pt-4 border-t">
<p class="text-xs font-medium text-gray-500 uppercase">Note</p>
<p class="mt-1 text-sm text-gray-700">{{ $territorio->note }}</p>
</div>
@endif
@if($territorio->confini)
<div class="mt-4 pt-4 border-t">
<p class="text-xs font-medium text-gray-500 uppercase">Confini</p>
<p class="mt-1 text-sm text-gray-700">{{ $territorio->confini }}</p>
</div>
@endif
</div>
{{-- PDF viewer --}}
@if($territorio->pdf_path)
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 mb-6">
<h3 class="text-sm font-semibold text-gray-700 mb-3">PDF Territorio</h3>
<div class="w-full" style="min-height: 500px;">
<embed src="{{ asset('storage/' . $territorio->pdf_path) }}" type="application/pdf" width="100%" height="500px">
<p class="mt-2 text-sm text-gray-500">
Se il PDF non è visibile:
<a href="{{ asset('storage/' . $territorio->pdf_path) }}" target="_blank" class="text-indigo-600 hover:underline">Scarica PDF</a>
</p>
</div>
</div>
@endif
{{-- Assignment history --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6">
<h3 class="text-lg font-semibold text-gray-900 mb-4">Storico Assegnazioni</h3>
@forelse($assegnazioniPerAnno as $annoLabel => $assegnazioni)
<div class="mb-6">
<h4 class="text-sm font-semibold text-indigo-600 mb-2">Anno Teocratico {{ $annoLabel }}</h4>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 text-sm">
<thead class="bg-gray-50">
<tr>
<th class="px-3 py-2 text-left text-xs font-medium text-gray-500">Proclamatore</th>
<th class="px-3 py-2 text-left text-xs font-medium text-gray-500">Assegnato</th>
<th class="px-3 py-2 text-left text-xs font-medium text-gray-500">Rientrato</th>
<th class="px-3 py-2 text-left text-xs font-medium text-gray-500">Giorni</th>
<th class="px-3 py-2 text-left text-xs font-medium text-gray-500">Campagna</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100">
@foreach($assegnazioni as $assegnazione)
<tr>
<td class="px-3 py-2">{{ $assegnazione->proclamatore?->nome_completo ?? 'N/A' }}</td>
<td class="px-3 py-2">{{ $assegnazione->assigned_at->format('d/m/Y') }}</td>
<td class="px-3 py-2">
@if($assegnazione->returned_at)
{{ $assegnazione->returned_at->format('d/m/Y') }}
@else
<span class="text-amber-600 font-medium">In corso</span>
@endif
</td>
<td class="px-3 py-2">{{ $assegnazione->giorni }}</td>
<td class="px-3 py-2">
@if($assegnazione->counted_in_campaign)
<span class="text-green-600"> {{ $assegnazione->campagna?->descrizione }}</span>
@elseif($assegnazione->counted_in_campaign === false)
<span class="text-gray-400">No</span>
@else
<span class="text-gray-300">-</span>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@empty
<p class="text-gray-500 text-sm">Nessuna assegnazione registrata.</p>
@endforelse
</div>
</div>