netgescon-master/resources/views/superadmin/archivi/index.blade.php
2025-07-20 14:57:25 +00:00

261 lines
11 KiB
PHP

@extends('layouts.app-universal-v2')
@section('title', 'Gestione Archivi di Sistema')
@section('content')
<div class="container-fluid">
<!-- Header Archivi Sistema -->
<div class="row mb-4">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center">
<div>
<h1 class="h3 mb-0"><i class="fas fa-database text-primary me-2"></i>Gestione Archivi di Sistema</h1>
<p class="text-muted mb-0">Gestione e sincronizzazione archivi di sistema per NetGesCon</p>
</div>
<div>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#importModal">
<i class="fas fa-upload me-2"></i>Importa ZIP
</button>
</div>
</div>
</div>
</div>
<!-- Statistiche Generali -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card border-0 shadow-sm">
<div class="card-body text-center">
<div class="display-6 text-primary mb-2">
<i class="fas fa-city"></i>
</div>
<h5 class="card-title">{{ number_format($stats['comuni_count']) }}</h5>
<p class="card-text text-muted">Comuni Italiani</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card border-0 shadow-sm">
<div class="card-body text-center">
<div class="display-6 text-success mb-2">
<i class="fas fa-clock"></i>
</div>
<h5 class="card-title">
@if($stats['last_import'])
{{ \Carbon\Carbon::parse($stats['last_import'])->format('d/m/Y') }}
@else
Mai
@endif
</h5>
<p class="card-text text-muted">Ultimo Import</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card border-0 shadow-sm">
<div class="card-body text-center">
<div class="display-6 text-warning mb-2">
<i class="fas fa-hdd"></i>
</div>
<h5 class="card-title">{{ $stats['storage_size'] }}</h5>
<p class="card-text text-muted">Spazio Utilizzato</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card border-0 shadow-sm">
<div class="card-body text-center">
<div class="display-6 text-info mb-2">
<i class="fas fa-archive"></i>
</div>
<h5 class="card-title">{{ count($stats['available_archives']) }}</h5>
<p class="card-text text-muted">Archivi Disponibili</p>
</div>
</div>
</div>
</div>
<!-- Lista Archivi Disponibili -->
<div class="row">
<div class="col-12">
<div class="card border-0 shadow-sm">
<div class="card-header">
<h5 class="card-title mb-0">
<i class="fas fa-list me-2"></i>Archivi di Sistema
</h5>
</div>
<div class="card-body">
<div class="row">
@foreach($stats['available_archives'] as $key => $archive)
<div class="col-md-4 mb-3">
<div class="card h-100">
<div class="card-body">
<div class="d-flex justify-content-between align-items-start mb-3">
<h6 class="card-title">{{ $archive['nome'] }}</h6>
@if($archive['ultima_sincronizzazione'])
<span class="badge bg-success">Sincronizzato</span>
@else
<span class="badge bg-warning">Non sincronizzato</span>
@endif
</div>
<p class="card-text text-muted">{{ $archive['descrizione'] }}</p>
@if($archive['ultima_sincronizzazione'])
<small class="text-muted">
Ultimo aggiornamento: {{ \Carbon\Carbon::parse($archive['ultima_sincronizzazione'])->format('d/m/Y H:i') }}
</small>
@endif
</div>
<div class="card-footer bg-transparent">
<div class="btn-group w-100" role="group">
@if($key === 'comuni_italiani')
<a href="{{ route('superadmin.archivi.comuni') }}" class="btn btn-outline-primary btn-sm">
<i class="fas fa-eye me-1"></i>Visualizza
</a>
@endif
<button class="btn btn-outline-secondary btn-sm" onclick="importArchive('{{ $key }}')">
<i class="fas fa-sync me-1"></i>Importa
</button>
@if($key === 'comuni_italiani')
<button class="btn btn-outline-info btn-sm" onclick="sincronizzaIstat()">
<i class="fas fa-cloud-download-alt me-1"></i>ISTAT
</button>
@endif
</div>
</div>
</div>
</div>
@endforeach
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal Import ZIP -->
<div class="modal fade" id="importModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><i class="fas fa-upload me-2"></i>Importa Archivio ZIP</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="importForm" enctype="multipart/form-data">
@csrf
<div class="mb-3">
<label for="tipo_archivio" class="form-label">Tipo Archivio</label>
<select class="form-select" id="tipo_archivio" name="tipo_archivio" required>
<option value="">Seleziona tipo archivio...</option>
<option value="comuni_italiani">Comuni Italiani</option>
<option value="province">Province</option>
<option value="regioni">Regioni</option>
</select>
</div>
<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">
Carica un file ZIP contenente i dati JSON dell'archivio. Dimensione massima: 50MB.
</div>
</div>
<div class="progress d-none" id="uploadProgress">
<div class="progress-bar" role="progressbar" style="width: 0%"></div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annulla</button>
<button type="button" class="btn btn-primary" onclick="submitImport()">
<i class="fas fa-upload me-2"></i>Importa
</button>
</div>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
function importArchive(tipo) {
document.getElementById('tipo_archivio').value = tipo;
new bootstrap.Modal(document.getElementById('importModal')).show();
}
function submitImport() {
const form = document.getElementById('importForm');
const formData = new FormData(form);
const progress = document.getElementById('uploadProgress');
const progressBar = progress.querySelector('.progress-bar');
// Mostra progress bar
progress.classList.remove('d-none');
fetch('{{ route("superadmin.archivi.import") }}', {
method: 'POST',
body: formData,
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
}
})
.then(response => response.json())
.then(data => {
progress.classList.add('d-none');
if (data.success) {
showAlert('success', data.message);
location.reload(); // Ricarica per aggiornare le statistiche
} else {
showAlert('danger', data.message);
}
bootstrap.Modal.getInstance(document.getElementById('importModal')).hide();
})
.catch(error => {
progress.classList.add('d-none');
showAlert('danger', 'Errore durante l\'importazione: ' + error.message);
bootstrap.Modal.getInstance(document.getElementById('importModal')).hide();
});
}
function sincronizzaIstat() {
if (confirm('Avviare la sincronizzazione automatica con ISTAT?')) {
fetch('{{ route("superadmin.archivi.sincronizza-istat") }}', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
showAlert('success', data.message);
location.reload();
} else {
showAlert('info', data.message);
}
})
.catch(error => {
showAlert('danger', 'Errore durante la sincronizzazione: ' + error.message);
});
}
}
function showAlert(type, message) {
const alertHtml = `
<div class="alert alert-${type} alert-dismissible fade show" role="alert">
<i class="fas fa-${type === 'success' ? 'check-circle' : type === 'danger' ? 'exclamation-circle' : 'info-circle'} me-2"></i>
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
`;
const container = document.querySelector('.container-fluid');
container.insertAdjacentHTML('afterbegin', alertHtml);
}
</script>
@endpush