diff --git a/src/components/masterData/TambahBarang.tsx b/src/components/masterData/TambahBarang.tsx index be0a8f6..297ccb1 100644 --- a/src/components/masterData/TambahBarang.tsx +++ b/src/components/masterData/TambahBarang.tsx @@ -1,4 +1,5 @@ // src/components/masterData/TambahBarang.tsx + import React, { useState, useEffect } from "react"; import axios from "axios"; import { PlusCircle, Image } from "lucide-react"; @@ -12,14 +13,42 @@ export default function TambahBarang({ onClose, onRefresh, }: TambahBarangProps) { + // STATE INPUT FORM const [kodeBarang, setKodeBarang] = useState(""); const [namaBarang, setNamaBarang] = useState(""); + + // BISA PILIH / KETIK SENDIRI const [kategoriSelected, setKategoriSelected] = useState(""); const [lokasiSelected, setLokasiSelected] = useState(""); + const [kondisiFisik, setKondisiFisik] = useState(""); const [stokAwal, setStokAwal] = useState(""); + // LIST DINAMIS + const [kategoriList, setKategoriList] = useState([ + "Elektronik", + "Alat Tulis", + "Kebersihan", + "Mebel dan Furnitur", + "Perangkat Jaringan", + "Peralatan Operasional", + "Peralatan Bengkel", + "Buku dan Modul", + ]); + + const [lokasiList, setLokasiList] = useState([ + "Gudang Pusat", + "Lab PPLG", + "Lab TKJ", + "X PPLG", + "XI PPLG", + "XII PPLG", + "X TKJ", + "XI TKJ", + "XII TKJ", + ]); + // FILE FOTO const [fotoBarang, setFotoBarang] = useState(null); @@ -34,37 +63,34 @@ export default function TambahBarang({ // LOGIKA KODE OTOMATIS useEffect(() => { if (kategoriSelected && lokasiSelected) { - const inisialKategori: { [key: string]: string } = { - Elektronik: "ELK", - "Alat Tulis": "ATK", - Kebersihan: "KBR", - "Mebel dan Furnitur": "MUB", - "Perangkat Jaringan": "JRG", - "Peralatan Operasional": "OPR", - "Peralatan Bengkel": "PBG", - "Buku dan Modul": "BKM", + + // AMBIL INISIAL OTOMATIS + const ambilInisial = (text: string) => { + const kata = text + .replace(/[^a-zA-Z0-9 ]/g, "") + .toUpperCase() + .split(" ") + .filter(Boolean); + + if (kata.length >= 2) { + return ( + kata[0].substring(0, 2) + + kata[1].substring(0, 1) + ); + } + + return kata[0]?.substring(0, 3) || "BRG"; }; - const inisialLokasi: { [key: string]: string } = { - "Gudang Pusat": "GUD", - "Lab PPLG": "LAB-PPLG", - "Lab TKJ": "LAB-TKJ", - "X PPLG": "KLS-X-PPLG", - "XI PPLG": "KLS-XI-PPLG", - "XII PPLG": "KLS-XII-PPLG", - "X TKJ": "KLS-X-TKJ", - "XI TKJ": "KLS-XI-TKJ", - "XII TKJ": "KLS-XII-TKJ", - }; - - const kat = inisialKategori[kategoriSelected] || "BRG"; - const lok = inisialLokasi[lokasiSelected] || "GUD"; + const kat = ambilInisial(kategoriSelected); + const lok = ambilInisial(lokasiSelected); const nomorUrut = String( Math.floor(100 + Math.random() * 900) ); setKodeBarang(`${kat}/${lok}/${nomorUrut}`); + } else { setKodeBarang(""); } @@ -74,7 +100,9 @@ export default function TambahBarang({ const handleFileChange = ( e: React.ChangeEvent ) => { + if (e.target.files && e.target.files[0]) { + const file = e.target.files[0]; setFotoBarang(file); @@ -83,7 +111,7 @@ export default function TambahBarang({ setPreviewUrl(localPreview); - // RESET LINK KALAU PAKAI FILE + // RESET LINK setFotoLink(""); } }; @@ -92,25 +120,27 @@ export default function TambahBarang({ const handleLinkChange = ( e: React.ChangeEvent ) => { + const value = e.target.value; setFotoLink(value); - // PREVIEW DARI LINK + // PREVIEW LINK setPreviewUrl(value); - // RESET FILE KALAU PAKAI LINK + // RESET FILE setFotoBarang(null); }; const handleSimpanKeDB = async ( e: React.FormEvent ) => { + e.preventDefault(); if (!kodeBarang) { alert( - "Pilih Kategori dan Lokasi dulu agar kode barang tercipta otomatis!" + "Pilih / ketik kategori dan lokasi dulu!" ); return; } @@ -121,23 +151,33 @@ export default function TambahBarang({ } if (!kondisiFisik) { - alert("Silakan pilih Kondisi Fisik dulu!"); + alert("Silakan pilih kondisi fisik!"); return; } if (!stokAwal) { - alert("Stok awal jangan dikosongkan!"); + alert("Stok awal jangan kosong!"); return; } // VALIDASI FOTO if (!fotoBarang && !fotoLink) { alert( - "Foto barang wajib dipilih atau menggunakan link online!" + "Foto barang wajib dipilih atau pakai link!" ); return; } + const formData = new FormData(); + + formData.append("kode_barang", kodeBarang); + + formData.append( + "nama_barang", + namaBarang.trim() + ); + + // WAJIB BACKEND LAMA const kategoriMapping: { [key: string]: number } = { Elektronik: 1, "Alat Tulis": 7, @@ -161,19 +201,33 @@ export default function TambahBarang({ "XII TKJ": 338, }; - const formData = new FormData(); + // KALAU INPUT BARU BELUM ADA + const kategoriId = + kategoriMapping[kategoriSelected] || 999; - formData.append("kode_barang", kodeBarang); - formData.append("nama_barang", namaBarang.trim()); + const lokasiId = + lokasiMapping[lokasiSelected] || 999; + // BACKEND LAMA formData.append( "kategori_id", - String(kategoriMapping[kategoriSelected] || 1) + String(kategoriId) ); formData.append( "lokasi_id", - String(lokasiMapping[lokasiSelected] || 1) + String(lokasiId) + ); + + // TAMBAHAN BARU + formData.append( + "nama_kategori", + kategoriSelected + ); + + formData.append( + "nama_lokasi", + lokasiSelected ); formData.append( @@ -183,19 +237,29 @@ export default function TambahBarang({ : "Rusak" ); - formData.append("stok", stokAwal); + formData.append( + "stok", + stokAwal + ); // FILE FOTO if (fotoBarang) { - formData.append("foto_barang", fotoBarang); + formData.append( + "foto_barang", + fotoBarang + ); } // LINK FOTO if (fotoLink) { - formData.append("foto_link", fotoLink); + formData.append( + "foto_link", + fotoLink + ); } try { + setLoading(true); const res = await axios.post( @@ -214,6 +278,29 @@ export default function TambahBarang({ res.status === 200 || res.status === 201 ) { + + // AUTO TAMBAH KE LIST KATEGORI + if ( + kategoriSelected && + !kategoriList.includes(kategoriSelected) + ) { + setKategoriList((prev) => [ + ...prev, + kategoriSelected, + ]); + } + + // AUTO TAMBAH KE LIST LOKASI + if ( + lokasiSelected && + !lokasiList.includes(lokasiSelected) + ) { + setLokasiList((prev) => [ + ...prev, + lokasiSelected, + ]); + } + alert( `Sukses! Barang terdaftar dengan kode ${kodeBarang}` ); @@ -231,23 +318,30 @@ export default function TambahBarang({ if (onRefresh) onRefresh(); if (onClose) onClose(); } + } catch (err: any) { + console.error(err); alert( err.response?.data?.message || - "Gagal menyimpan barang!" + "Gagal menyimpan barang!" ); + } finally { + setLoading(false); + } }; return (
+
+

Input Inventaris Baru

@@ -260,20 +354,25 @@ export default function TambahBarang({ ✕ )} +
+ {/* FOTO */}
+
+
@@ -291,10 +391,12 @@ export default function TambahBarang({ ? fotoBarang.name : "Belum ada file terpilih"}
+
{/* INPUT LINK FOTO */}
+ +
{/* PREVIEW */} {previewUrl && (
+ Preview +
)} +
{/* KATEGORI & LOKASI */}
+ {/* KATEGORI */}
+ -
+ {/* LOKASI */}
+ -
+
{/* KODE */}
+ @@ -442,10 +502,12 @@ export default function TambahBarang({ value={kodeBarang} className="w-full p-3 rounded-xl border border-gray-200 bg-gray-100 dark:bg-gray-900 font-mono font-bold text-blue-600 outline-none cursor-not-allowed" /> +
{/* NAMA */}
+ @@ -461,12 +523,14 @@ export default function TambahBarang({ } className="w-full p-3 rounded-xl border border-gray-300 dark:border-gray-600 dark:bg-gray-700 outline-none focus:border-blue-500" /> +
{/* KONDISI & STOK */}
+ @@ -480,6 +544,7 @@ export default function TambahBarang({ } className="w-full p-3 rounded-xl border border-gray-300 dark:border-gray-600 dark:bg-gray-700 outline-none focus:border-blue-500 bg-white text-black" > + @@ -491,10 +556,13 @@ export default function TambahBarang({ + +
+ @@ -510,7 +578,9 @@ export default function TambahBarang({ } className="w-full p-3 rounded-xl border border-gray-300 dark:border-gray-600 dark:bg-gray-700 outline-none focus:border-blue-500" /> +
+
{/* BUTTON */} @@ -531,15 +601,21 @@ export default function TambahBarang({ disabled={loading} className="flex items-center gap-2 bg-blue-600 hover:bg-blue-700 text-white px-6 py-3 rounded-xl font-semibold shadow transition disabled:opacity-50" > + {loading ? "Menyimpan..." : "Simpan ke DB"} + +
+ +
+ ); } \ No newline at end of file