370 lines
18 KiB
PHP
370 lines
18 KiB
PHP
@extends('layouts.adminlte')
|
|
@section('title', 'Eventi')
|
|
@section('page_title', 'Eventi')
|
|
|
|
@php
|
|
$canWriteEventi = Auth::user()->canManage('eventi');
|
|
$canDeleteEventi = Auth::user()->canDelete('eventi');
|
|
@endphp
|
|
|
|
@section('content')
|
|
|
|
@if(session('success'))
|
|
<div class="alert alert-success alert-dismissible">
|
|
<button type="button" class="close" data-dismiss="alert">×</button>
|
|
{{ session('success') }}
|
|
</div>
|
|
@endif
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Tutti gli Eventi</h3>
|
|
<div class="card-tools">
|
|
<a href="/eventi/calendar" class="btn btn-sm btn-outline-primary mr-2">
|
|
<i class="fas fa-calendar-alt mr-1"></i> Calendario
|
|
</a>
|
|
<button type="button" class="btn btn-sm btn-success mr-2" onclick="exportSelectedIcs()">
|
|
<i class="fas fa-calendar-plus mr-1"></i> Esporta ICS
|
|
</button>
|
|
@if($canDeleteEventi)
|
|
<div class="btn-group mr-2">
|
|
<button type="button" class="btn btn-sm btn-danger" onclick="deleteSelected()">
|
|
<i class="fas fa-trash mr-1"></i> Elimina Selezionati
|
|
</button>
|
|
</div>
|
|
@endif
|
|
@if($canWriteEventi)
|
|
<a href="/eventi/import" class="btn btn-sm btn-warning mr-2">
|
|
<i class="fas fa-file-import mr-1"></i> Importa ICS
|
|
</a>
|
|
<a href="/eventi/create" class="btn btn-xs btn-success">
|
|
<i class="fas fa-plus mr-1"></i> Nuovo Evento
|
|
</a>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<form method="GET" class="mb-3">
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<input type="text" name="search" class="form-control" placeholder="Cerca evento..." value="{{ request('search') }}">
|
|
</div>
|
|
<div class="col-md-3">
|
|
<select name="gruppo_id" class="form-control" onchange="this.form.submit()">
|
|
<option value="">Tutti i gruppi</option>
|
|
@foreach($gruppi as $g)
|
|
<option value="{{ $g->id }}" {{ request('gruppo_id') == $g->id ? 'selected' : '' }}>{{ $g->full_path }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<select name="tipo" class="form-control" onchange="this.form.submit()">
|
|
<option value="">Tutte le ricorrenze</option>
|
|
<option value="singolo" {{ request('tipo') == 'singolo' ? 'selected' : '' }}>Singolo</option>
|
|
<option value="settimanale" {{ request('tipo') == 'settimanale' ? 'selected' : '' }}>Settimanale</option>
|
|
<option value="mensile" {{ request('tipo') == 'mensile' ? 'selected' : '' }}>Mensile</option>
|
|
<option value="annuale" {{ request('tipo') == 'annuale' ? 'selected' : '' }}>Annuale</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<button type="submit" class="btn btn-primary"><i class="fas fa-search mr-1"></i> Cerca</button>
|
|
<a href="/eventi" class="btn btn-secondary"><i class="fas fa-times"></i></a>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<table class="table table-bordered table-hover">
|
|
<thead class="thead-light">
|
|
<tr>
|
|
<th style="width: 40px;">
|
|
@if($canDeleteEventi)
|
|
<div class="custom-control custom-checkbox">
|
|
<input type="checkbox" class="custom-control-input" id="select-all" onchange="toggleSelectAll(this)">
|
|
<label class="custom-control-label" for="select-all"></label>
|
|
</div>
|
|
@endif
|
|
</th>
|
|
<th>
|
|
<a href="{{ request()->fullUrlWithQuery(['sort' => 'nome_evento', 'direction' => request('sort') === 'nome_evento' && request('direction') === 'asc' ? 'desc' : 'asc']) }}" class="text-dark">
|
|
Nome Evento
|
|
@if(request('sort') === 'nome_evento')
|
|
<i class="fas fa-sort-{{ request('direction') === 'asc' ? 'up' : 'down' }} ml-1"></i>
|
|
@else
|
|
<i class="fas fa-sort ml-1 text-muted"></i>
|
|
@endif
|
|
</a>
|
|
</th>
|
|
<th>
|
|
<a href="{{ request()->fullUrlWithQuery(['sort' => 'descrizione_evento', 'direction' => request('sort') === 'descrizione_evento' && request('direction') === 'asc' ? 'desc' : 'asc']) }}" class="text-dark">
|
|
Descrizione
|
|
@if(request('sort') === 'descrizione_evento')
|
|
<i class="fas fa-sort-{{ request('direction') === 'asc' ? 'up' : 'down' }} ml-1"></i>
|
|
@else
|
|
<i class="fas fa-sort ml-1 text-muted"></i>
|
|
@endif
|
|
</a>
|
|
</th>
|
|
<th>
|
|
<a href="{{ request()->fullUrlWithQuery(['sort' => 'tipo_evento', 'direction' => request('sort') === 'tipo_evento' && request('direction') === 'asc' ? 'desc' : 'asc']) }}" class="text-dark">
|
|
Tipologia
|
|
@if(request('sort') === 'tipo_evento')
|
|
<i class="fas fa-sort-{{ request('direction') === 'asc' ? 'up' : 'down' }} ml-1"></i>
|
|
@else
|
|
<i class="fas fa-sort ml-1 text-muted"></i>
|
|
@endif
|
|
</a>
|
|
</th>
|
|
<th>
|
|
<a href="{{ request()->fullUrlWithQuery(['sort' => 'tipo_recorrenza', 'direction' => request('sort') === 'tipo_recorrenza' && request('direction') === 'asc' ? 'desc' : 'asc']) }}" class="text-dark">
|
|
Ricorrenza
|
|
@if(request('sort') === 'tipo_recorrenza')
|
|
<i class="fas fa-sort-{{ request('direction') === 'asc' ? 'up' : 'down' }} ml-1"></i>
|
|
@else
|
|
<i class="fas fa-sort ml-1 text-muted"></i>
|
|
@endif
|
|
</a>
|
|
</th>
|
|
<th>
|
|
<a href="{{ request()->fullUrlWithQuery(['sort' => 'gruppi', 'direction' => request('sort') === 'gruppi' && request('direction') === 'asc' ? 'desc' : 'asc']) }}" class="text-dark">
|
|
Gruppi
|
|
@if(request('sort') === 'gruppi')
|
|
<i class="fas fa-sort-{{ request('direction') === 'asc' ? 'up' : 'down' }} ml-1"></i>
|
|
@else
|
|
<i class="fas fa-sort ml-1 text-muted"></i>
|
|
@endif
|
|
</a>
|
|
</th>
|
|
<th>
|
|
<a href="{{ request()->fullUrlWithQuery(['sort' => 'responsabili', 'direction' => request('sort') === 'responsabili' && request('direction') === 'asc' ? 'desc' : 'asc']) }}" class="text-dark">
|
|
Responsabili
|
|
@if(request('sort') === 'responsabili')
|
|
<i class="fas fa-sort-{{ request('direction') === 'asc' ? 'up' : 'down' }} ml-1"></i>
|
|
@else
|
|
<i class="fas fa-sort ml-1 text-muted"></i>
|
|
@endif
|
|
</a>
|
|
</th>
|
|
<th style="width: 120px;">
|
|
<a href="{{ request()->fullUrlWithQuery(['sort' => 'created_at', 'direction' => request('sort') === 'created_at' && request('direction') === 'asc' ? 'desc' : 'asc']) }}" class="text-dark">
|
|
Creato
|
|
@if(request('sort') === 'created_at')
|
|
<i class="fas fa-sort-{{ request('direction') === 'asc' ? 'up' : 'down' }} ml-1"></i>
|
|
@else
|
|
<i class="fas fa-sort ml-1 text-muted"></i>
|
|
@endif
|
|
</a>
|
|
</th>
|
|
<th style="width: 120px;">Azioni</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse($eventi as $evento)
|
|
<tr data-id="{{ $evento->id }}">
|
|
<td>
|
|
@if($canDeleteEventi)
|
|
<div class="custom-control custom-checkbox">
|
|
<input type="checkbox" class="custom-control-input row-checkbox" id="row-checkbox-{{ $evento->id }}" value="{{ $evento->id }}">
|
|
<label class="custom-control-label" for="row-checkbox-{{ $evento->id }}"></label>
|
|
</div>
|
|
@endif
|
|
</td>
|
|
<td>
|
|
<a href="/eventi/{{ $evento->id }}">
|
|
<i class="fas fa-calendar mr-1 text-primary"></i>
|
|
{{ $evento->nome_evento }}
|
|
</a>
|
|
@if($evento->is_incontro_gruppo)
|
|
<span class="badge badge-success ml-1">Incluso</span>
|
|
@endif
|
|
</td>
|
|
<td>{{ Str::limit($evento->descrizione_evento, 50) ?: '-' }}</td>
|
|
<td>
|
|
@if($evento->tipo_evento)
|
|
@php
|
|
$tipologiaEvento = \App\Models\TipologiaEvento::where('nome', $evento->tipo_evento)->first();
|
|
@endphp
|
|
@if($tipologiaEvento)
|
|
<span class="badge badge-primary">{{ $tipologiaEvento->descrizione ?: $tipologiaEvento->nome }}</span>
|
|
@else
|
|
<span class="badge badge-secondary">{{ $evento->tipo_evento }}</span>
|
|
@endif
|
|
@else
|
|
<span class="text-muted">-</span>
|
|
@endif
|
|
</td>
|
|
<td>
|
|
@if($evento->tipo_recorrenza && $evento->tipo_recorrenza !== 'singolo')
|
|
<span class="badge badge-info">{{ $evento->periodicita_label }}</span>
|
|
@else
|
|
<span class="badge badge-secondary">Singolo</span>
|
|
@endif
|
|
</td>
|
|
<td>
|
|
@forelse($evento->gruppi->take(2) as $gruppo)
|
|
<a href="/gruppi/{{ $gruppo->id }}">
|
|
<span class="badge badge-warning">{{ $gruppo->nome }}</span>
|
|
</a>
|
|
@empty
|
|
<span class="text-muted">-</span>
|
|
@endforelse
|
|
@if($evento->gruppi->count() > 2)
|
|
<small class="text-muted">+{{ $evento->gruppi->count() - 2 }}</small>
|
|
@endif
|
|
</td>
|
|
<td>
|
|
@forelse($evento->responsabili->take(2) as $resp)
|
|
<small>{{ $resp->nome_completo }}</small><br>
|
|
@empty
|
|
<span class="text-muted">-</span>
|
|
@endforelse
|
|
@if($evento->responsabili->count() > 2)
|
|
<small class="text-muted">+{{ $evento->responsabili->count() - 2 }} altri</small>
|
|
@endif
|
|
</td>
|
|
<td><small class="text-muted">{{ $evento->created_at->format('d/m/Y') }}</small></td>
|
|
<td>
|
|
<a href="{{ url('/eventi/' . $evento->id) }}" class="btn btn-xs btn-info" title="Visualizza">
|
|
<i class="fas fa-eye"></i>
|
|
</a>
|
|
@if($canWriteEventi)
|
|
<a href="{{ url('/eventi/' . $evento->id . '/edit') }}" class="btn btn-xs btn-warning" title="Modifica">
|
|
<i class="fas fa-edit"></i>
|
|
</a>
|
|
<form action="{{ url('/eventi/' . $evento->id) }}" method="POST" class="d-inline">
|
|
@csrf @method('DELETE')
|
|
<button type="submit" class="btn btn-xs btn-danger" onclick="return confirm('Confermi l\'eliminazione?')" title="Elimina">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</form>
|
|
@endif
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="9" class="text-center text-muted py-4">
|
|
<i class="fas fa-calendar fa-2x mb-2"></i>
|
|
<p class="mb-0">Nessun evento trovato</p>
|
|
</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="card-footer d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<form method="GET" class="form-inline" id="perPageForm">
|
|
<label class="mr-2 small">Righe per pagina:</label>
|
|
<select name="perPage" class="form-control form-control-sm" onchange="this.form.submit()" style="width: auto;">
|
|
@foreach([10, 20, 25, 50, 100] as $p)
|
|
<option value="{{ $p }}" {{ (int) request('perPage', 20) === $p ? 'selected' : '' }}>{{ $p }}</option>
|
|
@endforeach
|
|
</select>
|
|
@foreach(request()->except(['perPage', 'page']) as $key => $value)
|
|
@if(is_array($value))
|
|
@foreach($value as $v)
|
|
<input type="hidden" name="{{ $key }}[]" value="{{ $v }}">
|
|
@endforeach
|
|
@else
|
|
<input type="hidden" name="{{ $key }}" value="{{ $value }}">
|
|
@endif
|
|
@endforeach
|
|
</form>
|
|
</div>
|
|
<div>
|
|
{{ $eventi->links() }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog">
|
|
@if($canDeleteEventi)
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header bg-danger">
|
|
<h5 class="modal-title text-white"><i class="fas fa-trash-alt mr-2"></i>Conferma Eliminazione</h5>
|
|
<button type="button" class="close text-white" data-dismiss="modal">
|
|
<span>×</span>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>Stai per eliminare <strong id="delete-count">0</strong> eventi selezionati.</p>
|
|
<p class="text-muted small">Verranno eliminati anche i collegamenti con gruppi e responsabili.</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annulla</button>
|
|
<button type="button" class="btn btn-danger" onclick="confirmDelete()">Elimina</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endsection
|
|
|
|
@section('scripts')
|
|
<script>
|
|
function toggleSelectAll(source) {
|
|
document.querySelectorAll('.row-checkbox').forEach(cb => cb.checked = source.checked);
|
|
}
|
|
|
|
function getSelectedIds() {
|
|
return Array.from(document.querySelectorAll('.row-checkbox:checked')).map(cb => cb.value);
|
|
}
|
|
|
|
function deleteSelected() {
|
|
const selectedIds = getSelectedIds();
|
|
if (selectedIds.length === 0) {
|
|
alert('Seleziona almeno un evento');
|
|
return;
|
|
}
|
|
|
|
document.getElementById('delete-count').textContent = selectedIds.length;
|
|
|
|
document.querySelector('#deleteModal .btn-danger').onclick = function() {
|
|
const form = document.createElement('form');
|
|
form.method = 'POST';
|
|
form.action = '/eventi/mass-elimina';
|
|
|
|
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content || '{{ csrf_token() }}';
|
|
|
|
let html = `<input type="hidden" name="_token" value="${csrfToken}">`;
|
|
selectedIds.forEach(function(id) {
|
|
html += `<input type="hidden" name="ids[]" value="${id}">`;
|
|
});
|
|
|
|
form.innerHTML = html;
|
|
document.body.appendChild(form);
|
|
form.submit();
|
|
};
|
|
|
|
$('#deleteModal').modal('show');
|
|
}
|
|
|
|
function exportSelectedIcs() {
|
|
const selectedIds = getSelectedIds();
|
|
const form = document.createElement('form');
|
|
form.method = 'POST';
|
|
form.action = '/eventi/export-ics';
|
|
|
|
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content || '{{ csrf_token() }}';
|
|
|
|
let html = `<input type="hidden" name="_token" value="${csrfToken}">`;
|
|
|
|
if (selectedIds.length > 0) {
|
|
selectedIds.forEach(function(id) {
|
|
html += `<input type="hidden" name="ids[]" value="${id}">`;
|
|
});
|
|
} else {
|
|
const params = new URLSearchParams(window.location.search);
|
|
params.forEach(function(value, key) {
|
|
if (key === 'search') html += `<input type="hidden" name="search" value="${value}">`;
|
|
if (key === 'gruppo_id') html += `<input type="hidden" name="gruppo_id" value="${value}">`;
|
|
if (key === 'tipo') html += `<input type="hidden" name="tipo" value="${value}">`;
|
|
});
|
|
}
|
|
|
|
form.innerHTML = html;
|
|
document.body.appendChild(form);
|
|
form.submit();
|
|
}
|
|
</script>
|
|
@endsection |