fitur tambah barang, edit barang modal, dan update halaman transaksi BAST

This commit is contained in:
fajar 2026-05-21 01:34:18 +07:00
parent d034a8f918
commit 3f5a7b848b
5 changed files with 55 additions and 26 deletions

View File

@ -51,7 +51,7 @@ export default function EditBarangModal({ itemSelected, onClose, onRefresh }: Ed
nama_barang: namaBarang,
kategori_id: kategoriMapping[kategoriInput] || itemSelected.kategori_id,
lokasi_id: lokasiMapping[lokasiInput] || itemSelected.lokasi_id,
status_barang: kondisiFisik === "Baik / Layak" ? "Baik" : kondisiFisik,
status_barang: kondisiFisik,
stok: parseInt(stokInput) || 0
};
@ -136,8 +136,10 @@ export default function EditBarangModal({ itemSelected, onClose, onRefresh }: Ed
onChange={(e) => setKondisiFisik(e.target.value)}
className="w-full p-3 rounded-xl border border-gray-300 dark:border-gray-600 dark:bg-gray-700 outline-none"
>
<option value="Baik / Layak">Baik / Layak</option>
<option value="Rusak">Rusak</option>
<option value="Baik">Baik</option>
<option value="Rusak Ringan">Rusak Ringan</option>
<option value="Rusak Berat">Rusak Berat</option>
<option value="Hilang">Hilang</option>
</select>
</div>

View File

@ -94,7 +94,7 @@ export default function TambahBarang({ onRefresh }: TambahBarangProps) {
formData.append("nama_barang", namaBarang.trim());
formData.append("nama_kategori", kategoriSelected.trim());
formData.append("nama_lokasi", lokasiSelected.trim());
formData.append("status_barang", kondisiFisik === "Baik / Layak" ? "Baik" : "Rusak");
formData.append("status_barang", kondisiFisik);
formData.append("stok", stokAwal);
if (tipeUpload === "file" && fotoBarang) {
@ -195,8 +195,10 @@ export default function TambahBarang({ onRefresh }: TambahBarangProps) {
className="w-full p-3 text-sm rounded-xl border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-800 dark:text-white outline-none focus:border-blue-500"
>
<option value="">-- Pilih --</option>
<option value="Baik / Layak">Baik / Layak</option>
<option value="Rusak">Rusak</option>
<option value="Baik">Baik</option>
<option value="Rusak Ringan">Rusak Ringan</option>
<option value="Rusak Berat">Rusak Berat</option>
<option value="Hilang">Hilang</option>
</select>
</div>

View File

@ -37,7 +37,7 @@ const menuItems = [
},
{
name: "Transaksi BAST",
name: "BAST",
path: "/dashboard/transaksi-bast",
icon: <FileText size={20} />,
},

View File

@ -188,7 +188,7 @@ export default function TransaksiBAST() {
<div className="flex justify-between items-center mb-8">
<div>
<h1 className="text-4xl font-bold dark:text-white">
Transaksi BAST
BAST
</h1>
<p className="text-gray-500 dark:text-gray-300 mt-2">
Data serah terima barang logistik resmi perusahaan & sekolah.

View File

@ -1,7 +1,7 @@
// src/routes/MasterData.tsx
import { useState, useEffect } from "react";
import axios from "axios";
import { Plus, Pencil, Loader2, PackageX } from "lucide-react";
import { Plus, Pencil, Loader2, PackageX, Search } from "lucide-react";
// COMPONENTS
import BarangHero from "../components/masterData/BarangHero";
@ -27,6 +27,12 @@ export default function MasterData() {
const [barangList, setBarangList] = useState<BarangType[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [selectedQr, setSelectedQr] = useState<string | null>(null);
const [searchQuery, setSearchQuery] = useState("");
const uniqueCategories = [
"Semua",
...Array.from(new Set(barangList.map((b) => b.nama_kategori).filter((k): k is string => !!k))),
];
const muatDataBarang = async () => {
setLoading(true);
@ -52,8 +58,10 @@ export default function MasterData() {
}, []);
const filteredBarang = barangList.filter((barang) => {
if (selectedKategori === "Semua") return true;
return barang.nama_kategori?.toLowerCase() === selectedKategori.toLowerCase();
const matchKategori = selectedKategori === "Semua" || barang.nama_kategori?.toLowerCase() === selectedKategori.toLowerCase();
const matchSearch = barang.nama_barang.toLowerCase().includes(searchQuery.toLowerCase()) ||
barang.kode_barang.toLowerCase().includes(searchQuery.toLowerCase());
return matchKategori && matchSearch;
});
const handleSaveSuccess = () => {
@ -102,21 +110,38 @@ export default function MasterData() {
</div>
)}
{/* 3. FILTER KATEGORI BARANG */}
<div className="flex gap-2 overflow-x-auto pb-2 pt-2">
{["Semua", "Elektronik", "Buku dan Modul", "Alat Tulis"].map((kat) => (
<button
key={kat}
onClick={() => setSelectedKategori(kat)}
className={`px-5 py-2.5 rounded-xl font-semibold transition text-sm ${
selectedKategori === kat
? "bg-blue-600 text-white shadow-sm"
: "bg-white text-gray-600 hover:bg-gray-50 border border-gray-200"
}`}
>
{kat}
</button>
))}
{/* 3. FILTER KATEGORI & PENCARIAN BARANG */}
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4 pb-2 pt-2">
{/* Kategori Filter */}
<div className="flex gap-2 overflow-x-auto">
{uniqueCategories.map((kat) => (
<button
key={kat}
onClick={() => setSelectedKategori(kat)}
className={`px-5 py-2.5 rounded-xl font-semibold transition text-sm whitespace-nowrap ${
selectedKategori === kat
? "bg-blue-600 text-white shadow-sm"
: "bg-white text-gray-600 hover:bg-gray-50 border border-gray-200"
}`}
>
{kat}
</button>
))}
</div>
{/* Search Bar */}
<div className="relative w-full md:w-72 shrink-0">
<div className="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
<Search size={18} className="text-gray-400" />
</div>
<input
type="text"
placeholder="Cari nama atau kode barang..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="w-full pl-11 pr-4 py-2.5 bg-white border border-gray-200 rounded-xl text-sm outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 transition-all text-gray-800"
/>
</div>
</div>
{/* 4. GRID DAFTAR INVENTARIS UTAMA */}