334 lines
17 KiB
PHP
334 lines
17 KiB
PHP
<x-app-layout>
|
|
@section('page-title', $pageTitle)
|
|
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-header bg-white d-flex justify-content-between align-items-center">
|
|
<h5 class="my-0 fw-bold">Daftar Buku</h5>
|
|
<a href="{{ route('admin.buku.create') }}" class="btn btn-primary">
|
|
<i class="bi bi-plus-circle-fill me-2"></i>Tambah Buku
|
|
</a>
|
|
</div>
|
|
<div class="card-body">
|
|
{{-- NAV TABS --}}
|
|
<ul class="nav nav-tabs" id="bukuTab" role="tablist">
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link active" id="offline-tab" data-bs-toggle="tab"
|
|
data-bs-target="#offline-tab-pane" type="button" role="tab">Peminjaman Offline (<span
|
|
id="countOffline">{{ $bukuOffline->count() }}</span>)</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link" id="online-tab" data-bs-toggle="tab" data-bs-target="#online-tab-pane"
|
|
type="button" role="tab">Baca Online (<span id="countOnline">{{ $bukuOnline->count()
|
|
}}</span>)</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link text-warning" id="arsip-tab" data-bs-toggle="tab"
|
|
data-bs-target="#arsip-tab-pane" type="button" role="tab">
|
|
<i class="bi bi-archive-fill me-1"></i>Diarsipkan (<span id="countArsip">{{ $bukuArsip->count() }}</span>)
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="tab-content" id="bukuTabContent">
|
|
|
|
{{-- BUKU OFFLINE --}}
|
|
<div class="tab-pane fade show active" id="offline-tab-pane" role="tabpanel">
|
|
<div class="table-responsive mt-3">
|
|
<table class="table table-hover align-middle" id="tableOffline">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>No</th>
|
|
<th>Cover</th>
|
|
<th>Judul</th>
|
|
<th>Kode Buku</th>
|
|
<th>Penulis</th>
|
|
<th>Stok</th>
|
|
<th>Status</th>
|
|
<th class="text-center">Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach($bukuOffline as $buku)
|
|
<tr data-tipe="offline" data-id="{{ $buku->id }}">
|
|
<td>{{ $loop->iteration }}</td>
|
|
<td><img src="{{ asset($buku['cover']) }}" alt="{{ $buku['judul'] }}"
|
|
width="50" class="rounded"></td>
|
|
<td>{{ $buku['judul'] }}</td>
|
|
<td>{{ $buku['kode_buku'] }}</td>
|
|
<td>{{ $buku['penulis'] }}</td>
|
|
<td>
|
|
<span class="badge bg-info-subtle text-info-emphasis">{{ $buku['stok'] ?? 0 }}</span>
|
|
</td>
|
|
<td>
|
|
@if ($buku['status'] == 'Tersedia')
|
|
<span
|
|
class="badge bg-success-subtle text-success-emphasis">Tersedia</span>
|
|
@else
|
|
<span
|
|
class="badge bg-warning-subtle text-warning-emphasis">Dipinjam</span>
|
|
@endif
|
|
</td>
|
|
<td>
|
|
<a href="{{ route('admin.buku.show', $buku->id) }}" class="btn btn-sm btn-outline-secondary">
|
|
<i class="bi bi-eye-fill"></i> Detail
|
|
</a>
|
|
<button class="btn btn-sm btn-outline-warning btn-arsipkan"
|
|
data-id="{{ $buku->id }}" data-judul="{{ $buku->judul }}" data-penulis="{{ $buku->penulis }}" title="Arsipkan Buku">
|
|
<i class="bi bi-archive-fill"></i> Arsip
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- BUKU ONLINE --}}
|
|
<div class="tab-pane fade" id="online-tab-pane" role="tabpanel">
|
|
<div class="table-responsive mt-3">
|
|
<table class="table table-hover align-middle" id="tableOnline">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>No</th>
|
|
<th>Cover</th>
|
|
<th>Judul</th>
|
|
<th>Penulis</th>
|
|
<th>File PDF</th>
|
|
<th class="text-center">Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach($bukuOnline as $buku)
|
|
<tr data-tipe="online" data-id="{{ $buku->id }}">
|
|
<td>{{ $loop->iteration }}</td>
|
|
<td><img src="{{ asset($buku['cover']) }}" alt="{{ $buku['judul'] }}"
|
|
width="50" class="rounded"></td>
|
|
<td>{{ $buku['judul'] }}</td>
|
|
<td>{{ $buku['penulis'] }}</td>
|
|
<td><span
|
|
class="badge bg-info-subtle text-info-emphasis">{{ $buku['file_pdf'] ?? 'N/A' }}</span>
|
|
</td>
|
|
<td>
|
|
<a href="{{ route('admin.buku.show', $buku->id) }}" class="btn btn-sm btn-outline-secondary">
|
|
<i class="bi bi-eye-fill"></i> Detail
|
|
</a>
|
|
<button class="btn btn-sm btn-outline-warning btn-arsipkan"
|
|
data-id="{{ $buku->id }}" data-judul="{{ $buku->judul }}" data-penulis="{{ $buku->penulis }}" title="Arsipkan Buku">
|
|
<i class="bi bi-archive-fill"></i> Arsip
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- ARSIP --}}
|
|
<div class="tab-pane fade" id="arsip-tab-pane" role="tabpanel">
|
|
<div class="table-responsive mt-3">
|
|
<table class="table table-hover align-middle" id="tableArsip">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>No</th>
|
|
<th>Cover</th>
|
|
<th>Judul</th>
|
|
<th>Penulis</th>
|
|
<th>Tipe Asal</th>
|
|
<th class="text-center">Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse($bukuArsip as $buku)
|
|
<tr data-id="{{ $buku->id }}" data-tipe="{{ in_array('offline', $buku->tipe_akses ?? []) ? 'offline' : 'online' }}">
|
|
<td class="row-number">{{ $loop->iteration }}</td>
|
|
<td><img src="{{ asset($buku['cover']) }}" alt="{{ $buku['judul'] }}"
|
|
width="50" class="rounded"></td>
|
|
<td class="fw-bold text-muted">{{ $buku->judul }}</td>
|
|
<td class="text-muted">{{ $buku->penulis }}</td>
|
|
<td>
|
|
@if(in_array('offline', $buku->tipe_akses ?? []))
|
|
<span class="badge bg-secondary"><i class="bi bi-book me-1"></i>Offline</span>
|
|
@else
|
|
<span class="badge bg-info"><i class="bi bi-globe me-1"></i>Online</span>
|
|
@endif
|
|
</td>
|
|
<td class="text-center">
|
|
<button class="btn btn-sm btn-outline-success btn-pulihkan"
|
|
data-id="{{ $buku->id }}" data-judul="{{ $buku->judul }}" title="Kembalikan ke Daftar Aktif">
|
|
<i class="bi bi-arrow-counterclockwise me-1"></i>Kembalikan
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr class="empty-row-arsip">
|
|
<td colspan="6" class="text-center py-5 text-muted">
|
|
<i class="bi bi-inbox fs-1 d-block mb-2 text-secondary opacity-50"></i>
|
|
Belum ada buku yang diarsipkan.
|
|
</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
@push('scripts')
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
function updateTableNumbers() {
|
|
['#tableOffline', '#tableOnline', '#tableArsip'].forEach(tableId => {
|
|
let count = 0;
|
|
$(tableId + ' tbody tr').not('[class^="empty-row"]').each(function(index) {
|
|
$(this).find('.row-number').text(index + 1);
|
|
count++;
|
|
});
|
|
|
|
if (tableId === '#tableOffline') $('#countOffline').text(count);
|
|
if (tableId === '#tableOnline') $('#countOnline').text(count);
|
|
if (tableId === '#tableArsip') {
|
|
$('#countArsip').text(count);
|
|
if (count === 0) $('.empty-row-arsip').show();
|
|
else $('.empty-row-arsip').hide();
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
// LOGIC ARSIPKAN BUKU
|
|
$(document).on('click', '.btn-arsipkan', function() {
|
|
const button = $(this);
|
|
const row = button.closest('tr');
|
|
const id = button.data('id');
|
|
const judul = button.data('judul');
|
|
const tipe = row.data('tipe');
|
|
|
|
modernSwal.fire({
|
|
title: 'Arsipkan Buku?',
|
|
text: `Buku "${judul}" akan dipindahkan ke tab Arsip.`,
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonText: 'Ya, Arsipkan',
|
|
cancelButtonText: 'Batal',
|
|
confirmButtonColor: '#ffc107',
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
$.ajax({
|
|
url: "{{ route('admin.buku.arsip') }}",
|
|
type: "POST",
|
|
data: {
|
|
_token: "{{ csrf_token() }}",
|
|
id: id
|
|
},
|
|
success: function(response) {
|
|
row.fadeOut(300, function() {
|
|
const coverHtml = row.find('td:eq(1)').html();
|
|
const penulis = button.data('penulis');
|
|
const badgeTipe = tipe === 'offline' ?
|
|
'<span class="badge bg-secondary"><i class="bi bi-book me-1"></i>Offline</span>' :
|
|
'<span class="badge bg-info"><i class="bi bi-globe me-1"></i>Online</span>';
|
|
|
|
const arsipRow = `
|
|
<tr data-id="${id}" data-tipe="${tipe}">
|
|
<td class="row-number"></td>
|
|
<td>${coverHtml}</td>
|
|
<td class="fw-bold text-muted">${judul}</td>
|
|
<td class="text-muted">${penulis}</td>
|
|
<td>${badgeTipe}</td>
|
|
<td class="text-center">
|
|
<button class="btn btn-sm btn-outline-success btn-pulihkan"
|
|
data-id="${id}" data-judul="${judul}" title="Kembalikan ke Daftar Aktif">
|
|
<i class="bi bi-arrow-counterclockwise me-1"></i>Kembalikan
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
`;
|
|
|
|
$('#tableArsip tbody').append(arsipRow);
|
|
if ($('.empty-row-arsip').length) $('.empty-row-arsip').hide();
|
|
|
|
row.remove();
|
|
updateTableNumbers();
|
|
|
|
Toast.fire({
|
|
icon: 'success',
|
|
title: 'Diarsipkan',
|
|
text: response.message
|
|
});
|
|
});
|
|
},
|
|
error: function(xhr) {
|
|
modernSwal.fire('Error', 'Gagal mengarsipkan buku.', 'error');
|
|
}
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
// LOGIC PULIHKAN BUKU
|
|
$(document).on('click', '.btn-pulihkan', function() {
|
|
const button = $(this);
|
|
const row = button.closest('tr');
|
|
const id = button.data('id');
|
|
const judul = button.data('judul');
|
|
const tipe = row.data('tipe');
|
|
|
|
modernSwal.fire({
|
|
title: 'Kembalikan Buku?',
|
|
text: `Buku "${judul}" akan dikembalikan ke daftar aktif.`,
|
|
icon: 'question',
|
|
showCancelButton: true,
|
|
confirmButtonText: 'Ya, Kembalikan',
|
|
cancelButtonText: 'Batal',
|
|
confirmButtonColor: '#198754',
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
$.ajax({
|
|
url: "{{ route('admin.buku.pulihkan') }}",
|
|
type: "POST",
|
|
data: {
|
|
_token: "{{ csrf_token() }}",
|
|
id: id
|
|
},
|
|
success: function(response) {
|
|
row.fadeOut(300, function() {
|
|
const targetTable = tipe === 'offline' ? '#tableOffline' : '#tableOnline';
|
|
|
|
// Because we don't have the original row data stored locally in a perfect way,
|
|
// the easiest way is to reload or just fade out and tell user it's back.
|
|
// For better UX without reload, we could hide it and notify.
|
|
|
|
row.remove();
|
|
updateTableNumbers();
|
|
|
|
Toast.fire({
|
|
icon: 'success',
|
|
title: 'Dipulihkan',
|
|
text: response.message + ' Silakan refresh untuk melihat di daftar aktif.'
|
|
});
|
|
|
|
// Optionally reload to show it in the right place with all data
|
|
setTimeout(() => location.reload(), 1500);
|
|
});
|
|
},
|
|
error: function(xhr) {
|
|
modernSwal.fire('Error', 'Gagal memulihkan buku.', 'error');
|
|
}
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
});
|
|
</script>
|
|
@endpush
|
|
</x-app-layout> |