Fix: kategori table migration and update admin buku views

This commit is contained in:
Lutfi Hakim 2026-04-30 07:51:09 +07:00
parent 5f8202e7ca
commit f64ea3a4fa
12 changed files with 1698 additions and 1409 deletions

View File

@ -141,10 +141,14 @@ public function show($id)
private function getRekomendasi($targetBuku)
{
$semuaBuku = Buku::where('id_buku', '!=', $targetBuku->id_buku)
->whereNotNull('nomor_panggil')
$semuaBuku = Buku::where('id', '!=', $targetBuku->id)
->get();
// Jika nomor_panggil tidak ada, tampilkan rekomendasi berdasarkan buku populer
if (empty($targetBuku->nomor_panggil)) {
return $semuaBuku->take(4);
}
$hasil = [];
$targetDdc = substr(preg_replace('/[^0-9]/', '', $targetBuku->nomor_panggil), 0, 3);
@ -153,6 +157,8 @@ private function getRekomendasi($targetBuku)
}
foreach ($semuaBuku as $b) {
if (empty($b->nomor_panggil)) continue;
$pembandingDdc = substr(preg_replace('/[^0-9]/', '', $b->nomor_panggil), 0, 3);
if (strlen($pembandingDdc) < 3) continue;

View File

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('kategori', function (Blueprint $table) {
$table->increments('id_kategori');
$table->string('nama_kategori');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('kategori');
}
};

View File

@ -19,11 +19,21 @@ public function run(): void
DB::table('buku_tamu')->insert([
[
'id_user' => $userId,
'nama_tamu' => 'Pengunjung 1',
'email' => 'pengunjung1@example.com',
'no_hp' => '081234567890',
'asal_instansi' => 'Sekolah A',
'status' => 'Aktif',
'tujuan_kunjungan' => 'Membaca Buku',
'tanggal_kunjungan' => now(),
],
[
'id_user' => $userId,
'nama_tamu' => 'Pengunjung 2',
'email' => 'pengunjung2@example.com',
'no_hp' => '082345678901',
'asal_instansi' => 'Sekolah B',
'status' => 'Aktif',
'tujuan_kunjungan' => 'Meminjam Buku',
'tanggal_kunjungan' => now()->subDay(),
],

View File

@ -16,20 +16,24 @@ class DatabaseSeeder extends Seeder
public function run(): void
{
// Admin user
User::create([
User::updateOrCreate(
['email' => 'admin@perpustakaan.com'],
[
'name' => 'Admin',
'email' => 'admin@perpustakaan.com',
'password' => Hash::make('password'),
'role' => 'admin',
]);
]
);
// Regular user
User::create([
User::updateOrCreate(
['email' => 'user@perpustakaan.com'],
[
'name' => 'User Test',
'email' => 'user@perpustakaan.com',
'password' => Hash::make('password'),
'role' => 'user',
]);
]
);
// Sample buku
Buku::create([
@ -67,4 +71,3 @@ public function run(): void
]);
}
}

View File

@ -18,21 +18,25 @@
</div>
@endif
<form action="{{ route('admin.buku.update', $buku->id_buku) }}" method="POST" enctype="multipart/form-data" class="p-6 space-y-6">
<form action="{{ route('admin.buku.update', $buku->id) }}" method="POST" enctype="multipart/form-data"
class="p-6 space-y-6">
@csrf
@method('PUT')
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<x-input-label for="bibid" value="BIBID" />
<x-text-input id="bibid" name="bibid" type="text" class="mt-1 block w-full" :value="old('bibid', $buku->bibid)" />
<x-text-input id="bibid" name="bibid" type="text" class="mt-1 block w-full"
:value="old('bibid', $buku->bibid)" />
</div>
<div>
<x-input-label for="id_kategori" value="Kategori" />
<select id="id_kategori" name="id_kategori" class="mt-1 block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm">
<select id="id_kategori" name="id_kategori"
class="mt-1 block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm">
<option value="">Pilih Kategori</option>
@foreach ($kategori as $kat)
<option value="{{ $kat->id_kategori }}" {{ old('id_kategori', $buku->id_kategori) == $kat->id_kategori ? 'selected' : '' }}>
<option value="{{ $kat->id_kategori }}"
{{ old('id_kategori', $buku->id_kategori) == $kat->id_kategori ? 'selected' : '' }}>
{{ $kat->nama_kategori }}
</option>
@endforeach
@ -48,47 +52,56 @@
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<x-input-label for="pengarang" value="Pengarang" />
<x-text-input id="pengarang" name="pengarang" type="text" class="mt-1 block w-full" :value="old('pengarang', $buku->pengarang)" />
<x-text-input id="pengarang" name="pengarang" type="text" class="mt-1 block w-full"
:value="old('pengarang', $buku->pengarang)" />
</div>
<div>
<x-input-label for="nomor_panggil" value="Nomor Panggil (DDC)" />
<x-text-input id="nomor_panggil" name="nomor_panggil" type="text" class="mt-1 block w-full" :value="old('nomor_panggil', $buku->nomor_panggil)" />
<x-text-input id="nomor_panggil" name="nomor_panggil" type="text" class="mt-1 block w-full"
:value="old('nomor_panggil', $buku->nomor_panggil)" />
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div>
<x-input-label for="penerbit" value="Penerbit" />
<x-text-input id="penerbit" name="penerbit" type="text" class="mt-1 block w-full" :value="old('penerbit', $buku->penerbit)" />
<x-text-input id="penerbit" name="penerbit" type="text" class="mt-1 block w-full"
:value="old('penerbit', $buku->penerbit)" />
</div>
<div>
<x-input-label for="tahun_terbit" value="Tahun Terbit" />
<x-text-input id="tahun_terbit" name="tahun_terbit" type="number" class="mt-1 block w-full" :value="old('tahun_terbit', $buku->tahun_terbit)" />
<x-text-input id="tahun_terbit" name="tahun_terbit" type="number" class="mt-1 block w-full"
:value="old('tahun_terbit', $buku->tahun_terbit)" />
</div>
<div>
<x-input-label for="edisi" value="Edisi" />
<x-text-input id="edisi" name="edisi" type="text" class="mt-1 block w-full" :value="old('edisi', $buku->edisi)" />
<x-text-input id="edisi" name="edisi" type="text" class="mt-1 block w-full"
:value="old('edisi', $buku->edisi)" />
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<x-input-label for="deskripsi_fisik" value="Deskripsi Fisik" />
<x-text-input id="deskripsi_fisik" name="deskripsi_fisik" type="text" class="mt-1 block w-full" :value="old('deskripsi_fisik', $buku->deskripsi_fisik)" />
<x-text-input id="deskripsi_fisik" name="deskripsi_fisik" type="text" class="mt-1 block w-full"
:value="old('deskripsi_fisik', $buku->deskripsi_fisik)" />
</div>
<div>
<x-input-label for="eksemplar" value="Jumlah Eksemplar" />
<x-text-input id="eksemplar" name="eksemplar" type="number" class="mt-1 block w-full" :value="old('eksemplar', $buku->eksemplar)" />
<x-text-input id="eksemplar" name="eksemplar" type="number" class="mt-1 block w-full"
:value="old('eksemplar', $buku->eksemplar)" />
</div>
</div>
<div class="border-t border-gray-100 pt-6">
<x-input-label for="cover" value="Unggah Gambar Cover (Opsional)" />
<input type="file" id="cover" name="cover" accept="image/*" class="mt-1 block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-indigo-50 file:text-indigo-700 hover:file:bg-indigo-100">
<input type="file" id="cover" name="cover" accept="image/*"
class="mt-1 block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-indigo-50 file:text-indigo-700 hover:file:bg-indigo-100">
</div>
<div class="flex items-center justify-end gap-4 pt-4 border-t border-gray-200">
<a href="{{ route('admin.buku.index') }}" class="text-gray-600 hover:text-gray-900 font-medium text-sm">Batal</a>
<a href="{{ route('admin.buku.index') }}"
class="text-gray-600 hover:text-gray-900 font-medium text-sm">Batal</a>
<x-primary-button>
Simpan Perubahan
</x-primary-button>

View File

@ -3,10 +3,11 @@
@section('title', 'Katalog Buku')
@section('content')
<div x-data="{ isModalBukuOpen: {{ ($errors->any() || request('add') == 'true') ? 'true' : 'false' }} }">
<div x-data="{ isModalBukuOpen: {{ $errors->any() || request('add') == 'true' ? 'true' : 'false' }} }">
<x-page-header title="Portofolio Katalog Buku">
<x-slot name="actions">
<button @click="isModalBukuOpen = true" class="bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white px-5 py-2.5 rounded-xl shadow-lg shadow-blue-500/30 transition-all font-semibold flex items-center gap-2 transform hover:scale-105">
<button @click="isModalBukuOpen = true"
class="bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white px-5 py-2.5 rounded-xl shadow-lg shadow-blue-500/30 transition-all font-semibold flex items-center gap-2 transform hover:scale-105">
<i class="fas fa-plus"></i> Tambah Buku Baru
</button>
</x-slot>
@ -16,13 +17,8 @@
<div class="mb-6">
<form method="GET" action="{{ route('admin.buku.index') }}" class="flex gap-2">
<x-text-input
type="text"
name="search"
value="{{ request('search') }}"
placeholder="Cari berdasarkan Judul atau BIBID..."
class="w-full md:w-80"
/>
<x-text-input type="text" name="search" value="{{ request('search') }}"
placeholder="Cari berdasarkan Judul atau BIBID..." class="w-full md:w-80" />
<x-primary-button>
Cari
</x-primary-button>
@ -46,19 +42,21 @@ class="w-full md:w-80"
<div class="text-sm font-bold text-gray-900">{{ $item->judul }}</div>
<div class="text-sm text-gray-500">{{ $item->pengarang }}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ $item->kategori->nama_kategori ?? 'Umum' }}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{{ $item->kategori->nama_kategori ?? 'Umum' }}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ $item->eksemplar }}</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<div class="flex justify-end gap-3">
<a href="{{ route('admin.buku.edit', $item->id_buku) }}" class="text-blue-600 hover:text-blue-900">
<a href="{{ route('admin.buku.edit', $item->id) }}"
class="text-blue-600 hover:text-blue-900">
Edit
</a>
<form action="{{ route('admin.buku.destroy', $item->id_buku) }}"
method="POST"
<form action="{{ route('admin.buku.destroy', $item->id) }}" method="POST"
onsubmit="return confirm('Apakah Anda yakin ingin menghapus aset buku ini?')">
@csrf
@method('DELETE')
<button type="submit" class="text-red-600 hover:text-red-900 font-medium transition duration-150 ease-in-out">
<button type="submit"
class="text-red-600 hover:text-red-900 font-medium transition duration-150 ease-in-out">
Hapus
</button>
</form>
@ -79,16 +77,18 @@ class="w-full md:w-80"
</div>
</x-card>
<!-- MODAL TAMBAH BUKU -->
<div x-show="isModalBukuOpen" style="display: none;" class="fixed inset-0 z-50 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div x-show="isModalBukuOpen" style="display: none;" class="fixed inset-0 z-50 overflow-y-auto"
aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div class="flex items-end justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<!-- Background overlay -->
<div x-show="isModalBukuOpen" x-transition.opacity class="fixed inset-0 transition-opacity bg-gray-900/60 backdrop-blur-sm" aria-hidden="true" @click="isModalBukuOpen = false"></div>
<div x-show="isModalBukuOpen" x-transition.opacity
class="fixed inset-0 transition-opacity bg-gray-900/60 backdrop-blur-sm" aria-hidden="true"
@click="isModalBukuOpen = false"></div>
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<!-- Modal panel -->
<div x-show="isModalBukuOpen"
x-transition:enter="ease-out duration-300"
<div x-show="isModalBukuOpen" x-transition:enter="ease-out duration-300"
x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
x-transition:leave="ease-in duration-200"
@ -99,15 +99,18 @@ class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transi
<div class="flex justify-between items-center mb-6 pl-2">
<div>
<h3 class="text-2xl font-bold text-gray-900" id="modal-title">Tambah Koleksi Buku</h3>
<p class="text-sm text-gray-500 mt-1">Masukkan detail buku baru ke dalam katalog perpustakaan.</p>
<p class="text-sm text-gray-500 mt-1">Masukkan detail buku baru ke dalam katalog perpustakaan.
</p>
</div>
<button @click="isModalBukuOpen = false" class="w-10 h-10 rounded-full bg-gray-50 hover:bg-red-50 text-gray-400 hover:text-red-500 flex items-center justify-center transition-colors">
<button @click="isModalBukuOpen = false"
class="w-10 h-10 rounded-full bg-gray-50 hover:bg-red-50 text-gray-400 hover:text-red-500 flex items-center justify-center transition-colors">
<i class="fas fa-times text-lg"></i>
</button>
</div>
@if ($errors->any())
<div class="bg-red-50 border-l-4 border-red-500 text-red-700 p-4 mb-6 rounded-r-xl text-sm shadow-sm" role="alert">
<div class="bg-red-50 border-l-4 border-red-500 text-red-700 p-4 mb-6 rounded-r-xl text-sm shadow-sm"
role="alert">
<p class="font-bold mb-1"><i class="fas fa-exclamation-circle mr-1"></i> Validasi Gagal</p>
<ul class="list-disc ml-5 space-y-1">
@foreach ($errors->all() as $error)
@ -117,20 +120,25 @@ class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transi
</div>
@endif
<form action="{{ route('admin.buku.store') }}" method="POST" enctype="multipart/form-data" class="space-y-6">
<form action="{{ route('admin.buku.store') }}" method="POST" enctype="multipart/form-data"
class="space-y-6">
@csrf
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<x-input-label for="bibid" value="BIBID" />
<x-text-input id="bibid" name="bibid" type="text" class="mt-1 block w-full bg-gray-50/50" :value="old('bibid')" required />
<x-text-input id="bibid" name="bibid" type="text"
class="mt-1 block w-full bg-gray-50/50" :value="old('bibid')" required />
</div>
<div>
<x-input-label for="id_kategori" value="Kategori" />
<select id="id_kategori" name="id_kategori" class="mt-1 block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-xl shadow-sm bg-gray-50/50" required>
<select id="id_kategori" name="id_kategori"
class="mt-1 block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-xl shadow-sm bg-gray-50/50"
required>
<option value="">Pilih Kategori</option>
@foreach ($kategori as $kat)
<option value="{{ $kat->id_kategori }}" {{ old('id_kategori') == $kat->id_kategori ? 'selected' : '' }}>
<option value="{{ $kat->id_kategori }}"
{{ old('id_kategori') == $kat->id_kategori ? 'selected' : '' }}>
{{ $kat->nama_kategori }}
</option>
@endforeach
@ -140,65 +148,79 @@ class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transi
<div>
<x-input-label for="judul" value="Judul Buku" />
<x-text-input id="judul" name="judul" type="text" class="mt-1 block w-full bg-gray-50/50" :value="old('judul')" required />
<x-text-input id="judul" name="judul" type="text"
class="mt-1 block w-full bg-gray-50/50" :value="old('judul')" required />
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<x-input-label for="pengarang" value="Pengarang" />
<x-text-input id="pengarang" name="pengarang" type="text" class="mt-1 block w-full bg-gray-50/50" :value="old('pengarang')" required />
<x-text-input id="pengarang" name="pengarang" type="text"
class="mt-1 block w-full bg-gray-50/50" :value="old('pengarang')" required />
</div>
<div>
<x-input-label for="nomor_panggil" value="Nomor Panggil (DDC)" />
<x-text-input id="nomor_panggil" name="nomor_panggil" type="text" class="mt-1 block w-full bg-gray-50/50" :value="old('nomor_panggil')" required />
<x-text-input id="nomor_panggil" name="nomor_panggil" type="text"
class="mt-1 block w-full bg-gray-50/50" :value="old('nomor_panggil')" required />
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div>
<x-input-label for="penerbit" value="Penerbit" />
<x-text-input id="penerbit" name="penerbit" type="text" class="mt-1 block w-full bg-gray-50/50" :value="old('penerbit')" />
<x-text-input id="penerbit" name="penerbit" type="text"
class="mt-1 block w-full bg-gray-50/50" :value="old('penerbit')" />
</div>
<div>
<x-input-label for="tahun_terbit" value="Tahun Terbit" />
<x-text-input id="tahun_terbit" name="tahun_terbit" type="number" class="mt-1 block w-full bg-gray-50/50" :value="old('tahun_terbit')" />
<x-text-input id="tahun_terbit" name="tahun_terbit" type="number"
class="mt-1 block w-full bg-gray-50/50" :value="old('tahun_terbit')" />
</div>
<div>
<x-input-label for="edisi" value="Edisi" />
<x-text-input id="edisi" name="edisi" type="text" class="mt-1 block w-full bg-gray-50/50" :value="old('edisi')" />
<x-text-input id="edisi" name="edisi" type="text"
class="mt-1 block w-full bg-gray-50/50" :value="old('edisi')" />
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<x-input-label for="deskripsi_fisik" value="Deskripsi Fisik" />
<x-text-input id="deskripsi_fisik" name="deskripsi_fisik" type="text" class="mt-1 block w-full bg-gray-50/50" :value="old('deskripsi_fisik')" />
<x-text-input id="deskripsi_fisik" name="deskripsi_fisik" type="text"
class="mt-1 block w-full bg-gray-50/50" :value="old('deskripsi_fisik')" />
</div>
<div>
<x-input-label for="eksemplar" value="Jumlah Eksemplar" />
<x-text-input id="eksemplar" name="eksemplar" type="number" class="mt-1 block w-full bg-gray-50/50" :value="old('eksemplar')" required />
<x-text-input id="eksemplar" name="eksemplar" type="number"
class="mt-1 block w-full bg-gray-50/50" :value="old('eksemplar')" required />
</div>
</div>
<div class="border-t border-gray-100 pt-6">
<x-input-label for="cover" value="Unggah Gambar Cover (Opsional)" class="mb-2" />
<div class="flex items-center justify-center w-full">
<label for="cover" class="flex flex-col items-center justify-center w-full h-32 border-2 border-dashed border-indigo-200 rounded-2xl cursor-pointer bg-indigo-50/30 hover:bg-indigo-50 transition-colors">
<label for="cover"
class="flex flex-col items-center justify-center w-full h-32 border-2 border-dashed border-indigo-200 rounded-2xl cursor-pointer bg-indigo-50/30 hover:bg-indigo-50 transition-colors">
<div class="flex flex-col items-center justify-center pt-5 pb-6">
<i class="fas fa-cloud-upload-alt text-3xl text-indigo-400 mb-2"></i>
<p class="mb-1 text-sm text-gray-500"><span class="font-semibold text-indigo-600">Klik untuk unggah</span> atau seret file ke sini</p>
<p class="mb-1 text-sm text-gray-500"><span
class="font-semibold text-indigo-600">Klik untuk unggah</span> atau seret
file ke sini</p>
<p class="text-xs text-gray-400">PNG, JPG, JPEG (Maks. 2MB)</p>
</div>
<input id="cover" name="cover" type="file" class="hidden" accept="image/jpeg, image/png, image/jpg" />
<input id="cover" name="cover" type="file" class="hidden"
accept="image/jpeg, image/png, image/jpg" />
</label>
</div>
</div>
<div class="flex items-center justify-end gap-3 pt-6 border-t border-gray-100 mt-8">
<button type="button" @click="isModalBukuOpen = false" class="px-5 py-2.5 text-gray-600 bg-gray-100 hover:bg-gray-200 hover:text-gray-900 rounded-xl font-semibold transition-colors">
<button type="button" @click="isModalBukuOpen = false"
class="px-5 py-2.5 text-gray-600 bg-gray-100 hover:bg-gray-200 hover:text-gray-900 rounded-xl font-semibold transition-colors">
Batal
</button>
<button type="submit" class="bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white px-6 py-2.5 rounded-xl font-bold shadow-lg shadow-blue-500/30 transition-all transform hover:scale-105">
<button type="submit"
class="bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white px-6 py-2.5 rounded-xl font-bold shadow-lg shadow-blue-500/30 transition-all transform hover:scale-105">
<i class="fas fa-save mr-2"></i> Simpan Buku
</button>
</div>

View File

@ -23,7 +23,8 @@
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Pilih Anggota / Member</label>
<select name="id_anggota" class="w-full border-gray-300 rounded-lg shadow-sm focus:border-blue-500 focus:ring-blue-500">
<select name="id_anggota"
class="w-full border-gray-300 rounded-lg shadow-sm focus:border-blue-500 focus:ring-blue-500">
<option value="">-- Pilih Member --</option>
@foreach ($anggota as $a)
<option value="{{ $a->id }}" {{ old('id_anggota') == $a->id ? 'selected' : '' }}>
@ -34,11 +35,13 @@
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Pilih Aset Buku (Hanya yang tersedia)</label>
<select name="id_buku" class="w-full border-gray-300 rounded-lg shadow-sm focus:border-blue-500 focus:ring-blue-500">
<label class="block text-sm font-medium text-gray-700 mb-2">Pilih Aset Buku (Hanya yang
tersedia)</label>
<select name="id_buku"
class="w-full border-gray-300 rounded-lg shadow-sm focus:border-blue-500 focus:ring-blue-500">
<option value="">-- Pilih Buku --</option>
@foreach ($buku as $b)
<option value="{{ $b->id_buku }}" {{ old('id_buku') == $b->id_buku ? 'selected' : '' }}>
<option value="{{ $b->id }}" {{ old('id_buku') == $b->id ? 'selected' : '' }}>
{{ $b->bibid }} - {{ $b->judul }} (Stok: {{ $b->eksemplar }})
</option>
@endforeach
@ -48,17 +51,22 @@
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Tanggal Pinjam</label>
<input type="date" name="tanggal_pinjam" value="{{ old('tanggal_pinjam', date('Y-m-d')) }}" class="w-full border-gray-300 rounded-lg shadow-sm focus:border-blue-500 focus:ring-blue-500">
<input type="date" name="tanggal_pinjam" value="{{ old('tanggal_pinjam', date('Y-m-d')) }}"
class="w-full border-gray-300 rounded-lg shadow-sm focus:border-blue-500 focus:ring-blue-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Tanggal Kembali (Tenggat)</label>
<input type="date" name="tanggal_kembali" value="{{ old('tanggal_kembali', date('Y-m-d', strtotime('+7 days'))) }}" class="w-full border-gray-300 rounded-lg shadow-sm focus:border-blue-500 focus:ring-blue-500">
<input type="date" name="tanggal_kembali"
value="{{ old('tanggal_kembali', date('Y-m-d', strtotime('+7 days'))) }}"
class="w-full border-gray-300 rounded-lg shadow-sm focus:border-blue-500 focus:ring-blue-500">
</div>
</div>
<div class="pt-6 border-t border-gray-100 flex justify-between items-center">
<a href="{{ route('admin.peminjaman.index') }}" class="text-gray-600 hover:text-gray-900 font-medium transition duration-300">Batal</a>
<button type="submit" id="btn-submit" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-8 rounded-lg shadow-md transition duration-300 ease-in-out">
<a href="{{ route('admin.peminjaman.index') }}"
class="text-gray-600 hover:text-gray-900 font-medium transition duration-300">Batal</a>
<button type="submit" id="btn-submit"
class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-8 rounded-lg shadow-md transition duration-300 ease-in-out">
Eksekusi Transaksi
</button>
</div>

View File

@ -4,9 +4,9 @@
@section('content')
<div x-data="{
isModalPeminjamanOpen: {{ ($errors->any() && !old('_method')) ? 'true' : 'false' }},
isModalPeminjamanOpen: {{ $errors->any() && !old('_method') ? 'true' : 'false' }},
isModalKembaliOpen: false,
isModalEditOpen: {{ ($errors->any() && old('_method') == 'PUT') ? 'true' : 'false' }},
isModalEditOpen: {{ $errors->any() && old('_method') == 'PUT' ? 'true' : 'false' }},
isModalDeleteOpen: false,
deleteId: '',
editData: {
@ -49,17 +49,21 @@
class="bg-white border border-gray-200 border-r-0 text-gray-900 text-sm rounded-l-lg focus:ring-blue-500 focus:border-blue-500 block w-full pl-9 px-3 py-2.5 shadow-sm transition-all outline-none"
placeholder="Cari judul/anggota...">
</div>
<button type="submit" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 text-sm rounded-r-lg font-bold shadow-sm transition-colors border-y border-r border-blue-600 focus:ring-2 focus:ring-blue-300">
<button type="submit"
class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 text-sm rounded-r-lg font-bold shadow-sm transition-colors border-y border-r border-blue-600 focus:ring-2 focus:ring-blue-300">
Cari
</button>
@if (request('search'))
<a href="{{ route('admin.peminjaman.index') }}" class="ml-2 bg-gray-100 hover:bg-red-50 border border-gray-200 text-gray-500 hover:text-red-500 px-3 flex items-center justify-center rounded-lg shadow-sm transition-colors" title="Reset Pencarian">
<a href="{{ route('admin.peminjaman.index') }}"
class="ml-2 bg-gray-100 hover:bg-red-50 border border-gray-200 text-gray-500 hover:text-red-500 px-3 flex items-center justify-center rounded-lg shadow-sm transition-colors"
title="Reset Pencarian">
<i class="fas fa-times"></i>
</a>
@endif
</form>
<button @click="isModalPeminjamanOpen = true" class="bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white px-5 py-2.5 rounded-lg border border-transparent shadow-[0_4px_10px_rgba(37,99,235,0.2)] hover:shadow-[0_6px_15px_rgba(37,99,235,0.3)] transition-all font-semibold flex items-center gap-2 transform hover:translate-y-[-1px]">
<button @click="isModalPeminjamanOpen = true"
class="bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white px-5 py-2.5 rounded-lg border border-transparent shadow-[0_4px_10px_rgba(37,99,235,0.2)] hover:shadow-[0_6px_15px_rgba(37,99,235,0.3)] transition-all font-semibold flex items-center gap-2 transform hover:translate-y-[-1px]">
<i class="fas fa-plus mr-1"></i> Catat Peminjaman Baru
</button>
</div>
@ -84,7 +88,8 @@ class="bg-white border border-gray-200 border-r-0 text-gray-900 text-sm rounded-
@if ($item->anggota)
<div class="text-sm font-bold text-gray-900">{{ $item->anggota->nama }}</div>
<div class="text-xs text-gray-500 mt-0.5">ID: {{ $item->anggota->no_identitas }}</div>
<div class="inline-flex items-center gap-1.5 px-2 py-1 mt-1.5 rounded bg-green-50 text-green-700 text-[11px] font-bold border border-green-200">
<div
class="inline-flex items-center gap-1.5 px-2 py-1 mt-1.5 rounded bg-green-50 text-green-700 text-[11px] font-bold border border-green-200">
<i class="fab fa-whatsapp text-green-600"></i> {{ $item->anggota->no_hp ?? '-' }}
</div>
@else
@ -93,7 +98,8 @@ class="bg-white border border-gray-200 border-r-0 text-gray-900 text-sm rounded-
@endif
</td>
<td class="px-6 py-4">
<div class="text-sm font-bold text-gray-900 line-clamp-1">{{ $item->buku->judul ?? 'Buku Dihapus' }}</div>
<div class="text-sm font-bold text-gray-900 line-clamp-1">
{{ $item->buku->judul ?? 'Buku Dihapus' }}</div>
<div class="text-sm text-gray-500">{{ $item->buku->nomor_panggil ?? '-' }}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
@ -104,18 +110,23 @@ class="bg-white border border-gray-200 border-r-0 text-gray-900 text-sm rounded-
@if ($item->status_peminjaman == 'Dipinjam')
@if (\Carbon\Carbon::parse($item->tanggal_kembali)->startOfDay()->lt(\Carbon\Carbon::now()->startOfDay()))
@php
$selisihHari = \Carbon\Carbon::now()->startOfDay()->diffInDays(\Carbon\Carbon::parse($item->tanggal_kembali)->startOfDay());
$selisihHari = \Carbon\Carbon::now()
->startOfDay()
->diffInDays(\Carbon\Carbon::parse($item->tanggal_kembali)->startOfDay());
$estimasiDenda = $selisihHari * 1000;
@endphp
<x-badge color="red"><i class="fas fa-exclamation-triangle mr-1"></i> Terlambat</x-badge>
<div class="text-[10px] text-red-600 mt-1 font-bold animate-pulse">Denda berjalan: Rp {{ number_format($estimasiDenda, 0, ',', '.') }}</div>
<x-badge color="red"><i class="fas fa-exclamation-triangle mr-1"></i>
Terlambat</x-badge>
<div class="text-[10px] text-red-600 mt-1 font-bold animate-pulse">Denda berjalan: Rp
{{ number_format($estimasiDenda, 0, ',', '.') }}</div>
@else
<x-badge color="yellow">Aktif Dipinjam</x-badge>
@endif
@else
<x-badge color="green">Selesai</x-badge>
@if ($item->denda > 0)
<div class="text-xs text-red-600 font-bold mt-1">Denda: Rp {{ number_format($item->denda, 0, ',', '.') }}</div>
<div class="text-xs text-red-600 font-bold mt-1">Denda: Rp
{{ number_format($item->denda, 0, ',', '.') }}</div>
@endif
@endif
</td>
@ -136,15 +147,23 @@ class="bg-blue-100 text-blue-700 hover:bg-blue-200 px-3 py-1.5 rounded text-xs f
Kembalikan
</button>
@else
<span class="text-green-600 font-bold px-3 py-1.5 text-xs bg-green-50 rounded border border-green-200 flex items-center">Tuntas</span>
<span
class="text-green-600 font-bold px-3 py-1.5 text-xs bg-green-50 rounded border border-green-200 flex items-center">Tuntas</span>
@endif
<a href="{{ route('admin.peminjaman.struk', $item->id_peminjaman) }}" target="_blank" class="bg-gray-800 text-white hover:bg-gray-900 px-3 py-1.5 rounded text-xs font-bold transition flex items-center">Cetak Struk</a>
<a href="{{ route('admin.peminjaman.struk', $item->id_peminjaman) }}" target="_blank"
class="bg-gray-800 text-white hover:bg-gray-900 px-3 py-1.5 rounded text-xs font-bold transition flex items-center">Cetak
Struk</a>
@if ($item->status_peminjaman == 'Dipinjam')
<button type="button" @click="openEditModal('{{ $item->id_peminjaman }}', '{{ $item->id_anggota ?? $item->id_user }}', '{{ $item->id_buku }}', '{{ \Carbon\Carbon::parse($item->tanggal_pinjam)->format('Y-m-d') }}', '{{ \Carbon\Carbon::parse($item->tanggal_kembali)->format('Y-m-d') }}')" class="bg-yellow-100 text-yellow-700 hover:bg-yellow-200 px-2 py-1.5 rounded text-xs font-bold transition flex items-center" title="Edit Transaksi">
<button type="button"
@click="openEditModal('{{ $item->id_peminjaman }}', '{{ $item->id_anggota ?? $item->id_user }}', '{{ $item->id_buku }}', '{{ \Carbon\Carbon::parse($item->tanggal_pinjam)->format('Y-m-d') }}', '{{ \Carbon\Carbon::parse($item->tanggal_kembali)->format('Y-m-d') }}')"
class="bg-yellow-100 text-yellow-700 hover:bg-yellow-200 px-2 py-1.5 rounded text-xs font-bold transition flex items-center"
title="Edit Transaksi">
<i class="fas fa-edit"></i>
</button>
@endif
<button type="button" @click="openDeleteModal('{{ $item->id_peminjaman }}')" class="bg-red-100 text-red-700 hover:bg-red-200 px-2 py-1.5 rounded text-xs font-bold transition flex items-center" title="Hapus Permanen">
<button type="button" @click="openDeleteModal('{{ $item->id_peminjaman }}')"
class="bg-red-100 text-red-700 hover:bg-red-200 px-2 py-1.5 rounded text-xs font-bold transition flex items-center"
title="Hapus Permanen">
<i class="fas fa-trash-alt"></i>
</button>
</div>
@ -165,16 +184,18 @@ class="bg-blue-100 text-blue-700 hover:bg-blue-200 px-3 py-1.5 rounded text-xs f
</x-card>
<!-- MODAL TAMBAH PEMINJAMAN -->
<div x-show="isModalPeminjamanOpen" style="display: none;" class="fixed inset-0 z-50 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div x-show="isModalPeminjamanOpen" style="display: none;" class="fixed inset-0 z-50 overflow-y-auto"
aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div class="flex items-end justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<!-- Background overlay -->
<div x-show="isModalPeminjamanOpen" x-transition.opacity class="fixed inset-0 transition-opacity bg-gray-900/60 backdrop-blur-sm" aria-hidden="true" @click="isModalPeminjamanOpen = false"></div>
<div x-show="isModalPeminjamanOpen" x-transition.opacity
class="fixed inset-0 transition-opacity bg-gray-900/60 backdrop-blur-sm" aria-hidden="true"
@click="isModalPeminjamanOpen = false"></div>
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<!-- Modal panel -->
<div x-show="isModalPeminjamanOpen"
x-transition:enter="ease-out duration-300"
<div x-show="isModalPeminjamanOpen" x-transition:enter="ease-out duration-300"
x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
x-transition:leave="ease-in duration-200"
@ -187,13 +208,15 @@ class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transi
<h3 class="text-2xl font-bold text-gray-900" id="modal-title">Formulir Peminjaman Buku</h3>
<p class="text-sm text-gray-500 mt-1">Pilih anggota dan judul buku yang akan dipinjamkan.</p>
</div>
<button @click="isModalPeminjamanOpen = false" class="w-10 h-10 rounded-full bg-gray-50 hover:bg-red-50 text-gray-400 hover:text-red-500 flex items-center justify-center transition-colors">
<button @click="isModalPeminjamanOpen = false"
class="w-10 h-10 rounded-full bg-gray-50 hover:bg-red-50 text-gray-400 hover:text-red-500 flex items-center justify-center transition-colors">
<i class="fas fa-times text-lg"></i>
</button>
</div>
@if ($errors->any())
<div class="bg-red-50 border-l-4 border-red-500 text-red-700 p-4 mb-6 rounded-r-xl text-sm shadow-sm" role="alert">
<div class="bg-red-50 border-l-4 border-red-500 text-red-700 p-4 mb-6 rounded-r-xl text-sm shadow-sm"
role="alert">
<p class="font-bold mb-1"><i class="fas fa-exclamation-circle mr-1"></i> Validasi Gagal</p>
<ul class="list-disc ml-5 space-y-1">
@foreach ($errors->all() as $error)
@ -208,10 +231,13 @@ class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transi
<div>
<x-input-label value="Pilih Anggota / Member" />
<select name="id_anggota" x-init="new TomSelect($el, {maxOptions: null})" class="mt-1 block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-xl shadow-sm bg-gray-50/50" required>
<select name="id_anggota" x-init="new TomSelect($el, { maxOptions: null })"
class="mt-1 block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-xl shadow-sm bg-gray-50/50"
required>
<option value="">-- Pilih Member --</option>
@foreach ($anggota as $a)
<option value="{{ $a->id }}" {{ old('id_anggota') == $a->id ? 'selected' : '' }}>
<option value="{{ $a->id }}"
{{ old('id_anggota') == $a->id ? 'selected' : '' }}>
{{ $a->nama }} ({{ $a->no_identitas }})
</option>
@endforeach
@ -220,10 +246,12 @@ class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transi
<div>
<x-input-label value="Pilih Buku (Hanya yang tersedia)" />
<select name="id_buku" x-init="new TomSelect($el, {maxOptions: null})" class="mt-1 block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-xl shadow-sm bg-gray-50/50" required>
<select name="id_buku" x-init="new TomSelect($el, { maxOptions: null })"
class="mt-1 block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-xl shadow-sm bg-gray-50/50"
required>
<option value="">-- Pilih Buku --</option>
@foreach ($buku as $b)
<option value="{{ $b->id_buku }}" {{ old('id_buku') == $b->id_buku ? 'selected' : '' }}>
<option value="{{ $b->id }}" {{ old('id_buku') == $b->id ? 'selected' : '' }}>
{{ $b->bibid }} - {{ $b->judul }} (Stok: {{ $b->eksemplar }})
</option>
@endforeach
@ -233,19 +261,25 @@ class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transi
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<x-input-label value="Tanggal Pinjam" />
<x-text-input type="date" name="tanggal_pinjam" value="{{ old('tanggal_pinjam', date('Y-m-d')) }}" class="mt-1 block w-full bg-gray-50/50" required />
<x-text-input type="date" name="tanggal_pinjam"
value="{{ old('tanggal_pinjam', date('Y-m-d')) }}"
class="mt-1 block w-full bg-gray-50/50" required />
</div>
<div>
<x-input-label value="Tanggal Kembali (Tenggat)" />
<x-text-input type="date" name="tanggal_kembali" value="{{ old('tanggal_kembali', date('Y-m-d', strtotime('+7 days'))) }}" class="mt-1 block w-full bg-gray-50/50" required />
<x-text-input type="date" name="tanggal_kembali"
value="{{ old('tanggal_kembali', date('Y-m-d', strtotime('+7 days'))) }}"
class="mt-1 block w-full bg-gray-50/50" required />
</div>
</div>
<div class="flex items-center justify-end gap-3 pt-6 border-t border-gray-100 mt-8">
<button type="button" @click="isModalPeminjamanOpen = false" class="px-5 py-2.5 text-gray-600 bg-gray-100 hover:bg-gray-200 hover:text-gray-900 rounded-xl font-semibold transition-colors">
<button type="button" @click="isModalPeminjamanOpen = false"
class="px-5 py-2.5 text-gray-600 bg-gray-100 hover:bg-gray-200 hover:text-gray-900 rounded-xl font-semibold transition-colors">
Batal
</button>
<button type="submit" class="bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white px-6 py-2.5 rounded-xl font-bold shadow-lg shadow-blue-500/30 transition-all transform hover:scale-105">
<button type="submit"
class="bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white px-6 py-2.5 rounded-xl font-bold shadow-lg shadow-blue-500/30 transition-all transform hover:scale-105">
<i class="fas fa-check-circle mr-2"></i> Eksekusi Transaksi
</button>
</div>
@ -254,14 +288,16 @@ class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transi
</div>
</div>
<!-- MODAL PENGEMBALIAN & PEMBAYARAN DENDA -->
<div x-show="isModalKembaliOpen" style="display: none;" class="fixed inset-0 z-50 overflow-y-auto" aria-labelledby="modal-kembali-title" role="dialog" aria-modal="true">
<div x-show="isModalKembaliOpen" style="display: none;" class="fixed inset-0 z-50 overflow-y-auto"
aria-labelledby="modal-kembali-title" role="dialog" aria-modal="true">
<div class="flex items-end justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<div x-show="isModalKembaliOpen" x-transition.opacity class="fixed inset-0 transition-opacity bg-gray-900/60 backdrop-blur-sm" aria-hidden="true" @click="isModalKembaliOpen = false"></div>
<div x-show="isModalKembaliOpen" x-transition.opacity
class="fixed inset-0 transition-opacity bg-gray-900/60 backdrop-blur-sm" aria-hidden="true"
@click="isModalKembaliOpen = false"></div>
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<div x-show="isModalKembaliOpen"
x-transition:enter="ease-out duration-300"
<div x-show="isModalKembaliOpen" x-transition:enter="ease-out duration-300"
x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
x-transition:leave="ease-in duration-200"
@ -274,7 +310,8 @@ class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transi
<h3 class="text-xl font-bold text-gray-900" id="modal-kembali-title">Detail Pengembalian</h3>
<p class="text-xs text-gray-500 mt-1">Selesaikan transaksi peminjaman buku ini.</p>
</div>
<button @click="isModalKembaliOpen = false" class="w-8 h-8 rounded-full bg-gray-50 hover:bg-red-50 text-gray-400 hover:text-red-500 flex items-center justify-center transition-colors">
<button @click="isModalKembaliOpen = false"
class="w-8 h-8 rounded-full bg-gray-50 hover:bg-red-50 text-gray-400 hover:text-red-500 flex items-center justify-center transition-colors">
<i class="fas fa-times text-sm"></i>
</button>
</div>
@ -294,27 +331,36 @@ class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transi
</div>
<div class="flex justify-between items-center pt-2">
<span class="text-xs font-bold text-red-600">Total Denda</span>
<span class="text-lg font-black text-red-700" x-text="'Rp ' + new Intl.NumberFormat('id-ID').format(kembaliData.denda)"></span>
<span class="text-lg font-black text-red-700"
x-text="'Rp ' + new Intl.NumberFormat('id-ID').format(kembaliData.denda)"></span>
</div>
</div>
<template x-if="kembaliData.denda > 0">
<div class="bg-red-50 p-4 rounded-xl border border-red-100 mb-5">
<h4 class="text-xs font-bold text-red-800 mb-2"><i class="fas fa-money-bill-wave mr-1"></i>Pembayaran Denda</h4>
<h4 class="text-xs font-bold text-red-800 mb-2"><i
class="fas fa-money-bill-wave mr-1"></i>Pembayaran Denda</h4>
<div class="space-y-3">
<div>
<label class="block text-[10px] font-semibold text-red-700 mb-1 uppercase tracking-wider">Uang yang Dibayar (Rp)</label>
<input type="number" x-model.number="uangDibayar" min="0" class="w-full text-sm border-red-200 focus:border-red-500 focus:ring-red-500 rounded-lg shadow-sm bg-white" placeholder="Nominal uang...">
<label
class="block text-[10px] font-semibold text-red-700 mb-1 uppercase tracking-wider">Uang
yang Dibayar (Rp)</label>
<input type="number" x-model.number="uangDibayar" min="0"
class="w-full text-sm border-red-200 focus:border-red-500 focus:ring-red-500 rounded-lg shadow-sm bg-white"
placeholder="Nominal uang...">
</div>
<div class="flex justify-between items-center bg-white p-2.5 rounded-lg border border-red-100 shadow-sm">
<div
class="flex justify-between items-center bg-white p-2.5 rounded-lg border border-red-100 shadow-sm">
<span class="text-xs font-bold text-gray-600">Kembalian:</span>
<span class="text-base font-black text-green-600" x-text="'Rp ' + new Intl.NumberFormat('id-ID').format(kembalian)"></span>
<span class="text-base font-black text-green-600"
x-text="'Rp ' + new Intl.NumberFormat('id-ID').format(kembalian)"></span>
</div>
</div>
</div>
</template>
<template x-if="kembaliData.denda == 0">
<div class="bg-green-50 text-green-700 p-3 rounded-lg text-center font-bold text-xs mb-5 border border-green-100">
<div
class="bg-green-50 text-green-700 p-3 rounded-lg text-center font-bold text-xs mb-5 border border-green-100">
<i class="fas fa-check-circle mr-1"></i> Tidak ada denda keterlambatan.
</div>
</template>
@ -323,13 +369,15 @@ class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transi
@csrf
@method('PUT')
<div class="flex items-center justify-end gap-2 pt-3 border-t border-gray-100">
<button type="button" @click="isModalKembaliOpen = false" class="px-4 py-2 text-xs text-gray-600 bg-gray-100 hover:bg-gray-200 rounded-lg font-semibold transition-colors">
<button type="button" @click="isModalKembaliOpen = false"
class="px-4 py-2 text-xs text-gray-600 bg-gray-100 hover:bg-gray-200 rounded-lg font-semibold transition-colors">
Batal
</button>
<button type="submit"
class="bg-blue-600 hover:bg-blue-700 text-white px-5 py-2 rounded-lg text-xs font-bold shadow-md transition-all"
:disabled="kembaliData.denda > 0 && uangDibayar < kembaliData.denda"
:class="(kembaliData.denda > 0 && uangDibayar < kembaliData.denda) ? 'opacity-50 cursor-not-allowed' : 'hover:scale-105'">
:class="(kembaliData.denda > 0 && uangDibayar < kembaliData.denda) ?
'opacity-50 cursor-not-allowed' : 'hover:scale-105'">
<i class="fas fa-save mr-1"></i> Selesaikan Transaksi
</button>
</div>
@ -339,12 +387,14 @@ class="bg-blue-600 hover:bg-blue-700 text-white px-5 py-2 rounded-lg text-xs fon
</div>
<!-- MODAL EDIT PEMINJAMAN -->
<div x-show="isModalEditOpen" style="display: none;" class="fixed inset-0 z-50 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div x-show="isModalEditOpen" style="display: none;" class="fixed inset-0 z-50 overflow-y-auto"
aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div class="flex items-end justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<div x-show="isModalEditOpen" x-transition.opacity class="fixed inset-0 transition-opacity bg-gray-900/60 backdrop-blur-sm" aria-hidden="true" @click="isModalEditOpen = false"></div>
<div x-show="isModalEditOpen" x-transition.opacity
class="fixed inset-0 transition-opacity bg-gray-900/60 backdrop-blur-sm" aria-hidden="true"
@click="isModalEditOpen = false"></div>
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<div x-show="isModalEditOpen"
x-transition:enter="ease-out duration-300"
<div x-show="isModalEditOpen" x-transition:enter="ease-out duration-300"
x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
x-transition:leave="ease-in duration-200"
@ -357,7 +407,8 @@ class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transi
<h3 class="text-2xl font-bold text-gray-900">Ubah Data Peminjaman</h3>
<p class="text-sm text-gray-500 mt-1">Perbarui informasi transaksi peminjaman.</p>
</div>
<button @click="isModalEditOpen = false" class="w-10 h-10 rounded-full bg-gray-50 hover:bg-red-50 text-gray-400 hover:text-red-500 flex items-center justify-center transition-colors">
<button @click="isModalEditOpen = false"
class="w-10 h-10 rounded-full bg-gray-50 hover:bg-red-50 text-gray-400 hover:text-red-500 flex items-center justify-center transition-colors">
<i class="fas fa-times text-lg"></i>
</button>
</div>
@ -369,20 +420,28 @@ class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transi
<div>
<x-input-label value="Pilih Anggota / Member" />
<select name="id_anggota" x-model="editData.id_anggota" x-init="let tsA = null; $watch('isModalEditOpen', value => { if(value && !tsA && $el.offsetHeight) setTimeout(() => { try { tsA = new TomSelect($el, {maxOptions: null}); } catch(e){} }, 100) })" class="mt-1 block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-xl shadow-sm bg-gray-50/50" required>
<select name="id_anggota" x-model="editData.id_anggota" x-init="let tsA = null;
$watch('isModalEditOpen', value => { if (value && !tsA && $el.offsetHeight) setTimeout(() => { try { tsA = new TomSelect($el, { maxOptions: null }); } catch (e) {} }, 100) })"
class="mt-1 block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-xl shadow-sm bg-gray-50/50"
required>
<option value="">-- Pilih Member --</option>
@foreach ($anggota as $a)
<option value="{{ $a->id }}">{{ $a->nama }} ({{ $a->no_identitas }})</option>
<option value="{{ $a->id }}">{{ $a->nama }} ({{ $a->no_identitas }})
</option>
@endforeach
</select>
</div>
<div>
<x-input-label value="Pilih Buku" />
<select name="id_buku" x-model="editData.id_buku" x-init="let tsB = null; $watch('isModalEditOpen', value => { if(value && !tsB && $el.offsetHeight) setTimeout(() => { try { tsB = new TomSelect($el, {maxOptions: null}); } catch(e){} }, 100) })" class="mt-1 block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-xl shadow-sm bg-gray-50/50" required>
<select name="id_buku" x-model="editData.id_buku" x-init="let tsB = null;
$watch('isModalEditOpen', value => { if (value && !tsB && $el.offsetHeight) setTimeout(() => { try { tsB = new TomSelect($el, { maxOptions: null }); } catch (e) {} }, 100) })"
class="mt-1 block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-xl shadow-sm bg-gray-50/50"
required>
<option value="">-- Pilih Buku --</option>
@foreach ($buku as $b)
<option value="{{ $b->id_buku }}">{{ $b->bibid }} - {{ $b->judul }}</option>
<option value="{{ $b->id }}">{{ $b->bibid }} - {{ $b->judul }}
</option>
@endforeach
</select>
</div>
@ -390,17 +449,21 @@ class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transi
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<x-input-label value="Tanggal Pinjam" />
<x-text-input type="date" name="tanggal_pinjam" x-model="editData.tanggal_pinjam" class="mt-1 block w-full bg-gray-50/50" required />
<x-text-input type="date" name="tanggal_pinjam" x-model="editData.tanggal_pinjam"
class="mt-1 block w-full bg-gray-50/50" required />
</div>
<div>
<x-input-label value="Tanggal Kembali (Tenggat)" />
<x-text-input type="date" name="tanggal_kembali" x-model="editData.tanggal_kembali" class="mt-1 block w-full bg-gray-50/50" required />
<x-text-input type="date" name="tanggal_kembali" x-model="editData.tanggal_kembali"
class="mt-1 block w-full bg-gray-50/50" required />
</div>
</div>
<div class="flex items-center justify-end gap-3 pt-6 border-t border-gray-100 mt-8">
<button type="button" @click="isModalEditOpen = false" class="px-5 py-2.5 text-gray-600 bg-gray-100 hover:bg-gray-200 rounded-xl font-semibold transition-colors">Batal</button>
<button type="submit" class="bg-gradient-to-r from-yellow-500 to-orange-600 hover:from-yellow-600 hover:to-orange-700 text-white px-6 py-2.5 rounded-xl font-bold shadow-lg transition-all transform hover:scale-105">
<button type="button" @click="isModalEditOpen = false"
class="px-5 py-2.5 text-gray-600 bg-gray-100 hover:bg-gray-200 rounded-xl font-semibold transition-colors">Batal</button>
<button type="submit"
class="bg-gradient-to-r from-yellow-500 to-orange-600 hover:from-yellow-600 hover:to-orange-700 text-white px-6 py-2.5 rounded-xl font-bold shadow-lg transition-all transform hover:scale-105">
<i class="fas fa-save mr-2"></i> Simpan Perubahan
</button>
</div>
@ -410,25 +473,21 @@ class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transi
</div>
<!-- MODAL KONFIRMASI HAPUS PREMIUM -->
<div x-show="isModalDeleteOpen"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0"
x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
class="fixed inset-0 z-50 overflow-y-auto" style="display: none;">
<div x-show="isModalDeleteOpen" x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-200" x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0" class="fixed inset-0 z-50 overflow-y-auto" style="display: none;">
<div class="flex items-center justify-center min-h-screen px-4">
<div class="fixed inset-0 bg-gray-900/60 backdrop-blur-sm" @click="isModalDeleteOpen = false"></div>
<div x-show="isModalDeleteOpen"
x-transition:enter="transition ease-out duration-300 transform"
<div x-show="isModalDeleteOpen" x-transition:enter="transition ease-out duration-300 transform"
x-transition:enter-start="opacity-0 scale-95 translate-y-4"
x-transition:enter-end="opacity-100 scale-100 translate-y-0"
class="relative bg-white rounded-[2rem] shadow-2xl max-w-md w-full p-8 overflow-hidden border border-gray-100">
<div class="absolute top-0 right-0 p-4">
<button @click="isModalDeleteOpen = false" class="text-gray-400 hover:text-gray-600 transition-colors">
<button @click="isModalDeleteOpen = false"
class="text-gray-400 hover:text-gray-600 transition-colors">
<i class="fas fa-times"></i>
</button>
</div>
@ -441,17 +500,20 @@ class="relative bg-white rounded-[2rem] shadow-2xl max-w-md w-full p-8 overflow-
</div>
<h3 class="text-2xl font-black text-gray-900 mb-2">Hapus Transaksi?</h3>
<p class="text-gray-500 mb-8 px-4 leading-relaxed">Data peminjaman ini akan dihapus permanen. Stok buku akan otomatis dikembalikan jika status masih dipinjam.</p>
<p class="text-gray-500 mb-8 px-4 leading-relaxed">Data peminjaman ini akan dihapus permanen. Stok
buku akan otomatis dikembalikan jika status masih dipinjam.</p>
<div class="flex flex-col gap-3">
<form :action="'/admin/peminjaman/' + deleteId" method="POST" class="w-full m-0">
@csrf
@method('DELETE')
<button type="submit" class="w-full py-4 bg-gradient-to-r from-red-600 to-rose-600 hover:from-red-700 hover:to-rose-700 text-white rounded-2xl font-bold shadow-lg shadow-red-500/30 transition-all transform hover:scale-[1.02] active:scale-95">
<button type="submit"
class="w-full py-4 bg-gradient-to-r from-red-600 to-rose-600 hover:from-red-700 hover:to-rose-700 text-white rounded-2xl font-bold shadow-lg shadow-red-500/30 transition-all transform hover:scale-[1.02] active:scale-95">
Ya, Hapus Sekarang
</button>
</form>
<button @click="isModalDeleteOpen = false" class="w-full py-4 bg-gray-50 hover:bg-gray-100 text-gray-600 rounded-2xl font-bold transition-all">
<button @click="isModalDeleteOpen = false"
class="w-full py-4 bg-gray-50 hover:bg-gray-100 text-gray-600 rounded-2xl font-bold transition-all">
Batalkan
</button>
</div>

View File

@ -2,31 +2,44 @@
@section('content')
<!-- Hero Section -->
<div class="relative bg-gradient-to-br from-blue-900 via-indigo-800 to-blue-900 py-16 sm:py-24 overflow-hidden shadow-2xl mb-12">
<div
class="relative bg-gradient-to-br from-blue-900 via-indigo-800 to-blue-900 py-16 sm:py-24 overflow-hidden shadow-2xl mb-12">
<!-- Decorative background elements -->
<div class="absolute inset-0 opacity-10 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] mix-blend-overlay"></div>
<div class="absolute top-0 right-0 -mr-20 -mt-20 w-72 h-72 rounded-full bg-blue-400 mix-blend-multiply filter blur-3xl opacity-30 animate-blob"></div>
<div class="absolute bottom-0 left-0 -ml-20 -mb-20 w-72 h-72 rounded-full bg-indigo-300 mix-blend-multiply filter blur-3xl opacity-30 animate-blob animation-delay-2000"></div>
<div
class="absolute inset-0 opacity-10 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] mix-blend-overlay">
</div>
<div
class="absolute top-0 right-0 -mr-20 -mt-20 w-72 h-72 rounded-full bg-blue-400 mix-blend-multiply filter blur-3xl opacity-30 animate-blob">
</div>
<div
class="absolute bottom-0 left-0 -ml-20 -mb-20 w-72 h-72 rounded-full bg-indigo-300 mix-blend-multiply filter blur-3xl opacity-30 animate-blob animation-delay-2000">
</div>
<div class="container mx-auto px-4 relative z-10">
<div class="text-center max-w-3xl mx-auto">
<h1 class="text-4xl sm:text-5xl font-extrabold text-white mb-6 tracking-tight">
Eksplorasi <span class="text-transparent bg-clip-text bg-gradient-to-r from-blue-200 to-cyan-200">Katalog Perpustakaan</span>
Eksplorasi <span class="text-transparent bg-clip-text bg-gradient-to-r from-blue-200 to-cyan-200">Katalog
Perpustakaan</span>
</h1>
<p class="text-blue-100 text-lg sm:text-xl mb-10 font-light">
Temukan ribuan koleksi buku, jurnal, dan referensi akademik untuk menginspirasi perjalanan literasi Anda.
Temukan ribuan koleksi buku, jurnal, dan referensi akademik untuk menginspirasi perjalanan literasi
Anda.
</p>
<!-- Search Bar -->
<form action="{{ route('katalog.index') }}" method="GET" class="relative group max-w-2xl mx-auto">
<div class="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
<svg class="h-6 w-6 text-gray-400 group-focus-within:text-blue-500 transition-colors" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
<svg class="h-6 w-6 text-gray-400 group-focus-within:text-blue-500 transition-colors"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</div>
<input type="text" name="search" value="{{ $search }}" placeholder="Cari judul buku, pengarang, atau penerbit..."
<input type="text" name="search" value="{{ $search }}"
placeholder="Cari judul buku, pengarang, atau penerbit..."
class="block w-full pl-12 pr-32 py-4 bg-white/95 backdrop-blur-sm border-0 rounded-2xl shadow-xl focus:ring-4 focus:ring-blue-500/30 text-gray-800 text-lg transition-all placeholder-gray-400">
<button type="submit" class="absolute right-2 top-2 bottom-2 bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white font-semibold px-6 lg:px-8 rounded-xl shadow-md transition-all transform hover:scale-[1.02] active:scale-[0.98]">
<button type="submit"
class="absolute right-2 top-2 bottom-2 bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white font-semibold px-6 lg:px-8 rounded-xl shadow-md transition-all transform hover:scale-[1.02] active:scale-[0.98]">
Cari
</button>
</form>
@ -38,32 +51,41 @@ class="block w-full pl-12 pr-32 py-4 bg-white/95 backdrop-blur-sm border-0 round
<!-- Results Info -->
@if (isset($search) && $search != '')
<div class="mb-8 flex justify-between items-center text-gray-600">
<p>Menampilkan hasil pencarian untuk: <span class="font-semibold text-gray-900">"{{ $search }}"</span></p>
<p>Menampilkan hasil pencarian untuk: <span class="font-semibold text-gray-900">"{{ $search }}"</span>
</p>
</div>
@endif
<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-6">
@forelse($buku as $item)
@php
$habis = ($item->eksemplar <= 0);
$habis = $item->eksemplar <= 0;
@endphp
<div class="group bg-white rounded-2xl shadow-sm hover:shadow-2xl border border-gray-100 overflow-hidden transition-all duration-300 transform {{ $habis ? 'grayscale opacity-75 cursor-not-allowed' : 'hover:-translate-y-1' }} flex flex-col h-full">
<div
class="group bg-white rounded-2xl shadow-sm hover:shadow-2xl border border-gray-100 overflow-hidden transition-all duration-300 transform {{ $habis ? 'grayscale opacity-75 cursor-not-allowed' : 'hover:-translate-y-1' }} flex flex-col h-full">
<!-- Book Cover -->
<div class="relative w-full pt-[140%] overflow-hidden bg-gray-50 flex-shrink-0">
@if ($item->cover)
<img src="{{ asset('storage/' . $item->cover) }}" alt="{{ $item->judul }}"
class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:scale-110' : '' }} transition-transform duration-700 ease-in-out">
@else
<div class="absolute inset-0 flex flex-col items-center justify-center text-gray-300 bg-gray-100 {{ !$habis ? 'group-hover:bg-gray-200' : '' }} transition-colors duration-300">
<svg class="w-12 h-12 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path></svg>
<div
class="absolute inset-0 flex flex-col items-center justify-center text-gray-300 bg-gray-100 {{ !$habis ? 'group-hover:bg-gray-200' : '' }} transition-colors duration-300">
<svg class="w-12 h-12 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253">
</path>
</svg>
<span class="text-xs font-medium">Cover Tidak Tersedia</span>
</div>
@endif
@if ($habis)
<!-- Overlay Dipinjam Semua -->
<div class="absolute inset-0 bg-red-900/30 backdrop-blur-[1px] flex items-center justify-center z-10">
<div class="bg-red-600/90 text-white font-black text-sm md:text-base px-6 py-2 border-y-2 border-white transform -rotate-12 shadow-2xl tracking-widest uppercase pointer-events-none">
<div
class="absolute inset-0 bg-red-900/30 backdrop-blur-[1px] flex items-center justify-center z-10">
<div
class="bg-red-600/90 text-white font-black text-sm md:text-base px-6 py-2 border-y-2 border-white transform -rotate-12 shadow-2xl tracking-widest uppercase pointer-events-none">
TIDAK TERSEDIA
</div>
</div>
@ -74,7 +96,7 @@ class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:sca
$isBaru = false;
$tahunSekarang = date('Y');
if (isset($item->tahun_terbit) && intval($item->tahun_terbit) >= ($tahunSekarang - 1)) {
if (isset($item->tahun_terbit) && intval($item->tahun_terbit) >= $tahunSekarang - 1) {
$isBaru = true;
} elseif (isset($item->created_at)) {
$tanggalMasuk = \Carbon\Carbon::parse($item->created_at);
@ -86,7 +108,8 @@ class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:sca
@if ($isBaru && !$habis)
<div class="absolute top-0 right-0 z-20">
<div class="bg-gradient-to-r from-yellow-400 to-orange-500 text-white text-[9px] sm:text-[10px] font-extrabold px-3 py-1.5 shadow-lg rounded-bl-xl origin-top-right transform">
<div
class="bg-gradient-to-r from-yellow-400 to-orange-500 text-white text-[9px] sm:text-[10px] font-extrabold px-3 py-1.5 shadow-lg rounded-bl-xl origin-top-right transform">
<i class="fas fa-sparkles mr-1"></i> BUKU BARU
</div>
</div>
@ -94,11 +117,13 @@ class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:sca
<!-- Overlay Badges -->
<div class="absolute top-2 inset-x-2 flex justify-between items-start z-20">
<span class="bg-white/90 backdrop-blur-md text-gray-800 text-[10px] sm:text-xs font-bold px-2 py-1 rounded shadow-sm">
<span
class="bg-white/90 backdrop-blur-md text-gray-800 text-[10px] sm:text-xs font-bold px-2 py-1 rounded shadow-sm">
{{ $item->nomor_panggil }}
</span>
@if (isset($item->similarity_score))
<span class="bg-blue-600/90 backdrop-blur-md text-white text-[10px] sm:text-xs font-semibold px-2 py-1 rounded shadow-sm">
<span
class="bg-blue-600/90 backdrop-blur-md text-white text-[10px] sm:text-xs font-semibold px-2 py-1 rounded shadow-sm">
{{ $item->similarity_score >= 1 ? 'Exact' : 'Rel: ' . number_format($item->similarity_score, 1) }}
</span>
@endif
@ -107,7 +132,8 @@ class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:sca
<!-- Content -->
<div class="p-4 flex-grow flex flex-col">
<h2 class="text-sm sm:text-base font-bold text-gray-900 mb-1 line-clamp-2 md:leading-snug {{ !$habis ? 'group-hover:text-blue-600 transition-colors' : '' }}" title="{{ $item->judul }}">
<h2 class="text-sm sm:text-base font-bold text-gray-900 mb-1 line-clamp-2 md:leading-snug {{ !$habis ? 'group-hover:text-blue-600 transition-colors' : '' }}"
title="{{ $item->judul }}">
{{ $item->judul }}
</h2>
<p class="text-blue-600 font-medium text-xs sm:text-sm mb-2 line-clamp-1">
@ -116,7 +142,8 @@ class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:sca
<div class="mt-auto pt-3 flex flex-col gap-2 border-t border-gray-50">
<div class="flex justify-between items-center text-[10px] sm:text-xs text-gray-500">
<span class="truncate pr-1">{{ $item->penerbit }}</span>
<span class="font-medium bg-gray-100 px-1.5 py-0.5 rounded">{{ $item->tahun_terbit ?? '-' }}</span>
<span
class="font-medium bg-gray-100 px-1.5 py-0.5 rounded">{{ $item->tahun_terbit ?? '-' }}</span>
</div>
</div>
</div>
@ -124,25 +151,30 @@ class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:sca
<!-- Action Area -->
<div class="px-4 pb-4 pt-0 mt-auto relative z-30">
@if ($habis)
<button disabled class="w-full text-center bg-gray-100 text-gray-500 text-sm font-semibold py-2 px-3 rounded-xl border border-gray-200 cursor-not-allowed opacity-80 backdrop-blur-sm">
<button disabled
class="w-full text-center bg-gray-100 text-gray-500 text-sm font-semibold py-2 px-3 rounded-xl border border-gray-200 cursor-not-allowed opacity-80 backdrop-blur-sm">
Habis Dipinjam
</button>
@else
<a href="{{ route('katalog.show', $item->id_buku) }}" class="block w-full text-center bg-gray-50 hover:bg-blue-600 text-gray-700 hover:text-white text-sm font-semibold py-2 px-3 rounded-xl border border-gray-200 hover:border-transparent transition-all duration-300">
<a href="{{ route('katalog.show', $item->id) }}"
class="block w-full text-center bg-gray-50 hover:bg-blue-600 text-gray-700 hover:text-white text-sm font-semibold py-2 px-3 rounded-xl border border-gray-200 hover:border-transparent transition-all duration-300">
Lihat Detail
</a>
@endif
</div>
</div>
@empty
<div class="col-span-full py-20 bg-white rounded-3xl shadow-sm border border-gray-100 flex flex-col items-center justify-center text-center px-4">
<div
class="col-span-full py-20 bg-white rounded-3xl shadow-sm border border-gray-100 flex flex-col items-center justify-center text-center px-4">
<div class="w-20 h-20 sm:w-24 sm:h-24 bg-gray-50 rounded-full flex items-center justify-center mb-6">
<svg class="h-10 w-10 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
</svg>
</div>
<h3 class="text-xl sm:text-2xl font-bold text-gray-900 mb-2">Tidak Ada Koleksi</h3>
<p class="text-gray-500 max-w-md text-sm sm:text-base">Koleksi buku yang Anda cari belum tersedia saat ini. Silakan coba dengan kata kunci lain.</p>
<p class="text-gray-500 max-w-md text-sm sm:text-base">Koleksi buku yang Anda cari belum tersedia saat
ini. Silakan coba dengan kata kunci lain.</p>
</div>
@endforelse
</div>
@ -156,7 +188,8 @@ class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:sca
@if (isset($bukuPopuler) && $bukuPopuler->count() > 0)
<div class="mt-20 max-w-5xl mx-auto bg-white rounded-[2rem] shadow-sm border border-gray-100 p-6 sm:p-10">
<div class="flex items-center gap-3 mb-6 border-b border-gray-100 pb-4">
<div class="w-10 h-10 bg-gradient-to-br from-orange-400 to-red-500 rounded-xl flex items-center justify-center text-white shadow-lg shadow-orange-200">
<div
class="w-10 h-10 bg-gradient-to-br from-orange-400 to-red-500 rounded-xl flex items-center justify-center text-white shadow-lg shadow-orange-200">
<i class="fas fa-fire text-lg"></i>
</div>
<h3 class="text-2xl font-black text-gray-900 tracking-tight">Top 5 Buku Terpopuler</h3>
@ -164,15 +197,18 @@ class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:sca
<ul class="divide-y divide-gray-50">
@foreach ($bukuPopuler as $top)
<li class="py-4 flex flex-col sm:flex-row sm:justify-between sm:items-center gap-4 hover:bg-gray-50/80 -mx-4 px-4 rounded-2xl transition-colors group">
<li
class="py-4 flex flex-col sm:flex-row sm:justify-between sm:items-center gap-4 hover:bg-gray-50/80 -mx-4 px-4 rounded-2xl transition-colors group">
<div>
<a href="{{ route('katalog.show', $top->id_buku) }}" class="font-bold text-gray-900 text-base md:text-lg group-hover:text-blue-600 transition-colors block mb-1">
<a href="{{ route('katalog.show', $top->id) }}"
class="font-bold text-gray-900 text-base md:text-lg group-hover:text-blue-600 transition-colors block mb-1">
{{ $top->judul }}
</a>
<p class="text-sm text-gray-500">{{ $top->pengarang }}</p>
</div>
<div class="self-start sm:self-auto">
<span class="inline-flex items-center gap-1.5 bg-gradient-to-r from-blue-50 to-indigo-50 text-blue-700 border border-blue-100 text-xs font-bold px-4 py-2 rounded-full whitespace-nowrap shadow-sm transition-all group-hover:shadow-md">
<span
class="inline-flex items-center gap-1.5 bg-gradient-to-r from-blue-50 to-indigo-50 text-blue-700 border border-blue-100 text-xs font-bold px-4 py-2 rounded-full whitespace-nowrap shadow-sm transition-all group-hover:shadow-md">
<i class="fas fa-chart-line text-blue-500"></i> {{ $top->peminjaman_count }} Peminjaman
</span>
</div>

View File

@ -10,6 +10,7 @@
border-radius: 0.75rem;
background: #E2E8F0;
}
.map-container img {
display: block;
width: 100%;
@ -26,10 +27,12 @@
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.25));
transition: filter 0.3s ease;
}
.map-pin:hover {
filter: drop-shadow(0 6px 14px rgba(227, 38, 54, 0.5));
z-index: 40;
}
.map-pin.active {
animation: pinBounce 1.5s infinite;
}
@ -40,6 +43,7 @@
flex-direction: column;
align-items: center;
}
.map-pin__circle {
width: 32px;
height: 32px;
@ -51,10 +55,12 @@
border: 2.5px solid #fff;
box-shadow: 0 2px 8px rgba(227, 38, 54, 0.4);
}
.map-pin__circle i {
color: #fff;
font-size: 13px;
}
.map-pin__tail {
width: 0;
height: 0;
@ -83,6 +89,7 @@
opacity: 0;
transition: opacity 0.2s ease;
}
.map-pin:hover .map-pin__label,
.map-pin.active .map-pin__label {
opacity: 1;
@ -100,6 +107,7 @@
background: rgba(227, 38, 54, 0.35);
z-index: -1;
}
.map-pin.active .map-pin__pulse {
animation: pinPulse 2s infinite;
}
@ -119,12 +127,27 @@
}
@keyframes pinBounce {
0%, 100% { transform: translate(-50%, -100%); }
50% { transform: translate(-50%, calc(-100% - 8px)); }
0%,
100% {
transform: translate(-50%, -100%);
}
50% {
transform: translate(-50%, calc(-100% - 8px));
}
}
@keyframes pinPulse {
0% { transform: translateX(-50%) scale(1); opacity: 0.6; }
100% { transform: translateX(-50%) scale(3.5); opacity: 0; }
0% {
transform: translateX(-50%) scale(1);
opacity: 0.6;
}
100% {
transform: translateX(-50%) scale(3.5);
opacity: 0;
}
}
/* Responsive adjustments */
@ -133,14 +156,17 @@
width: 24px;
height: 24px;
}
.map-pin__circle i {
font-size: 10px;
}
.map-pin__tail {
border-left-width: 5px;
border-right-width: 5px;
border-top-width: 7px;
}
.map-pin__label {
font-size: 8px;
padding: 2px 6px;
@ -153,14 +179,17 @@
<div class="container mx-auto px-4 py-12 max-w-7xl">
<!-- Header: Back button & Search Bar -->
<div class="flex flex-col md:flex-row justify-between items-center mb-10 gap-6">
<a href="{{ route('katalog.index') }}" class="text-gray-500 hover:text-blue-600 font-bold flex items-center transition-colors px-4 py-2 bg-white rounded-full shadow-sm border border-gray-100 hover:shadow-md">
<a href="{{ route('katalog.index') }}"
class="text-gray-500 hover:text-blue-600 font-bold flex items-center transition-colors px-4 py-2 bg-white rounded-full shadow-sm border border-gray-100 hover:shadow-md">
<i class="fas fa-arrow-left mr-2"></i> Kembali
</a>
<!-- Search Bar -->
<form action="{{ route('katalog.index') }}" method="GET" class="w-full md:w-80 relative group">
<input type="text" name="search" placeholder="Cari Buku..." class="w-full pl-5 pr-14 py-3 bg-white border border-gray-200 rounded-full shadow-sm focus:ring-4 focus:ring-blue-500/20 focus:border-blue-500 text-sm font-medium transition-all outline-none">
<button type="submit" class="absolute right-1 top-1 bottom-1 w-10 flex items-center justify-center bg-gray-100 text-gray-600 rounded-full hover:bg-blue-600 hover:text-white transition-colors">
<input type="text" name="search" placeholder="Cari Buku..."
class="w-full pl-5 pr-14 py-3 bg-white border border-gray-200 rounded-full shadow-sm focus:ring-4 focus:ring-blue-500/20 focus:border-blue-500 text-sm font-medium transition-all outline-none">
<button type="submit"
class="absolute right-1 top-1 bottom-1 w-10 flex items-center justify-center bg-gray-100 text-gray-600 rounded-full hover:bg-blue-600 hover:text-white transition-colors">
<i class="fas fa-search"></i>
</button>
</form>
@ -171,23 +200,33 @@
<!-- Column 1: Book Cover Card -->
<div class="md:col-span-12 lg:col-span-3">
<div class="bg-white rounded-3xl shadow-[0_10px_40px_-10px_rgba(0,0,0,0.08)] border border-gray-50 p-5 flex flex-col items-center text-center overflow-hidden transition-transform duration-500 hover:-translate-y-2">
<div
class="bg-white rounded-3xl shadow-[0_10px_40px_-10px_rgba(0,0,0,0.08)] border border-gray-50 p-5 flex flex-col items-center text-center overflow-hidden transition-transform duration-500 hover:-translate-y-2">
@if ($buku->cover)
<img src="{{ asset('storage/' . $buku->cover) }}" alt="{{ $buku->judul }}" class="w-full aspect-[3/4] object-cover rounded-2xl mb-6 shadow-md border border-gray-100">
<img src="{{ asset('storage/' . $buku->cover) }}" alt="{{ $buku->judul }}"
class="w-full aspect-[3/4] object-cover rounded-2xl mb-6 shadow-md border border-gray-100">
@else
<div class="w-full aspect-[3/4] bg-gradient-to-br from-indigo-50 to-blue-50 rounded-2xl flex items-center justify-center mb-6 overflow-hidden relative shadow-inner border border-blue-100/50">
<div class="absolute inset-0 opacity-40 bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGNpcmNsZSBjeD0iMiIgY3k9IjIiIHI9IjIiIGZpbGw9IiMzYjgyZjYiIGZpbGwtb3BhY2l0eT0iMC4wNSIvPjwvc3ZnPg==')]"></div>
<div
class="w-full aspect-[3/4] bg-gradient-to-br from-indigo-50 to-blue-50 rounded-2xl flex items-center justify-center mb-6 overflow-hidden relative shadow-inner border border-blue-100/50">
<div
class="absolute inset-0 opacity-40 bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGNpcmNsZSBjeD0iMiIgY3k9IjIiIHI9IjIiIGZpbGw9IiMzYjgyZjYiIGZpbGwtb3BhY2l0eT0iMC4wNSIvPjwvc3ZnPg==')]">
</div>
<div class="relative z-10 flex flex-col items-center justify-center p-6 w-full h-full">
<div class="w-20 h-20 bg-white/80 backdrop-blur rounded-full flex items-center justify-center mb-4 shadow-sm text-blue-400">
<div
class="w-20 h-20 bg-white/80 backdrop-blur rounded-full flex items-center justify-center mb-4 shadow-sm text-blue-400">
<i class="fas fa-book-open text-3xl"></i>
</div>
<h3 class="text-sm font-black text-blue-900 leading-snug break-words drop-shadow-sm uppercase line-clamp-4">{{ $buku->judul }}</h3>
<h3
class="text-sm font-black text-blue-900 leading-snug break-words drop-shadow-sm uppercase line-clamp-4">
{{ $buku->judul }}</h3>
<div class="w-8 h-1 bg-blue-300/50 rounded-full my-3"></div>
<p class="text-[10px] text-blue-700 font-bold uppercase tracking-widest">{{ $buku->pengarang }}</p>
<p class="text-[10px] text-blue-700 font-bold uppercase tracking-widest">
{{ $buku->pengarang }}</p>
</div>
</div>
@endif
<h2 class="font-extrabold text-gray-900 uppercase tracking-widest text-xs leading-relaxed px-2 mb-2">{{ $buku->judul }}</h2>
<h2 class="font-extrabold text-gray-900 uppercase tracking-widest text-xs leading-relaxed px-2 mb-2">
{{ $buku->judul }}</h2>
</div>
</div>
@ -201,7 +240,8 @@
<!-- Data Row -->
<div class="flex flex-col sm:flex-row gap-2 border-b border-gray-100 pb-5">
<span class="text-gray-500 font-semibold text-sm w-full sm:w-1/3 flex-shrink-0">Kode Buku:</span>
<span class="text-gray-900 font-bold text-sm bg-gray-100 px-3 py-1 rounded w-fit">{{ $buku->nomor_panggil ?? '-' }}</span>
<span
class="text-gray-900 font-bold text-sm bg-gray-100 px-3 py-1 rounded w-fit">{{ $buku->nomor_panggil ?? '-' }}</span>
</div>
<!-- Data Row -->
<div class="flex flex-col sm:flex-row gap-2 border-b border-gray-100 pb-5">
@ -215,18 +255,24 @@
</div>
<!-- Data Row -->
<div class="flex flex-col sm:flex-row gap-2 border-b border-gray-100 pb-5">
<span class="text-gray-500 font-semibold text-sm w-full sm:w-1/3 flex-shrink-0">Deskripsi Fisik:</span>
<span class="text-gray-700 font-medium text-sm leading-relaxed">{{ $buku->deskripsi_fisik ?: 'Tidak ada deskripsi fisik.' }}</span>
<span class="text-gray-500 font-semibold text-sm w-full sm:w-1/3 flex-shrink-0">Deskripsi
Fisik:</span>
<span
class="text-gray-700 font-medium text-sm leading-relaxed">{{ $buku->deskripsi_fisik ?: 'Tidak ada deskripsi fisik.' }}</span>
</div>
<!-- Data Row -->
<div class="flex flex-col sm:flex-row gap-2 border-b border-gray-100 pb-5">
<span class="text-gray-500 font-semibold text-sm w-full sm:w-1/3 flex-shrink-0">Nama Kategori:</span>
<span class="text-blue-600 font-bold text-sm">{{ $buku->kategori->nama_kategori ?? $lokasi['area'] }}</span>
<span class="text-gray-500 font-semibold text-sm w-full sm:w-1/3 flex-shrink-0">Nama
Kategori:</span>
<span
class="text-blue-600 font-bold text-sm">{{ $buku->kategori->nama_kategori ?? $lokasi['area'] }}</span>
</div>
<!-- Data Row -->
<div class="flex flex-col sm:flex-row gap-2 pb-5">
<span class="text-gray-500 font-semibold text-sm w-full sm:w-1/3 flex-shrink-0">Detail Kategori:</span>
<span class="text-gray-900 font-bold text-sm">{{ $lokasi['area'] }} (Rak {{ $lokasi['rak'] }})</span>
<span class="text-gray-500 font-semibold text-sm w-full sm:w-1/3 flex-shrink-0">Detail
Kategori:</span>
<span class="text-gray-900 font-bold text-sm">{{ $lokasi['area'] }} (Rak
{{ $lokasi['rak'] }})</span>
</div>
</div>
</div>
@ -234,7 +280,8 @@
<div class="w-full lg:w-96 flex-shrink-0 flex flex-col gap-6 mx-auto relative">
<!-- MAP CONTAINER -->
<div class="map-container shadow-sm border-2 border-slate-300 select-none font-sans min-h-[300px]" id="mapContainer">
<div class="map-container shadow-sm border-2 border-slate-300 select-none font-sans min-h-[300px]"
id="mapContainer">
<!-- Background Image Map -->
<img src="{{ asset('img/img 2.png') }}" alt="Denah Perpustakaan" id="mapImage">
@ -252,8 +299,11 @@
</div>
<!-- Detail Mini location box directly below map -->
<div class="bg-blue-900 border border-blue-800 rounded-2xl p-5 text-center shadow-lg w-full relative z-20 transform transition hover:scale-[1.02]">
<span class="text-[10px] text-blue-300 font-bold uppercase tracking-widest block mb-2 opacity-80">Informasi Lokasi Fisik</span>
<div
class="bg-blue-900 border border-blue-800 rounded-2xl p-5 text-center shadow-lg w-full relative z-20 transform transition hover:scale-[1.02]">
<span
class="text-[10px] text-blue-300 font-bold uppercase tracking-widest block mb-2 opacity-80">Informasi
Lokasi Fisik</span>
<span class="text-2xl font-black text-white block mb-1 drop-shadow-sm">{{ $lokasi['rak'] }}</span>
<span class="text-sm font-semibold text-blue-200">{{ $lokasi['area'] }}</span>
</div>
@ -262,7 +312,8 @@
<!-- Riwayat Peminjaman -->
<div class="mt-12 mb-8">
<h2 class="text-2xl font-extrabold text-gray-900 mb-6 border-b-2 border-blue-500 inline-block pb-2">Riwayat Peminjaman</h2>
<h2 class="text-2xl font-extrabold text-gray-900 mb-6 border-b-2 border-blue-500 inline-block pb-2">Riwayat
Peminjaman</h2>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
@if ($buku->peminjaman && $buku->peminjaman->count() > 0)
<div class="overflow-x-auto">
@ -281,9 +332,12 @@
<td class="py-4 px-6 font-medium text-gray-900">
@php
$nama = $history->user->name ?? 'Pengguna Tidak Diketahui';
$disensor = $nama !== 'Pengguna Tidak Diketahui' && strlen($nama) >= 3
$disensor =
$nama !== 'Pengguna Tidak Diketahui' && strlen($nama) >= 3
? substr($nama, 0, 3) . '***'
: ($nama !== 'Pengguna Tidak Diketahui' ? substr($nama, 0, 1) . '***' : $nama);
: ($nama !== 'Pengguna Tidak Diketahui'
? substr($nama, 0, 1) . '***'
: $nama);
@endphp
{{ $disensor }}
</td>
@ -293,21 +347,27 @@
<td class="py-4 px-6">
@if ($history->status_peminjaman === 'Dikembalikan' && $history->tanggal_dikembalikan)
<span class="text-green-600 font-medium">
{{ \Carbon\Carbon::parse($history->tanggal_dikembalikan)->translatedFormat('d F Y') }} (Dikembalikan)
{{ \Carbon\Carbon::parse($history->tanggal_dikembalikan)->translatedFormat('d F Y') }}
(Dikembalikan)
</span>
@else
<span class="text-gray-600">
Batas: {{ \Carbon\Carbon::parse($history->tanggal_kembali)->translatedFormat('d F Y') }}
Batas:
{{ \Carbon\Carbon::parse($history->tanggal_kembali)->translatedFormat('d F Y') }}
</span>
@endif
</td>
<td class="py-4 px-6">
@if ($history->status_peminjaman === 'Dipinjam')
<span class="px-3 py-1 bg-yellow-100 text-yellow-700 font-bold rounded-full text-xs">Sedang Dipinjam</span>
<span
class="px-3 py-1 bg-yellow-100 text-yellow-700 font-bold rounded-full text-xs">Sedang
Dipinjam</span>
@elseif($history->status_peminjaman === 'Dikembalikan')
<span class="px-3 py-1 bg-green-100 text-green-700 font-bold rounded-full text-xs">Selesai</span>
<span
class="px-3 py-1 bg-green-100 text-green-700 font-bold rounded-full text-xs">Selesai</span>
@else
<span class="px-3 py-1 bg-gray-100 text-gray-700 font-bold rounded-full text-xs">{{ $history->status_peminjaman }}</span>
<span
class="px-3 py-1 bg-gray-100 text-gray-700 font-bold rounded-full text-xs">{{ $history->status_peminjaman }}</span>
@endif
</td>
</tr>
@ -328,20 +388,25 @@
@if ($rekomendasi->count() > 0)
<div class="mt-12">
<h2 class="text-2xl font-extrabold text-gray-900 mb-6 border-b-2 border-blue-500 inline-block pb-2">Rekomendasi Buku Serupa</h2>
<h2 class="text-2xl font-extrabold text-gray-900 mb-6 border-b-2 border-blue-500 inline-block pb-2">
Rekomendasi Buku Serupa</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
@foreach ($rekomendasi as $rek)
<div class="bg-white rounded-xl shadow-sm border border-gray-200 hover:shadow-md transition duration-300 flex flex-col overflow-hidden">
<div
class="bg-white rounded-xl shadow-sm border border-gray-200 hover:shadow-md transition duration-300 flex flex-col overflow-hidden">
<div class="p-5 flex-grow">
<div class="flex justify-between items-start mb-2">
<span class="text-xs font-bold text-blue-600 bg-blue-50 px-2 py-1 rounded">{{ $rek->nomor_panggil }}</span>
<span class="text-xs font-semibold text-green-600">Skor: {{ number_format($rek->similarity_score, 1) }}</span>
<span
class="text-xs font-bold text-blue-600 bg-blue-50 px-2 py-1 rounded">{{ $rek->nomor_panggil }}</span>
<span class="text-xs font-semibold text-green-600">Skor:
{{ number_format($rek->similarity_score, 1) }}</span>
</div>
<h3 class="text-lg font-bold text-gray-900 mb-1 line-clamp-2">{{ $rek->judul }}</h3>
<p class="text-sm text-gray-600 line-clamp-1">{{ $rek->pengarang }}</p>
</div>
<div class="px-5 py-3 bg-gray-50 border-t border-gray-100 mt-auto">
<a href="{{ route('katalog.show', $rek->id_buku) }}" class="text-sm font-semibold text-blue-600 hover:text-blue-800 flex items-center justify-center w-full">
<a href="{{ route('katalog.show', $rek->id) }}"
class="text-sm font-semibold text-blue-600 hover:text-blue-800 flex items-center justify-center w-full">
Lihat Detail
</a>
</div>

View File

@ -3,14 +3,17 @@
<div class="max-w-7xl mx-auto px-6 relative z-10">
@if (!empty($bukuPopuler) && $bukuPopuler->count())
<div>
<div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-10 gap-4 text-center md:text-left">
<div
class="flex flex-col md:flex-row justify-between items-start md:items-center mb-10 gap-4 text-center md:text-left">
<div class="w-full md:w-auto">
<div class="inline-flex items-center gap-2 px-4 py-2 bg-blue-100 rounded-full mb-4 mx-auto md:mx-0">
<div
class="inline-flex items-center gap-2 px-4 py-2 bg-blue-100 rounded-full mb-4 mx-auto md:mx-0">
<i class="fas fa-fire text-red-500 text-xs"></i>
<span class="text-xs font-semibold text-blue-800 tracking-wide">Paling Laris</span>
</div>
<h2 class="text-3xl md:text-4xl font-black text-gray-900 tracking-tight">
Buku <span class="text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-indigo-600">Terpopuler</span>
Buku <span
class="text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-indigo-600">Terpopuler</span>
</h2>
<p class="text-gray-500 mt-2 max-w-md mx-auto md:mx-0">
Koleksi buku favorit yang paling banyak dipinjam oleh para pengunjung perpustakaan kami.
@ -21,13 +24,15 @@
<div class="grid grid-cols-2 lg:grid-cols-5 md:grid-cols-3 gap-6">
@foreach ($bukuPopuler as $item)
@php
$habis = ($item->eksemplar <= 0);
$habis = $item->eksemplar <= 0;
@endphp
<div class="group bg-white rounded-2xl shadow-sm hover:shadow-2xl border border-gray-100 overflow-hidden transition-all duration-300 transform {{ $habis ? 'grayscale opacity-75 cursor-not-allowed' : 'hover:-translate-y-1' }} flex flex-col h-full relative">
<div
class="group bg-white rounded-2xl shadow-sm hover:shadow-2xl border border-gray-100 overflow-hidden transition-all duration-300 transform {{ $habis ? 'grayscale opacity-75 cursor-not-allowed' : 'hover:-translate-y-1' }} flex flex-col h-full relative">
<!-- Peminjaman Count Badge -->
<div class="absolute top-2 left-2 z-20">
<span class="bg-blue-600/90 backdrop-blur-md text-white text-[10px] sm:text-xs font-bold px-2 py-1 rounded shadow-sm flex items-center gap-1">
<span
class="bg-blue-600/90 backdrop-blur-md text-white text-[10px] sm:text-xs font-bold px-2 py-1 rounded shadow-sm flex items-center gap-1">
<i class="fas fa-book-reader"></i> {{ $item->peminjaman_count }}x
</span>
</div>
@ -35,26 +40,36 @@
<!-- Book Cover -->
<div class="relative w-full pt-[140%] overflow-hidden bg-gray-50 flex-shrink-0">
@if ($item->cover ?? $item->sampul)
<img src="{{ asset('storage/' . ($item->cover ?? $item->sampul)) }}" alt="{{ $item->judul }}"
<img src="{{ asset('storage/' . ($item->cover ?? $item->sampul)) }}"
alt="{{ $item->judul }}"
class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:scale-110' : '' }} transition-transform duration-700 ease-in-out">
@else
<div class="absolute inset-0 flex flex-col items-center justify-center text-gray-300 bg-gray-100 {{ !$habis ? 'group-hover:bg-gray-200' : '' }} transition-colors duration-300">
<svg class="w-12 h-12 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path></svg>
<div
class="absolute inset-0 flex flex-col items-center justify-center text-gray-300 bg-gray-100 {{ !$habis ? 'group-hover:bg-gray-200' : '' }} transition-colors duration-300">
<svg class="w-12 h-12 mb-2" fill="none" stroke="currentColor"
viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253">
</path>
</svg>
<span class="text-xs font-medium">No Cover</span>
</div>
@endif
@if ($habis)
<!-- Overlay Dipinjam Semua -->
<div class="absolute inset-0 bg-red-900/30 backdrop-blur-[1px] flex items-center justify-center z-10">
<div class="bg-red-600/90 text-white font-black text-sm md:text-base px-2 py-2 border-y-2 border-white transform -rotate-12 shadow-2xl tracking-widest uppercase pointer-events-none text-center">
<div
class="absolute inset-0 bg-red-900/30 backdrop-blur-[1px] flex items-center justify-center z-10">
<div
class="bg-red-600/90 text-white font-black text-sm md:text-base px-2 py-2 border-y-2 border-white transform -rotate-12 shadow-2xl tracking-widest uppercase pointer-events-none text-center">
TIDAK TERSEDIA
</div>
</div>
@endif
<div class="absolute top-2 right-2 flex justify-between items-start z-10">
<span class="bg-white/90 backdrop-blur-md text-gray-800 text-[10px] sm:text-xs font-bold px-2 py-1 rounded shadow-sm">
<span
class="bg-white/90 backdrop-blur-md text-gray-800 text-[10px] sm:text-xs font-bold px-2 py-1 rounded shadow-sm">
{{ $item->nomor_panggil ?? '-' }}
</span>
</div>
@ -62,7 +77,8 @@ class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:sca
<!-- Content -->
<div class="p-4 flex-grow flex flex-col">
<h2 class="text-xs sm:text-sm font-bold text-gray-900 mb-1 line-clamp-2 {{ !$habis ? 'group-hover:text-blue-600 transition-colors' : '' }} leading-snug" title="{{ $item->judul }}">
<h2 class="text-xs sm:text-sm font-bold text-gray-900 mb-1 line-clamp-2 {{ !$habis ? 'group-hover:text-blue-600 transition-colors' : '' }} leading-snug"
title="{{ $item->judul }}">
{{ $item->judul }}
</h2>
<p class="text-blue-600 font-medium text-[10px] sm:text-xs mb-2 line-clamp-1">
@ -71,7 +87,8 @@ class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:sca
<div class="mt-auto pt-3 flex flex-col gap-2 border-t border-gray-50">
<div class="flex justify-between items-center text-[10px] text-gray-500">
<span class="truncate pr-1">{{ $item->penerbit }}</span>
<span class="font-medium bg-gray-100 px-1.5 py-0.5 rounded">{{ $item->tahun_terbit ?? '-' }}</span>
<span
class="font-medium bg-gray-100 px-1.5 py-0.5 rounded">{{ $item->tahun_terbit ?? '-' }}</span>
</div>
</div>
</div>
@ -79,11 +96,13 @@ class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:sca
<!-- Action Area -->
<div class="px-4 pb-4 pt-0 mt-auto relative z-30">
@if ($habis)
<button disabled class="w-full text-center bg-gray-100 text-gray-500 text-xs font-semibold py-2 px-3 rounded-xl border border-gray-200 cursor-not-allowed opacity-80 backdrop-blur-sm">
<button disabled
class="w-full text-center bg-gray-100 text-gray-500 text-xs font-semibold py-2 px-3 rounded-xl border border-gray-200 cursor-not-allowed opacity-80 backdrop-blur-sm">
Habis Dipinjam
</button>
@else
<a href="{{ route('katalog.show', $item->id_buku ?? 1) }}" class="block w-full text-center bg-gray-50 hover:bg-blue-600 text-gray-700 hover:text-white text-xs font-semibold py-2 px-3 rounded-xl border border-gray-200 hover:border-transparent transition-all duration-300">
<a href="{{ route('katalog.show', $item->id ?? 1) }}"
class="block w-full text-center bg-gray-50 hover:bg-blue-600 text-gray-700 hover:text-white text-xs font-semibold py-2 px-3 rounded-xl border border-gray-200 hover:border-transparent transition-all duration-300">
Lihat Detail
</a>
@endif

View File

@ -16,7 +16,8 @@
Buku-buku rilis baru dan penambahan paling anyar di perpustakaan kami.
</p>
</div>
<a href="{{ route('katalog.index') }}" class="px-6 py-3 bg-white text-primary-600 rounded-2xl font-semibold text-sm border border-primary-200 hover:bg-primary-50 transition-colors shadow-sm inline-flex items-center gap-2">
<a href="{{ route('katalog.index') }}"
class="px-6 py-3 bg-white text-primary-600 rounded-2xl font-semibold text-sm border border-primary-200 hover:bg-primary-50 transition-colors shadow-sm inline-flex items-center gap-2">
Lihat Semua Katalog <i class="fas fa-arrow-right text-xs"></i>
</a>
</div>
@ -25,13 +26,15 @@
<div class="grid grid-cols-2 md:grid-cols-4 gap-6">
@foreach ($bukuTerbaru as $item)
@php
$habis = ($item->eksemplar <= 0);
$habis = $item->eksemplar <= 0;
@endphp
<div class="group bg-white rounded-2xl shadow-sm hover:shadow-2xl border border-gray-100 overflow-hidden transition-all duration-300 transform {{ $habis ? 'grayscale opacity-75 cursor-not-allowed' : 'hover:-translate-y-1' }} flex flex-col h-full relative">
<div
class="group bg-white rounded-2xl shadow-sm hover:shadow-2xl border border-gray-100 overflow-hidden transition-all duration-300 transform {{ $habis ? 'grayscale opacity-75 cursor-not-allowed' : 'hover:-translate-y-1' }} flex flex-col h-full relative">
<!-- Badge BUKU BARU (Pojok Kanan Atas Kartu) -->
@if (!$habis)
<div class="absolute top-0 right-0 z-20">
<div class="bg-gradient-to-r from-yellow-400 to-orange-500 text-white text-[9px] sm:text-[10px] font-extrabold px-3 py-1.5 shadow-lg rounded-bl-xl origin-top-right transform">
<div
class="bg-gradient-to-r from-yellow-400 to-orange-500 text-white text-[9px] sm:text-[10px] font-extrabold px-3 py-1.5 shadow-lg rounded-bl-xl origin-top-right transform">
<i class="fas fa-sparkles mr-1"></i> BUKU BARU
</div>
</div>
@ -40,19 +43,28 @@
<!-- Book Cover -->
<div class="relative w-full pt-[140%] overflow-hidden bg-gray-50 flex-shrink-0">
@if ($item->cover ?? $item->sampul)
<img src="{{ asset('storage/' . ($item->cover ?? $item->sampul)) }}" alt="{{ $item->judul }}"
<img src="{{ asset('storage/' . ($item->cover ?? $item->sampul)) }}"
alt="{{ $item->judul }}"
class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:scale-110' : '' }} transition-transform duration-700 ease-in-out">
@else
<div class="absolute inset-0 flex flex-col items-center justify-center text-gray-300 bg-gray-100 {{ !$habis ? 'group-hover:bg-gray-200' : '' }} transition-colors duration-300">
<svg class="w-12 h-12 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path></svg>
<div
class="absolute inset-0 flex flex-col items-center justify-center text-gray-300 bg-gray-100 {{ !$habis ? 'group-hover:bg-gray-200' : '' }} transition-colors duration-300">
<svg class="w-12 h-12 mb-2" fill="none" stroke="currentColor"
viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253">
</path>
</svg>
<span class="text-xs font-medium">Cover Tidak Tersedia</span>
</div>
@endif
@if ($habis)
<!-- Overlay Dipinjam Semua -->
<div class="absolute inset-0 bg-red-900/30 backdrop-blur-[1px] flex items-center justify-center z-10">
<div class="bg-red-600/90 text-white font-black text-sm md:text-base px-6 py-2 border-y-2 border-white transform -rotate-12 shadow-2xl tracking-widest uppercase pointer-events-none">
<div
class="absolute inset-0 bg-red-900/30 backdrop-blur-[1px] flex items-center justify-center z-10">
<div
class="bg-red-600/90 text-white font-black text-sm md:text-base px-6 py-2 border-y-2 border-white transform -rotate-12 shadow-2xl tracking-widest uppercase pointer-events-none">
TIDAK TERSEDIA
</div>
</div>
@ -60,7 +72,8 @@ class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:sca
<!-- Overlay Badges (Nomor Panggil) -->
<div class="absolute top-2 inset-x-2 flex justify-between items-start z-10">
<span class="bg-white/90 backdrop-blur-md text-gray-800 text-[10px] sm:text-xs font-bold px-2 py-1 rounded shadow-sm">
<span
class="bg-white/90 backdrop-blur-md text-gray-800 text-[10px] sm:text-xs font-bold px-2 py-1 rounded shadow-sm">
{{ $item->nomor_panggil ?? '-' }}
</span>
</div>
@ -68,7 +81,8 @@ class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:sca
<!-- Content -->
<div class="p-4 flex-grow flex flex-col">
<h2 class="text-sm sm:text-base font-bold text-gray-900 mb-1 line-clamp-2 {{ !$habis ? 'group-hover:text-blue-600 transition-colors' : '' }} leading-snug" title="{{ $item->judul }}">
<h2 class="text-sm sm:text-base font-bold text-gray-900 mb-1 line-clamp-2 {{ !$habis ? 'group-hover:text-blue-600 transition-colors' : '' }} leading-snug"
title="{{ $item->judul }}">
{{ $item->judul }}
</h2>
<p class="text-blue-600 font-medium text-xs sm:text-sm mb-2 line-clamp-1">
@ -77,7 +91,8 @@ class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:sca
<div class="mt-auto pt-3 flex flex-col gap-2 border-t border-gray-50">
<div class="flex justify-between items-center text-[10px] sm:text-xs text-gray-500">
<span class="truncate pr-1">{{ $item->penerbit }}</span>
<span class="font-medium bg-gray-100 px-1.5 py-0.5 rounded">{{ $item->tahun_terbit ?? '-' }}</span>
<span
class="font-medium bg-gray-100 px-1.5 py-0.5 rounded">{{ $item->tahun_terbit ?? '-' }}</span>
</div>
</div>
</div>
@ -85,11 +100,13 @@ class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:sca
<!-- Action Area -->
<div class="px-4 pb-4 pt-0 mt-auto relative z-30">
@if ($habis)
<button disabled class="w-full text-center bg-gray-100 text-gray-500 text-sm font-semibold py-2 px-3 rounded-xl border border-gray-200 cursor-not-allowed opacity-80 backdrop-blur-sm">
<button disabled
class="w-full text-center bg-gray-100 text-gray-500 text-sm font-semibold py-2 px-3 rounded-xl border border-gray-200 cursor-not-allowed opacity-80 backdrop-blur-sm">
Habis Dipinjam
</button>
@else
<a href="{{ route('katalog.show', $item->id_buku ?? 1) }}" class="block w-full text-center bg-gray-50 hover:bg-blue-600 text-gray-700 hover:text-white text-sm font-semibold py-2 px-3 rounded-xl border border-gray-200 hover:border-transparent transition-all duration-300">
<a href="{{ route('katalog.show', $item->id ?? 1) }}"
class="block w-full text-center bg-gray-50 hover:bg-blue-600 text-gray-700 hover:text-white text-sm font-semibold py-2 px-3 rounded-xl border border-gray-200 hover:border-transparent transition-all duration-300">
Lihat Detail
</a>
@endif