Files
rahmatrafli1 5f00a0dbf1 feat: Add CRUD functionality for books, categories, and loans
- Implemented Create, Edit, and Index pages for Buku (Books) with form handling and validation.
- Added Create, Edit, and Index pages for Kategori (Categories) with form handling and validation.
- Developed Create and Index pages for Peminjaman (Loans) with form handling and validation.
- Integrated status management and action buttons for loan records.
- Enhanced UI with responsive design and user-friendly navigation.
2026-03-17 22:05:20 +07:00

183 lines
8.0 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import MainLayout from "@/Layouts/MainLayout";
import { Head, useForm, Link } from "@inertiajs/react";
export default function BukuEdit({ buku, kategoris }) {
const { data, setData, put, processing, errors } = useForm({
kategori_id: buku.kategori_id,
judul: buku.judul,
pengarang: buku.pengarang,
penerbit: buku.penerbit,
tahun_terbit: buku.tahun_terbit,
isbn: buku.isbn,
stok: buku.stok,
sinopsis: buku.sinopsis ?? "",
});
const handleSubmit = (e) => {
e.preventDefault();
put(`/buku/${buku.id}`);
};
return (
<MainLayout>
<Head title="Edit Buku" />
<div className="max-w-2xl mx-auto">
<div className="flex items-center gap-2 mb-6">
<Link
href="/buku"
className="text-indigo-600 hover:underline"
>
Kembali
</Link>
<span className="text-gray-400">/</span>
<span className="text-gray-600">Edit Buku</span>
</div>
<div className="bg-white rounded-xl shadow p-6">
<h1 className="text-xl font-bold text-gray-800 mb-6">
Edit Buku
</h1>
<form onSubmit={handleSubmit} className="space-y-4">
<FormField label="Kategori" error={errors.kategori_id}>
<select
value={data.kategori_id}
onChange={(e) =>
setData("kategori_id", e.target.value)
}
className="w-full border rounded-lg px-3 py-2 focus:ring-2 focus:ring-indigo-400 focus:outline-none"
>
<option value="">-- Pilih Kategori --</option>
{kategoris.map((k) => (
<option key={k.id} value={k.id}>
{k.nama_kategori}
</option>
))}
</select>
</FormField>
<FormField label="Judul Buku" error={errors.judul}>
<input
type="text"
value={data.judul}
onChange={(e) =>
setData("judul", e.target.value)
}
className="w-full border rounded-lg px-3 py-2 focus:ring-2 focus:ring-indigo-400 focus:outline-none"
/>
</FormField>
<div className="grid grid-cols-2 gap-4">
<FormField
label="Pengarang"
error={errors.pengarang}
>
<input
type="text"
value={data.pengarang}
onChange={(e) =>
setData("pengarang", e.target.value)
}
className="w-full border rounded-lg px-3 py-2 focus:ring-2 focus:ring-indigo-400 focus:outline-none"
/>
</FormField>
<FormField label="Penerbit" error={errors.penerbit}>
<input
type="text"
value={data.penerbit}
onChange={(e) =>
setData("penerbit", e.target.value)
}
className="w-full border rounded-lg px-3 py-2 focus:ring-2 focus:ring-indigo-400 focus:outline-none"
/>
</FormField>
</div>
<div className="grid grid-cols-2 gap-4">
<FormField
label="Tahun Terbit"
error={errors.tahun_terbit}
>
<input
type="number"
value={data.tahun_terbit}
onChange={(e) =>
setData("tahun_terbit", e.target.value)
}
className="w-full border rounded-lg px-3 py-2 focus:ring-2 focus:ring-indigo-400 focus:outline-none"
min="1900"
max="2099"
/>
</FormField>
<FormField label="ISBN" error={errors.isbn}>
<input
type="text"
value={data.isbn}
onChange={(e) =>
setData("isbn", e.target.value)
}
className="w-full border rounded-lg px-3 py-2 focus:ring-2 focus:ring-indigo-400 focus:outline-none"
/>
</FormField>
</div>
<FormField label="Stok Buku" error={errors.stok}>
<input
type="number"
value={data.stok}
onChange={(e) =>
setData("stok", e.target.value)
}
className="w-full border rounded-lg px-3 py-2 focus:ring-2 focus:ring-indigo-400 focus:outline-none"
min="0"
/>
</FormField>
<FormField label="Sinopsis" error={errors.sinopsis}>
<textarea
value={data.sinopsis}
onChange={(e) =>
setData("sinopsis", e.target.value)
}
className="w-full border rounded-lg px-3 py-2 focus:ring-2 focus:ring-indigo-400 focus:outline-none"
rows={4}
/>
</FormField>
<div className="flex gap-3 pt-4">
<button
type="submit"
disabled={processing}
className="bg-indigo-600 text-white px-6 py-2 rounded-lg hover:bg-indigo-700 disabled:opacity-50 transition-colors"
>
{processing ? "Menyimpan..." : "💾 Update Buku"}
</button>
<Link
href="/buku"
className="bg-gray-200 text-gray-700 px-6 py-2 rounded-lg hover:bg-gray-300 transition-colors"
>
Batal
</Link>
</div>
</form>
</div>
</div>
</MainLayout>
);
}
function FormField({ label, error, children }) {
return (
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
{label}
</label>
{children}
{error && <p className="text-red-500 text-xs mt-1">{error}</p>}
</div>
);
}