netgescon-master/netgescon-laravel/resources/views/superadmin/comuni/index.blade.php

447 lines
18 KiB
PHP

{{-- Dashboard gestione comuni italiani SuperAdmin --}}
@extends('layouts.app-universal-v2')
@section('title', 'Gestione Comuni Italiani')
@section('content')
<div class="container-fluid">
<div class="row mb-4">
<div class="col-12">
<div class="d-flex align-items-center justify-content-between">
<div>
<h1 class="h4 mb-1 text-primary">
<i class="fas fa-map-marked-alt me-2"></i>Gestione Comuni Italiani
</h1>
<p class="text-muted mb-0 small">
Importazione, gestione e ricerca comuni italiani da archivi ufficiali
</p>
</div>
<div class="text-muted text-end small">
<i class="fas fa-crown me-1"></i>SuperAdmin Panel
</div>
</div>
</div>
</div>
{{-- Statistiche comuni --}}
<div class="row mb-4">
<div class="col-md-3">
<div class="card bg-primary text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h6 class="card-title mb-1 small">
<i class="fas fa-city me-2"></i>Comuni Totali
</h6>
<h3 class="mb-0">{{ number_format($stats['comuni_totali']) }}</h3>
<small class="opacity-75">Comuni caricati</small>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-success text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h6 class="card-title mb-1 small">
<i class="fas fa-map me-2"></i>Regioni
</h6>
<h3 class="mb-0">{{ $stats['regioni_totali'] }}</h3>
<small class="opacity-75">Regioni coperte</small>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-info text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h6 class="card-title mb-1 small">
<i class="fas fa-location-dot me-2"></i>Province
</h6>
<h3 class="mb-0">{{ $stats['province_totali'] }}</h3>
<small class="opacity-75">Province coperte</small>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-warning text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h6 class="card-title mb-1 small">
<i class="fas fa-clock me-2"></i>Ultimo Aggiornamento
</h6>
<div class="mb-0">
@if($stats['ultimo_aggiornamento'])
{{ \Carbon\Carbon::parse($stats['ultimo_aggiornamento'])->format('d/m/Y') }}
@else
<small>Nessun dato</small>
@endif
</div>
<small class="opacity-75">Data ultimo import</small>
</div>
</div>
</div>
</div>
</div>
</div>
{{-- Sezioni gestione --}}
<div class="row">
{{-- Upload ZIP --}}
<div class="col-md-6 mb-4">
<div class="card h-100">
<div class="card-header">
<h5 class="mb-0">
<i class="fas fa-file-archive me-2"></i>Importazione da ZIP
</h5>
</div>
<div class="card-body">
<p class="text-muted">
Carica un file ZIP contenente i dati dei comuni italiani in formato JSON.
Il sistema supporta l'importazione di più file JSON contemporaneamente.
</p>
<form id="upload-form" enctype="multipart/form-data">
@csrf
<div class="mb-3">
<label for="zip_file" class="form-label">File ZIP</label>
<input type="file" class="form-control" id="zip_file" name="zip_file" accept=".zip" required>
<div class="form-text">Formato supportato: ZIP (max 50MB)</div>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="overwrite" name="overwrite">
<label class="form-check-label" for="overwrite">
Sovrascrivi dati esistenti
</label>
<div class="form-text text-warning">
<i class="fas fa-exclamation-triangle me-1"></i>
Se selezionato, i comuni esistenti verranno aggiornati
</div>
</div>
<button type="submit" class="btn btn-primary">
<i class="fas fa-upload me-2"></i>Avvia Importazione
</button>
</form>
<div id="upload-progress" class="mt-3" style="display: none;">
<div class="progress">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 0%"></div>
</div>
<div class="text-center mt-2">
<small class="text-muted">Importazione in corso...</small>
</div>
</div>
</div>
</div>
</div>
{{-- Ricerca comuni --}}
<div class="col-md-6 mb-4">
<div class="card h-100">
<div class="card-header">
<h5 class="mb-0">
<i class="fas fa-search me-2"></i>Ricerca Comuni
</h5>
</div>
<div class="card-body">
<div class="mb-3">
<label for="search-comuni" class="form-label">Cerca comune</label>
<input type="text" class="form-control" id="search-comuni" placeholder="Nome comune o codice catastale">
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="filter-regione" class="form-label">Regione</label>
<select class="form-select" id="filter-regione">
<option value="">Tutte le regioni</option>
</select>
</div>
<div class="col-md-6 mb-3">
<label for="filter-provincia" class="form-label">Provincia</label>
<select class="form-select" id="filter-provincia">
<option value="">Tutte le province</option>
</select>
</div>
</div>
<button type="button" class="btn btn-info w-100" onclick="searchComuni()">
<i class="fas fa-search me-2"></i>Cerca
</button>
</div>
</div>
</div>
</div>
{{-- Risultati ricerca --}}
<div class="row" id="search-results" style="display: none;">
<div class="col-12">
<div class="card">
<div class="card-header">
<h5 class="mb-0">
<i class="fas fa-list me-2"></i>Risultati Ricerca
</h5>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped" id="comuni-table">
<thead>
<tr>
<th>Denominazione</th>
<th>Cod. Catastale</th>
<th>CAP</th>
<th>Provincia</th>
<th>Regione</th>
</tr>
</thead>
<tbody id="comuni-table-body">
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{{-- Azioni amministrative --}}
<div class="row mt-4">
<div class="col-12">
<div class="card border-danger">
<div class="card-header bg-danger text-white">
<h5 class="mb-0">
<i class="fas fa-exclamation-triangle me-2"></i>Azioni Amministrative
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-4">
<button type="button" class="btn btn-outline-info w-100" onclick="exportComuni()">
<i class="fas fa-download me-2"></i>Esporta Comuni
</button>
</div>
<div class="col-md-4">
<button type="button" class="btn btn-outline-warning w-100" onclick="showStats()">
<i class="fas fa-chart-bar me-2"></i>Statistiche Dettagliate
</button>
</div>
<div class="col-md-4">
<button type="button" class="btn btn-outline-danger w-100" onclick="resetDatabase()">
<i class="fas fa-trash me-2"></i>Reset Database
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{{-- Modal statistiche --}}
<div class="modal fade" id="statsModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="fas fa-chart-bar me-2"></i>Statistiche Dettagliate
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body" id="stats-content">
<div class="text-center">
<i class="fas fa-spinner fa-spin"></i> Caricamento...
</div>
</div>
</div>
</div>
</div>
@push('scripts')
<script>
document.addEventListener('DOMContentLoaded', function() {
// Upload form handler
document.getElementById('upload-form').addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(this);
const progressContainer = document.getElementById('upload-progress');
const progressBar = progressContainer.querySelector('.progress-bar');
// Mostra progress bar
progressContainer.style.display = 'block';
progressBar.style.width = '0%';
fetch('{{ route("superadmin.comuni.upload") }}', {
method: 'POST',
body: formData,
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
}
})
.then(response => response.json())
.then(data => {
progressBar.style.width = '100%';
if (data.success) {
alert('Importazione completata: ' + data.message);
window.location.reload();
} else {
alert('Errore: ' + data.message);
}
})
.catch(error => {
console.error('Errore:', error);
alert('Errore durante l\'importazione');
})
.finally(() => {
progressContainer.style.display = 'none';
});
});
});
function searchComuni() {
const query = document.getElementById('search-comuni').value;
const regione = document.getElementById('filter-regione').value;
const provincia = document.getElementById('filter-provincia').value;
const params = new URLSearchParams();
if (query) params.append('q', query);
if (regione) params.append('regione', regione);
if (provincia) params.append('provincia', provincia);
fetch(`{{ route("superadmin.comuni.search") }}?${params}`)
.then(response => response.json())
.then(data => {
displaySearchResults(data);
})
.catch(error => {
console.error('Errore ricerca:', error);
alert('Errore durante la ricerca');
});
}
function displaySearchResults(comuni) {
const tbody = document.getElementById('comuni-table-body');
const resultsContainer = document.getElementById('search-results');
tbody.innerHTML = '';
comuni.forEach(comune => {
const row = tbody.insertRow();
row.innerHTML = `
<td>${comune.denominazione}</td>
<td>${comune.codice_catastale || '-'}</td>
<td>${comune.cap || '-'}</td>
<td>${comune.provincia || '-'}</td>
<td>${comune.regione || '-'}</td>
`;
});
resultsContainer.style.display = 'block';
}
function exportComuni() {
const regione = document.getElementById('filter-regione').value;
const provincia = document.getElementById('filter-provincia').value;
const params = new URLSearchParams();
if (regione) params.append('regione', regione);
if (provincia) params.append('provincia', provincia);
window.open(`{{ route("superadmin.comuni.export") }}?${params}`, '_blank');
}
function showStats() {
const modal = new bootstrap.Modal(document.getElementById('statsModal'));
modal.show();
fetch('{{ route("superadmin.comuni.stats") }}')
.then(response => response.json())
.then(data => {
document.getElementById('stats-content').innerHTML = generateStatsHTML(data);
})
.catch(error => {
document.getElementById('stats-content').innerHTML = '<div class="alert alert-danger">Errore nel caricamento delle statistiche</div>';
});
}
function generateStatsHTML(data) {
return `
<div class="row">
<div class="col-md-6">
<h6>Comuni per Regione (Top 10)</h6>
<ul class="list-group">
${data.per_regione.slice(0, 10).map(item =>
`<li class="list-group-item d-flex justify-content-between">
<span>${item.regione || 'N/D'}</span>
<badge class="badge bg-primary">${item.totale}</badge>
</li>`
).join('')}
</ul>
</div>
<div class="col-md-6">
<h6>Totali</h6>
<ul class="list-group">
<li class="list-group-item d-flex justify-content-between">
<span>Comuni totali</span>
<badge class="badge bg-success">${data.totali.comuni}</badge>
</li>
<li class="list-group-item d-flex justify-content-between">
<span>Regioni</span>
<badge class="badge bg-info">${data.totali.regioni}</badge>
</li>
<li class="list-group-item d-flex justify-content-between">
<span>Province</span>
<badge class="badge bg-warning">${data.totali.province}</badge>
</li>
</ul>
</div>
</div>
`;
}
function resetDatabase() {
if (!confirm('ATTENZIONE: Questa operazione eliminerà TUTTI i comuni dal database. Sei sicuro?')) {
return;
}
const confirmation = prompt('Per confermare, scrivi "RESET_COMUNI":');
if (confirmation !== 'RESET_COMUNI') {
alert('Operazione annullata');
return;
}
fetch('{{ route("superadmin.comuni.reset") }}', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
'Content-Type': 'application/json'
},
body: JSON.stringify({ confirm: 'RESET_COMUNI' })
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert(data.message);
window.location.reload();
} else {
alert('Errore: ' + data.message);
}
})
.catch(error => {
console.error('Errore:', error);
alert('Errore durante il reset');
});
}
</script>
@endpush
@endsection