import { useEffect, useState } from 'react'; import { useNavigate, useParams, useLocation } from 'react-router-dom'; import { Divider, Typography, Button, Steps, Form, Row, Col, Card, Spin, Modal, ConfigProvider } from 'antd'; import { NotifAlert, NotifOk } from '../../../components/Global/ToastNotif'; import { useBreadcrumb } from '../../../layout/LayoutBreadcrumb'; import { getBrandById, updateBrand } from '../../../api/master-brand'; import { getFileUrl } from '../../../api/file-uploads'; import BrandForm from './component/BrandForm'; import ErrorCodeSimpleForm from './component/ErrorCodeSimpleForm'; import SolutionForm from './component/SolutionForm'; import SparepartForm from './component/SparepartForm'; import ErrorCodeListModal from './component/ErrorCodeListModal'; import FormActions from './component/FormActions'; import { useErrorCodeLogic } from './hooks/errorCode'; import { useSolutionLogic } from './hooks/solution'; import { useSparepartLogic } from './hooks/sparepart'; const { Title } = Typography; const { Step } = Steps; const defaultData = { brand_name: '', brand_type: '', brand_model: '', brand_manufacture: '', is_active: true, brand_code: '', }; const EditBrandDevice = () => { const navigate = useNavigate(); const { id } = useParams(); const location = useLocation(); const { setBreadcrumbItems } = useBreadcrumb(); const [brandForm] = Form.useForm(); const [errorCodeForm] = Form.useForm(); const [confirmLoading, setConfirmLoading] = useState(false); const [currentStep, setCurrentStep] = useState(0); const [fileList, setFileList] = useState([]); const [isErrorCodeFormReadOnly, setIsErrorCodeFormReadOnly] = useState(false); const [editingErrorCodeKey, setEditingErrorCodeKey] = useState(null); const [loading, setLoading] = useState(true); const [formData, setFormData] = useState(defaultData); const [errorCodes, setErrorCodes] = useState([]); const [errorCodeIcon, setErrorCodeIcon] = useState(null); const [showErrorCodeModal, setShowErrorCodeModal] = useState(false); const [sparepartImages, setSparepartImages] = useState({}); const [solutionForm] = Form.useForm(); const [sparepartForm] = Form.useForm(); const { errorCodeFields, addErrorCode, removeErrorCode, editErrorCode, } = useErrorCodeLogic(errorCodeForm, fileList); const { solutionFields, solutionTypes, solutionStatuses, handleAddSolutionField, handleRemoveSolutionField, handleSolutionTypeChange, handleSolutionStatusChange, resetSolutionFields, getSolutionData, setSolutionsForExistingRecord, } = useSolutionLogic(solutionForm); const { sparepartFields, sparepartTypes, sparepartStatuses, handleAddSparepartField, handleRemoveSparepartField, handleSparepartTypeChange, handleSparepartStatusChange, resetSparepartFields, getSparepartData, setSparepartForExistingRecord, } = useSparepartLogic(sparepartForm); // Handlers for sparepart image upload const handleSparepartImageUpload = (fieldKey, imageData) => { setSparepartImages(prev => ({ ...prev, [fieldKey]: imageData })); }; const handleSparepartImageRemove = (fieldKey) => { setSparepartImages(prev => { const newImages = { ...prev }; delete newImages[fieldKey]; return newImages; }); }; useEffect(() => { const fetchBrandData = async () => { const token = localStorage.getItem('token'); if (!token) { navigate('/signin'); return; } const savedPhase = location.state?.phase || localStorage.getItem(`brand_device_edit_${id}_last_phase`); if (savedPhase) { setCurrentStep(parseInt(savedPhase)); localStorage.removeItem(`brand_device_edit_${id}_last_phase`); } setBreadcrumbItems([ { title: • Master }, { title: ( navigate('/master/brand-device')} > Brand Device ), }, { title: ( Edit Brand Device ), }, ]); try { setLoading(true); const response = await getBrandById(id); if (response && response.statusCode === 200) { const brandData = response.data; const newFormData = { brand_name: brandData.brand_name, brand_type: brandData.brand_type, brand_model: brandData.brand_model, brand_manufacture: brandData.brand_manufacture, is_active: brandData.is_active, brand_code: brandData.brand_code, }; const existingErrorCodes = brandData.error_code ? brandData.error_code.map((ec, index) => ({ key: `existing-${ec.error_code_id}`, error_code_id: ec.error_code_id, error_code: ec.error_code, error_code_name: ec.error_code_name || '', error_code_description: ec.error_code_description || '', error_code_color: ec.error_code_color || '#000000', path_icon: ec.path_icon || '', status: ec.is_active, solution: ec.solution || [], errorCodeIcon: ec.path_icon ? { name: 'icon', uploadPath: ec.path_icon, url: (() => { const pathParts = ec.path_icon.split('/'); const folder = pathParts[0]; const filename = pathParts.slice(1).join('/'); return getFileUrl(folder, filename); })(), type_solution: 'image' } : null, })) : []; setFormData(newFormData); brandForm.setFieldsValue(newFormData); setErrorCodes(existingErrorCodes); } else { NotifAlert({ icon: 'error', title: 'Error', message: response?.message || 'Failed to fetch brand device data', }); } } catch (error) { NotifAlert({ icon: 'error', title: 'Error', message: error.message || 'Failed to fetch brand device data', }); } finally { setLoading(false); } }; fetchBrandData(); }, [id, setBreadcrumbItems, navigate, brandForm, location]); const handleCancel = () => { localStorage.removeItem(`brand_device_edit_${id}_temp_data`); navigate('/master/brand-device'); }; const handleNextStep = async () => { try { await brandForm.validateFields(); setCurrentStep(1); } catch (error) { NotifAlert({ icon: 'warning', title: 'Perhatian', message: 'Harap isi semua kolom wajib untuk brand device!', }); } }; const handleFinish = async () => { setConfirmLoading(true); try { // Get current solution and sparepart data from forms const currentSolutionData = getSolutionData(); const currentSparepartData = getSparepartData(); const finalFormData = { brand_name: formData.brand_name, brand_type: formData.brand_type || '', brand_model: formData.brand_model || '', brand_manufacture: formData.brand_manufacture, is_active: formData.is_active, error_code: errorCodes.map((ec) => { // If editing current error code, get latest data from forms if (ec.key === editingErrorCodeKey) { return { error_code: ec.error_code, error_code_name: ec.error_code_name || '', error_code_description: ec.error_code_description || '', error_code_color: ec.error_code_color || '#000000', path_icon: ec.errorCodeIcon?.uploadPath || ec.path_icon || '', is_active: ec.status !== undefined ? ec.status : true, solution: currentSolutionData.map((sol) => ({ solution_name: sol.solution_name, type_solution: sol.type_solution, text_solution: sol.text_solution || '', path_solution: sol.path_solution || '', is_active: sol.is_active !== false, })), sparepart: currentSparepartData.map((sp) => ({ name: sp.name, description: sp.description || '', is_active: sp.is_active !== false, sparepart_image: sparepartImages[sp.key || sp.id] || null, })), }; } // Return existing data for other error codes return { error_code: ec.error_code, error_code_name: ec.error_code_name || '', error_code_description: ec.error_code_description || '', error_code_color: ec.error_code_color || '#000000', path_icon: ec.errorCodeIcon?.uploadPath || ec.path_icon || '', is_active: ec.status !== undefined ? ec.status : true, solution: (ec.solution || []).map((sol) => ({ solution_name: sol.solution_name, type_solution: sol.type_solution, text_solution: sol.text_solution || '', path_solution: sol.path_solution || '', is_active: sol.is_active !== false, })), sparepart: (ec.sparepart || []).map((sp) => ({ name: sp.name, description: sp.description || '', is_active: sp.is_active !== false, sparepart_image: sp.sparepart_image || null, })), }; }), }; const response = await updateBrand(id, finalFormData); if (response && (response.statusCode === 200 || response.statusCode === 201)) { localStorage.removeItem(`brand_device_edit_${id}_temp_data`); NotifOk({ icon: 'success', title: 'Berhasil', message: response.message || 'Brand Device dan Error Codes berhasil diupdate.', }); navigate('/master/brand-device'); } else { NotifAlert({ icon: 'error', title: 'Gagal', message: response?.message || 'Gagal mengupdate Brand Device', }); } } catch (error) { NotifAlert({ icon: 'error', title: 'Gagal', message: error.message || 'Gagal mengupdate data. Silakan coba lagi.', }); } finally { setConfirmLoading(false); } }; const handlePreviewErrorCode = (record) => { errorCodeForm.setFieldsValue({ error_code: record.error_code, error_code_name: record.error_code_name, error_code_description: record.error_code_description, error_code_color: record.error_code_color, status: record.status, }); setErrorCodeIcon(record.errorCodeIcon || null); setIsErrorCodeFormReadOnly(true); setEditingErrorCodeKey(record.key); if (record.solution && record.solution.length > 0) { setSolutionsForExistingRecord(record.solution, errorCodeForm); } }; const handleEditErrorCode = (record) => { errorCodeForm.setFieldsValue({ error_code: record.error_code, error_code_name: record.error_code_name, error_code_description: record.error_code_description, error_code_color: record.error_code_color, status: record.status, }); setErrorCodeIcon(record.errorCodeIcon || null); setIsErrorCodeFormReadOnly(false); setEditingErrorCodeKey(record.key); // Load solutions to solution form if (record.solution && record.solution.length > 0) { setSolutionsForExistingRecord(record.solution, solutionForm); } // Load spareparts to sparepart form if (record.sparepart && record.sparepart.length > 0) { setSparepartForExistingRecord(record.sparepart, sparepartForm); // Load sparepart images const newSparepartImages = {}; record.sparepart.forEach(sparepart => { if (sparepart.sparepart_image) { newSparepartImages[sparepart.id || sparepart.key] = sparepart.sparepart_image; } }); setSparepartImages(newSparepartImages); } const formElement = document.querySelector('.ant-form'); if (formElement) { formElement.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }; const handleAddErrorCode = (newErrorCode) => { // Include the current icon in the error code const errorCodeWithIcon = { ...newErrorCode, errorCodeIcon: errorCodeIcon }; let updatedErrorCodes; if (editingErrorCodeKey) { updatedErrorCodes = errorCodes.map((item) => item.key === editingErrorCodeKey ? errorCodeWithIcon : item ); NotifOk({ icon: 'success', title: 'Berhasil', message: 'Error code berhasil diupdate!', }); } else { updatedErrorCodes = [...errorCodes, errorCodeWithIcon]; NotifOk({ icon: 'success', title: 'Berhasil', message: 'Error code berhasil ditambahkan!', }); } setErrorCodes(updatedErrorCodes); resetErrorCodeForm(); }; const resetErrorCodeForm = () => { errorCodeForm.resetFields(); errorCodeForm.setFieldsValue({ status: true, solution_status_0: true, solution_type_0: 'text', }); setFileList([]); setErrorCodeIcon(null); resetSolutionFields(); setIsErrorCodeFormReadOnly(false); setEditingErrorCodeKey(null); }; const handleDeleteErrorCode = async (key) => { if (errorCodes.length <= 1) { NotifAlert({ icon: 'warning', title: 'Perhatian', message: 'Setiap brand harus memiliki minimal 1 error code!', }); return; } const updatedErrorCodes = errorCodes.filter((item) => item.key !== key); setErrorCodes(updatedErrorCodes); NotifOk({ icon: 'success', title: 'Berhasil', message: 'Error code berhasil dihapus!', }); }; const handleCreateNewErrorCode = () => { resetErrorCodeForm(); resetSolutionFields(); resetSparepartFields(); setErrorCodeIcon(null); setSparepartImages({}); setIsErrorCodeFormReadOnly(false); setEditingErrorCodeKey(null); }; const handleErrorCodeIconUpload = (iconData) => { setErrorCodeIcon(iconData); }; const handleErrorCodeIconRemove = () => { setErrorCodeIcon(null); }; const handleFileView = (pathSolution, fileType) => { localStorage.setItem(`brand_device_edit_${id}_last_phase`, currentStep.toString()); const tempData = { errorCodes: errorCodes, fileList: fileList, solutionFields: solutionFields, solutionTypes: solutionTypes, solutionStatuses: solutionStatuses, editingErrorCodeKey: editingErrorCodeKey, isErrorCodeFormReadOnly: isErrorCodeFormReadOnly, solutionsToDelete: Array.from(solutionsToDelete), currentSolutionData: window.currentSolutionData || {}, }; localStorage.setItem(`brand_device_edit_${id}_temp_data`, JSON.stringify(tempData)); const filePath = pathSolution || ''; if (!filePath) return; const parts = filePath.split('/'); if (parts.length < 2) return; const [folder, filename] = parts; const encodedFileName = encodeURIComponent(filename); const navigationPath = `/master/brand-device/edit/${id}/files/${folder}/${encodedFileName}`; navigate(navigationPath); }; const handleSolutionFileUpload = (file) => { setFileList((prevList) => [...prevList, file]); }; const handleFileRemove = (file) => { const newFileList = fileList.filter((item) => item.uid !== file.uid); setFileList(newFileList); }; const renderStepContent = () => { if (currentStep === 0) { return ( setFormData((prev) => ({ ...prev, ...allValues })) } isEdit={true} /> ); } if (currentStep === 1) { return ( <> {isErrorCodeFormReadOnly ? editingErrorCodeKey ? 'View Error Code' : 'Error Code Form' : editingErrorCodeKey ? 'Edit Error Code' : 'Tambah Error Code'} } size="small" >
Solutions} size="small" >
Spareparts} size="small" >
{/* Error Codes List Button */} {/* Error Codes List Modal */} setShowErrorCodeModal(false)} errorCodes={errorCodes} loading={loading} onPreview={handlePreviewErrorCode} onEdit={handleEditErrorCode} onDelete={handleDeleteErrorCode} onAddNew={handleCreateNewErrorCode} /> ); } return null; }; return ( Edit Brand Device
{loading && (
)}
{renderStepContent()}
setCurrentStep(currentStep - 1)} onNextStep={handleNextStep} onSave={handleFinish} onCancel={handleCancel} confirmLoading={confirmLoading} isEditMode={true} />
); }; export default EditBrandDevice;