import React, { useState } from 'react'; import dayjs from 'dayjs'; import { Card, Button, Row, Col, Typography, Divider, Tag, Space, InputNumber, Input } from 'antd'; import { EditOutlined, DeleteOutlined, PlusOutlined, MinusOutlined } from '@ant-design/icons'; import { updateSparepart } from '../../../../api/sparepart'; import { NotifAlert, NotifOk } from '../../../../components/Global/ToastNotif'; const { Text, Title } = Typography; const SparepartCardList = ({ data, header, showPreviewModal, showEditModal, showDeleteDialog, fieldColor, cardColor, onStockUpdate, // Prop to refresh the list }) => { const [updateQuantities, setUpdateQuantities] = useState({}); const [loadingQuantities, setLoadingQuantities] = useState({}); const handleQuantityChange = (id, value) => { // Prevent the adjustment from going below the negative value of the original quantity // This ensures the final quantity (original + adjustment) never goes below 0 const originalQty = data.find((item) => item.sparepart_id === id)?.sparepart_qty || 0; const maxNegativeAdjustment = -originalQty; const clampedValue = Math.max(value, maxNegativeAdjustment); const newQuantities = { ...updateQuantities }; newQuantities[id] = clampedValue; setUpdateQuantities(newQuantities); }; const handleUpdateStock = async (item) => { const quantityToAdd = updateQuantities[item.sparepart_id] || 0; if (quantityToAdd === 0) { NotifAlert({ icon: 'info', title: 'Info', message: 'Please change the quantity first.', }); return; } const currentQty = Number(item.sparepart_qty) || 0; const newQty = currentQty + quantityToAdd; if (newQty < 0) { NotifAlert({ icon: 'error', title: 'Error', message: 'Quantity cannot be negative.' }); return; } setLoadingQuantities((prev) => ({ ...prev, [item.sparepart_id]: true })); // sparepart_qty disimpan sebagai angka kuantitas (update boleh 0 sesuai validasi update schema) const payload = { sparepart_qty: newQty, sparepart_stok: newQty > 0 ? 'Available' : 'Not Available', // Otomatis tentukan status }; // Hanya tambahkan field jika nilainya tidak kosong untuk menghindari validasi error if (item.sparepart_unit && item.sparepart_unit.trim() !== '') { payload.sparepart_unit = item.sparepart_unit; } if (item.sparepart_merk && item.sparepart_merk.trim() !== '') { payload.sparepart_merk = item.sparepart_merk; } if (item.sparepart_model && item.sparepart_model.trim() !== '') { payload.sparepart_model = item.sparepart_model; } if (item.sparepart_description && item.sparepart_description.trim() !== '') { payload.sparepart_description = item.sparepart_description; } if (item.sparepart_item_type && item.sparepart_item_type !== null) { payload.sparepart_item_type = item.sparepart_item_type; } if (item.sparepart_foto && item.sparepart_foto.trim() !== '') { payload.sparepart_foto = item.sparepart_foto; } try { const response = await updateSparepart(item.sparepart_id, payload); // Periksa apakah response valid sebelum mengakses propertinya if (response && response.statusCode === 200) { NotifOk({ icon: 'success', title: 'Success', message: 'Stock updated successfully.', }); // Cek apakah qty baru kurang dari 1, tampilkan alert if (newQty < 1) { NotifAlert({ icon: 'warning', title: 'Low Stock', message: `Warning: Sparepart "${item.sparepart_name}" is out of stock. Please restock immediately.`, }); } if (onStockUpdate) { onStockUpdate(); } handleQuantityChange(item.sparepart_id, 0); // Reset quantity } else { NotifAlert({ icon: 'error', title: 'Failed', message: response?.message || 'Failed to update stock.', }); } } catch (error) { NotifAlert({ icon: 'error', title: 'Error', message: error.message || 'An error occurred.', }); } finally { setLoadingQuantities((prev) => ({ ...prev, [item.sparepart_id]: false })); } }; return ( {data.map((item) => { const quantity = updateQuantities[item.sparepart_id] || 0; const isLoading = loadingQuantities[item.sparepart_id] || false; return (
{item.sparepart_item_type && ( {item.sparepart_item_type} )}
{(() => { // Debug: log the image path construction let imgSrc; if (item.sparepart_foto) { if (item.sparepart_foto.startsWith('http')) { imgSrc = item.sparepart_foto; } else { // Gunakan format file URL seperti di brandDevice const fileName = item.sparepart_foto .split('/') .pop(); // Jika filename adalah default file, gunakan dari public assets if ( fileName === 'defaultSparepartImg.jpg' ) { imgSrc = `/assets/defaultSparepartImg.jpg`; } else { // Gunakan API getFileUrl untuk mendapatkan URL yang benar untuk file upload const token = localStorage.getItem('token'); const baseURL = import.meta.env.VITE_API_SERVER || ''; imgSrc = `${baseURL}/file-uploads/images/${encodeURIComponent( fileName )}${ token ? `?token=${encodeURIComponent( token )}` : '' }`; } } console.log( 'Image path being constructed:', imgSrc ); } else { imgSrc = 'https://via.placeholder.com/150'; } return (
{item[header]} { console.error( 'Image failed to load:', imgSrc ); e.target.src = 'https://via.placeholder.com/150'; }} onLoad={() => console.log( 'Image loaded successfully:', imgSrc ) } />
); })()}
{showEditModal && (
{item[header]} Stok: {item.sparepart_stok || 'Not Available'} Qty )}
Last updated:{' '} {item.updated_at ? dayjs(item.updated_at).format('DD MMM YYYY') : 'N/A'}
); })}
); }; export default SparepartCardList;