From 15b3339dcb708674342abd36710d365262e3ca56 Mon Sep 17 00:00:00 2001 From: Iqbal Rizqi Kurniawan Date: Fri, 17 Oct 2025 14:42:55 +0700 Subject: [PATCH] feat: refactor plant section components to use sub-section terminology and improve modal handling --- .../master/plantSection/IndexPlantSection.jsx | 15 +- .../component/DetailPlantSection.jsx | 237 +++++++++--------- .../component/ListPlantSection.jsx | 192 +++++--------- 3 files changed, 178 insertions(+), 266 deletions(-) diff --git a/src/pages/master/plantSection/IndexPlantSection.jsx b/src/pages/master/plantSection/IndexPlantSection.jsx index c3fdd8d..3ec995f 100644 --- a/src/pages/master/plantSection/IndexPlantSection.jsx +++ b/src/pages/master/plantSection/IndexPlantSection.jsx @@ -11,34 +11,31 @@ const IndexPlantSection = memo(function IndexPlantSection() { const navigate = useNavigate(); const { setBreadcrumbItems } = useBreadcrumb(); - const [activeTab, setActiveTab] = useState('plantSection'); const [actionMode, setActionMode] = useState('list'); const [selectedData, setSelectedData] = useState(null); const [readOnly, setReadOnly] = useState(false); - const [showModal, setShowmodal] = useState(false); + const [showModal, setShowModal] = useState(false); const setMode = (param) => { - setActionMode(param); + setShowModal(true); switch (param) { case 'add': setReadOnly(false); - setShowmodal(true); break; case 'edit': setReadOnly(false); - setShowmodal(true); break; case 'preview': setReadOnly(true); - setShowmodal(true); break; default: - setShowmodal(false); + setShowModal(false); break; } + setActionMode(param); }; useEffect(() => { @@ -61,8 +58,6 @@ const IndexPlantSection = memo(function IndexPlantSection() { selectedData={selectedData} setSelectedData={setSelectedData} readOnly={readOnly} - activeTab={activeTab} - setActiveTab={setActiveTab} /> { const [confirmLoading, setConfirmLoading] = useState(false); const defaultData = { - plant_section_id: '', - plantName: '', - status: true, + sub_section_id: '', + sub_section_code: '', + sub_section_name: '', + is_active: true, }; const [FormData, setFormData] = useState(defaultData); - const handleCancel = () => { - props.setSelectedData(null); - props.setActionMode('list'); - }; - - const handleSave = async () => { - setConfirmLoading(true); - - if (!FormData.plantName) { - NotifOk({ - icon: 'warning', - title: 'Peringatan', - message: 'Kolom Plant Name Tidak Boleh Kosong', - }); - setConfirmLoading(false); - return; - } - - const payload = { - plantName: FormData.plantName, - status: FormData.status, - }; - - try { - await new Promise((resolve) => setTimeout(resolve, 500)); - - const response = { - statusCode: FormData.plant_section_id ? 200 : 201, - data: { - plantName: FormData.plantName, - }, - }; - - if (response && (response.statusCode === 200 || response.statusCode === 201)) { - NotifOk({ - icon: 'success', - title: 'Berhasil', - message: `Data Plant Section "${ - response.data?.plantName || FormData.plantName - }" berhasil ${FormData.plant_section_id ? 'diubah' : 'ditambahkan'}.`, - }); - - props.setActionMode('list'); - } else { - NotifAlert({ - icon: 'error', - title: 'Gagal', - message: response?.message || 'Terjadi kesalahan saat menyimpan data.', - }); - } - } catch (error) { - console.error('Save Plant Section Error:', error); - NotifAlert({ - icon: 'error', - title: 'Error', - message: error.message || 'Terjadi kesalahan pada server. Coba lagi nanti.', - }); - } - - setConfirmLoading(false); - }; - const handleInputChange = (e) => { const { name, value } = e.target; setFormData({ @@ -85,25 +33,84 @@ const DetailPlantSection = (props) => { }); }; - const handleStatusChange = (value) => { + const handleCancel = () => { + props.setSelectedData(null); + props.setActionMode('list'); + }; + + const handleSave = async () => { + setConfirmLoading(true); + + if (!FormData.sub_section_name) { + NotifOk({ + icon: 'warning', + title: 'Peringatan', + message: 'Kolom Plant Sub Section Name Tidak Boleh Kosong', + }); + setConfirmLoading(false); + return; + } + + try { + let response; + let payload; + + if (props.actionMode === 'edit') { + payload = { + is_active: FormData.is_active, + sub_section_name: FormData.sub_section_name + }; + response = await updatePlantSection(FormData.sub_section_id, payload); + } else { + // Backend generates the code, so we only send the name and status + payload = { + sub_section_name: FormData.sub_section_name, + is_active: FormData.is_active, + } + response = await createPlantSection(payload); + } + + if (response && (response.statusCode === 200 || response.statusCode === 201)) { + const action = props.actionMode === 'edit' ? 'diubah' : 'ditambahkan'; + NotifOk({ + icon: 'success', + title: 'Berhasil', + message: `Data Plant Section berhasil ${action}.`, + }); + props.setActionMode('list'); + } else { + NotifAlert({ + icon: 'error', + title: 'Gagal', + message: response?.message || 'Terjadi kesalahan saat menyimpan data.', + }); + } + } catch (error) { + NotifAlert({ + icon: 'error', + title: 'Error', + message: error.message || 'Terjadi kesalahan pada server.', + }); + } finally { + setConfirmLoading(false); + } + }; + + const handleStatusToggle = (checked) => { setFormData({ ...FormData, - status: value, + is_active: checked, }); }; + useEffect(() => { - const token = localStorage.getItem('token'); - if (token) { - if (props.selectedData != null) { - setFormData(props.selectedData); - } else { - setFormData(defaultData); - } + if (props.selectedData) { + setFormData(props.selectedData); } else { - // navigate('/signin'); // Uncomment if useNavigate is imported + setFormData(defaultData); } - }, [props.showModal]); + }, [props.showModal, props.selectedData]); return ( { open={props.showModal} onCancel={handleCancel} footer={[ - <> + - + { )} - , + , ]} > {FormData && (
- -
- Status - * -
+
+
+ Status +
+
- {FormData.status === true ? 'Active' : 'Inactive'} + + {FormData.is_active ? 'Active' : 'Inactive'} +
+ + + {props.actionMode !== 'add' && ( +
+ Plant Section Code + +
+ )} +
- Plant Name + Plant Sub Section Name *
@@ -215,4 +212,4 @@ const DetailPlantSection = (props) => { ); }; -export default DetailPlantSection; +export default DetailPlantSection; \ No newline at end of file diff --git a/src/pages/master/plantSection/component/ListPlantSection.jsx b/src/pages/master/plantSection/component/ListPlantSection.jsx index dff4c08..863525a 100644 --- a/src/pages/master/plantSection/component/ListPlantSection.jsx +++ b/src/pages/master/plantSection/component/ListPlantSection.jsx @@ -1,104 +1,67 @@ import React, { memo, useState, useEffect } from 'react'; -import { Button, Col, Row, Space, Input, ConfigProvider, Card, Tag, Tabs } from 'antd'; +import { Space, Tag, ConfigProvider, Button, Row, Col, Card, Input } from 'antd'; import { PlusOutlined, EditOutlined, DeleteOutlined, - SearchOutlined, EyeOutlined, + SearchOutlined, } from '@ant-design/icons'; import { NotifAlert, NotifConfirmDialog } from '../../../../components/Global/ToastNotif'; import { useNavigate } from 'react-router-dom'; +import { deletePlantSection, getAllPlantSection } from '../../../../api/master-plant-section'; import TableList from '../../../../components/Global/TableList'; -// Dummy data for Plant Section -const initialPlantSectionData = [ - { - plant_section_id: 1, - plantName: 'Assembly', - status: 'Active', - }, - { - plant_section_id: 2, - plantName: 'Assembly', - status: 'Active', - }, - { - plant_section_id: 3, - plantName: 'Painting', - status: 'Active', - }, - { - plant_section_id: 4, - plantName: 'Warehouse', - status: 'Inactive', - }, -]; - const columns = (showPreviewModal, showEditModal, showDeleteDialog) => [ { - title: 'No', - key: 'no', - width: '5%', - align: 'center', - render: (_, __, index) => index + 1, + title: 'Section Code', + dataIndex: 'sub_section_code', + key: 'sub_section_code', + width: '20%', }, { - title: 'Plant Name', - dataIndex: 'plantName', - key: 'plantName', - width: '60%', + title: 'Plant Sub Section Name', + dataIndex: 'sub_section_name', + key: 'sub_section_name', + width: '40%', }, { title: 'Status', - dataIndex: 'status', - key: 'status', + dataIndex: 'is_active', + key: 'is_active', width: '15%', align: 'center', - render: (_, { status }) => ( - <> - {status === 'Active' ? ( - - Active - - ) : ( - - Inactive - - )} - + render: (status) => ( + + {status ? 'Active' : 'Inactive'} + ), }, { title: 'Aksi', - key: 'action', + key: 'aksi', align: 'center', - width: '20%', + width: '15%', render: (_, record) => ( - +