324 lines
17 KiB
PHP
324 lines
17 KiB
PHP
@extends('layouts.edit')
|
|
|
|
@section('content')
|
|
<div class="form-page-wrapper py-3 py-md-4">
|
|
|
|
<div class="container-fluid px-3 px-md-5">
|
|
|
|
<div class="mb-4 border-bottom pb-3 d-flex flex-column flex-sm-row align-items-sm-center justify-content-between gap-3">
|
|
<h4 class="mb-0 fw-bold text-dark fs-5">
|
|
<i class="fas fa-book-open text-primary me-2"></i> Tambah Koleksi Buku
|
|
</h4>
|
|
</div>
|
|
|
|
@if(session('success'))
|
|
<div class="alert alert-success alert-dismissible fade show shadow-sm border-0 mb-4" role="alert">
|
|
<i class="fas fa-check-circle me-2"></i> {{ session('success') }}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
@endif
|
|
|
|
<div class="card shadow-sm border-0 rounded-4 overflow-hidden w-100">
|
|
<div class="card-body p-3 p-sm-4 bg-white">
|
|
<form action="{{ route('admin.koleksi.store') }}" method="POST" enctype="multipart/form-data" class="needs-validation" novalidate>
|
|
@csrf
|
|
|
|
<input type="hidden" name="kode_eksemplar" id="kode_eksemplar">
|
|
|
|
<h5 class="fw-bold text-secondary mb-3 pb-2 border-bottom text-uppercase fs-7">
|
|
<i class="fas fa-info-circle me-1"></i> Informasi Utama Buku
|
|
</h5>
|
|
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-lg-8 col-md-7 col-12">
|
|
<label class="form-label fw-semibold">Judul Buku <span class="text-danger">*</span></label>
|
|
<input type="text" name="title" id="title" class="form-control shadow-sm" required maxlength="255"
|
|
placeholder="Masukkan judul lengkap buku">
|
|
<div class="invalid-feedback">Judul buku wajib diisi (Maksimal 255 karakter).</div>
|
|
</div>
|
|
|
|
<div class="col-lg-4 col-md-5 col-12">
|
|
<label class="form-label fw-semibold">Jumlah Eksemplar <span class="text-danger">*</span></label>
|
|
<input type="number" name="jumlah_eksemplar" class="form-control shadow-sm numeric-only" min="1" max="9999" value="1" required
|
|
oninput="this.value = this.value.replace(/[^0-9]/g, '')">
|
|
<small class="text-muted fs-8">Jumlah fisik buku yang tersedia (contoh: 2)</small>
|
|
</div>
|
|
|
|
<div class="col-md-6 col-12">
|
|
<label class="form-label fw-semibold">Pengarang / Penulis</label>
|
|
<input type="text" name="sor" class="form-control shadow-sm" maxlength="255"
|
|
placeholder="Masukkan nama pengarang"
|
|
oninput="this.value = this.value.replace(/[^a-zA-Z\s.,']/g, '')">
|
|
</div>
|
|
|
|
<div class="col-md-6 col-12">
|
|
<label class="form-label fw-semibold">ISBN / ISSN</label>
|
|
<input type="text" name="isbn_issn" class="form-control shadow-sm numeric-spec" maxlength="25"
|
|
placeholder="Contoh: 9786028519939 (Hanya Angka)"
|
|
oninput="this.value = this.value.replace(/[^0-9.-]/g, '')">
|
|
</div>
|
|
</div>
|
|
|
|
<h5 class="fw-bold text-secondary mb-3 pt-2 pb-2 border-bottom text-uppercase fs-7">
|
|
<i class="fas fa-building me-1"></i> Detail Penerbitan & Klasifikasi
|
|
</h5>
|
|
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-lg-4 col-md-6 col-12">
|
|
<label class="form-label fw-semibold">Penerbit</label>
|
|
<input list="publisherList" type="text" name="publisher_name" class="form-control shadow-sm" maxlength="255"
|
|
placeholder="Ketik atau pilih nama penerbit">
|
|
<datalist id="publisherList">
|
|
@foreach($publishers as $publisher)
|
|
<option value="{{ $publisher->name }}">
|
|
@endforeach
|
|
</datalist>
|
|
</div>
|
|
|
|
<div class="col-lg-4 col-md-6 col-12">
|
|
<label class="form-label fw-semibold">Tempat Terbit</label>
|
|
<input list="publishPlaceList" type="text" id="publish_place_input" name="publish_place_name" class="form-control shadow-sm" maxlength="150"
|
|
placeholder="Ketik kota terbit">
|
|
<datalist id="publishPlaceList">
|
|
@foreach($publishPlaces as $place)
|
|
<option value="{{ $place->name }}">
|
|
@endforeach
|
|
</datalist>
|
|
</div>
|
|
|
|
<div class="col-lg-4 col-md-12 col-12">
|
|
<label class="form-label fw-semibold">Tahun Terbit</label>
|
|
<input list="yearSuggestions" type="text" inputmode="numeric" name="publish_year" id="publish_year" class="form-control shadow-sm" maxlength="4"
|
|
placeholder="Pilih atau ketik tahun"
|
|
oninput="this.value = this.value.replace(/[^0-9]/g, '')">
|
|
<datalist id="yearSuggestions">
|
|
</datalist>
|
|
</div>
|
|
|
|
<div class="col-md-6 col-12">
|
|
<label class="form-label fw-semibold">Edisi / Cetakan</label>
|
|
<input type="text" name="edition" class="form-control shadow-sm" maxlength="50"
|
|
placeholder="Contoh: Cetakan ke-2, Edisi Revisi">
|
|
</div>
|
|
|
|
<div class="col-md-6 col-12">
|
|
<label class="form-label fw-semibold">Nomor Klasifikasi (DDC)</label>
|
|
<input type="text" name="classification" class="form-control shadow-sm numeric-spec" maxlength="50"
|
|
placeholder="Contoh: 005.1 atau 800 (Hanya Angka)"
|
|
oninput="this.value = this.value.replace(/[^0-9.]/g, '')">
|
|
</div>
|
|
</div>
|
|
|
|
<h5 class="fw-bold text-secondary mb-3 pt-2 pb-2 border-bottom text-uppercase fs-7">
|
|
<i class="fas fa-sliders-h me-1"></i> Pengaturan Tambahan
|
|
</h5>
|
|
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-md-6 col-12">
|
|
<label class="form-label fw-semibold">Sampul Buku</label>
|
|
<input type="file" name="image" class="form-control shadow-sm" accept="image/jpeg,image/png,image/webp">
|
|
<small class="text-muted fs-8">Format: JPG, PNG, WEBP. Maksimal 5 MB</small>
|
|
</div>
|
|
|
|
<div class="col-md-6 col-12">
|
|
<label class="form-label fw-semibold">Tag / Label</label>
|
|
<input type="text" name="labels" class="form-control shadow-sm" maxlength="255"
|
|
placeholder="Fiksi, Pemrograman, Sejarah (pisahkan dengan koma)">
|
|
</div>
|
|
|
|
<div class="col-md-6 col-12">
|
|
<div class="card border bg-light shadow-none p-2.5 rounded-3 h-100">
|
|
<label class="form-label fw-bold mb-1 fs-7.5">Tampilkan di Katalog Publik (OPAC)?</label>
|
|
<div class="d-flex gap-3 mt-1">
|
|
<div class="form-check mb-0">
|
|
<input type="radio" name="opac_hide" value="0" id="opac_show" class="form-check-input" checked>
|
|
<label for="opac_show" class="form-check-label text-dark fw-normal small">Ya</label>
|
|
</div>
|
|
<div class="form-check mb-0">
|
|
<input type="radio" name="opac_hide" value="1" id="opac_hide" class="form-check-input">
|
|
<label for="opac_hide" class="form-check-label text-dark fw-normal small">Tidak</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6 col-12">
|
|
<div class="card border bg-light shadow-none p-2.5 rounded-3 h-100">
|
|
<label class="form-label fw-bold mb-1 fs-7.5">Promosikan di Beranda Depan?</label>
|
|
<div class="d-flex gap-3 mt-1">
|
|
<div class="form-check mb-0">
|
|
<input type="radio" name="promoted" value="1" id="promote_yes" class="form-check-input">
|
|
<label for="promote_yes" class="form-check-label text-dark fw-normal small">Ya</label>
|
|
</div>
|
|
<div class="form-check mb-0">
|
|
<input type="radio" name="promoted" value="0" id="promote_no" class="form-check-input" checked>
|
|
<label for="promote_no" class="form-check-label text-dark fw-normal small">Tidak</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex flex-row gap-2 mt-4 pt-3 border-top justify-content-end align-items-center bottom-actions-wrapper">
|
|
<button type="reset" class="btn btn-light border rounded-pill px-3 py-1.5 shadow-sm text-secondary fw-semibold btn-custom-md">
|
|
<i class="fas fa-undo me-1 small"></i> Reset
|
|
</button>
|
|
<button type="submit" class="btn btn-success rounded-pill px-4 py-1.5 shadow-sm fw-bold btn-custom-md">
|
|
<i class="fas fa-save me-1 small"></i> Simpan Buku
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.form-page-wrapper {
|
|
background-color: #f8fafc;
|
|
min-height: 100vh;
|
|
width: 100%;
|
|
}
|
|
.fs-7 { font-size: 0.875rem; }
|
|
.fs-7.5 { font-size: 0.85rem; }
|
|
.fs-8 { font-size: 0.75rem; display: block; margin-top: 0.2rem; }
|
|
|
|
label {
|
|
color: #1f2937;
|
|
font-size: 0.88rem;
|
|
margin-bottom: 0.3rem;
|
|
}
|
|
|
|
.form-control {
|
|
border-radius: 0.375rem !important;
|
|
border: 1px solid #cbd5e1;
|
|
padding: 0.5rem 0.75rem;
|
|
font-size: 0.9rem;
|
|
color: #334155;
|
|
transition: all 0.2s ease-in-out;
|
|
}
|
|
|
|
.form-control:focus {
|
|
border-color: #3b82f6;
|
|
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15) !important;
|
|
}
|
|
|
|
.rounded-4 { border-radius: 0.75rem !important; }
|
|
.form-check-input:checked { background-color: #2563eb; border-color: #2563eb; }
|
|
.p-2.5 { padding: 0.65rem 0.85rem !important; }
|
|
|
|
.btn-custom-md {
|
|
font-size: 0.88rem !important;
|
|
height: 38px;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
input::-webkit-outer-spin-button,
|
|
input::-webkit-inner-spin-button {
|
|
-webkit-appearance: none;
|
|
margin: 0;
|
|
}
|
|
input[type=number] {
|
|
-moz-appearance: textfield;
|
|
}
|
|
|
|
@media (max-width: 480px) {
|
|
.bottom-actions-wrapper {
|
|
flex-direction: column !important;
|
|
align-items: stretch !important;
|
|
gap: 2px;
|
|
}
|
|
.bottom-actions-wrapper .btn-custom-md {
|
|
width: 100%;
|
|
border-radius: 0.5rem !important;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<style>
|
|
html, body {
|
|
-ms-overflow-style: none;
|
|
scrollbar-width: none;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
// 1. Generate Dropdown List Tahun Otomatis (Mulai Tahun Ini Berjalan mundur 40 Tahun ke belakang)
|
|
const currentYear = new Date().getFullYear();
|
|
const yearSelect = document.getElementById('yearSuggestions');
|
|
for (let i = currentYear; i >= currentYear - 40; i--) {
|
|
let option = document.createElement('option');
|
|
option.value = i;
|
|
yearSelect.appendChild(option);
|
|
}
|
|
|
|
// 2. Integrasi Pengambilan Data Tempat Terbit Melalui API Eksternal/Instansi (Dinamis saat diketik)
|
|
const placeInput = document.getElementById('publish_place_input');
|
|
const placeDatalist = document.getElementById('publishPlaceList');
|
|
|
|
placeInput.addEventListener('input', function() {
|
|
const query = this.value.trim();
|
|
if (query.length >= 3) { // Trigger API setelah user mengetik minimal 3 huruf
|
|
// Ganti URL ini dengan endpoint API Instansi Anda yang sebenarnya
|
|
const apiUrl = `https://api.instansi.go.id/v1/wilayah/kota?search=${query}`;
|
|
|
|
fetch(apiUrl)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
// Bersihkan opsi datalist lama terlebih dahulu agar tidak menumpuk
|
|
placeDatalist.innerHTML = '';
|
|
|
|
// Menampilkan data hasil response API ke dropdown datalist secara real-time
|
|
data.forEach(item => {
|
|
let option = document.createElement('option');
|
|
option.value = item.nama_kota || item.name;
|
|
placeDatalist.appendChild(option);
|
|
});
|
|
})
|
|
.catch(error => console.log('Log error / API luar belum diaktifkan:', error));
|
|
}
|
|
});
|
|
|
|
// 3. Sistem Auto Generator Kode Eksemplar
|
|
document.getElementById('title').addEventListener('input', function () {
|
|
let cleanTitle = this.value.trim()
|
|
.toUpperCase()
|
|
.replace(/[^A-Z0-9\s-]/g, '')
|
|
.replace(/\s+/g, '-');
|
|
|
|
if(cleanTitle.length > 10) {
|
|
cleanTitle = cleanTitle.substring(0, 10);
|
|
}
|
|
|
|
const random = Date.now().toString().slice(-6);
|
|
|
|
if(cleanTitle) {
|
|
document.getElementById('kode_eksemplar').value = "BK-" + cleanTitle + "-" + random;
|
|
} else {
|
|
document.getElementById('kode_eksemplar').value = "";
|
|
}
|
|
});
|
|
|
|
// 4. Pengunci Hard-Level Keyboard Input Khusus Angka (mencegah karakter 'e' , 'E' dll)
|
|
document.querySelectorAll('.numeric-only, .numeric-spec').forEach(function(input) {
|
|
input.addEventListener('keydown', function(e) {
|
|
const allowedKeys = ['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab'];
|
|
|
|
// Jika input adalah tipe spesifik seperti ISBN/Klasifikasi DDC, izinkan karakter titik atau strip
|
|
if (input.classList.contains('numeric-spec')) {
|
|
if (['.', '-'].includes(e.key)) return;
|
|
}
|
|
|
|
if (allowedKeys.includes(e.key)) return;
|
|
|
|
if (isNaN(Number(e.key)) && e.key !== ' ') {
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
@endsection
|
|
|