feat: filter Jenis Pelanggaran di Laporan Rekap — dropdown kategori+jenis (poin), berlaku untuk tampilan & cetak PDF
This commit is contained in:
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Admin;
|
|||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Classes;
|
use App\Models\Classes;
|
||||||
use App\Models\Setting;
|
use App\Models\Setting;
|
||||||
|
use App\Models\ViolationType;
|
||||||
use App\Models\Violation;
|
use App\Models\Violation;
|
||||||
use Barryvdh\DomPDF\Facade\Pdf;
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
@@ -19,6 +20,10 @@ class ViolationReportController extends Controller
|
|||||||
public function index(Request $request): View
|
public function index(Request $request): View
|
||||||
{
|
{
|
||||||
$classes = Classes::orderBy('name')->get();
|
$classes = Classes::orderBy('name')->get();
|
||||||
|
$violationTypes = ViolationType::with('category')
|
||||||
|
->orderBy('category_id')
|
||||||
|
->orderBy('name')
|
||||||
|
->get();
|
||||||
$filters = $this->filters($request);
|
$filters = $this->filters($request);
|
||||||
|
|
||||||
$query = $this->baseQuery($filters);
|
$query = $this->baseQuery($filters);
|
||||||
@@ -30,7 +35,7 @@ class ViolationReportController extends Controller
|
|||||||
->limit(20)
|
->limit(20)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
return view('reports.violations', compact('classes', 'filters', 'stats', 'recent'));
|
return view('reports.violations', compact('classes', 'violationTypes', 'filters', 'stats', 'recent'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function pdf(Request $request)
|
public function pdf(Request $request)
|
||||||
@@ -85,9 +90,12 @@ class ViolationReportController extends Controller
|
|||||||
|
|
||||||
$periode = ($filters['date_from'] ?? 'Awal').' s/d '.($filters['date_to'] ?? 'Sekarang');
|
$periode = ($filters['date_from'] ?? 'Awal').' s/d '.($filters['date_to'] ?? 'Sekarang');
|
||||||
$filterKelas = $filters['class_id'] ? (Classes::find($filters['class_id'])?->name ?? '-') : 'Semua Kelas';
|
$filterKelas = $filters['class_id'] ? (Classes::find($filters['class_id'])?->name ?? '-') : 'Semua Kelas';
|
||||||
|
$filterJenis = $filters['violation_type_id']
|
||||||
|
? (ViolationType::find($filters['violation_type_id'])?->name ?? '-')
|
||||||
|
: 'Semua Jenis Pelanggaran';
|
||||||
|
|
||||||
$pdf = Pdf::loadView('reports.violation-report-pdf', compact(
|
$pdf = Pdf::loadView('reports.violation-report-pdf', compact(
|
||||||
'violations', 'summary', 'perJenis', 'perKelas', 'school', 'periode', 'filterKelas'
|
'violations', 'summary', 'perJenis', 'perKelas', 'school', 'periode', 'filterKelas', 'filterJenis'
|
||||||
))->setPaper('a4', 'landscape');
|
))->setPaper('a4', 'landscape');
|
||||||
|
|
||||||
return $pdf->download('rekap-pelanggaran-'.now()->format('Ymd-His').'.pdf');
|
return $pdf->download('rekap-pelanggaran-'.now()->format('Ymd-His').'.pdf');
|
||||||
@@ -104,6 +112,7 @@ class ViolationReportController extends Controller
|
|||||||
'date_from' => ['nullable', 'date'],
|
'date_from' => ['nullable', 'date'],
|
||||||
'date_to' => ['nullable', 'date', 'after_or_equal:date_from'],
|
'date_to' => ['nullable', 'date', 'after_or_equal:date_from'],
|
||||||
'class_id' => ['nullable', 'integer', 'exists:classes,id'],
|
'class_id' => ['nullable', 'integer', 'exists:classes,id'],
|
||||||
|
'violation_type_id' => ['nullable', 'integer', 'exists:violation_types,id'],
|
||||||
];
|
];
|
||||||
|
|
||||||
$data = $validate ? $request->validate($rules) : $request->validate($rules);
|
$data = $validate ? $request->validate($rules) : $request->validate($rules);
|
||||||
@@ -112,6 +121,7 @@ class ViolationReportController extends Controller
|
|||||||
'date_from' => $data['date_from'] ?? null,
|
'date_from' => $data['date_from'] ?? null,
|
||||||
'date_to' => $data['date_to'] ?? null,
|
'date_to' => $data['date_to'] ?? null,
|
||||||
'class_id' => isset($data['class_id']) ? (int) $data['class_id'] : null,
|
'class_id' => isset($data['class_id']) ? (int) $data['class_id'] : null,
|
||||||
|
'violation_type_id' => isset($data['violation_type_id']) ? (int) $data['violation_type_id'] : null,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,6 +134,7 @@ class ViolationReportController extends Controller
|
|||||||
->when($filters['date_from'], fn ($q) => $q->whereDate('violation_date', '>=', $filters['date_from']))
|
->when($filters['date_from'], fn ($q) => $q->whereDate('violation_date', '>=', $filters['date_from']))
|
||||||
->when($filters['date_to'], fn ($q) => $q->whereDate('violation_date', '<=', $filters['date_to']))
|
->when($filters['date_to'], fn ($q) => $q->whereDate('violation_date', '<=', $filters['date_to']))
|
||||||
->when($filters['class_id'], fn ($q) => $q->whereHas('student', fn ($qq) => $qq->where('class_id', $filters['class_id'])))
|
->when($filters['class_id'], fn ($q) => $q->whereHas('student', fn ($qq) => $qq->where('class_id', $filters['class_id'])))
|
||||||
|
->when($filters['violation_type_id'], fn ($q) => $q->where('violation_type_id', $filters['violation_type_id']))
|
||||||
->when(auth()->user()->isScopedWaliKelas(), fn ($q) => $q->whereHas('student', fn ($qq) => $qq->whereIn('class_id', auth()->user()->homeroomClassIds())));
|
->when(auth()->user()->isScopedWaliKelas(), fn ($q) => $q->whereHas('student', fn ($qq) => $qq->whereIn('class_id', auth()->user()->homeroomClassIds())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
{{-- Judul --}}
|
{{-- Judul --}}
|
||||||
<div class="judul">
|
<div class="judul">
|
||||||
<h2>Rekap Laporan Pelanggaran Siswa</h2>
|
<h2>Rekap Laporan Pelanggaran Siswa</h2>
|
||||||
<p>Periode: {{ $periode }} • Kelas: {{ $filterKelas }}</p>
|
<p>Periode: {{ $periode }} • Kelas: {{ $filterKelas }} • Jenis: {{ $filterJenis }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{-- Ringkasan --}}
|
{{-- Ringkasan --}}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
{{-- ===== Filter Bar ===== --}}
|
{{-- ===== Filter Bar ===== --}}
|
||||||
<form method="GET" action="{{ route('reports.violations') }}" id="filter-form"
|
<form method="GET" action="{{ route('reports.violations') }}" id="filter-form"
|
||||||
class="bg-white rounded-2xl shadow-sm border border-slate-200 p-5">
|
class="bg-white rounded-2xl shadow-sm border border-slate-200 p-5">
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3">
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wider mb-1.5">Dari Tanggal</label>
|
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wider mb-1.5">Dari Tanggal</label>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
@@ -76,6 +76,21 @@
|
|||||||
</select>
|
</select>
|
||||||
<i class="fa-solid fa-chevron-down absolute right-3.5 top-1/2 -translate-y-1/2 text-gray-400 text-xs pointer-events-none"></i>
|
<i class="fa-solid fa-chevron-down absolute right-3.5 top-1/2 -translate-y-1/2 text-gray-400 text-xs pointer-events-none"></i>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-xs font-semibold text-gray-500 uppercase tracking-wider mb-1.5">Jenis Pelanggaran</label>
|
||||||
|
<div class="relative">
|
||||||
|
<i class="fa-solid fa-tag absolute left-3.5 top-1/2 -translate-y-1/2 text-gray-400 text-sm pointer-events-none"></i>
|
||||||
|
<select name="violation_type_id" x-model="jenisId"
|
||||||
|
class="w-full pl-9 pr-3 py-2.5 border border-slate-200 rounded-xl text-sm bg-gray-50/50 focus:bg-white focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition appearance-none">
|
||||||
|
<option value="">— Semua Jenis —</option>
|
||||||
|
@foreach ($violationTypes as $type)
|
||||||
|
<option value="{{ $type->id }}" @selected($filters['violation_type_id'] == $type->id)>
|
||||||
|
{{ $type->category?->name ? '['.$type->category->name.'] ' : '' }}{{ $type->name }} ({{ $type->points }} poin)
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
<i class="fa-solid fa-chevron-down absolute right-3.5 top-1/2 -translate-y-1/2 text-gray-400 text-xs pointer-events-none"></i>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-end">
|
<div class="flex items-end">
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
@@ -251,7 +266,7 @@
|
|||||||
<span class="w-8 h-8 rounded-lg bg-amber-50 text-amber-600 flex items-center justify-center"><i class="fa-solid fa-list-check text-sm"></i></span>
|
<span class="w-8 h-8 rounded-lg bg-amber-50 text-amber-600 flex items-center justify-center"><i class="fa-solid fa-list-check text-sm"></i></span>
|
||||||
Rincian Pelanggaran Terbaru
|
Rincian Pelanggaran Terbaru
|
||||||
</h3>
|
</h3>
|
||||||
<a href="{{ route('violations.index', request()->only(['date_from', 'date_to'])) }}"
|
<a href="{{ route('violations.index', request()->only(['date_from', 'date_to', 'violation_type_id'])) }}"
|
||||||
class="text-xs font-semibold text-blue-600 hover:text-blue-800 inline-flex items-center gap-1.5">
|
class="text-xs font-semibold text-blue-600 hover:text-blue-800 inline-flex items-center gap-1.5">
|
||||||
Lihat Semua <i class="fa-solid fa-arrow-right text-[10px]"></i>
|
Lihat Semua <i class="fa-solid fa-arrow-right text-[10px]"></i>
|
||||||
</a>
|
</a>
|
||||||
@@ -311,6 +326,7 @@
|
|||||||
dateFrom: {{ json_encode($filters['date_from'] ?? '') }},
|
dateFrom: {{ json_encode($filters['date_from'] ?? '') }},
|
||||||
dateTo: {{ json_encode($filters['date_to'] ?? '') }},
|
dateTo: {{ json_encode($filters['date_to'] ?? '') }},
|
||||||
classId: {{ json_encode($filters['class_id'] ?? '') }},
|
classId: {{ json_encode($filters['class_id'] ?? '') }},
|
||||||
|
jenisId: {{ json_encode($filters['violation_type_id'] ?? '') }},
|
||||||
applyPreset(from, to) {
|
applyPreset(from, to) {
|
||||||
this.dateFrom = from;
|
this.dateFrom = from;
|
||||||
this.dateTo = to;
|
this.dateTo = to;
|
||||||
@@ -320,6 +336,7 @@
|
|||||||
this.dateFrom = '';
|
this.dateFrom = '';
|
||||||
this.dateTo = '';
|
this.dateTo = '';
|
||||||
this.classId = '';
|
this.classId = '';
|
||||||
|
this.jenisId = '';
|
||||||
this.$nextTick(() => document.getElementById('filter-form').submit());
|
this.$nextTick(() => document.getElementById('filter-form').submit());
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user