Fix: kategori table migration and update admin buku views
This commit is contained in:
parent
5f8202e7ca
commit
f64ea3a4fa
|
|
@ -12,9 +12,9 @@ public function index(Request $request)
|
||||||
$originalSearch = $request->input('search');
|
$originalSearch = $request->input('search');
|
||||||
|
|
||||||
$bukuPopuler = Buku::withCount('peminjaman')
|
$bukuPopuler = Buku::withCount('peminjaman')
|
||||||
->orderBy('peminjaman_count', 'desc')
|
->orderBy('peminjaman_count', 'desc')
|
||||||
->take(5)
|
->take(5)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
if (empty($originalSearch)) {
|
if (empty($originalSearch)) {
|
||||||
$buku = Buku::paginate(12);
|
$buku = Buku::paginate(12);
|
||||||
|
|
@ -31,7 +31,7 @@ public function index(Request $request)
|
||||||
$words = explode(' ', $cleanInput);
|
$words = explode(' ', $cleanInput);
|
||||||
|
|
||||||
// Filter stopword
|
// Filter stopword
|
||||||
$filteredWords = array_filter($words, function($word) use ($stopwords) {
|
$filteredWords = array_filter($words, function ($word) use ($stopwords) {
|
||||||
return !in_array($word, $stopwords) && trim($word) !== '';
|
return !in_array($word, $stopwords) && trim($word) !== '';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -72,7 +72,7 @@ public function index(Request $request)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Urutkan berdasarkan similarity_score terbesar (descending)
|
// Urutkan berdasarkan similarity_score terbesar (descending)
|
||||||
usort($hasil, function($a, $b) {
|
usort($hasil, function ($a, $b) {
|
||||||
return $b->similarity_score <=> $a->similarity_score;
|
return $b->similarity_score <=> $a->similarity_score;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -141,9 +141,13 @@ public function show($id)
|
||||||
|
|
||||||
private function getRekomendasi($targetBuku)
|
private function getRekomendasi($targetBuku)
|
||||||
{
|
{
|
||||||
$semuaBuku = Buku::where('id_buku', '!=', $targetBuku->id_buku)
|
$semuaBuku = Buku::where('id', '!=', $targetBuku->id)
|
||||||
->whereNotNull('nomor_panggil')
|
->get();
|
||||||
->get();
|
|
||||||
|
// Jika nomor_panggil tidak ada, tampilkan rekomendasi berdasarkan buku populer
|
||||||
|
if (empty($targetBuku->nomor_panggil)) {
|
||||||
|
return $semuaBuku->take(4);
|
||||||
|
}
|
||||||
|
|
||||||
$hasil = [];
|
$hasil = [];
|
||||||
$targetDdc = substr(preg_replace('/[^0-9]/', '', $targetBuku->nomor_panggil), 0, 3);
|
$targetDdc = substr(preg_replace('/[^0-9]/', '', $targetBuku->nomor_panggil), 0, 3);
|
||||||
|
|
@ -153,6 +157,8 @@ private function getRekomendasi($targetBuku)
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($semuaBuku as $b) {
|
foreach ($semuaBuku as $b) {
|
||||||
|
if (empty($b->nomor_panggil)) continue;
|
||||||
|
|
||||||
$pembandingDdc = substr(preg_replace('/[^0-9]/', '', $b->nomor_panggil), 0, 3);
|
$pembandingDdc = substr(preg_replace('/[^0-9]/', '', $b->nomor_panggil), 0, 3);
|
||||||
if (strlen($pembandingDdc) < 3) continue;
|
if (strlen($pembandingDdc) < 3) continue;
|
||||||
|
|
||||||
|
|
@ -173,7 +179,7 @@ private function getRekomendasi($targetBuku)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
usort($hasil, function($a, $b) {
|
usort($hasil, function ($a, $b) {
|
||||||
return $b->similarity_score <=> $a->similarity_score;
|
return $b->similarity_score <=> $a->similarity_score;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -189,23 +195,23 @@ private function prediksiLokasiRak($nomor_panggil)
|
||||||
$kode_utama = (int) substr(trim($nomor_panggil), 0, 3);
|
$kode_utama = (int) substr(trim($nomor_panggil), 0, 3);
|
||||||
|
|
||||||
return match (true) {
|
return match (true) {
|
||||||
$kode_utama >= 0 && $kode_utama <= 99 => match(true) {
|
$kode_utama >= 0 && $kode_utama <= 99 => match (true) {
|
||||||
$kode_utama <= 19 => ['rak' => 'Rak 01', 'area' => 'Karya Umum (Bibliografi)', 'kode_rak' => 'rak_000'],
|
$kode_utama <= 19 => ['rak' => 'Rak 01', 'area' => 'Karya Umum (Bibliografi)', 'kode_rak' => 'rak_000'],
|
||||||
$kode_utama <= 50 => ['rak' => 'Rak 02', 'area' => 'Karya Umum (Ensiklopedia)', 'kode_rak' => 'rak_000'],
|
$kode_utama <= 50 => ['rak' => 'Rak 02', 'area' => 'Karya Umum (Ensiklopedia)', 'kode_rak' => 'rak_000'],
|
||||||
default => ['rak' => 'Rak 03-05', 'area' => 'Karya Umum Lainnya', 'kode_rak' => 'rak_000'],
|
default => ['rak' => 'Rak 03-05', 'area' => 'Karya Umum Lainnya', 'kode_rak' => 'rak_000'],
|
||||||
},
|
},
|
||||||
|
|
||||||
$kode_utama >= 100 && $kode_utama <= 199 => match(true) {
|
$kode_utama >= 100 && $kode_utama <= 199 => match (true) {
|
||||||
$kode_utama <= 150 => ['rak' => 'Rak 06-10', 'area' => 'Filsafat', 'kode_rak' => 'rak_100'],
|
$kode_utama <= 150 => ['rak' => 'Rak 06-10', 'area' => 'Filsafat', 'kode_rak' => 'rak_100'],
|
||||||
default => ['rak' => 'Rak 11-14', 'area' => 'Psikologi', 'kode_rak' => 'rak_100'],
|
default => ['rak' => 'Rak 11-14', 'area' => 'Psikologi', 'kode_rak' => 'rak_100'],
|
||||||
},
|
},
|
||||||
|
|
||||||
$kode_utama >= 200 && $kode_utama <= 299 => match(true) {
|
$kode_utama >= 200 && $kode_utama <= 299 => match (true) {
|
||||||
$kode_utama == 297 => ['rak' => 'Rak 25-32', 'area' => 'Agama Islam', 'kode_rak' => 'rak_200'],
|
$kode_utama == 297 => ['rak' => 'Rak 25-32', 'area' => 'Agama Islam', 'kode_rak' => 'rak_200'],
|
||||||
default => ['rak' => 'Rak 15-24', 'area' => 'Agama Umum & Lainnya', 'kode_rak' => 'rak_200'],
|
default => ['rak' => 'Rak 15-24', 'area' => 'Agama Umum & Lainnya', 'kode_rak' => 'rak_200'],
|
||||||
},
|
},
|
||||||
|
|
||||||
$kode_utama >= 300 && $kode_utama <= 399 => match(true) {
|
$kode_utama >= 300 && $kode_utama <= 399 => match (true) {
|
||||||
$kode_utama <= 330 => ['rak' => 'Rak 33-36', 'area' => 'Sosiologi & Ilmu Politik', 'kode_rak' => 'rak_300'],
|
$kode_utama <= 330 => ['rak' => 'Rak 33-36', 'area' => 'Sosiologi & Ilmu Politik', 'kode_rak' => 'rak_300'],
|
||||||
$kode_utama <= 360 => ['rak' => 'Rak 37-40', 'area' => 'Ekonomi & Hukum', 'kode_rak' => 'rak_300'],
|
$kode_utama <= 360 => ['rak' => 'Rak 37-40', 'area' => 'Ekonomi & Hukum', 'kode_rak' => 'rak_300'],
|
||||||
default => ['rak' => 'Rak 41-44', 'area' => 'Pendidikan & Adat', 'kode_rak' => 'rak_300'],
|
default => ['rak' => 'Rak 41-44', 'area' => 'Pendidikan & Adat', 'kode_rak' => 'rak_300'],
|
||||||
|
|
@ -215,14 +221,14 @@ private function prediksiLokasiRak($nomor_panggil)
|
||||||
|
|
||||||
$kode_utama >= 500 && $kode_utama <= 599 => ['rak' => 'Rak 46-48', 'area' => 'Ilmu Murni', 'kode_rak' => 'rak_500'],
|
$kode_utama >= 500 && $kode_utama <= 599 => ['rak' => 'Rak 46-48', 'area' => 'Ilmu Murni', 'kode_rak' => 'rak_500'],
|
||||||
|
|
||||||
$kode_utama >= 600 && $kode_utama <= 699 => match(true) {
|
$kode_utama >= 600 && $kode_utama <= 699 => match (true) {
|
||||||
$kode_utama <= 610 => ['rak' => 'Rak 49-53', 'area' => 'Ilmu Kedokteran', 'kode_rak' => 'rak_600'],
|
$kode_utama <= 610 => ['rak' => 'Rak 49-53', 'area' => 'Ilmu Kedokteran', 'kode_rak' => 'rak_600'],
|
||||||
$kode_utama <= 630 => ['rak' => 'Rak 54-58', 'area' => 'Ilmu Teknik', 'kode_rak' => 'rak_600'],
|
$kode_utama <= 630 => ['rak' => 'Rak 54-58', 'area' => 'Ilmu Teknik', 'kode_rak' => 'rak_600'],
|
||||||
$kode_utama <= 650 => ['rak' => 'Rak 59-63', 'area' => 'Pertanian', 'kode_rak' => 'rak_600'],
|
$kode_utama <= 650 => ['rak' => 'Rak 59-63', 'area' => 'Pertanian', 'kode_rak' => 'rak_600'],
|
||||||
default => ['rak' => 'Rak 64-68', 'area' => 'Manajemen & Bisnis', 'kode_rak' => 'rak_600'],
|
default => ['rak' => 'Rak 64-68', 'area' => 'Manajemen & Bisnis', 'kode_rak' => 'rak_600'],
|
||||||
},
|
},
|
||||||
|
|
||||||
$kode_utama >= 700 && $kode_utama <= 799 => match(true) {
|
$kode_utama >= 700 && $kode_utama <= 799 => match (true) {
|
||||||
$kode_utama <= 739 => ['rak' => 'Rak 71', 'area' => 'Kesenian Murni', 'kode_rak' => 'rak_700'],
|
$kode_utama <= 739 => ['rak' => 'Rak 71', 'area' => 'Kesenian Murni', 'kode_rak' => 'rak_700'],
|
||||||
$kode_utama <= 769 => ['rak' => 'Rak 72', 'area' => 'Seni Rupa & Kriya', 'kode_rak' => 'rak_700'],
|
$kode_utama <= 769 => ['rak' => 'Rak 72', 'area' => 'Seni Rupa & Kriya', 'kode_rak' => 'rak_700'],
|
||||||
$kode_utama <= 789 => ['rak' => 'Rak 73', 'area' => 'Fotografi & Musik', 'kode_rak' => 'rak_700'],
|
$kode_utama <= 789 => ['rak' => 'Rak 73', 'area' => 'Fotografi & Musik', 'kode_rak' => 'rak_700'],
|
||||||
|
|
@ -231,7 +237,7 @@ private function prediksiLokasiRak($nomor_panggil)
|
||||||
|
|
||||||
$kode_utama >= 800 && $kode_utama <= 899 => ['rak' => 'Rak 77-79', 'area' => 'Kesusastraan (Sastra)', 'kode_rak' => 'rak_800'],
|
$kode_utama >= 800 && $kode_utama <= 899 => ['rak' => 'Rak 77-79', 'area' => 'Kesusastraan (Sastra)', 'kode_rak' => 'rak_800'],
|
||||||
|
|
||||||
$kode_utama >= 900 && $kode_utama <= 999 => match(true) {
|
$kode_utama >= 900 && $kode_utama <= 999 => match (true) {
|
||||||
$kode_utama <= 919 => ['rak' => 'Rak 69, 70', 'area' => 'Geografi & Perjalanan', 'kode_rak' => 'rak_900'],
|
$kode_utama <= 919 => ['rak' => 'Rak 69, 70', 'area' => 'Geografi & Perjalanan', 'kode_rak' => 'rak_900'],
|
||||||
default => ['rak' => 'Rak 80-84', 'area' => 'Sejarah Umum', 'kode_rak' => 'rak_900'],
|
default => ['rak' => 'Rak 80-84', 'area' => 'Sejarah Umum', 'kode_rak' => 'rak_900'],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -19,11 +19,21 @@ public function run(): void
|
||||||
DB::table('buku_tamu')->insert([
|
DB::table('buku_tamu')->insert([
|
||||||
[
|
[
|
||||||
'id_user' => $userId,
|
'id_user' => $userId,
|
||||||
|
'nama_tamu' => 'Pengunjung 1',
|
||||||
|
'email' => 'pengunjung1@example.com',
|
||||||
|
'no_hp' => '081234567890',
|
||||||
|
'asal_instansi' => 'Sekolah A',
|
||||||
|
'status' => 'Aktif',
|
||||||
'tujuan_kunjungan' => 'Membaca Buku',
|
'tujuan_kunjungan' => 'Membaca Buku',
|
||||||
'tanggal_kunjungan' => now(),
|
'tanggal_kunjungan' => now(),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'id_user' => $userId,
|
'id_user' => $userId,
|
||||||
|
'nama_tamu' => 'Pengunjung 2',
|
||||||
|
'email' => 'pengunjung2@example.com',
|
||||||
|
'no_hp' => '082345678901',
|
||||||
|
'asal_instansi' => 'Sekolah B',
|
||||||
|
'status' => 'Aktif',
|
||||||
'tujuan_kunjungan' => 'Meminjam Buku',
|
'tujuan_kunjungan' => 'Meminjam Buku',
|
||||||
'tanggal_kunjungan' => now()->subDay(),
|
'tanggal_kunjungan' => now()->subDay(),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -16,20 +16,24 @@ class DatabaseSeeder extends Seeder
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
// Admin user
|
// Admin user
|
||||||
User::create([
|
User::updateOrCreate(
|
||||||
'name' => 'Admin',
|
['email' => 'admin@perpustakaan.com'],
|
||||||
'email' => 'admin@perpustakaan.com',
|
[
|
||||||
'password' => Hash::make('password'),
|
'name' => 'Admin',
|
||||||
'role' => 'admin',
|
'password' => Hash::make('password'),
|
||||||
]);
|
'role' => 'admin',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
// Regular user
|
// Regular user
|
||||||
User::create([
|
User::updateOrCreate(
|
||||||
'name' => 'User Test',
|
['email' => 'user@perpustakaan.com'],
|
||||||
'email' => 'user@perpustakaan.com',
|
[
|
||||||
'password' => Hash::make('password'),
|
'name' => 'User Test',
|
||||||
'role' => 'user',
|
'password' => Hash::make('password'),
|
||||||
]);
|
'role' => 'user',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
// Sample buku
|
// Sample buku
|
||||||
Buku::create([
|
Buku::create([
|
||||||
|
|
@ -67,4 +71,3 @@ public function run(): void
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,31 +8,35 @@
|
||||||
<x-card class="max-w-4xl mx-auto">
|
<x-card class="max-w-4xl mx-auto">
|
||||||
|
|
||||||
@if ($errors->any())
|
@if ($errors->any())
|
||||||
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 m-6 mb-0" role="alert">
|
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 m-6 mb-0" role="alert">
|
||||||
<p class="font-bold">Validasi Gagal</p>
|
<p class="font-bold">Validasi Gagal</p>
|
||||||
<ul class="list-disc ml-5">
|
<ul class="list-disc ml-5">
|
||||||
@foreach ($errors->all() as $error)
|
@foreach ($errors->all() as $error)
|
||||||
<li>{{ $error }}</li>
|
<li>{{ $error }}</li>
|
||||||
@endforeach
|
@endforeach
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@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
|
@csrf
|
||||||
@method('PUT')
|
@method('PUT')
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="bibid" value="BIBID" />
|
<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>
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="id_kategori" value="Kategori" />
|
<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>
|
<option value="">Pilih Kategori</option>
|
||||||
@foreach($kategori as $kat)
|
@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 }}
|
{{ $kat->nama_kategori }}
|
||||||
</option>
|
</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
@ -48,47 +52,56 @@
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="pengarang" value="Pengarang" />
|
<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>
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="nomor_panggil" value="Nomor Panggil (DDC)" />
|
<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>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="penerbit" value="Penerbit" />
|
<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>
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="tahun_terbit" value="Tahun Terbit" />
|
<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>
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="edisi" value="Edisi" />
|
<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>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="deskripsi_fisik" value="Deskripsi Fisik" />
|
<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>
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="eksemplar" value="Jumlah Eksemplar" />
|
<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>
|
</div>
|
||||||
|
|
||||||
<div class="border-t border-gray-100 pt-6">
|
<div class="border-t border-gray-100 pt-6">
|
||||||
<x-input-label for="cover" value="Unggah Gambar Cover (Opsional)" />
|
<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>
|
||||||
|
|
||||||
<div class="flex items-center justify-end gap-4 pt-4 border-t border-gray-200">
|
<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>
|
<x-primary-button>
|
||||||
Simpan Perubahan
|
Simpan Perubahan
|
||||||
</x-primary-button>
|
</x-primary-button>
|
||||||
|
|
|
||||||
|
|
@ -3,208 +3,230 @@
|
||||||
@section('title', 'Katalog Buku')
|
@section('title', 'Katalog Buku')
|
||||||
|
|
||||||
@section('content')
|
@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-page-header title="Portofolio Katalog Buku">
|
||||||
<x-slot name="actions">
|
<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"
|
||||||
<i class="fas fa-plus"></i> Tambah Buku Baru
|
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>
|
<i class="fas fa-plus"></i> Tambah Buku Baru
|
||||||
</x-slot>
|
</button>
|
||||||
</x-page-header>
|
|
||||||
|
|
||||||
<x-alert type="success" :message="session('success')" />
|
|
||||||
|
|
||||||
<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-primary-button>
|
|
||||||
Cari
|
|
||||||
</x-primary-button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<x-card>
|
|
||||||
<x-table>
|
|
||||||
<x-slot name="head">
|
|
||||||
<x-th>BIBID</x-th>
|
|
||||||
<x-th>Judul & Pengarang</x-th>
|
|
||||||
<x-th>Kategori</x-th>
|
|
||||||
<x-th>Stok</x-th>
|
|
||||||
<x-th class="text-right">Aksi</x-th>
|
|
||||||
</x-slot>
|
</x-slot>
|
||||||
|
</x-page-header>
|
||||||
|
|
||||||
@forelse ($buku as $item)
|
<x-alert type="success" :message="session('success')" />
|
||||||
<tr class="hover:bg-gray-50 transition-colors">
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-bold text-gray-900">{{ $item->bibid }}</td>
|
|
||||||
<td class="px-6 py-4">
|
|
||||||
<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->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">
|
|
||||||
Edit
|
|
||||||
</a>
|
|
||||||
<form action="{{ route('admin.buku.destroy', $item->id_buku) }}"
|
|
||||||
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">
|
|
||||||
Hapus
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@empty
|
|
||||||
<tr>
|
|
||||||
<td colspan="5" class="px-6 py-8 text-center text-sm text-gray-500">
|
|
||||||
Tidak ada data aset buku ditemukan.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforelse
|
|
||||||
</x-table>
|
|
||||||
|
|
||||||
<div class="mt-4">
|
<div class="mb-6">
|
||||||
{{ $buku->withQueryString()->links() }}
|
<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-primary-button>
|
||||||
|
Cari
|
||||||
|
</x-primary-button>
|
||||||
|
</form>
|
||||||
</div>
|
</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 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>
|
|
||||||
|
|
||||||
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
|
<x-card>
|
||||||
|
<x-table>
|
||||||
|
<x-slot name="head">
|
||||||
|
<x-th>BIBID</x-th>
|
||||||
|
<x-th>Judul & Pengarang</x-th>
|
||||||
|
<x-th>Kategori</x-th>
|
||||||
|
<x-th>Stok</x-th>
|
||||||
|
<x-th class="text-right">Aksi</x-th>
|
||||||
|
</x-slot>
|
||||||
|
|
||||||
<!-- Modal panel -->
|
@forelse ($buku as $item)
|
||||||
<div x-show="isModalBukuOpen"
|
<tr class="hover:bg-gray-50 transition-colors">
|
||||||
x-transition:enter="ease-out duration-300"
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-bold text-gray-900">{{ $item->bibid }}</td>
|
||||||
x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
<td class="px-6 py-4">
|
||||||
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
|
<div class="text-sm font-bold text-gray-900">{{ $item->judul }}</div>
|
||||||
x-transition:leave="ease-in duration-200"
|
<div class="text-sm text-gray-500">{{ $item->pengarang }}</div>
|
||||||
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
</td>
|
||||||
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||||
class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transition-all transform bg-white rounded-3xl shadow-2xl shadow-indigo-500/10 sm:my-8 sm:align-middle sm:max-w-4xl sm:w-full sm:p-8 border border-gray-100">
|
{{ $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) }}"
|
||||||
|
class="text-blue-600 hover:text-blue-900">
|
||||||
|
Edit
|
||||||
|
</a>
|
||||||
|
<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">
|
||||||
|
Hapus
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@empty
|
||||||
|
<tr>
|
||||||
|
<td colspan="5" class="px-6 py-8 text-center text-sm text-gray-500">
|
||||||
|
Tidak ada data aset buku ditemukan.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforelse
|
||||||
|
</x-table>
|
||||||
|
|
||||||
<div class="flex justify-between items-center mb-6 pl-2">
|
<div class="mt-4">
|
||||||
<div>
|
{{ $buku->withQueryString()->links() }}
|
||||||
<h3 class="text-2xl font-bold text-gray-900" id="modal-title">Tambah Koleksi Buku</h3>
|
</div>
|
||||||
<p class="text-sm text-gray-500 mt-1">Masukkan detail buku baru ke dalam katalog perpustakaan.</p>
|
</x-card>
|
||||||
</div>
|
<!-- MODAL TAMBAH BUKU -->
|
||||||
<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">
|
<div x-show="isModalBukuOpen" style="display: none;" class="fixed inset-0 z-50 overflow-y-auto"
|
||||||
<i class="fas fa-times text-lg"></i>
|
aria-labelledby="modal-title" role="dialog" aria-modal="true">
|
||||||
</button>
|
<div class="flex items-end justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
|
||||||
</div>
|
<!-- 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>
|
||||||
|
|
||||||
@if ($errors->any())
|
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
|
||||||
<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)
|
|
||||||
<li>{{ $error }}</li>
|
|
||||||
@endforeach
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<form action="{{ route('admin.buku.store') }}" method="POST" enctype="multipart/form-data" class="space-y-6">
|
<!-- Modal panel -->
|
||||||
@csrf
|
<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"
|
||||||
|
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
|
class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transition-all transform bg-white rounded-3xl shadow-2xl shadow-indigo-500/10 sm:my-8 sm:align-middle sm:max-w-4xl sm:w-full sm:p-8 border border-gray-100">
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div class="flex justify-between items-center mb-6 pl-2">
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="bibid" value="BIBID" />
|
<h3 class="text-2xl font-bold text-gray-900" id="modal-title">Tambah Koleksi Buku</h3>
|
||||||
<x-text-input id="bibid" name="bibid" type="text" class="mt-1 block w-full bg-gray-50/50" :value="old('bibid')" required />
|
<p class="text-sm text-gray-500 mt-1">Masukkan detail buku baru ke dalam katalog perpustakaan.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<button @click="isModalBukuOpen = false"
|
||||||
<x-input-label for="id_kategori" value="Kategori" />
|
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">
|
||||||
<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>
|
<i class="fas fa-times text-lg"></i>
|
||||||
<option value="">Pilih Kategori</option>
|
</button>
|
||||||
@foreach($kategori as $kat)
|
</div>
|
||||||
<option value="{{ $kat->id_kategori }}" {{ old('id_kategori') == $kat->id_kategori ? 'selected' : '' }}>
|
|
||||||
{{ $kat->nama_kategori }}
|
@if ($errors->any())
|
||||||
</option>
|
<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)
|
||||||
|
<li>{{ $error }}</li>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@endif
|
||||||
|
|
||||||
<div>
|
<form action="{{ route('admin.buku.store') }}" method="POST" enctype="multipart/form-data"
|
||||||
<x-input-label for="judul" value="Judul Buku" />
|
class="space-y-6">
|
||||||
<x-text-input id="judul" name="judul" type="text" class="mt-1 block w-full bg-gray-50/50" :value="old('judul')" required />
|
@csrf
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="pengarang" value="Pengarang" />
|
<x-input-label for="bibid" value="BIBID" />
|
||||||
<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="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>
|
||||||
|
<option value="">Pilih Kategori</option>
|
||||||
|
@foreach ($kategori as $kat)
|
||||||
|
<option value="{{ $kat->id_kategori }}"
|
||||||
|
{{ old('id_kategori') == $kat->id_kategori ? 'selected' : '' }}>
|
||||||
|
{{ $kat->nama_kategori }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</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 />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="penerbit" value="Penerbit" />
|
<x-input-label for="judul" value="Judul Buku" />
|
||||||
<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="judul" name="judul" type="text"
|
||||||
|
class="mt-1 block w-full bg-gray-50/50" :value="old('judul')" required />
|
||||||
</div>
|
</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')" />
|
|
||||||
</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')" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="deskripsi_fisik" value="Deskripsi Fisik" />
|
<x-input-label for="pengarang" value="Pengarang" />
|
||||||
<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="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 />
|
||||||
|
</div>
|
||||||
</div>
|
</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 />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="border-t border-gray-100 pt-6">
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||||
<x-input-label for="cover" value="Unggah Gambar Cover (Opsional)" class="mb-2" />
|
<div>
|
||||||
<div class="flex items-center justify-center w-full">
|
<x-input-label for="penerbit" value="Penerbit" />
|
||||||
<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">
|
<x-text-input id="penerbit" name="penerbit" type="text"
|
||||||
<div class="flex flex-col items-center justify-center pt-5 pb-6">
|
class="mt-1 block w-full bg-gray-50/50" :value="old('penerbit')" />
|
||||||
<i class="fas fa-cloud-upload-alt text-3xl text-indigo-400 mb-2"></i>
|
</div>
|
||||||
<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>
|
<div>
|
||||||
<p class="text-xs text-gray-400">PNG, JPG, JPEG (Maks. 2MB)</p>
|
<x-input-label for="tahun_terbit" value="Tahun Terbit" />
|
||||||
</div>
|
<x-text-input id="tahun_terbit" name="tahun_terbit" type="number"
|
||||||
<input id="cover" name="cover" type="file" class="hidden" accept="image/jpeg, image/png, image/jpg" />
|
class="mt-1 block w-full bg-gray-50/50" :value="old('tahun_terbit')" />
|
||||||
</label>
|
</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')" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex items-center justify-end gap-3 pt-6 border-t border-gray-100 mt-8">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<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">
|
<div>
|
||||||
Batal
|
<x-input-label for="deskripsi_fisik" value="Deskripsi Fisik" />
|
||||||
</button>
|
<x-text-input id="deskripsi_fisik" name="deskripsi_fisik" type="text"
|
||||||
<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">
|
class="mt-1 block w-full bg-gray-50/50" :value="old('deskripsi_fisik')" />
|
||||||
<i class="fas fa-save mr-2"></i> Simpan Buku
|
</div>
|
||||||
</button>
|
<div>
|
||||||
</div>
|
<x-input-label for="eksemplar" value="Jumlah Eksemplar" />
|
||||||
</form>
|
<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">
|
||||||
|
<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="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" />
|
||||||
|
</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">
|
||||||
|
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">
|
||||||
|
<i class="fas fa-save mr-2"></i> Simpan Buku
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -1,77 +1,85 @@
|
||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="container mx-auto px-4 py-8 max-w-2xl">
|
<div class="container mx-auto px-4 py-8 max-w-2xl">
|
||||||
<div class="bg-white shadow-lg rounded-xl overflow-hidden border border-gray-100">
|
<div class="bg-white shadow-lg rounded-xl overflow-hidden border border-gray-100">
|
||||||
<div class="p-6 bg-blue-50 border-b border-blue-100">
|
<div class="p-6 bg-blue-50 border-b border-blue-100">
|
||||||
<h1 class="text-2xl font-extrabold text-blue-900">Formulir Peminjaman Aset</h1>
|
<h1 class="text-2xl font-extrabold text-blue-900">Formulir Peminjaman Aset</h1>
|
||||||
</div>
|
|
||||||
|
|
||||||
@if ($errors->any())
|
|
||||||
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 m-6 mb-0" role="alert">
|
|
||||||
<p class="font-bold">Validasi Gagal</p>
|
|
||||||
<ul class="list-disc ml-5">
|
|
||||||
@foreach ($errors->all() as $error)
|
|
||||||
<li>{{ $error }}</li>
|
|
||||||
@endforeach
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<form action="{{ route('admin.peminjaman.store') }}" method="POST" class="p-6 space-y-6" id="form-peminjaman">
|
|
||||||
@csrf
|
|
||||||
|
|
||||||
<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">
|
|
||||||
<option value="">-- Pilih Member --</option>
|
|
||||||
@foreach($anggota as $a)
|
|
||||||
<option value="{{ $a->id }}" {{ old('id_anggota') == $a->id ? 'selected' : '' }}>
|
|
||||||
{{ $a->nama }} ({{ $a->no_identitas }})
|
|
||||||
</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
@if ($errors->any())
|
||||||
<label class="block text-sm font-medium text-gray-700 mb-2">Pilih Aset Buku (Hanya yang tersedia)</label>
|
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 m-6 mb-0" role="alert">
|
||||||
<select name="id_buku" class="w-full border-gray-300 rounded-lg shadow-sm focus:border-blue-500 focus:ring-blue-500">
|
<p class="font-bold">Validasi Gagal</p>
|
||||||
<option value="">-- Pilih Buku --</option>
|
<ul class="list-disc ml-5">
|
||||||
@foreach($buku as $b)
|
@foreach ($errors->all() as $error)
|
||||||
<option value="{{ $b->id_buku }}" {{ old('id_buku') == $b->id_buku ? 'selected' : '' }}>
|
<li>{{ $error }}</li>
|
||||||
{{ $b->bibid }} - {{ $b->judul }} (Stok: {{ $b->eksemplar }})
|
@endforeach
|
||||||
</option>
|
</ul>
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<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">
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
@endif
|
||||||
<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">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="pt-6 border-t border-gray-100 flex justify-between items-center">
|
<form action="{{ route('admin.peminjaman.store') }}" method="POST" class="p-6 space-y-6" id="form-peminjaman">
|
||||||
<a href="{{ route('admin.peminjaman.index') }}" class="text-gray-600 hover:text-gray-900 font-medium transition duration-300">Batal</a>
|
@csrf
|
||||||
<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
|
<div>
|
||||||
</button>
|
<label class="block text-sm font-medium text-gray-700 mb-2">Pilih Anggota / Member</label>
|
||||||
</div>
|
<select name="id_anggota"
|
||||||
</form>
|
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' : '' }}>
|
||||||
|
{{ $a->nama }} ({{ $a->no_identitas }})
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</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">
|
||||||
|
<option value="">-- Pilih Buku --</option>
|
||||||
|
@foreach ($buku as $b)
|
||||||
|
<option value="{{ $b->id }}" {{ old('id_buku') == $b->id ? 'selected' : '' }}>
|
||||||
|
{{ $b->bibid }} - {{ $b->judul }} (Stok: {{ $b->eksemplar }})
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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">
|
||||||
|
</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">
|
||||||
|
</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">
|
||||||
|
Eksekusi Transaksi
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.getElementById('form-peminjaman').addEventListener('submit', function() {
|
document.getElementById('form-peminjaman').addEventListener('submit', function() {
|
||||||
const btn = document.getElementById('btn-submit');
|
const btn = document.getElementById('btn-submit');
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
btn.innerHTML = 'Memproses...';
|
btn.innerHTML = 'Memproses...';
|
||||||
btn.classList.add('opacity-50', 'cursor-not-allowed');
|
btn.classList.add('opacity-50', 'cursor-not-allowed');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -3,461 +3,523 @@
|
||||||
@section('title', 'Sirkulasi Peminjaman')
|
@section('title', 'Sirkulasi Peminjaman')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div x-data="{
|
<div x-data="{
|
||||||
isModalPeminjamanOpen: {{ ($errors->any() && !old('_method')) ? 'true' : 'false' }},
|
isModalPeminjamanOpen: {{ $errors->any() && !old('_method') ? 'true' : 'false' }},
|
||||||
isModalKembaliOpen: false,
|
isModalKembaliOpen: false,
|
||||||
isModalEditOpen: {{ ($errors->any() && old('_method') == 'PUT') ? 'true' : 'false' }},
|
isModalEditOpen: {{ $errors->any() && old('_method') == 'PUT' ? 'true' : 'false' }},
|
||||||
isModalDeleteOpen: false,
|
isModalDeleteOpen: false,
|
||||||
deleteId: '',
|
deleteId: '',
|
||||||
editData: {
|
editData: {
|
||||||
id: '{{ old('peminjaman_id_edit') ?? '' }}',
|
id: '{{ old('peminjaman_id_edit') ?? '' }}',
|
||||||
id_anggota: '{{ old('id_anggota') ?? '' }}',
|
id_anggota: '{{ old('id_anggota') ?? '' }}',
|
||||||
id_buku: '{{ old('id_buku') ?? '' }}',
|
id_buku: '{{ old('id_buku') ?? '' }}',
|
||||||
tanggal_pinjam: '{{ old('tanggal_pinjam') ?? '' }}',
|
tanggal_pinjam: '{{ old('tanggal_pinjam') ?? '' }}',
|
||||||
tanggal_kembali: '{{ old('tanggal_kembali') ?? '' }}'
|
tanggal_kembali: '{{ old('tanggal_kembali') ?? '' }}'
|
||||||
},
|
},
|
||||||
openEditModal(id, anggotaId, buku, pinjam, kembali) {
|
openEditModal(id, anggotaId, buku, pinjam, kembali) {
|
||||||
this.editData = { id: id, id_anggota: anggotaId, id_buku: buku, tanggal_pinjam: pinjam, tanggal_kembali: kembali };
|
this.editData = { id: id, id_anggota: anggotaId, id_buku: buku, tanggal_pinjam: pinjam, tanggal_kembali: kembali };
|
||||||
this.isModalEditOpen = true;
|
this.isModalEditOpen = true;
|
||||||
},
|
},
|
||||||
openDeleteModal(id) {
|
openDeleteModal(id) {
|
||||||
this.deleteId = id;
|
this.deleteId = id;
|
||||||
this.isModalDeleteOpen = true;
|
this.isModalDeleteOpen = true;
|
||||||
},
|
},
|
||||||
kembaliData: { id: '', judul: '', tgl_pinjam: '', tgl_tenggat: '', denda: 0 },
|
kembaliData: { id: '', judul: '', tgl_pinjam: '', tgl_tenggat: '', denda: 0 },
|
||||||
uangDibayar: '',
|
uangDibayar: '',
|
||||||
get kembalian() {
|
get kembalian() {
|
||||||
if (!this.uangDibayar) return 0;
|
if (!this.uangDibayar) return 0;
|
||||||
return Math.max(0, this.uangDibayar - this.kembaliData.denda);
|
return Math.max(0, this.uangDibayar - this.kembaliData.denda);
|
||||||
},
|
},
|
||||||
openKembaliModal(id, judul, pinjam, tenggat, denda) {
|
openKembaliModal(id, judul, pinjam, tenggat, denda) {
|
||||||
this.kembaliData = { id: id, judul: judul, tgl_pinjam: pinjam, tgl_tenggat: tenggat, denda: denda };
|
this.kembaliData = { id: id, judul: judul, tgl_pinjam: pinjam, tgl_tenggat: tenggat, denda: denda };
|
||||||
this.uangDibayar = '';
|
this.uangDibayar = '';
|
||||||
this.isModalKembaliOpen = true;
|
this.isModalKembaliOpen = true;
|
||||||
}
|
}
|
||||||
}" x-cloak>
|
}" x-cloak>
|
||||||
<x-page-header title="Sirkulasi Peminjaman Buku">
|
<x-page-header title="Sirkulasi Peminjaman Buku">
|
||||||
<x-slot name="actions">
|
<x-slot name="actions">
|
||||||
<div class="flex flex-col sm:flex-row gap-2 items-center">
|
<div class="flex flex-col sm:flex-row gap-2 items-center">
|
||||||
<!-- Search Form -->
|
<!-- Search Form -->
|
||||||
<form action="{{ route('admin.peminjaman.index') }}" method="GET" class="relative w-full sm:w-auto flex">
|
<form action="{{ route('admin.peminjaman.index') }}" method="GET" class="relative w-full sm:w-auto flex">
|
||||||
<div class="relative flex-grow min-w-[200px]">
|
<div class="relative flex-grow min-w-[200px]">
|
||||||
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||||
<i class="fas fa-search text-gray-400"></i>
|
<i class="fas fa-search text-gray-400"></i>
|
||||||
</div>
|
|
||||||
<input type="text" name="search" value="{{ $search ?? '' }}"
|
|
||||||
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">
|
|
||||||
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">
|
|
||||||
<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]">
|
|
||||||
<i class="fas fa-plus mr-1"></i> Catat Peminjaman Baru
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</x-slot>
|
|
||||||
</x-page-header>
|
|
||||||
|
|
||||||
<x-alert type="success" :message="session('success')" />
|
|
||||||
|
|
||||||
<x-card>
|
|
||||||
<x-table>
|
|
||||||
<x-slot name="head">
|
|
||||||
<x-th>Anggota</x-th>
|
|
||||||
<x-th>Buku</x-th>
|
|
||||||
<x-th>Durasi Pinjam</x-th>
|
|
||||||
<x-th class="text-center">Status</x-th>
|
|
||||||
<x-th class="text-right">Aksi</x-th>
|
|
||||||
</x-slot>
|
|
||||||
|
|
||||||
@forelse ($peminjaman as $item)
|
|
||||||
<tr class="hover:bg-gray-50 transition-colors">
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
|
||||||
@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">
|
|
||||||
<i class="fab fa-whatsapp text-green-600"></i> {{ $item->anggota->no_hp ?? '-' }}
|
|
||||||
</div>
|
</div>
|
||||||
@else
|
<input type="text" name="search" value="{{ $search ?? '' }}"
|
||||||
<div class="text-sm font-bold text-gray-900">{{ $item->user?->name ?? 'Anonim' }}</div>
|
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"
|
||||||
<div class="text-[10px] text-amber-600 font-bold uppercase italic">Riwayat User Lama</div>
|
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">
|
||||||
|
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">
|
||||||
|
<i class="fas fa-times"></i>
|
||||||
|
</a>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</form>
|
||||||
<td class="px-6 py-4">
|
|
||||||
<div class="text-sm font-bold text-gray-900 line-clamp-1">{{ $item->buku->judul ?? 'Buku Dihapus' }}</div>
|
<button @click="isModalPeminjamanOpen = true"
|
||||||
<div class="text-sm text-gray-500">{{ $item->buku->nomor_panggil ?? '-' }}</div>
|
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]">
|
||||||
</td>
|
<i class="fas fa-plus mr-1"></i> Catat Peminjaman Baru
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
</button>
|
||||||
{{ \Carbon\Carbon::parse($item->tanggal_pinjam)->format('d M Y') }} -
|
</div>
|
||||||
{{ \Carbon\Carbon::parse($item->tanggal_kembali)->format('d M Y') }}
|
</x-slot>
|
||||||
</td>
|
</x-page-header>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-center">
|
|
||||||
@if($item->status_peminjaman == 'Dipinjam')
|
<x-alert type="success" :message="session('success')" />
|
||||||
@if(\Carbon\Carbon::parse($item->tanggal_kembali)->startOfDay()->lt(\Carbon\Carbon::now()->startOfDay()))
|
|
||||||
@php
|
<x-card>
|
||||||
$selisihHari = \Carbon\Carbon::now()->startOfDay()->diffInDays(\Carbon\Carbon::parse($item->tanggal_kembali)->startOfDay());
|
<x-table>
|
||||||
$estimasiDenda = $selisihHari * 1000;
|
<x-slot name="head">
|
||||||
@endphp
|
<x-th>Anggota</x-th>
|
||||||
<x-badge color="red"><i class="fas fa-exclamation-triangle mr-1"></i> Terlambat</x-badge>
|
<x-th>Buku</x-th>
|
||||||
<div class="text-[10px] text-red-600 mt-1 font-bold animate-pulse">Denda berjalan: Rp {{ number_format($estimasiDenda, 0, ',', '.') }}</div>
|
<x-th>Durasi Pinjam</x-th>
|
||||||
|
<x-th class="text-center">Status</x-th>
|
||||||
|
<x-th class="text-right">Aksi</x-th>
|
||||||
|
</x-slot>
|
||||||
|
|
||||||
|
@forelse ($peminjaman as $item)
|
||||||
|
<tr class="hover:bg-gray-50 transition-colors">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
@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">
|
||||||
|
<i class="fab fa-whatsapp text-green-600"></i> {{ $item->anggota->no_hp ?? '-' }}
|
||||||
|
</div>
|
||||||
@else
|
@else
|
||||||
<x-badge color="yellow">Aktif Dipinjam</x-badge>
|
<div class="text-sm font-bold text-gray-900">{{ $item->user?->name ?? 'Anonim' }}</div>
|
||||||
|
<div class="text-[10px] text-amber-600 font-bold uppercase italic">Riwayat User Lama</div>
|
||||||
@endif
|
@endif
|
||||||
@else
|
</td>
|
||||||
<x-badge color="green">Selesai</x-badge>
|
<td class="px-6 py-4">
|
||||||
@if($item->denda > 0)
|
<div class="text-sm font-bold text-gray-900 line-clamp-1">
|
||||||
<div class="text-xs text-red-600 font-bold mt-1">Denda: Rp {{ number_format($item->denda, 0, ',', '.') }}</div>
|
{{ $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">
|
||||||
|
{{ \Carbon\Carbon::parse($item->tanggal_pinjam)->format('d M Y') }} -
|
||||||
|
{{ \Carbon\Carbon::parse($item->tanggal_kembali)->format('d M Y') }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-center">
|
||||||
|
@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());
|
||||||
|
$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>
|
||||||
|
@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>
|
||||||
|
@endif
|
||||||
@endif
|
@endif
|
||||||
@endif
|
</td>
|
||||||
</td>
|
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
<div class="flex items-center justify-end gap-2">
|
||||||
<div class="flex items-center justify-end gap-2">
|
@if ($item->status_peminjaman == 'Dipinjam')
|
||||||
@if($item->status_peminjaman == 'Dipinjam')
|
@php
|
||||||
@php
|
$dendaItem = 0;
|
||||||
$dendaItem = 0;
|
$tglTenggat = \Carbon\Carbon::parse($item->tanggal_kembali)->startOfDay();
|
||||||
$tglTenggat = \Carbon\Carbon::parse($item->tanggal_kembali)->startOfDay();
|
$tglSekarang = \Carbon\Carbon::now()->startOfDay();
|
||||||
$tglSekarang = \Carbon\Carbon::now()->startOfDay();
|
if ($tglSekarang->gt($tglTenggat)) {
|
||||||
if ($tglSekarang->gt($tglTenggat)) {
|
$dendaItem = $tglSekarang->diffInDays($tglTenggat) * 1000;
|
||||||
$dendaItem = $tglSekarang->diffInDays($tglTenggat) * 1000;
|
}
|
||||||
}
|
@endphp
|
||||||
@endphp
|
<button type="button"
|
||||||
<button type="button"
|
|
||||||
@click="openKembaliModal('{{ $item->id_peminjaman }}', '{{ addslashes($item->buku->judul ?? 'Buku Dihapus') }}', '{{ \Carbon\Carbon::parse($item->tanggal_pinjam)->format('d M Y') }}', '{{ \Carbon\Carbon::parse($item->tanggal_kembali)->format('d M Y') }}', {{ $dendaItem }})"
|
@click="openKembaliModal('{{ $item->id_peminjaman }}', '{{ addslashes($item->buku->judul ?? 'Buku Dihapus') }}', '{{ \Carbon\Carbon::parse($item->tanggal_pinjam)->format('d M Y') }}', '{{ \Carbon\Carbon::parse($item->tanggal_kembali)->format('d M Y') }}', {{ $dendaItem }})"
|
||||||
class="bg-blue-100 text-blue-700 hover:bg-blue-200 px-3 py-1.5 rounded text-xs font-bold transition">
|
class="bg-blue-100 text-blue-700 hover:bg-blue-200 px-3 py-1.5 rounded text-xs font-bold transition">
|
||||||
Kembalikan
|
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>
|
||||||
|
@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>
|
||||||
|
@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">
|
||||||
|
<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">
|
||||||
|
<i class="fas fa-trash-alt"></i>
|
||||||
</button>
|
</button>
|
||||||
@else
|
</div>
|
||||||
<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>
|
</td>
|
||||||
@endif
|
</tr>
|
||||||
<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>
|
@empty
|
||||||
@if($item->status_peminjaman == 'Dipinjam')
|
<tr>
|
||||||
<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">
|
<td colspan="5" class="px-6 py-8 text-center text-sm text-gray-500">
|
||||||
<i class="fas fa-edit"></i>
|
Belum ada rekam jejak transaksi.
|
||||||
</button>
|
</td>
|
||||||
@endif
|
</tr>
|
||||||
<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">
|
@endforelse
|
||||||
<i class="fas fa-trash-alt"></i>
|
</x-table>
|
||||||
|
|
||||||
|
<div class="mt-4">
|
||||||
|
{{ $peminjaman->links() }}
|
||||||
|
</div>
|
||||||
|
</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 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>
|
||||||
|
|
||||||
|
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
|
||||||
|
|
||||||
|
<!-- Modal panel -->
|
||||||
|
<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"
|
||||||
|
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
|
class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transition-all transform bg-white rounded-3xl shadow-2xl shadow-blue-500/10 sm:my-8 sm:align-middle sm:max-w-3xl sm:w-full sm:p-8 border border-gray-100">
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center mb-6 pl-2">
|
||||||
|
<div>
|
||||||
|
<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">
|
||||||
|
<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">
|
||||||
|
<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)
|
||||||
|
<li>{{ $error }}</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<form action="{{ route('admin.peminjaman.store') }}" method="POST" class="space-y-6">
|
||||||
|
@csrf
|
||||||
|
|
||||||
|
<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>
|
||||||
|
<option value="">-- Pilih Member --</option>
|
||||||
|
@foreach ($anggota as $a)
|
||||||
|
<option value="{{ $a->id }}"
|
||||||
|
{{ old('id_anggota') == $a->id ? 'selected' : '' }}>
|
||||||
|
{{ $a->nama }} ({{ $a->no_identitas }})
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
<option value="">-- Pilih Buku --</option>
|
||||||
|
@foreach ($buku as $b)
|
||||||
|
<option value="{{ $b->id }}" {{ old('id_buku') == $b->id ? 'selected' : '' }}>
|
||||||
|
{{ $b->bibid }} - {{ $b->judul }} (Stok: {{ $b->eksemplar }})
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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 />
|
||||||
|
</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 />
|
||||||
|
</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">
|
||||||
|
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">
|
||||||
|
<i class="fas fa-check-circle mr-2"></i> Eksekusi Transaksi
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</form>
|
||||||
</tr>
|
|
||||||
@empty
|
|
||||||
<tr>
|
|
||||||
<td colspan="5" class="px-6 py-8 text-center text-sm text-gray-500">
|
|
||||||
Belum ada rekam jejak transaksi.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforelse
|
|
||||||
</x-table>
|
|
||||||
|
|
||||||
<div class="mt-4">
|
|
||||||
{{ $peminjaman->links() }}
|
|
||||||
</div>
|
|
||||||
</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 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>
|
|
||||||
|
|
||||||
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
|
|
||||||
|
|
||||||
<!-- Modal panel -->
|
|
||||||
<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"
|
|
||||||
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
|
||||||
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
|
||||||
class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transition-all transform bg-white rounded-3xl shadow-2xl shadow-blue-500/10 sm:my-8 sm:align-middle sm:max-w-3xl sm:w-full sm:p-8 border border-gray-100">
|
|
||||||
|
|
||||||
<div class="flex justify-between items-center mb-6 pl-2">
|
|
||||||
<div>
|
|
||||||
<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">
|
|
||||||
<i class="fas fa-times text-lg"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
</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">
|
|
||||||
<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)
|
|
||||||
<li>{{ $error }}</li>
|
|
||||||
@endforeach
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<form action="{{ route('admin.peminjaman.store') }}" method="POST" class="space-y-6">
|
|
||||||
@csrf
|
|
||||||
|
|
||||||
<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>
|
|
||||||
<option value="">-- Pilih Member --</option>
|
|
||||||
@foreach($anggota as $a)
|
|
||||||
<option value="{{ $a->id }}" {{ old('id_anggota') == $a->id ? 'selected' : '' }}>
|
|
||||||
{{ $a->nama }} ({{ $a->no_identitas }})
|
|
||||||
</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
<option value="">-- Pilih Buku --</option>
|
|
||||||
@foreach($buku as $b)
|
|
||||||
<option value="{{ $b->id_buku }}" {{ old('id_buku') == $b->id_buku ? 'selected' : '' }}>
|
|
||||||
{{ $b->bibid }} - {{ $b->judul }} (Stok: {{ $b->eksemplar }})
|
|
||||||
</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<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 />
|
|
||||||
</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 />
|
|
||||||
</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">
|
|
||||||
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">
|
|
||||||
<i class="fas fa-check-circle mr-2"></i> Eksekusi Transaksi
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<!-- MODAL PENGEMBALIAN & PEMBAYARAN DENDA -->
|
||||||
<!-- MODAL PENGEMBALIAN & PEMBAYARAN DENDA -->
|
<div x-show="isModalKembaliOpen" style="display: none;" class="fixed inset-0 z-50 overflow-y-auto"
|
||||||
<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">
|
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 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">​</span>
|
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
|
||||||
|
|
||||||
<div x-show="isModalKembaliOpen"
|
<div x-show="isModalKembaliOpen" x-transition:enter="ease-out duration-300"
|
||||||
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-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:enter-end="opacity-100 translate-y-0 sm:scale-100"
|
x-transition:leave="ease-in duration-200"
|
||||||
x-transition:leave="ease-in duration-200"
|
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
||||||
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transition-all transform bg-white rounded-3xl shadow-2xl shadow-blue-500/10 sm:my-8 sm:align-middle sm:max-w-xl sm:w-full sm:p-8 border border-gray-100">
|
||||||
class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transition-all transform bg-white rounded-3xl shadow-2xl shadow-blue-500/10 sm:my-8 sm:align-middle sm:max-w-xl sm:w-full sm:p-8 border border-gray-100">
|
|
||||||
|
|
||||||
<div class="flex justify-between items-center mb-6 pl-2 border-b pb-4">
|
<div class="flex justify-between items-center mb-6 pl-2 border-b pb-4">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-xl font-bold text-gray-900" id="modal-kembali-title">Detail Pengembalian</h3>
|
<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>
|
<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">
|
||||||
|
<i class="fas fa-times text-sm"></i>
|
||||||
|
</button>
|
||||||
</div>
|
</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">
|
|
||||||
<i class="fas fa-times text-sm"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="space-y-3 mb-5 bg-gray-50 p-4 rounded-xl border border-gray-100">
|
<div class="space-y-3 mb-5 bg-gray-50 p-4 rounded-xl border border-gray-100">
|
||||||
<div class="flex justify-between border-b border-gray-200 pb-2">
|
<div class="flex justify-between border-b border-gray-200 pb-2">
|
||||||
<span class="text-xs font-semibold text-gray-500">Judul Buku</span>
|
<span class="text-xs font-semibold text-gray-500">Judul Buku</span>
|
||||||
<span class="text-xs font-bold text-gray-900 text-right" x-text="kembaliData.judul"></span>
|
<span class="text-xs font-bold text-gray-900 text-right" x-text="kembaliData.judul"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between border-b border-gray-200 pb-2">
|
<div class="flex justify-between border-b border-gray-200 pb-2">
|
||||||
<span class="text-xs font-semibold text-gray-500">Tanggal Peminjaman</span>
|
<span class="text-xs font-semibold text-gray-500">Tanggal Peminjaman</span>
|
||||||
<span class="text-xs font-bold text-gray-900" x-text="kembaliData.tgl_pinjam"></span>
|
<span class="text-xs font-bold text-gray-900" x-text="kembaliData.tgl_pinjam"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between border-b border-gray-200 pb-2">
|
<div class="flex justify-between border-b border-gray-200 pb-2">
|
||||||
<span class="text-xs font-semibold text-gray-500">Tenggat Pengembalian</span>
|
<span class="text-xs font-semibold text-gray-500">Tenggat Pengembalian</span>
|
||||||
<span class="text-xs font-bold text-gray-900" x-text="kembaliData.tgl_tenggat"></span>
|
<span class="text-xs font-bold text-gray-900" x-text="kembaliData.tgl_tenggat"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between items-center pt-2">
|
<div class="flex justify-between items-center pt-2">
|
||||||
<span class="text-xs font-bold text-red-600">Total Denda</span>
|
<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"
|
||||||
</div>
|
x-text="'Rp ' + new Intl.NumberFormat('id-ID').format(kembaliData.denda)"></span>
|
||||||
</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>
|
|
||||||
<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...">
|
|
||||||
</div>
|
|
||||||
<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>
|
|
||||||
</div>
|
|
||||||
</div>
|
</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">
|
|
||||||
<i class="fas fa-check-circle mr-1"></i> Tidak ada denda keterlambatan.
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<form :action="'/admin/peminjaman/' + kembaliData.id + '/kembali'" method="POST">
|
<template x-if="kembaliData.denda > 0">
|
||||||
@csrf
|
<div class="bg-red-50 p-4 rounded-xl border border-red-100 mb-5">
|
||||||
@method('PUT')
|
<h4 class="text-xs font-bold text-red-800 mb-2"><i
|
||||||
<div class="flex items-center justify-end gap-2 pt-3 border-t border-gray-100">
|
class="fas fa-money-bill-wave mr-1"></i>Pembayaran Denda</h4>
|
||||||
<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">
|
<div class="space-y-3">
|
||||||
Batal
|
<div>
|
||||||
</button>
|
<label
|
||||||
<button type="submit"
|
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">
|
||||||
|
<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>
|
||||||
|
</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">
|
||||||
|
<i class="fas fa-check-circle mr-1"></i> Tidak ada denda keterlambatan.
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<form :action="'/admin/peminjaman/' + kembaliData.id + '/kembali'" method="POST">
|
||||||
|
@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">
|
||||||
|
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"
|
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"
|
: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) ?
|
||||||
<i class="fas fa-save mr-1"></i> Selesaikan Transaksi
|
'opacity-50 cursor-not-allowed' : 'hover:scale-105'">
|
||||||
</button>
|
<i class="fas fa-save mr-1"></i> Selesaikan Transaksi
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</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 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>
|
|
||||||
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
|
|
||||||
<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"
|
|
||||||
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
|
||||||
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
|
||||||
class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transition-all transform bg-white rounded-3xl shadow-2xl sm:my-8 sm:align-middle sm:max-w-3xl sm:w-full sm:p-8 border border-gray-100">
|
|
||||||
|
|
||||||
<div class="flex justify-between items-center mb-6 pl-2">
|
|
||||||
<div>
|
|
||||||
<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">
|
|
||||||
<i class="fas fa-times text-lg"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form :action="'/admin/peminjaman/' + editData.id" method="POST" class="space-y-6">
|
|
||||||
@csrf
|
|
||||||
@method('PUT')
|
|
||||||
<input type="hidden" name="peminjaman_id_edit" :value="editData.id">
|
|
||||||
|
|
||||||
<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>
|
|
||||||
<option value="">-- Pilih Member --</option>
|
|
||||||
@foreach($anggota as $a)
|
|
||||||
<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>
|
|
||||||
<option value="">-- Pilih Buku --</option>
|
|
||||||
@foreach($buku as $b)
|
|
||||||
<option value="{{ $b->id_buku }}">{{ $b->bibid }} - {{ $b->judul }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<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 />
|
|
||||||
</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 />
|
|
||||||
</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">
|
|
||||||
<i class="fas fa-save mr-2"></i> Simpan Perubahan
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</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 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"
|
|
||||||
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">
|
|
||||||
<i class="fas fa-times"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text-center">
|
|
||||||
<div class="mx-auto flex items-center justify-center h-20 w-20 rounded-full bg-red-50 mb-6">
|
|
||||||
<div class="h-12 w-12 rounded-full bg-red-100 flex items-center justify-center animate-pulse">
|
|
||||||
<i class="fas fa-trash-alt text-2xl text-red-600"></i>
|
|
||||||
</div>
|
|
||||||
</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>
|
|
||||||
|
|
||||||
<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">
|
|
||||||
Ya, Hapus Sekarang
|
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</div>
|
||||||
<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">
|
</form>
|
||||||
Batalkan
|
</div>
|
||||||
|
</div>
|
||||||
|
</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 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>
|
||||||
|
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
|
||||||
|
<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"
|
||||||
|
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
|
class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transition-all transform bg-white rounded-3xl shadow-2xl sm:my-8 sm:align-middle sm:max-w-3xl sm:w-full sm:p-8 border border-gray-100">
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center mb-6 pl-2">
|
||||||
|
<div>
|
||||||
|
<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">
|
||||||
|
<i class="fas fa-times text-lg"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<form :action="'/admin/peminjaman/' + editData.id" method="POST" class="space-y-6">
|
||||||
|
@csrf
|
||||||
|
@method('PUT')
|
||||||
|
<input type="hidden" name="peminjaman_id_edit" :value="editData.id">
|
||||||
|
|
||||||
|
<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>
|
||||||
|
<option value="">-- Pilih Member --</option>
|
||||||
|
@foreach ($anggota as $a)
|
||||||
|
<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>
|
||||||
|
<option value="">-- Pilih Buku --</option>
|
||||||
|
@foreach ($buku as $b)
|
||||||
|
<option value="{{ $b->id }}">{{ $b->bibid }} - {{ $b->judul }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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 />
|
||||||
|
</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 />
|
||||||
|
</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">
|
||||||
|
<i class="fas fa-save mr-2"></i> Simpan Perubahan
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</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 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"
|
||||||
|
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">
|
||||||
|
<i class="fas fa-times"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="mx-auto flex items-center justify-center h-20 w-20 rounded-full bg-red-50 mb-6">
|
||||||
|
<div class="h-12 w-12 rounded-full bg-red-100 flex items-center justify-center animate-pulse">
|
||||||
|
<i class="fas fa-trash-alt text-2xl text-red-600"></i>
|
||||||
|
</div>
|
||||||
|
</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>
|
||||||
|
|
||||||
|
<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">
|
||||||
|
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">
|
||||||
|
Batalkan
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -1,185 +1,221 @@
|
||||||
@extends('layouts.guest')
|
@extends('layouts.guest')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<!-- Hero Section -->
|
<!-- 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
|
||||||
<!-- Decorative background elements -->
|
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="absolute inset-0 opacity-10 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] mix-blend-overlay"></div>
|
<!-- Decorative background elements -->
|
||||||
<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
|
||||||
<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>
|
class="absolute inset-0 opacity-10 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] mix-blend-overlay">
|
||||||
|
</div>
|
||||||
<div class="container mx-auto px-4 relative z-10">
|
<div
|
||||||
<div class="text-center max-w-3xl mx-auto">
|
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">
|
||||||
<h1 class="text-4xl sm:text-5xl font-extrabold text-white mb-6 tracking-tight">
|
</div>
|
||||||
Eksplorasi <span class="text-transparent bg-clip-text bg-gradient-to-r from-blue-200 to-cyan-200">Katalog Perpustakaan</span>
|
<div
|
||||||
</h1>
|
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">
|
||||||
<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.
|
|
||||||
</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>
|
|
||||||
</div>
|
|
||||||
<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]">
|
|
||||||
Cari
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container mx-auto px-4 pb-16">
|
<div class="container mx-auto px-4 relative z-10">
|
||||||
<!-- Results Info -->
|
<div class="text-center max-w-3xl mx-auto">
|
||||||
@if(isset($search) && $search != '')
|
<h1 class="text-4xl sm:text-5xl font-extrabold text-white mb-6 tracking-tight">
|
||||||
<div class="mb-8 flex justify-between items-center text-gray-600">
|
Eksplorasi <span class="text-transparent bg-clip-text bg-gradient-to-r from-blue-200 to-cyan-200">Katalog
|
||||||
<p>Menampilkan hasil pencarian untuk: <span class="font-semibold text-gray-900">"{{ $search }}"</span></p>
|
Perpustakaan</span>
|
||||||
</div>
|
</h1>
|
||||||
@endif
|
<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
|
||||||
<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-6">
|
Anda.
|
||||||
@forelse($buku as $item)
|
|
||||||
@php
|
|
||||||
$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">
|
|
||||||
<!-- 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>
|
|
||||||
<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">
|
|
||||||
TIDAK TERSEDIA
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<!-- Badge BUKU BARU Dinamis (Buku terbit/masuk dalam 1 tahun terakhir) -->
|
|
||||||
@php
|
|
||||||
$isBaru = false;
|
|
||||||
$tahunSekarang = date('Y');
|
|
||||||
|
|
||||||
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);
|
|
||||||
if ($tanggalMasuk->diffInDays(now()) <= 30) {
|
|
||||||
$isBaru = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
@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">
|
|
||||||
<i class="fas fa-sparkles mr-1"></i> BUKU BARU
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<!-- 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">
|
|
||||||
{{ $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">
|
|
||||||
{{ $item->similarity_score >= 1 ? 'Exact' : 'Rel: '.number_format($item->similarity_score, 1) }}
|
|
||||||
</span>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 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 }}">
|
|
||||||
{{ $item->judul }}
|
|
||||||
</h2>
|
|
||||||
<p class="text-blue-600 font-medium text-xs sm:text-sm mb-2 line-clamp-1">
|
|
||||||
{{ $item->pengarang }}
|
|
||||||
</p>
|
</p>
|
||||||
<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">
|
<!-- Search Bar -->
|
||||||
<span class="truncate pr-1">{{ $item->penerbit }}</span>
|
<form action="{{ route('katalog.index') }}" method="GET" class="relative group max-w-2xl mx-auto">
|
||||||
<span class="font-medium bg-gray-100 px-1.5 py-0.5 rounded">{{ $item->tahun_terbit ?? '-' }}</span>
|
<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>
|
||||||
|
</div>
|
||||||
|
<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]">
|
||||||
|
Cari
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container mx-auto px-4 pb-16">
|
||||||
|
<!-- 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>
|
||||||
|
</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;
|
||||||
|
@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">
|
||||||
|
<!-- 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>
|
||||||
|
<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">
|
||||||
|
TIDAK TERSEDIA
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<!-- Badge BUKU BARU Dinamis (Buku terbit/masuk dalam 1 tahun terakhir) -->
|
||||||
|
@php
|
||||||
|
$isBaru = false;
|
||||||
|
$tahunSekarang = date('Y');
|
||||||
|
|
||||||
|
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);
|
||||||
|
if ($tanggalMasuk->diffInDays(now()) <= 30) {
|
||||||
|
$isBaru = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@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">
|
||||||
|
<i class="fas fa-sparkles mr-1"></i> BUKU BARU
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<!-- 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">
|
||||||
|
{{ $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">
|
||||||
|
{{ $item->similarity_score >= 1 ? 'Exact' : 'Rel: ' . number_format($item->similarity_score, 1) }}
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 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 }}">
|
||||||
|
{{ $item->judul }}
|
||||||
|
</h2>
|
||||||
|
<p class="text-blue-600 font-medium text-xs sm:text-sm mb-2 line-clamp-1">
|
||||||
|
{{ $item->pengarang }}
|
||||||
|
</p>
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 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">
|
||||||
|
Habis Dipinjam
|
||||||
|
</button>
|
||||||
|
@else
|
||||||
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@empty
|
||||||
|
<div
|
||||||
<!-- Action Area -->
|
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="px-4 pb-4 pt-0 mt-auto relative z-30">
|
<div class="w-20 h-20 sm:w-24 sm:h-24 bg-gray-50 rounded-full flex items-center justify-center mb-6">
|
||||||
@if($habis)
|
<svg class="h-10 w-10 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<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">
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
|
||||||
Habis Dipinjam
|
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" />
|
||||||
</button>
|
</svg>
|
||||||
@else
|
</div>
|
||||||
<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">
|
<h3 class="text-xl sm:text-2xl font-bold text-gray-900 mb-2">Tidak Ada Koleksi</h3>
|
||||||
Lihat Detail
|
<p class="text-gray-500 max-w-md text-sm sm:text-base">Koleksi buku yang Anda cari belum tersedia saat
|
||||||
</a>
|
ini. Silakan coba dengan kata kunci lain.</p>
|
||||||
@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="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" />
|
|
||||||
</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>
|
|
||||||
</div>
|
|
||||||
@endforelse
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Pagination -->
|
|
||||||
<div class="mt-12 flex justify-center">
|
|
||||||
{{ $buku->links() }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Widget Buku Terpopuler -->
|
|
||||||
@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">
|
|
||||||
<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>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<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">
|
|
||||||
<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">
|
|
||||||
{{ $top->judul }}
|
|
||||||
</a>
|
|
||||||
<p class="text-sm text-gray-500">{{ $top->pengarang }}</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="self-start sm:self-auto">
|
@endforelse
|
||||||
<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">
|
</div>
|
||||||
<i class="fas fa-chart-line text-blue-500"></i> {{ $top->peminjaman_count }} Peminjaman
|
|
||||||
</span>
|
<!-- Pagination -->
|
||||||
|
<div class="mt-12 flex justify-center">
|
||||||
|
{{ $buku->links() }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Widget Buku Terpopuler -->
|
||||||
|
@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">
|
||||||
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
|
||||||
@endforeach
|
<ul class="divide-y divide-gray-50">
|
||||||
</ul>
|
@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">
|
||||||
|
<div>
|
||||||
|
<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">
|
||||||
|
<i class="fas fa-chart-line text-blue-500"></i> {{ $top->peminjaman_count }} Peminjaman
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -1,247 +1,294 @@
|
||||||
@extends('layouts.guest')
|
@extends('layouts.guest')
|
||||||
|
|
||||||
@push('styles')
|
@push('styles')
|
||||||
<style>
|
<style>
|
||||||
/* ===== Map Pin Visualization ===== */
|
/* ===== Map Pin Visualization ===== */
|
||||||
.map-container {
|
.map-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
background: #E2E8F0;
|
background: #E2E8F0;
|
||||||
}
|
}
|
||||||
.map-container img {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
opacity: 0.95;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pin Pointer */
|
.map-container img {
|
||||||
.map-pin {
|
display: block;
|
||||||
position: absolute;
|
width: 100%;
|
||||||
transform: translate(-50%, -100%);
|
height: auto;
|
||||||
z-index: 30;
|
opacity: 0.95;
|
||||||
cursor: pointer;
|
}
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pin Icon (red circle + triangle tail) */
|
/* Pin Pointer */
|
||||||
.map-pin__icon {
|
.map-pin {
|
||||||
display: flex;
|
position: absolute;
|
||||||
flex-direction: column;
|
transform: translate(-50%, -100%);
|
||||||
align-items: center;
|
z-index: 30;
|
||||||
}
|
cursor: pointer;
|
||||||
.map-pin__circle {
|
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.25));
|
||||||
width: 32px;
|
transition: filter 0.3s ease;
|
||||||
height: 32px;
|
}
|
||||||
background: linear-gradient(135deg, #E32636, #c0392b);
|
|
||||||
border-radius: 50%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
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;
|
|
||||||
border-left: 7px solid transparent;
|
|
||||||
border-right: 7px solid transparent;
|
|
||||||
border-top: 10px solid #c0392b;
|
|
||||||
margin-top: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pin Label (tooltip di bawah) */
|
.map-pin:hover {
|
||||||
.map-pin__label {
|
filter: drop-shadow(0 6px 14px rgba(227, 38, 54, 0.5));
|
||||||
position: absolute;
|
z-index: 40;
|
||||||
top: calc(100% + 6px);
|
}
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
background: #0B5394;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 9px;
|
|
||||||
font-weight: 800;
|
|
||||||
padding: 3px 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
white-space: nowrap;
|
|
||||||
box-shadow: 0 2px 6px rgba(11,83,148,0.4);
|
|
||||||
border: 1px solid rgba(96,165,250,0.4);
|
|
||||||
pointer-events: none;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 0.2s ease;
|
|
||||||
}
|
|
||||||
.map-pin:hover .map-pin__label,
|
|
||||||
.map-pin.active .map-pin__label {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pulse dot di dasar pin */
|
.map-pin.active {
|
||||||
.map-pin__pulse {
|
animation: pinBounce 1.5s infinite;
|
||||||
position: absolute;
|
}
|
||||||
bottom: -4px;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: rgba(227,38,54,0.35);
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
.map-pin.active .map-pin__pulse {
|
|
||||||
animation: pinPulse 2s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Overlay Not Found */
|
/* Pin Icon (red circle + triangle tail) */
|
||||||
.map-overlay-notfound {
|
.map-pin__icon {
|
||||||
position: absolute;
|
display: flex;
|
||||||
inset: 0;
|
flex-direction: column;
|
||||||
display: flex;
|
align-items: center;
|
||||||
flex-direction: column;
|
}
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background: rgba(255,255,255,0.85);
|
|
||||||
backdrop-filter: blur(6px);
|
|
||||||
z-index: 50;
|
|
||||||
border-radius: 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes pinBounce {
|
|
||||||
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; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Responsive adjustments */
|
|
||||||
@media (max-width: 640px) {
|
|
||||||
.map-pin__circle {
|
.map-pin__circle {
|
||||||
width: 24px;
|
width: 32px;
|
||||||
height: 24px;
|
height: 32px;
|
||||||
|
background: linear-gradient(135deg, #E32636, #c0392b);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: 2.5px solid #fff;
|
||||||
|
box-shadow: 0 2px 8px rgba(227, 38, 54, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.map-pin__circle i {
|
.map-pin__circle i {
|
||||||
font-size: 10px;
|
color: #fff;
|
||||||
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.map-pin__tail {
|
.map-pin__tail {
|
||||||
border-left-width: 5px;
|
width: 0;
|
||||||
border-right-width: 5px;
|
height: 0;
|
||||||
border-top-width: 7px;
|
border-left: 7px solid transparent;
|
||||||
|
border-right: 7px solid transparent;
|
||||||
|
border-top: 10px solid #c0392b;
|
||||||
|
margin-top: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Pin Label (tooltip di bawah) */
|
||||||
.map-pin__label {
|
.map-pin__label {
|
||||||
font-size: 8px;
|
position: absolute;
|
||||||
padding: 2px 6px;
|
top: calc(100% + 6px);
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background: #0B5394;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 9px;
|
||||||
|
font-weight: 800;
|
||||||
|
padding: 3px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
white-space: nowrap;
|
||||||
|
box-shadow: 0 2px 6px rgba(11, 83, 148, 0.4);
|
||||||
|
border: 1px solid rgba(96, 165, 250, 0.4);
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</style>
|
.map-pin:hover .map-pin__label,
|
||||||
|
.map-pin.active .map-pin__label {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pulse dot di dasar pin */
|
||||||
|
.map-pin__pulse {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -4px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(227, 38, 54, 0.35);
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-pin.active .map-pin__pulse {
|
||||||
|
animation: pinPulse 2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Overlay Not Found */
|
||||||
|
.map-overlay-notfound {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: rgba(255, 255, 255, 0.85);
|
||||||
|
backdrop-filter: blur(6px);
|
||||||
|
z-index: 50;
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pinBounce {
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive adjustments */
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.map-pin__circle {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@endpush
|
@endpush
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="container mx-auto px-4 py-12 max-w-7xl">
|
<div class="container mx-auto px-4 py-12 max-w-7xl">
|
||||||
<!-- Header: Back button & Search Bar -->
|
<!-- Header: Back button & Search Bar -->
|
||||||
<div class="flex flex-col md:flex-row justify-between items-center mb-10 gap-6">
|
<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') }}"
|
||||||
<i class="fas fa-arrow-left mr-2"></i> Kembali
|
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>
|
<i class="fas fa-arrow-left mr-2"></i> Kembali
|
||||||
|
</a>
|
||||||
|
|
||||||
<!-- Search Bar -->
|
<!-- Search Bar -->
|
||||||
<form action="{{ route('katalog.index') }}" method="GET" class="w-full md:w-80 relative group">
|
<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">
|
<input type="text" name="search" placeholder="Cari Buku..."
|
||||||
<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">
|
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">
|
||||||
<i class="fas fa-search"></i>
|
<button type="submit"
|
||||||
</button>
|
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">
|
||||||
</form>
|
<i class="fas fa-search"></i>
|
||||||
</div>
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Main Content Grid 3 Columns -->
|
<!-- Main Content Grid 3 Columns -->
|
||||||
<div class="grid grid-cols-1 md:grid-cols-12 gap-10 items-start">
|
<div class="grid grid-cols-1 md:grid-cols-12 gap-10 items-start">
|
||||||
|
|
||||||
<!-- Column 1: Book Cover Card -->
|
<!-- Column 1: Book Cover Card -->
|
||||||
<div class="md:col-span-12 lg:col-span-3">
|
<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
|
||||||
@if($buku->cover)
|
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">
|
||||||
<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">
|
@if ($buku->cover)
|
||||||
@else
|
<img src="{{ asset('storage/' . $buku->cover) }}" alt="{{ $buku->judul }}"
|
||||||
<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">
|
class="w-full aspect-[3/4] object-cover rounded-2xl mb-6 shadow-md border border-gray-100">
|
||||||
<div class="absolute inset-0 opacity-40 bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGNpcmNsZSBjeD0iMiIgY3k9IjIiIHI9IjIiIGZpbGw9IiMzYjgyZjYiIGZpbGwtb3BhY2l0eT0iMC4wNSIvPjwvc3ZnPg==')]"></div>
|
@else
|
||||||
<div class="relative z-10 flex flex-col items-center justify-center p-6 w-full h-full">
|
<div
|
||||||
<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">
|
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">
|
||||||
<i class="fas fa-book-open text-3xl"></i>
|
<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">
|
||||||
|
<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>
|
||||||
|
<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>
|
||||||
</div>
|
</div>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
|
@endif
|
||||||
|
<h2 class="font-extrabold text-gray-900 uppercase tracking-widest text-xs leading-relaxed px-2 mb-2">
|
||||||
|
{{ $buku->judul }}</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Column 2: Details Description -->
|
||||||
|
<div class="md:col-span-12 lg:col-span-5 flex flex-col gap-8 lg:px-4">
|
||||||
|
<div class="text-center lg:text-left">
|
||||||
|
<h2 class="text-3xl font-black text-gray-900 mb-2 tracking-tight">Deskripsi Buku</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-6">
|
||||||
|
<!-- 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>
|
||||||
|
</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">Judul Buku:</span>
|
||||||
|
<span class="text-gray-900 font-bold text-sm">{{ $buku->judul }}</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 Penulis:</span>
|
||||||
|
<span class="text-gray-900 font-bold text-sm">{{ $buku->pengarang }}</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">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>
|
||||||
|
</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>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
|
||||||
<h2 class="font-extrabold text-gray-900 uppercase tracking-widest text-xs leading-relaxed px-2 mb-2">{{ $buku->judul }}</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Column 2: Details Description -->
|
|
||||||
<div class="md:col-span-12 lg:col-span-5 flex flex-col gap-8 lg:px-4">
|
|
||||||
<div class="text-center lg:text-left">
|
|
||||||
<h2 class="text-3xl font-black text-gray-900 mb-2 tracking-tight">Deskripsi Buku</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="space-y-6">
|
|
||||||
<!-- 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>
|
|
||||||
</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">Judul Buku:</span>
|
|
||||||
<span class="text-gray-900 font-bold text-sm">{{ $buku->judul }}</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 Penulis:</span>
|
|
||||||
<span class="text-gray-900 font-bold text-sm">{{ $buku->pengarang }}</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">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>
|
|
||||||
</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>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="w-full lg:w-96 flex-shrink-0 flex flex-col gap-6 mx-auto relative">
|
<div class="w-full lg:w-96 flex-shrink-0 flex flex-col gap-6 mx-auto relative">
|
||||||
|
|
||||||
<!-- MAP CONTAINER -->
|
<!-- 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 -->
|
<!-- Background Image Map -->
|
||||||
<img src="{{ asset('img/img 2.png') }}" alt="Denah Perpustakaan" id="mapImage">
|
<img src="{{ asset('img/img 2.png') }}" alt="Denah Perpustakaan" id="mapImage">
|
||||||
|
|
||||||
<!-- Pin Container (JavaScript akan merender pin di sini) -->
|
<!-- Pin Container (JavaScript akan merender pin di sini) -->
|
||||||
<div id="pinContainer"></div>
|
<div id="pinContainer"></div>
|
||||||
|
|
||||||
@if(!$buku->lokasi_x || !$buku->lokasi_y)
|
@if (!$buku->lokasi_x || !$buku->lokasi_y)
|
||||||
<!-- Overlay Not Found -->
|
<!-- Overlay Not Found -->
|
||||||
<div class="map-overlay-notfound">
|
<div class="map-overlay-notfound">
|
||||||
<i class="fas fa-exclamation-triangle text-red-500 text-3xl mb-2 animate-pulse"></i>
|
<i class="fas fa-exclamation-triangle text-red-500 text-3xl mb-2 animate-pulse"></i>
|
||||||
|
|
@ -252,171 +299,189 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Detail Mini location box directly below map -->
|
<!-- 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]">
|
<div
|
||||||
<span class="text-[10px] text-blue-300 font-bold uppercase tracking-widest block mb-2 opacity-80">Informasi Lokasi Fisik</span>
|
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-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>
|
<span class="text-sm font-semibold text-blue-200">{{ $lokasi['area'] }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 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>
|
|
||||||
<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">
|
|
||||||
<table class="w-full text-left border-collapse">
|
|
||||||
<thead>
|
|
||||||
<tr class="bg-gray-50 border-b border-gray-200 text-gray-600 text-sm">
|
|
||||||
<th class="py-4 px-6 font-semibold">Nama Peminjam</th>
|
|
||||||
<th class="py-4 px-6 font-semibold">Tanggal Pinjam</th>
|
|
||||||
<th class="py-4 px-6 font-semibold">Tanggal Kembali</th>
|
|
||||||
<th class="py-4 px-6 font-semibold">Status</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody class="text-gray-700 text-sm">
|
|
||||||
@foreach($buku->peminjaman->sortByDesc('tanggal_pinjam') as $history)
|
|
||||||
<tr class="border-b border-gray-100 hover:bg-gray-50 transition-colors">
|
|
||||||
<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
|
|
||||||
? substr($nama, 0, 3) . '***'
|
|
||||||
: ($nama !== 'Pengguna Tidak Diketahui' ? substr($nama, 0, 1) . '***' : $nama);
|
|
||||||
@endphp
|
|
||||||
{{ $disensor }}
|
|
||||||
</td>
|
|
||||||
<td class="py-4 px-6">
|
|
||||||
{{ \Carbon\Carbon::parse($history->tanggal_pinjam)->translatedFormat('d F Y') }}
|
|
||||||
</td>
|
|
||||||
<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)
|
|
||||||
</span>
|
|
||||||
@else
|
|
||||||
<span class="text-gray-600">
|
|
||||||
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>
|
|
||||||
@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>
|
|
||||||
@else
|
|
||||||
<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>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
@else
|
|
||||||
<div class="p-8 text-center flex flex-col items-center justify-center bg-gray-50/50">
|
|
||||||
<div class="w-16 h-16 bg-blue-50 text-blue-300 rounded-full flex items-center justify-center mb-3">
|
|
||||||
<i class="fas fa-history text-2xl"></i>
|
|
||||||
</div>
|
|
||||||
<p class="text-gray-500 font-medium">Belum ada riwayat peminjaman untuk buku ini.</p>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
@if($rekomendasi->count() > 0)
|
<!-- Riwayat Peminjaman -->
|
||||||
<div class="mt-12">
|
<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">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">Riwayat
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
Peminjaman</h2>
|
||||||
@foreach($rekomendasi as $rek)
|
<div class="bg-white rounded-xl shadow-sm border border-gray-200 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">
|
@if ($buku->peminjaman && $buku->peminjaman->count() > 0)
|
||||||
<div class="p-5 flex-grow">
|
<div class="overflow-x-auto">
|
||||||
<div class="flex justify-between items-start mb-2">
|
<table class="w-full text-left border-collapse">
|
||||||
<span class="text-xs font-bold text-blue-600 bg-blue-50 px-2 py-1 rounded">{{ $rek->nomor_panggil }}</span>
|
<thead>
|
||||||
<span class="text-xs font-semibold text-green-600">Skor: {{ number_format($rek->similarity_score, 1) }}</span>
|
<tr class="bg-gray-50 border-b border-gray-200 text-gray-600 text-sm">
|
||||||
|
<th class="py-4 px-6 font-semibold">Nama Peminjam</th>
|
||||||
|
<th class="py-4 px-6 font-semibold">Tanggal Pinjam</th>
|
||||||
|
<th class="py-4 px-6 font-semibold">Tanggal Kembali</th>
|
||||||
|
<th class="py-4 px-6 font-semibold">Status</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="text-gray-700 text-sm">
|
||||||
|
@foreach ($buku->peminjaman->sortByDesc('tanggal_pinjam') as $history)
|
||||||
|
<tr class="border-b border-gray-100 hover:bg-gray-50 transition-colors">
|
||||||
|
<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
|
||||||
|
? substr($nama, 0, 3) . '***'
|
||||||
|
: ($nama !== 'Pengguna Tidak Diketahui'
|
||||||
|
? substr($nama, 0, 1) . '***'
|
||||||
|
: $nama);
|
||||||
|
@endphp
|
||||||
|
{{ $disensor }}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 px-6">
|
||||||
|
{{ \Carbon\Carbon::parse($history->tanggal_pinjam)->translatedFormat('d F Y') }}
|
||||||
|
</td>
|
||||||
|
<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)
|
||||||
|
</span>
|
||||||
|
@else
|
||||||
|
<span class="text-gray-600">
|
||||||
|
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>
|
||||||
|
@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>
|
||||||
|
@else
|
||||||
|
<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>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-lg font-bold text-gray-900 mb-1 line-clamp-2">{{ $rek->judul }}</h3>
|
@else
|
||||||
<p class="text-sm text-gray-600 line-clamp-1">{{ $rek->pengarang }}</p>
|
<div class="p-8 text-center flex flex-col items-center justify-center bg-gray-50/50">
|
||||||
</div>
|
<div class="w-16 h-16 bg-blue-50 text-blue-300 rounded-full flex items-center justify-center mb-3">
|
||||||
<div class="px-5 py-3 bg-gray-50 border-t border-gray-100 mt-auto">
|
<i class="fas fa-history text-2xl"></i>
|
||||||
<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">
|
</div>
|
||||||
Lihat Detail
|
<p class="text-gray-500 font-medium">Belum ada riwayat peminjaman untuk buku ini.</p>
|
||||||
</a>
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@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>
|
||||||
|
<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="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>
|
||||||
|
</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) }}"
|
||||||
|
class="text-sm font-semibold text-blue-600 hover:text-blue-800 flex items-center justify-center w-full">
|
||||||
|
Lihat Detail
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endif
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@push('scripts')
|
@push('scripts')
|
||||||
@php
|
@php
|
||||||
$pinDataJson = [
|
$pinDataJson = [
|
||||||
'x' => $buku->lokasi_x,
|
'x' => $buku->lokasi_x,
|
||||||
'y' => $buku->lokasi_y,
|
'y' => $buku->lokasi_y,
|
||||||
'label' => $lokasi['rak'] . ' — ' . $lokasi['area'],
|
'label' => $lokasi['rak'] . ' — ' . $lokasi['area'],
|
||||||
];
|
];
|
||||||
@endphp
|
@endphp
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
// Data koordinat dari Laravel
|
// Data koordinat dari Laravel
|
||||||
const pinData = @json($pinDataJson);
|
const pinData = @json($pinDataJson);
|
||||||
|
|
||||||
const container = document.getElementById('pinContainer');
|
const container = document.getElementById('pinContainer');
|
||||||
if (!container || !pinData.x || !pinData.y) return;
|
if (!container || !pinData.x || !pinData.y) return;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Membuat elemen pin pointer dan menambahkannya ke container.
|
* Membuat elemen pin pointer dan menambahkannya ke container.
|
||||||
* @param {number} x - Posisi X dalam persentase (0-100)
|
* @param {number} x - Posisi X dalam persentase (0-100)
|
||||||
* @param {number} y - Posisi Y dalam persentase (0-100)
|
* @param {number} y - Posisi Y dalam persentase (0-100)
|
||||||
* @param {string} label - Label teks untuk pin
|
* @param {string} label - Label teks untuk pin
|
||||||
* @param {boolean} isActive - Apakah pin ini aktif (bounce + label visible)
|
* @param {boolean} isActive - Apakah pin ini aktif (bounce + label visible)
|
||||||
*/
|
*/
|
||||||
function renderPin(x, y, label, isActive) {
|
function renderPin(x, y, label, isActive) {
|
||||||
// Wrapper pin
|
// Wrapper pin
|
||||||
const pin = document.createElement('div');
|
const pin = document.createElement('div');
|
||||||
pin.className = 'map-pin' + (isActive ? ' active' : '');
|
pin.className = 'map-pin' + (isActive ? ' active' : '');
|
||||||
pin.style.left = x + '%';
|
pin.style.left = x + '%';
|
||||||
pin.style.top = y + '%';
|
pin.style.top = y + '%';
|
||||||
|
|
||||||
// Ikon pin (circle + tail)
|
// Ikon pin (circle + tail)
|
||||||
const icon = document.createElement('div');
|
const icon = document.createElement('div');
|
||||||
icon.className = 'map-pin__icon';
|
icon.className = 'map-pin__icon';
|
||||||
|
|
||||||
const circle = document.createElement('div');
|
const circle = document.createElement('div');
|
||||||
circle.className = 'map-pin__circle';
|
circle.className = 'map-pin__circle';
|
||||||
circle.innerHTML = '<i class="fas fa-map-marker-alt"></i>';
|
circle.innerHTML = '<i class="fas fa-map-marker-alt"></i>';
|
||||||
|
|
||||||
const tail = document.createElement('div');
|
const tail = document.createElement('div');
|
||||||
tail.className = 'map-pin__tail';
|
tail.className = 'map-pin__tail';
|
||||||
|
|
||||||
icon.appendChild(circle);
|
icon.appendChild(circle);
|
||||||
icon.appendChild(tail);
|
icon.appendChild(tail);
|
||||||
pin.appendChild(icon);
|
pin.appendChild(icon);
|
||||||
|
|
||||||
// Pulse effect
|
// Pulse effect
|
||||||
const pulse = document.createElement('div');
|
const pulse = document.createElement('div');
|
||||||
pulse.className = 'map-pin__pulse';
|
pulse.className = 'map-pin__pulse';
|
||||||
pin.appendChild(pulse);
|
pin.appendChild(pulse);
|
||||||
|
|
||||||
// Label tooltip
|
// Label tooltip
|
||||||
if (label) {
|
if (label) {
|
||||||
const labelEl = document.createElement('span');
|
const labelEl = document.createElement('span');
|
||||||
labelEl.className = 'map-pin__label';
|
labelEl.className = 'map-pin__label';
|
||||||
labelEl.textContent = label;
|
labelEl.textContent = label;
|
||||||
pin.appendChild(labelEl);
|
pin.appendChild(labelEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
container.appendChild(pin);
|
container.appendChild(pin);
|
||||||
return pin;
|
return pin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render pin utama buku ini
|
// Render pin utama buku ini
|
||||||
renderPin(pinData.x, pinData.y, pinData.label, true);
|
renderPin(pinData.x, pinData.y, pinData.label, true);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@endpush
|
@endpush
|
||||||
|
|
|
||||||
|
|
@ -1,97 +1,116 @@
|
||||||
{{-- BUKU TERPOPULER SECTION --}}
|
{{-- BUKU TERPOPULER SECTION --}}
|
||||||
<section id="populer" class="py-24 bg-gray-50 relative overflow-hidden border-b border-gray-100">
|
<section id="populer" class="py-24 bg-gray-50 relative overflow-hidden border-b border-gray-100">
|
||||||
<div class="max-w-7xl mx-auto px-6 relative z-10">
|
<div class="max-w-7xl mx-auto px-6 relative z-10">
|
||||||
@if(!empty($bukuPopuler) && $bukuPopuler->count())
|
@if (!empty($bukuPopuler) && $bukuPopuler->count())
|
||||||
<div>
|
<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
|
||||||
<div class="w-full md:w-auto">
|
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="inline-flex items-center gap-2 px-4 py-2 bg-blue-100 rounded-full mb-4 mx-auto md:mx-0">
|
<div class="w-full md:w-auto">
|
||||||
<i class="fas fa-fire text-red-500 text-xs"></i>
|
<div
|
||||||
<span class="text-xs font-semibold text-blue-800 tracking-wide">Paling Laris</span>
|
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>
|
||||||
|
</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.
|
||||||
|
</p>
|
||||||
</div>
|
</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>
|
|
||||||
</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.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="grid grid-cols-2 lg:grid-cols-5 md:grid-cols-3 gap-6">
|
<div class="grid grid-cols-2 lg:grid-cols-5 md:grid-cols-3 gap-6">
|
||||||
@foreach($bukuPopuler as $item)
|
@foreach ($bukuPopuler as $item)
|
||||||
@php
|
@php
|
||||||
$habis = ($item->eksemplar <= 0);
|
$habis = $item->eksemplar <= 0;
|
||||||
@endphp
|
@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 -->
|
<!-- Peminjaman Count Badge -->
|
||||||
<div class="absolute top-2 left-2 z-20">
|
<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
|
||||||
<i class="fas fa-book-reader"></i> {{ $item->peminjaman_count }}x
|
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>
|
<i class="fas fa-book-reader"></i> {{ $item->peminjaman_count }}x
|
||||||
</div>
|
</span>
|
||||||
|
|
||||||
<!-- 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 }}"
|
|
||||||
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>
|
|
||||||
<span class="text-xs font-medium">No Cover</span>
|
|
||||||
</div>
|
</div>
|
||||||
@endif
|
|
||||||
|
|
||||||
@if($habis)
|
<!-- Book Cover -->
|
||||||
<!-- Overlay Dipinjam Semua -->
|
<div class="relative w-full pt-[140%] overflow-hidden bg-gray-50 flex-shrink-0">
|
||||||
<div class="absolute inset-0 bg-red-900/30 backdrop-blur-[1px] flex items-center justify-center z-10">
|
@if ($item->cover ?? $item->sampul)
|
||||||
<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">
|
<img src="{{ asset('storage/' . ($item->cover ?? $item->sampul)) }}"
|
||||||
TIDAK TERSEDIA
|
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>
|
||||||
|
<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">
|
||||||
|
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">
|
||||||
|
{{ $item->nomor_panggil ?? '-' }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="absolute top-2 right-2 flex justify-between items-start z-10">
|
<!-- Content -->
|
||||||
<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">
|
<div class="p-4 flex-grow flex flex-col">
|
||||||
{{ $item->nomor_panggil ?? '-' }}
|
<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"
|
||||||
</span>
|
title="{{ $item->judul }}">
|
||||||
</div>
|
{{ $item->judul }}
|
||||||
</div>
|
</h2>
|
||||||
|
<p class="text-blue-600 font-medium text-[10px] sm:text-xs mb-2 line-clamp-1">
|
||||||
|
{{ $item->pengarang }}
|
||||||
|
</p>
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Content -->
|
<!-- Action Area -->
|
||||||
<div class="p-4 flex-grow flex flex-col">
|
<div class="px-4 pb-4 pt-0 mt-auto relative z-30">
|
||||||
<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 }}">
|
@if ($habis)
|
||||||
{{ $item->judul }}
|
<button disabled
|
||||||
</h2>
|
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">
|
||||||
<p class="text-blue-600 font-medium text-[10px] sm:text-xs mb-2 line-clamp-1">
|
Habis Dipinjam
|
||||||
{{ $item->pengarang }}
|
</button>
|
||||||
</p>
|
@else
|
||||||
<div class="mt-auto pt-3 flex flex-col gap-2 border-t border-gray-50">
|
<a href="{{ route('katalog.show', $item->id ?? 1) }}"
|
||||||
<div class="flex justify-between items-center text-[10px] text-gray-500">
|
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">
|
||||||
<span class="truncate pr-1">{{ $item->penerbit }}</span>
|
Lihat Detail
|
||||||
<span class="font-medium bg-gray-100 px-1.5 py-0.5 rounded">{{ $item->tahun_terbit ?? '-' }}</span>
|
</a>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@endforeach
|
||||||
|
|
||||||
<!-- 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">
|
|
||||||
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">
|
|
||||||
Lihat Detail
|
|
||||||
</a>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -16,85 +16,102 @@
|
||||||
Buku-buku rilis baru dan penambahan paling anyar di perpustakaan kami.
|
Buku-buku rilis baru dan penambahan paling anyar di perpustakaan kami.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</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>
|
Lihat Semua Katalog <i class="fas fa-arrow-right text-xs"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if(!empty($bukuTerbaru) && $bukuTerbaru->count())
|
@if (!empty($bukuTerbaru) && $bukuTerbaru->count())
|
||||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-6">
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-6">
|
||||||
@foreach($bukuTerbaru as $item)
|
@foreach ($bukuTerbaru as $item)
|
||||||
@php
|
@php
|
||||||
$habis = ($item->eksemplar <= 0);
|
$habis = $item->eksemplar <= 0;
|
||||||
@endphp
|
@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
|
||||||
<!-- Badge BUKU BARU (Pojok Kanan Atas Kartu) -->
|
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">
|
||||||
@if(!$habis)
|
<!-- Badge BUKU BARU (Pojok Kanan Atas Kartu) -->
|
||||||
<div class="absolute top-0 right-0 z-20">
|
@if (!$habis)
|
||||||
<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="absolute top-0 right-0 z-20">
|
||||||
<i class="fas fa-sparkles mr-1"></i> BUKU BARU
|
<div
|
||||||
</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>
|
<i class="fas fa-sparkles mr-1"></i> BUKU BARU
|
||||||
@endif
|
|
||||||
|
|
||||||
<!-- 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 }}"
|
|
||||||
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>
|
|
||||||
<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">
|
|
||||||
TIDAK TERSEDIA
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<!-- Overlay Badges (Nomor Panggil) -->
|
<!-- Book Cover -->
|
||||||
<div class="absolute top-2 inset-x-2 flex justify-between items-start z-10">
|
<div class="relative w-full pt-[140%] overflow-hidden bg-gray-50 flex-shrink-0">
|
||||||
<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">
|
@if ($item->cover ?? $item->sampul)
|
||||||
{{ $item->nomor_panggil ?? '-' }}
|
<img src="{{ asset('storage/' . ($item->cover ?? $item->sampul)) }}"
|
||||||
</span>
|
alt="{{ $item->judul }}"
|
||||||
</div>
|
class="absolute inset-0 w-full h-full object-cover {{ !$habis ? 'group-hover:scale-110' : '' }} transition-transform duration-700 ease-in-out">
|
||||||
</div>
|
@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>
|
||||||
|
<span class="text-xs font-medium">Cover Tidak Tersedia</span>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<!-- Content -->
|
@if ($habis)
|
||||||
<div class="p-4 flex-grow flex flex-col">
|
<!-- Overlay Dipinjam Semua -->
|
||||||
<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 }}">
|
<div
|
||||||
{{ $item->judul }}
|
class="absolute inset-0 bg-red-900/30 backdrop-blur-[1px] flex items-center justify-center z-10">
|
||||||
</h2>
|
<div
|
||||||
<p class="text-blue-600 font-medium text-xs sm:text-sm mb-2 line-clamp-1">
|
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">
|
||||||
{{ $item->pengarang }}
|
TIDAK TERSEDIA
|
||||||
</p>
|
</div>
|
||||||
<div class="mt-auto pt-3 flex flex-col gap-2 border-t border-gray-50">
|
</div>
|
||||||
<div class="flex justify-between items-center text-[10px] sm:text-xs text-gray-500">
|
@endif
|
||||||
<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>
|
<!-- 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">
|
||||||
|
{{ $item->nomor_panggil ?? '-' }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Action Area -->
|
<!-- Content -->
|
||||||
<div class="px-4 pb-4 pt-0 mt-auto relative z-30">
|
<div class="p-4 flex-grow flex flex-col">
|
||||||
@if($habis)
|
<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"
|
||||||
<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">
|
title="{{ $item->judul }}">
|
||||||
Habis Dipinjam
|
{{ $item->judul }}
|
||||||
</button>
|
</h2>
|
||||||
@else
|
<p class="text-blue-600 font-medium text-xs sm:text-sm mb-2 line-clamp-1">
|
||||||
<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">
|
{{ $item->pengarang }}
|
||||||
Lihat Detail
|
</p>
|
||||||
</a>
|
<div class="mt-auto pt-3 flex flex-col gap-2 border-t border-gray-50">
|
||||||
@endif
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 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">
|
||||||
|
Habis Dipinjam
|
||||||
|
</button>
|
||||||
|
@else
|
||||||
|
<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
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue