import { useEffect, useState } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { Card, Typography, Button, Form, Row, Col, Spin, Upload, } from 'antd'; import { ArrowLeftOutlined, UploadOutlined } from '@ant-design/icons'; import { getBrandById, getErrorCodeById, updateBrand, getErrorCodesByBrandId } from '../../../api/master-brand'; import { useBreadcrumb } from '../../../layout/LayoutBreadcrumb'; import { useBrandForm } from '../../../context/BrandFormContext'; import { uploadFile } from '../../../api/file-uploads'; import ErrorCodeSimpleForm from './component/ErrorCodeSimpleForm'; import SolutionForm from './component/SolutionForm'; import { useSolutionLogic } from './hooks/solution'; import SingleSparepartSelect from './component/SingleSparepartSelect'; import { NotifAlert, NotifOk } from '../../../components/Global/ToastNotif'; const { Title } = Typography; const AddEditErrorCode = () => { const navigate = useNavigate(); const { brandId: routeBrandId, errorCodeId } = useParams(); const { setBreadcrumbItems } = useBreadcrumb(); // Use BrandForm context const { brandId: contextBrandId, routeBrandId: contextRouteBrandId, setRouteBrandId, setErrorCodeId, initializeFromRoute, tempErrorCodes, existingErrorCodes, addErrorCode, updateErrorCode, setCurrentErrorCode } = useBrandForm(); // Use brandId from context first, fallback to route const currentBrandId = contextBrandId || routeBrandId; // Forms const [errorCodeForm] = Form.useForm(); const [solutionForm] = Form.useForm(); const [loading, setLoading] = useState(false); const [confirmLoading, setConfirmLoading] = useState(false); const [errorCodeIcon, setErrorCodeIcon] = useState(null); const [selectedSparepartIds, setSelectedSparepartIds] = useState([]); const [isEdit, setIsEdit] = useState(false); const [fileList, setFileList] = useState([]); const { solutionFields, solutionTypes, solutionStatuses, solutionsToDelete, firstSolutionValid, handleAddSolutionField, handleRemoveSolutionField, handleSolutionTypeChange, handleSolutionStatusChange, resetSolutionFields, getSolutionData, setSolutionsForExistingRecord, } = useSolutionLogic(solutionForm); useEffect(() => { const isEditMode = errorCodeId && errorCodeId !== 'add'; setIsEdit(isEditMode); // Initialize context with route parameters if (routeBrandId) { initializeFromRoute(routeBrandId, errorCodeId); } setBreadcrumbItems([ { title: • Master }, { title: ( navigate('/master/brand-device')} > Brand Device ), }, { title: ( navigate(`/master/brand-device/edit/${currentBrandId}?tab=error-codes`)} > Edit Brand Device ), }, { title: ( {isEditMode ? 'Edit Error Code' : 'Add Error Code'} ), }, ]); if (isEditMode && errorCodeId) { // For existing error codes, construct the proper tempId format const tempId = errorCodeId.startsWith('existing_') ? errorCodeId : `existing_${errorCodeId}`; loadExistingErrorCode(tempId); } }, [currentBrandId, errorCodeId, navigate, setBreadcrumbItems]); const loadExistingErrorCode = async (tempId) => { try { setLoading(true); // console.log(' Looking for error code with tempId:', tempId); // console.log(' Available error codes in context:', tempErrorCodes); // Find error code in tempErrorCodes first let existingErrorCode = tempErrorCodes.find(ec => ec.tempId === tempId); // If not found, check in existingErrorCodes with format existing_${error_code_id} if (!existingErrorCode && tempId.startsWith('existing_')) { const errorId = tempId.replace('existing_', ''); existingErrorCode = existingErrorCodes.find(ec => ec.error_code_id == errorId); if (existingErrorCode) { existingErrorCode = { ...existingErrorCode, tempId: tempId }; } } // console.log(' Found error code in context:', existingErrorCode); if (existingErrorCode) { errorCodeForm.setFieldsValue({ error_code: existingErrorCode.error_code, error_code_name: existingErrorCode.error_code_name || '', error_code_description: existingErrorCode.error_code_description || '', error_code_color: existingErrorCode.error_code_color || '#000000', status: existingErrorCode.is_active !== false, }); if (existingErrorCode.path_icon) { setErrorCodeIcon({ name: existingErrorCode.path_icon.split('/').pop(), uploadPath: existingErrorCode.path_icon, url: existingErrorCode.path_icon, }); } if (existingErrorCode.solution && existingErrorCode.solution.length > 0) { // console.log('🔍 Setting solutions from context:', existingErrorCode.solution); setSolutionsForExistingRecord(existingErrorCode.solution, solutionForm); } if (existingErrorCode.spareparts && existingErrorCode.spareparts.length > 0) { // console.log('🔍 Setting spareparts from context:', existingErrorCode.spareparts); setSelectedSparepartIds(existingErrorCode.spareparts); } } else { // console.log('🔍 Error code not found in context, trying API...'); let errorIdToUse = tempId; // Extract the actual error_code_id from tempId format if (tempId.startsWith('existing_')) { errorIdToUse = tempId.replace('existing_', ''); } const errorCodeResponse = await getErrorCodeById(errorIdToUse); if (errorCodeResponse && errorCodeResponse.statusCode === 200) { const errorData = errorCodeResponse.data; if (errorData) { errorCodeForm.setFieldsValue({ error_code: errorData.error_code, error_code_name: errorData.error_code_name || '', error_code_description: errorData.error_code_description || '', error_code_color: errorData.error_code_color || '#000000', status: errorData.is_active !== false, }); if (errorData.path_icon) { setErrorCodeIcon({ name: errorData.path_icon.split('/').pop(), uploadPath: errorData.path_icon, url: errorData.path_icon, }); } // Set solutions from API data (include file data) if (errorData.solution && errorData.solution.length > 0) { setSolutionsForExistingRecord(errorData.solution, solutionForm); } // Set spareparts from API data if (errorData.spareparts && errorData.spareparts.length > 0) { const sparepartIds = errorData.spareparts.map(sp => sp.sparepart_id); setSelectedSparepartIds(sparepartIds); } // Don't add to context - this is existing data from API // The context should already have this error code from the brand data loading } } else { // console.log('🔍 API Response error or not found:', errorCodeResponse); errorCodeForm.setFieldsValue({ error_code: '', error_code_name: '', error_code_description: '', error_code_color: '#000000', status: true, }); NotifAlert({ icon: 'warning', title: 'Peringatan', message: 'Error code not found. Creating new error code.', }); } } } catch (error) { console.error('Failed to load error code:', error); NotifAlert({ icon: 'error', title: 'Error', message: 'Failed to load error code data', }); } finally { setLoading(false); } }; const handleSave = async () => { try { await errorCodeForm.validateFields(); const solutionValues = solutionForm.getFieldsValue(); const firstSolutionPath = `solution_items,${solutionFields[0]?.key || 0}`; const firstSolution = solutionValues[firstSolutionPath]; let isValid = false; if (firstSolution && firstSolution.name && firstSolution.name.trim() !== '') { const firstSolutionType = solutionTypes[solutionFields[0]?.key || 0]; if (firstSolutionType === 'text') { isValid = firstSolution.text && firstSolution.text.trim() !== ''; } else { isValid = true; } } if (!isValid) { NotifAlert({ icon: 'warning', title: 'Perhatian', message: 'Harap lengkapi minimal 1 solution', }); return; } const errorCodeValues = errorCodeForm.getFieldsValue(); const solutionData = getSolutionData(); // Determine the correct tempId for editing let updateTempId; if (isEdit) { // For existing error codes, find the correct tempId if (errorCodeId && !errorCodeId.startsWith('pending-')) { // Look for existing error code in context const existingEc = existingErrorCodes.find(ec => ec.error_code_id == errorCodeId); if (existingEc && existingEc.tempId) { updateTempId = existingEc.tempId; } else { updateTempId = `existing_${errorCodeId}`; } } else { updateTempId = errorCodeId; } } else { updateTempId = Date.now().toString(); } const currentErrorCode = { tempId: updateTempId, error_code_id: isEdit && errorCodeId && !errorCodeId.startsWith('pending-') ? errorCodeId : null, error_code: errorCodeValues.error_code || '', error_code_name: errorCodeValues.error_code_name || '', error_code_description: errorCodeValues.error_code_description || '', error_code_color: errorCodeValues.error_code_color || '#000000', path_icon: errorCodeIcon?.uploadPath || '', is_active: errorCodeValues.status !== undefined ? errorCodeValues.status : true, solution: solutionData || [], spareparts: selectedSparepartIds || [], errorCodeIcon: errorCodeIcon, }; if (isEdit) { updateErrorCode(updateTempId, currentErrorCode); } else { addErrorCode(currentErrorCode); } NotifOk({ icon: 'success', title: 'Berhasil', message: isEdit ? 'Error Code berhasil diupdate!' : 'Error Code berhasil ditambahkan!', }); navigate(`/master/brand-device/edit/${currentBrandId}?tab=error-codes`); } catch (error) { console.error('Error saving error code:', error); NotifAlert({ icon: 'error', title: 'Error', message: 'Gagal menyimpan error code. Silakan coba lagi.', }); } }; const handleCancel = () => { navigate(`/master/brand-device/edit/${currentBrandId}?tab=error-codes`); }; const handleErrorCodeIconUpload = async (file) => { if (!file) return null; try { const folder = 'images'; const response = await uploadFile(file, folder); if (response && response.statusCode === 200) { const iconData = { name: file.name, uploadPath: response.data.path_document, url: response.data.path_document, }; setErrorCodeIcon(iconData); NotifOk({ icon: 'success', title: 'Berhasil', message: 'Error code icon uploaded successfully', }); return iconData; } else { NotifAlert({ icon: 'error', title: 'Gagal', message: response?.message || 'Failed to upload error code icon', }); return null; } } catch (error) { console.error('Error uploading icon:', error); NotifAlert({ icon: 'error', title: 'Gagal', message: 'Failed to upload error code icon', }); return null; } }; const handleErrorCodeIconRemove = () => { setErrorCodeIcon(null); }; const handleSolutionFileUpload = async (file, solutionKey) => { if (!file) return null; try { // Determine folder based on file type const fileExtension = file.name.split('.').pop().toLowerCase(); const folder = ['pdf'].includes(fileExtension) ? 'pdf' : 'images'; const response = await uploadFile(file, folder); if (response && response.statusCode === 200) { const fileData = { name: file.name, uploadPath: response.data.path_document, url: response.data.path_document, size: file.size, type: file.type, }; NotifOk({ icon: 'success', title: 'Berhasil', message: 'Solution file uploaded successfully', }); return fileData; } else { NotifAlert({ icon: 'error', title: 'Gagal', message: response?.message || 'Failed to upload solution file', }); return null; } } catch (error) { console.error('Error uploading solution file:', error); NotifAlert({ icon: 'error', title: 'Gagal', message: 'Failed to upload solution file', }); return null; } }; const handleSolutionFileView = (fileData) => { if (fileData && fileData.url) { window.open(fileData.url, '_blank'); } }; const resetForm = () => { errorCodeForm.resetFields(); errorCodeForm.setFieldsValue({ status: true, }); setErrorCodeIcon(null); resetSolutionFields(); setSelectedSparepartIds([]); }; return ( {/* Header */}
{isEdit ? 'Edit Error Code' : 'Add Error Code'}
{/* Content */}
{loading && (
)} {/* Error Code Form */}
{/* Solutions Form */}
{ // console.log('🔍 checkFirstSolutionValid function:', typeof checkFirstSolutionValid); return checkFirstSolutionValid(); }} onAddSolutionField={handleAddSolutionField} onRemoveSolutionField={handleRemoveSolutionField} onSolutionTypeChange={handleSolutionTypeChange} onSolutionStatusChange={handleSolutionStatusChange} onSolutionFileUpload={handleSolutionFileUpload} onFileView={handleSolutionFileView} fileList={fileList} isReadOnly={false} />
{/* Sparepart Selection */}
{/* Save Button */}
); }; export default AddEditErrorCode;