319 lines
20 KiB
PHP
319 lines
20 KiB
PHP
<x-app-layout>
|
|
<x-slot name="header">
|
|
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
|
|
{{ __('Gestione Chiavi') }} - {{ $stabile->denominazione }}
|
|
</h2>
|
|
</x-slot>
|
|
|
|
<div class="py-12">
|
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8 space-y-6">
|
|
|
|
{{-- Breadcrumb --}}
|
|
<nav class="flex" aria-label="Breadcrumb">
|
|
<ol class="inline-flex items-center space-x-1 md:space-x-3">
|
|
<li class="inline-flex items-center">
|
|
<a href="{{ route('admin.stabili.index') }}" class="text-gray-700 hover:text-gray-900">
|
|
<i class="fas fa-building mr-2"></i>Stabili
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<div class="flex items-center">
|
|
<i class="fas fa-chevron-right text-gray-400 mx-2"></i>
|
|
<a href="{{ route('admin.stabili.show', $stabile) }}" class="text-gray-700 hover:text-gray-900">
|
|
{{ $stabile->denominazione }}
|
|
</a>
|
|
</div>
|
|
</li>
|
|
<li aria-current="page">
|
|
<div class="flex items-center">
|
|
<i class="fas fa-chevron-right text-gray-400 mx-2"></i>
|
|
<span class="text-gray-500">Gestione Chiavi</span>
|
|
</div>
|
|
</li>
|
|
</ol>
|
|
</nav>
|
|
|
|
{{-- Header con statistiche --}}
|
|
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
|
|
<div class="p-6">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100">Archivio Chiavi</h3>
|
|
<button type="button"
|
|
onclick="document.getElementById('modal-nuova-chiave').classList.remove('hidden')"
|
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded transition-colors">
|
|
<i class="fas fa-plus mr-2"></i>Nuova Chiave
|
|
</button>
|
|
</div>
|
|
|
|
{{-- Statistiche Rapide --}}
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
|
|
<div class="bg-green-50 p-4 rounded-lg">
|
|
<div class="flex items-center">
|
|
<i class="fas fa-check-circle text-2xl text-green-600"></i>
|
|
<div class="ml-3">
|
|
<p class="text-sm font-medium text-green-600">Disponibili</p>
|
|
<p class="text-2xl font-bold text-green-900">{{ $chiavi->where('stato', 'disponibile')->count() }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-yellow-50 p-4 rounded-lg">
|
|
<div class="flex items-center">
|
|
<i class="fas fa-hand-paper text-2xl text-yellow-600"></i>
|
|
<div class="ml-3">
|
|
<p class="text-sm font-medium text-yellow-600">In Uso</p>
|
|
<p class="text-2xl font-bold text-yellow-900">{{ $chiavi->where('stato', 'in_uso')->count() }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-red-50 p-4 rounded-lg">
|
|
<div class="flex items-center">
|
|
<i class="fas fa-exclamation-triangle text-2xl text-red-600"></i>
|
|
<div class="ml-3">
|
|
<p class="text-sm font-medium text-red-600">Smarrite</p>
|
|
<p class="text-2xl font-bold text-red-900">{{ $chiavi->where('stato', 'smarrita')->count() }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-blue-50 p-4 rounded-lg">
|
|
<div class="flex items-center">
|
|
<i class="fas fa-key text-2xl text-blue-600"></i>
|
|
<div class="ml-3">
|
|
<p class="text-sm font-medium text-blue-600">Totali</p>
|
|
<p class="text-2xl font-bold text-blue-900">{{ $chiavi->count() }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Lista Chiavi --}}
|
|
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
|
|
<div class="p-6">
|
|
@if($chiavi->count() > 0)
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
|
<thead class="bg-gray-50 dark:bg-gray-700">
|
|
<tr>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
|
|
Chiave
|
|
</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
|
|
Tipo
|
|
</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
|
|
Stato
|
|
</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
|
|
QR Code
|
|
</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
|
|
Ultimo Movimento
|
|
</th>
|
|
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
|
|
Azioni
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
|
|
@foreach($chiavi as $chiave)
|
|
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700">
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
<div>
|
|
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">
|
|
{{ $chiave->nome }}
|
|
</div>
|
|
<div class="text-sm text-gray-500">
|
|
{{ $chiave->codice_identificativo }}
|
|
</div>
|
|
@if($chiave->descrizione)
|
|
<div class="text-xs text-gray-400 mt-1">
|
|
{{ Str::limit($chiave->descrizione, 50) }}
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
<span class="px-2 py-1 text-xs rounded-full {{ $chiave->tipo_badge }}">
|
|
<i class="{{ $chiave->tipo_icona }} mr-1"></i>
|
|
{{ $chiave->tipo_nome }}
|
|
</span>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
<span class="px-2 py-1 text-xs rounded-full {{ $chiave->stato_badge }}">
|
|
{{ $chiave->stato_nome }}
|
|
</span>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
<div class="text-xs text-gray-500 font-mono">
|
|
{{ Str::limit($chiave->qr_code, 20) }}
|
|
</div>
|
|
<button type="button"
|
|
class="text-blue-600 hover:text-blue-900 text-xs"
|
|
onclick="alert('QR Code: {{ $chiave->qr_code }}')">
|
|
<i class="fas fa-qrcode mr-1"></i>Mostra QR
|
|
</button>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
@if($chiave->movimenti->count() > 0)
|
|
@php $ultimo = $chiave->movimenti->first() @endphp
|
|
<div class="text-sm text-gray-900 dark:text-gray-100">
|
|
{{ $ultimo->tipo_movimento }}
|
|
</div>
|
|
<div class="text-xs text-gray-500">
|
|
{{ $ultimo->data_movimento->format('d/m/Y H:i') }}
|
|
</div>
|
|
<div class="text-xs text-gray-400">
|
|
{{ Str::limit($ultimo->soggetto_riferimento, 30) }}
|
|
</div>
|
|
@else
|
|
<span class="text-xs text-gray-400">Nessun movimento</span>
|
|
@endif
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
|
<button type="button"
|
|
onclick="openModalMovimento({{ $chiave->id }}, '{{ $chiave->nome }}')"
|
|
class="text-blue-600 hover:text-blue-900 mr-2">
|
|
<i class="fas fa-exchange-alt"></i>
|
|
</button>
|
|
<button type="button"
|
|
onclick="alert('Cronologia movimenti chiave: {{ $chiave->nome }}')"
|
|
class="text-green-600 hover:text-green-900">
|
|
<i class="fas fa-history"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
{{-- Paginazione --}}
|
|
<div class="mt-6">
|
|
{{ $chiavi->links() }}
|
|
</div>
|
|
@else
|
|
<div class="text-center py-12">
|
|
<i class="fas fa-key text-6xl text-gray-300 mb-4"></i>
|
|
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100 mb-2">Nessuna chiave registrata</h3>
|
|
<p class="text-gray-500 dark:text-gray-400 mb-6">Inizia creando la prima chiave per questo stabile</p>
|
|
<button type="button"
|
|
onclick="document.getElementById('modal-nuova-chiave').classList.remove('hidden')"
|
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
|
|
<i class="fas fa-plus mr-2"></i>Crea Prima Chiave
|
|
</button>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Modal Nuova Chiave --}}
|
|
<div id="modal-nuova-chiave" class="hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50">
|
|
<div class="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white">
|
|
<div class="mt-3">
|
|
<h3 class="text-lg font-medium text-gray-900 mb-4">Nuova Chiave</h3>
|
|
<form action="{{ route('admin.stabili.chiavi.store', $stabile) }}" method="POST">
|
|
@csrf
|
|
<div class="space-y-4">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700">Nome Chiave</label>
|
|
<input type="text" name="nome" required
|
|
class="mt-1 block w-full border-gray-300 rounded-md shadow-sm">
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700">Tipo</label>
|
|
<select name="tipo" required class="mt-1 block w-full border-gray-300 rounded-md shadow-sm">
|
|
<option value="">Seleziona tipo...</option>
|
|
<option value="unita">Unità Immobiliare</option>
|
|
<option value="comune">Spazio Comune</option>
|
|
<option value="tecnico">Locale Tecnico</option>
|
|
<option value="emergenza">Emergenza</option>
|
|
<option value="master">Master</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700">Descrizione (opzionale)</label>
|
|
<textarea name="descrizione" rows="3"
|
|
class="mt-1 block w-full border-gray-300 rounded-md shadow-sm"></textarea>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700">Codice Identificativo (opzionale)</label>
|
|
<input type="text" name="codice_identificativo"
|
|
placeholder="Se vuoto, verrà generato automaticamente"
|
|
class="mt-1 block w-full border-gray-300 rounded-md shadow-sm">
|
|
</div>
|
|
</div>
|
|
<div class="flex justify-end space-x-2 mt-6">
|
|
<button type="button"
|
|
onclick="document.getElementById('modal-nuova-chiave').classList.add('hidden')"
|
|
class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded">
|
|
Annulla
|
|
</button>
|
|
<button type="submit"
|
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
|
|
Crea Chiave
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Modal Movimento Chiave --}}
|
|
<div id="modal-movimento" class="hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50">
|
|
<div class="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white">
|
|
<div class="mt-3">
|
|
<h3 class="text-lg font-medium text-gray-900 mb-4">Movimento Chiave: <span id="movimento-chiave-nome"></span></h3>
|
|
<form id="form-movimento" method="POST">
|
|
@csrf
|
|
<div class="space-y-4">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700">Tipo Movimento</label>
|
|
<select name="tipo_movimento" required class="mt-1 block w-full border-gray-300 rounded-md shadow-sm">
|
|
<option value="">Seleziona movimento...</option>
|
|
<option value="consegna">Consegna</option>
|
|
<option value="restituzione">Restituzione</option>
|
|
<option value="smarrimento">Smarrimento</option>
|
|
<option value="duplicazione">Duplicazione</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700">Soggetto di Riferimento</label>
|
|
<input type="text" name="soggetto_riferimento" required
|
|
placeholder="Nome e cognome o descrizione"
|
|
class="mt-1 block w-full border-gray-300 rounded-md shadow-sm">
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700">Note (opzionali)</label>
|
|
<textarea name="note" rows="3"
|
|
class="mt-1 block w-full border-gray-300 rounded-md shadow-sm"></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="flex justify-end space-x-2 mt-6">
|
|
<button type="button"
|
|
onclick="document.getElementById('modal-movimento').classList.add('hidden')"
|
|
class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded">
|
|
Annulla
|
|
</button>
|
|
<button type="submit"
|
|
class="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">
|
|
Registra Movimento
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function openModalMovimento(chiaveId, nomeChiave) {
|
|
document.getElementById('movimento-chiave-nome').textContent = nomeChiave;
|
|
document.getElementById('form-movimento').action =
|
|
"{{ route('admin.stabili.chiavi.movimento', [$stabile, 'CHIAVE_ID']) }}".replace('CHIAVE_ID', chiaveId);
|
|
document.getElementById('modal-movimento').classList.remove('hidden');
|
|
}
|
|
</script>
|
|
</x-app-layout>
|