384 lines
20 KiB
PHP
384 lines
20 KiB
PHP
@extends('admin.layouts.netgescon')
|
|
|
|
@section('title', 'Contabilità GESCON')
|
|
|
|
@section('content')
|
|
<!-- Breadcrumb -->
|
|
<nav class="flex mb-6" aria-label="Breadcrumb">
|
|
<ol class="inline-flex items-center space-x-1 md:space-x-3">
|
|
@foreach($breadcrumbs as $breadcrumb)
|
|
<li class="inline-flex items-center">
|
|
@if(!$loop->last)
|
|
@if(isset($breadcrumb['url']))
|
|
<a href="{{ $breadcrumb['url'] }}"
|
|
class="inline-flex items-center text-sm font-medium text-gray-700 hover:text-blue-600 dark:text-gray-400 dark:hover:text-white">
|
|
<i class="{{ $breadcrumb['icon'] }} w-3 h-3 mr-2.5"></i>
|
|
{{ $breadcrumb['title'] }}
|
|
</a>
|
|
<svg class="w-3 h-3 text-gray-400 mx-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
|
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4"/>
|
|
</svg>
|
|
@else
|
|
<span class="inline-flex items-center text-sm font-medium text-gray-700 dark:text-gray-400">
|
|
<i class="{{ $breadcrumb['icon'] }} w-3 h-3 mr-2.5"></i>
|
|
{{ $breadcrumb['title'] }}
|
|
</span>
|
|
<svg class="w-3 h-3 text-gray-400 mx-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
|
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4"/>
|
|
</svg>
|
|
@endif
|
|
@else
|
|
<span class="ml-1 text-sm font-medium text-gray-500 md:ml-2 dark:text-gray-400">
|
|
<i class="{{ $breadcrumb['icon'] }} w-3 h-3 mr-2.5"></i>
|
|
{{ $breadcrumb['title'] }}
|
|
</span>
|
|
@endif
|
|
</li>
|
|
@endforeach
|
|
</ol>
|
|
</nav>
|
|
|
|
<!-- Page Header -->
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 mb-6">
|
|
<div class="p-6">
|
|
<div class="flex flex-col lg:flex-row lg:items-center lg:justify-between">
|
|
<!-- Title & Subtitle -->
|
|
<div class="mb-4 lg:mb-0">
|
|
<h1 class="text-2xl font-bold text-gray-900 dark:text-white mb-2">
|
|
{{ $pageTitle }}
|
|
</h1>
|
|
<p class="text-gray-600 dark:text-gray-400">
|
|
{{ $pageSubtitle }}
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Page Actions -->
|
|
<div class="flex flex-col sm:flex-row space-y-2 sm:space-y-0 sm:space-x-3">
|
|
@foreach($pageActions as $action)
|
|
<a href="{{ $action['url'] }}"
|
|
class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md
|
|
@if($action['type'] === 'primary')
|
|
text-white bg-blue-600 hover:bg-blue-700 focus:ring-blue-500
|
|
@else
|
|
text-gray-700 bg-white border-gray-300 hover:bg-gray-50 focus:ring-blue-500
|
|
@endif
|
|
focus:outline-none focus:ring-2 focus:ring-offset-2">
|
|
<i class="{{ $action['icon'] }} w-4 h-4 mr-2"></i>
|
|
{{ $action['label'] }}
|
|
</a>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Statistics Cards -->
|
|
<div class="mt-6 grid grid-cols-2 md:grid-cols-4 lg:grid-cols-8 gap-4">
|
|
<div class="bg-blue-50 dark:bg-blue-900 p-3 rounded-lg">
|
|
<div class="text-sm font-medium text-blue-600 dark:text-blue-400">Operazioni</div>
|
|
<div class="text-lg font-bold text-blue-900 dark:text-blue-100">{{ $stats['operazioni'] }}</div>
|
|
</div>
|
|
<div class="bg-green-50 dark:bg-green-900 p-3 rounded-lg">
|
|
<div class="text-sm font-medium text-green-600 dark:text-green-400">Entrate</div>
|
|
<div class="text-lg font-bold text-green-900 dark:text-green-100">{{ $stats['entrate'] }}</div>
|
|
</div>
|
|
<div class="bg-red-50 dark:bg-red-900 p-3 rounded-lg">
|
|
<div class="text-sm font-medium text-red-600 dark:text-red-400">Uscite</div>
|
|
<div class="text-lg font-bold text-red-900 dark:text-red-100">{{ $stats['uscite'] }}</div>
|
|
</div>
|
|
<div class="bg-purple-50 dark:bg-purple-900 p-3 rounded-lg">
|
|
<div class="text-sm font-medium text-purple-600 dark:text-purple-400">Saldo</div>
|
|
<div class="text-lg font-bold text-purple-900 dark:text-purple-100">€{{ $stats['saldo'] }}</div>
|
|
</div>
|
|
<div class="bg-yellow-50 dark:bg-yellow-900 p-3 rounded-lg">
|
|
<div class="text-sm font-medium text-yellow-600 dark:text-yellow-400">Tot. Entrate</div>
|
|
<div class="text-lg font-bold text-yellow-900 dark:text-yellow-100">€{{ $stats['totale_entrate'] }}</div>
|
|
</div>
|
|
<div class="bg-orange-50 dark:bg-orange-900 p-3 rounded-lg">
|
|
<div class="text-sm font-medium text-orange-600 dark:text-orange-400">Tot. Uscite</div>
|
|
<div class="text-lg font-bold text-orange-900 dark:text-orange-100">€{{ $stats['totale_uscite'] }}</div>
|
|
</div>
|
|
<div class="bg-indigo-50 dark:bg-indigo-900 p-3 rounded-lg">
|
|
<div class="text-sm font-medium text-indigo-600 dark:text-indigo-400">Voci</div>
|
|
<div class="text-lg font-bold text-indigo-900 dark:text-indigo-100">{{ $stats['voci_utilizzate'] }}</div>
|
|
</div>
|
|
<div class="bg-teal-50 dark:bg-teal-900 p-3 rounded-lg">
|
|
<div class="text-sm font-medium text-teal-600 dark:text-teal-400">Fornitori</div>
|
|
<div class="text-lg font-bold text-teal-900 dark:text-teal-100">{{ $stats['fornitori_utilizzati'] }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab Navigation -->
|
|
<div class="mb-6">
|
|
<nav class="flex space-x-8" aria-label="Tabs">
|
|
<button class="contabilita-tab-button active" data-tab="elenco">
|
|
<i class="fas fa-list w-4 h-4 mr-2"></i>
|
|
Elenco Operazioni
|
|
</button>
|
|
<button class="contabilita-tab-button" data-tab="dettaglio">
|
|
<i class="fas fa-chart-pie w-4 h-4 mr-2"></i>
|
|
Dettaglio Personali
|
|
</button>
|
|
</nav>
|
|
</div>
|
|
|
|
<!-- Tab: Elenco Operazioni -->
|
|
<div id="tab-elenco" class="contabilita-tab-content active">
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
|
<!-- Filtri -->
|
|
<div class="p-4 border-b border-gray-200 dark:border-gray-700">
|
|
<form method="GET" class="space-y-4" id="filter-form">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-6 gap-4">
|
|
<!-- Search -->
|
|
<div class="lg:col-span-2">
|
|
<label for="search" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
|
Cerca operazioni
|
|
</label>
|
|
<div class="relative">
|
|
<input type="text"
|
|
name="search"
|
|
id="search"
|
|
value="{{ request('search') }}"
|
|
class="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md leading-5 bg-white dark:bg-gray-700 placeholder-gray-500 focus:outline-none focus:placeholder-gray-400 focus:ring-1 focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
|
placeholder="Descrizione, fornitore, fattura...">
|
|
<div class="absolute inset-y-0 left-0 pl-3 flex items-center">
|
|
<i class="fas fa-search h-4 w-4 text-gray-400"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Natura -->
|
|
<div>
|
|
<label for="natura" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
|
Natura
|
|
</label>
|
|
<select name="natura" id="natura"
|
|
class="block w-full px-3 py-2 border border-gray-300 rounded-md bg-white dark:bg-gray-700 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
|
|
<option value="">Tutte</option>
|
|
@foreach($filters['natura'] as $filter)
|
|
<option value="{{ $filter['value'] }}"
|
|
{{ request('natura') === $filter['value'] ? 'selected' : '' }}>
|
|
{{ $filter['label'] }}
|
|
</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Anno -->
|
|
<div>
|
|
<label for="anno" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
|
Anno
|
|
</label>
|
|
<select name="anno" id="anno"
|
|
class="block w-full px-3 py-2 border border-gray-300 rounded-md bg-white dark:bg-gray-700 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
|
|
<option value="">Tutti</option>
|
|
@foreach($filters['anno'] as $filter)
|
|
<option value="{{ $filter['value'] }}"
|
|
{{ request('anno') === $filter['value'] ? 'selected' : '' }}>
|
|
{{ $filter['label'] }}
|
|
</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Tipo -->
|
|
<div>
|
|
<label for="tipo" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
|
Tipo
|
|
</label>
|
|
<select name="tipo" id="tipo"
|
|
class="block w-full px-3 py-2 border border-gray-300 rounded-md bg-white dark:bg-gray-700 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
|
|
<option value="">Tutti</option>
|
|
@foreach($filters['tipo'] as $filter)
|
|
<option value="{{ $filter['value'] }}"
|
|
{{ request('tipo') === $filter['value'] ? 'selected' : '' }}>
|
|
{{ $filter['label'] }}
|
|
</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Actions -->
|
|
<div class="flex items-end space-x-2">
|
|
<button type="submit"
|
|
class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-md text-sm font-medium focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
<i class="fas fa-search w-4 h-4 mr-1"></i>
|
|
Filtra
|
|
</button>
|
|
<a href="{{ route('admin.contabilita-gescon.index') }}"
|
|
class="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-md text-sm font-medium focus:outline-none focus:ring-2 focus:ring-gray-500">
|
|
<i class="fas fa-times w-4 h-4 mr-1"></i>
|
|
Reset
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Tabella Operazioni -->
|
|
<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-800">
|
|
<tr>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
Data
|
|
</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
Voce
|
|
</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
Descrizione
|
|
</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
Fornitore
|
|
</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
Natura
|
|
</th>
|
|
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
Euro
|
|
</th>
|
|
<th class="px-6 py-3 text-center text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
Azioni
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
|
|
@forelse($operazioni as $operazione)
|
|
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700">
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
|
|
{{ $operazione->data_spesa ? \Carbon\Carbon::parse($operazione->data_spesa)->format('d/m/Y') : '-' }}
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-gray-100">
|
|
{{ $operazione->cod_spe ?? '-' }}
|
|
</td>
|
|
<td class="px-6 py-4 text-sm text-gray-900 dark:text-gray-100 max-w-xs truncate">
|
|
{{ $operazione->descrizione_spesa ?? '-' }}
|
|
</td>
|
|
<td class="px-6 py-4 text-sm text-gray-900 dark:text-gray-100 max-w-xs truncate">
|
|
{{ $operazione->ragione_sociale_fornitore ?? $operazione->beneficiario ?? '-' }}
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
|
|
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full
|
|
{{ $operazione->natura === 'A' ? 'bg-blue-100 text-blue-800' :
|
|
($operazione->natura === 'P' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800') }}">
|
|
{{ $operazione->natura ?? '-' }}
|
|
</span>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-right font-medium">
|
|
@if($operazione->importo_euro > 0)
|
|
<span class="text-green-600 dark:text-green-400">
|
|
+€{{ number_format($operazione->importo_euro, 2) }}
|
|
</span>
|
|
@elseif($operazione->importo_euro < 0)
|
|
<span class="text-red-600 dark:text-red-400">
|
|
-€{{ number_format(abs($operazione->importo_euro), 2) }}
|
|
</span>
|
|
@else
|
|
<span class="text-gray-500">€0,00</span>
|
|
@endif
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-center text-sm font-medium">
|
|
<a href="{{ route('admin.contabilita-gescon.show', $operazione->id) }}"
|
|
class="text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300">
|
|
<i class="fas fa-eye w-4 h-4"></i>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="7" class="px-6 py-8 text-center text-sm text-gray-500 dark:text-gray-400">
|
|
<i class="fas fa-inbox text-gray-300 text-4xl mb-3"></i>
|
|
<div>Nessuna operazione trovata con i filtri applicati</div>
|
|
</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Paginazione -->
|
|
@if($operazioni->hasPages())
|
|
<div class="px-6 py-4 border-t border-gray-200 dark:border-gray-700">
|
|
{{ $operazioni->links() }}
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab: Dettaglio Personali -->
|
|
<div id="tab-dettaglio" class="contabilita-tab-content hidden">
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6">
|
|
<div class="text-center py-12">
|
|
<i class="fas fa-chart-pie text-gray-300 text-6xl mb-4"></i>
|
|
<h3 class="text-lg font-medium text-gray-900 dark:text-white mb-2">
|
|
Dettaglio Personali
|
|
</h3>
|
|
<p class="text-gray-500 dark:text-gray-400">
|
|
Funzionalità in sviluppo - Qui verranno mostrati grafici e analisi dettagliate delle operazioni
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@endsection
|
|
|
|
@push('styles')
|
|
<style>
|
|
.contabilita-tab-button {
|
|
@apply inline-flex items-center px-4 py-2 border-b-2 border-transparent text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300;
|
|
}
|
|
|
|
.contabilita-tab-button.active {
|
|
@apply border-blue-500 text-blue-600;
|
|
}
|
|
|
|
.contabilita-tab-content {
|
|
@apply block;
|
|
}
|
|
|
|
.contabilita-tab-content.hidden {
|
|
@apply hidden;
|
|
}
|
|
</style>
|
|
@endpush
|
|
|
|
@push('scripts')
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Tab Navigation
|
|
const tabButtons = document.querySelectorAll('.contabilita-tab-button');
|
|
const tabContents = document.querySelectorAll('.contabilita-tab-content');
|
|
|
|
tabButtons.forEach(button => {
|
|
button.addEventListener('click', function() {
|
|
const tabName = this.dataset.tab;
|
|
|
|
// Remove active class from all buttons and contents
|
|
tabButtons.forEach(btn => btn.classList.remove('active'));
|
|
tabContents.forEach(content => content.classList.add('hidden'));
|
|
|
|
// Add active class to clicked button and corresponding content
|
|
this.classList.add('active');
|
|
document.getElementById(`tab-${tabName}`).classList.remove('hidden');
|
|
});
|
|
});
|
|
|
|
// Auto-submit filtri quando cambiano
|
|
const filterSelects = document.querySelectorAll('#filter-form select');
|
|
filterSelects.forEach(select => {
|
|
select.addEventListener('change', function() {
|
|
document.getElementById('filter-form').submit();
|
|
});
|
|
});
|
|
|
|
// Enter su search field
|
|
document.getElementById('search').addEventListener('keypress', function(e) {
|
|
if (e.key === 'Enter') {
|
|
document.getElementById('filter-form').submit();
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
@endpush
|