344 lines
18 KiB
PHP
344 lines
18 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('title', 'Cetak Barcode Massal')
|
|
|
|
@section('content')
|
|
<div class="container-fluid py-4">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card shadow">
|
|
<div class="card-header bg-primary text-white">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-barcode me-2"></i>Cetak Barcode Koleksi
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
{{-- Form Filter dan Sort --}}
|
|
<form method="GET" action="{{ route('admin.koleksi.cetak_barcode') }}" class="mb-4">
|
|
<div class="row mb-3">
|
|
{{-- Search Box --}}
|
|
<div class="col-md-4">
|
|
<label class="form-label text-muted small">🔍 Cari Judul</label>
|
|
<div class="input-group input-group-sm">
|
|
<input type="text" name="search" class="form-control"
|
|
placeholder="Cari judul buku..." value="{{ $search ?? '' }}">
|
|
<button type="submit" class="btn btn-outline-primary">
|
|
<i class="fas fa-search"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Sort --}}
|
|
<div class="col-md-4">
|
|
<label class="form-label text-muted small">↕️ Urutkan</label>
|
|
<select name="sort" class="form-select form-select-sm" onchange="this.form.submit()">
|
|
<option value="newest" {{ ($sort ?? 'newest') == 'newest' ? 'selected' : '' }}>
|
|
📥 Terbaru Masuk
|
|
</option>
|
|
<option value="oldest" {{ ($sort ?? '') == 'oldest' ? 'selected' : '' }}>
|
|
📤 Terlama Masuk
|
|
</option>
|
|
<option value="title_asc" {{ ($sort ?? '') == 'title_asc' ? 'selected' : '' }}>
|
|
🔤 A → Z (Judul)
|
|
</option>
|
|
<option value="title_desc" {{ ($sort ?? '') == 'title_desc' ? 'selected' : '' }}>
|
|
🔤 Z → A (Judul)
|
|
</option>
|
|
</select>
|
|
</div>
|
|
|
|
{{-- Filter Button --}}
|
|
<div class="col-md-4">
|
|
<label class="form-label text-muted small"> </label>
|
|
<button type="button" class="btn btn-outline-secondary btn-sm w-100"
|
|
data-bs-toggle="collapse" data-bs-target="#advancedFilters">
|
|
<i class="fas fa-filter me-1"></i>Filter Lanjutan
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Advanced Filters (Collapse) --}}
|
|
<div class="collapse" id="advancedFilters">
|
|
<div class="card card-body bg-light mb-3">
|
|
<div class="row">
|
|
{{-- Filter Klasifikasi --}}
|
|
<div class="col-md-4">
|
|
<label class="form-label small">📚 Klasifikasi</label>
|
|
<select name="filter_klasifikasi" class="form-select form-select-sm">
|
|
<option value="">-- Semua Klasifikasi --</option>
|
|
@foreach ($klasifikasiList as $klf)
|
|
<option value="{{ $klf }}"
|
|
{{ ($filterKlasifikasi ?? '') == $klf ? 'selected' : '' }}>
|
|
{{ $klf }}
|
|
</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
{{-- Filter Source --}}
|
|
<div class="col-md-4">
|
|
<label class="form-label small">🏷️ Sumber Buku</label>
|
|
<select name="filter_source" class="form-select form-select-sm">
|
|
<option value="">-- Semua Sumber --</option>
|
|
@foreach ($sourceList as $src)
|
|
<option value="{{ $src }}"
|
|
{{ ($filterSource ?? '') == $src ? 'selected' : '' }}>
|
|
{{ $src }}
|
|
</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
{{-- Filter Tahun --}}
|
|
<div class="col-md-2">
|
|
<label class="form-label small">📅 Tahun Awal</label>
|
|
<input type="number" name="filter_tahun_awal"
|
|
class="form-control form-control-sm" placeholder="Dari" min="1900"
|
|
max="{{ date('Y') }}" value="{{ $filterTahunAwal ?? '' }}">
|
|
</div>
|
|
|
|
<div class="col-md-2">
|
|
<label class="form-label small">📅 Tahun Akhir</label>
|
|
<input type="number" name="filter_tahun_akhir"
|
|
class="form-control form-control-sm" placeholder="Sampai" min="1900"
|
|
max="{{ date('Y') }}" value="{{ $filterTahunAkhir ?? '' }}">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mt-3">
|
|
<div class="col-12">
|
|
<button type="submit" class="btn btn-primary btn-sm">
|
|
<i class="fas fa-filter me-1"></i>Terapkan Filter
|
|
</button>
|
|
<a href="{{ route('admin.koleksi.cetak_barcode') }}"
|
|
class="btn btn-secondary btn-sm">
|
|
<i class="fas fa-redo me-1"></i>Reset Filter
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
{{-- Info Hasil Filter --}}
|
|
@if (
|
|
!empty($search) ||
|
|
!empty($filterKlasifikasi) ||
|
|
!empty($filterSource) ||
|
|
!empty($filterTahunAwal) ||
|
|
!empty($filterTahunAkhir))
|
|
<div class="alert alert-info mb-3">
|
|
<i class="fas fa-info-circle me-2"></i>
|
|
<strong>Filter diterapkan:</strong>
|
|
Menampilkan <strong>{{ $koleksi->count() }}</strong> koleksi
|
|
@if (!empty($search))
|
|
dengan judul "<strong>{{ $search }}</strong>"
|
|
@endif
|
|
@if (!empty($filterKlasifikasi))
|
|
Klasifikasi: "<strong>{{ $filterKlasifikasi }}</strong>"
|
|
@endif
|
|
@if (!empty($filterSource))
|
|
Sumber: "<strong>{{ $filterSource }}</strong>"
|
|
@endif
|
|
@if (!empty($filterTahunAwal) || !empty($filterTahunAkhir))
|
|
Tahun: <strong>{{ $filterTahunAwal ?? '1900' }} -
|
|
{{ $filterTahunAkhir ?? date('Y') }}</strong>
|
|
@endif
|
|
</div>
|
|
@endif
|
|
|
|
{{-- Sort Info --}}
|
|
@php
|
|
$sortLabels = [
|
|
'newest' => '📥 Terbaru Masuk',
|
|
'oldest' => '📤 Terlama Masuk',
|
|
'title_asc' => '🔤 A → Z (Judul)',
|
|
'title_desc' => '🔤 Z → A (Judul)',
|
|
];
|
|
@endphp
|
|
<div class="alert alert-light border mb-3">
|
|
<small class="text-muted">
|
|
<i class="fas fa-sort me-1"></i>Urutan:
|
|
<strong>{{ $sortLabels[$sort] ?? 'Terbaru Masuk' }}</strong>
|
|
</small>
|
|
</div>
|
|
|
|
<form id="barcodeForm" method="POST" action="{{ route('admin.koleksi.barcode_multiple') }}"
|
|
target="_blank">
|
|
@csrf
|
|
<div class="row mb-4">
|
|
<div class="col-md-6">
|
|
<label for="jumlah" class="form-label fw-bold">Jumlah Barcode per Halaman</label>
|
|
<select name="jumlah_per_halaman" id="jumlah" class="form-select" required>
|
|
<option value="4">4 barcode per halaman</option>
|
|
<option value="6">6 barcode per halaman</option>
|
|
<option value="8">8 barcode per halaman</option>
|
|
<option value="10">10 barcode per halaman</option>
|
|
<option value="12">12 barcode per halaman</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label for="total" class="form-label fw-bold">Total Barcode yang Dicetak</label>
|
|
<input type="number" name="total_barcode" id="total" class="form-control"
|
|
min="1" max="100" value="20" required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<h6 class="fw-bold mb-3">Pilih Koleksi untuk Dicetak Barcode:</h6>
|
|
<div class="table-responsive" style="max-height: 400px; overflow-y: auto;">
|
|
<table class="table table-bordered table-hover">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th width="5%">
|
|
<input type="checkbox" id="selectAll" class="form-check-input">
|
|
</th>
|
|
<th>Judul</th>
|
|
<th>Kode Eksemplar</th>
|
|
<th>Klasifikasi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse($koleksi as $item)
|
|
<tr>
|
|
<td class="text-center">
|
|
<input type="checkbox" name="selected[]"
|
|
value="{{ $item->kode_eksemplar }}"
|
|
class="form-check-input koleksi-checkbox">
|
|
</td>
|
|
<td>{{ $item->title }}</td>
|
|
<td><code>{{ $item->kode_eksemplar }}</code></td>
|
|
<td>{{ $item->classification }}</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="4" class="text-center text-muted py-4">
|
|
Tidak ada koleksi tersedia
|
|
</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex gap-2">
|
|
<button type="submit" class="btn btn-success">
|
|
<i class="fas fa-print me-2"></i>Cetak Barcode Terpilih
|
|
</button>
|
|
<button type="button" id="generateEmpty" class="btn btn-warning">
|
|
<i class="fas fa-plus me-2"></i>Generate Barcode Kosong
|
|
</button>
|
|
<a href="{{ route('admin.koleksi.index') }}" class="btn btn-secondary">
|
|
<i class="fas fa-arrow-left me-2"></i>Kembali
|
|
</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.getElementById('selectAll').addEventListener('change', function() {
|
|
const checkboxes = document.querySelectorAll('.koleksi-checkbox');
|
|
checkboxes.forEach(cb => cb.checked = this.checked);
|
|
});
|
|
|
|
document.getElementById('generateEmpty').addEventListener('click', function() {
|
|
const form = document.getElementById('barcodeForm');
|
|
// Uncheck all selected
|
|
document.querySelectorAll('.koleksi-checkbox').forEach(cb => cb.checked = false);
|
|
// Set action to generate empty
|
|
form.action = '{{ route('admin.koleksi.barcode_empty') }}';
|
|
form.submit();
|
|
});
|
|
|
|
// Live search functionality
|
|
let searchTimeout;
|
|
const searchInput = document.querySelector('input[name="search"]');
|
|
|
|
if (searchInput) {
|
|
searchInput.addEventListener('input', function() {
|
|
clearTimeout(searchTimeout);
|
|
const searchValue = this.value.trim();
|
|
|
|
// Debounce search - wait 500ms after user stops typing
|
|
searchTimeout = setTimeout(() => {
|
|
if (searchValue.length >= 2 || searchValue.length === 0) {
|
|
// Auto-submit the search form
|
|
const searchForm = this.closest('form');
|
|
searchForm.submit();
|
|
}
|
|
}, 500);
|
|
});
|
|
|
|
// Clear search on Escape key
|
|
searchInput.addEventListener('keydown', function(e) {
|
|
if (e.key === 'Escape') {
|
|
this.value = '';
|
|
const searchForm = this.closest('form');
|
|
searchForm.submit();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Highlight search terms in results
|
|
@if (!empty($search))
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const searchTerm = "{{ $search }}";
|
|
const tableCells = document.querySelectorAll('td:nth-child(2)'); // Judul column
|
|
|
|
tableCells.forEach(cell => {
|
|
const text = cell.textContent;
|
|
if (text.toLowerCase().includes(searchTerm.toLowerCase())) {
|
|
const regex = new RegExp(`(${searchTerm})`, 'gi');
|
|
cell.innerHTML = text.replace(regex, '<mark class="bg-warning">$1</mark>');
|
|
}
|
|
});
|
|
});
|
|
@endif
|
|
</script>
|
|
|
|
<style>
|
|
.table th,
|
|
.table td {
|
|
vertical-align: middle;
|
|
}
|
|
|
|
/* Highlight search results */
|
|
mark.bg-warning {
|
|
background-color: #fff3cd !important;
|
|
color: #856404 !important;
|
|
padding: 2px 4px;
|
|
border-radius: 3px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
/* Search input styling */
|
|
.input-group-text {
|
|
background-color: #f8f9fa;
|
|
border-color: #dee2e6;
|
|
}
|
|
|
|
/* Alert styling */
|
|
.alert-info {
|
|
border-left: 4px solid #0dcaf0;
|
|
}
|
|
|
|
/* Responsive search bar */
|
|
@media (max-width: 768px) {
|
|
.input-group {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.input-group .btn {
|
|
margin-top: 10px;
|
|
width: 100%;
|
|
}
|
|
}
|
|
</style>
|
|
@endsection
|
|
|