Add Checkbox and Input Scheduler Date

This commit is contained in:
2026-04-23 22:26:34 +07:00
parent 0a8a767261
commit 8d03a0a52e
4 changed files with 197 additions and 28 deletions

View File

@@ -1,9 +1,11 @@
import React, { useEffect, useState } from 'react';
import { Modal, Input, Divider, Typography, Switch, Button, ConfigProvider, Select } from 'antd';
import { Modal, Input, Divider, Typography, Switch, Button, ConfigProvider, Select, DatePicker } from 'antd';
import { NotifAlert, NotifOk } from '../../../../components/Global/ToastNotif';
import { createDevice, updateDevice } from '../../../../api/master-device';
import { getAllBrands } from '../../../../api/master-brand';
import { validateRun } from '../../../../Utils/validate';
import { toApiDateFormatter } from '../../../../components/Global/Formatter';
import dayjs from 'dayjs';
const { Text } = Typography;
const { TextArea } = Input;
@@ -12,6 +14,8 @@ const DetailDevice = (props) => {
const [confirmLoading, setConfirmLoading] = useState(false);
const [brands, setBrands] = useState([]);
const [loadingBrands, setLoadingBrands] = useState(false);
const dateNow = dayjs();
const [schedulerDate, setSchedulerDate] = useState(dateNow);
const defaultData = {
device_id: '',
@@ -23,6 +27,7 @@ const DetailDevice = (props) => {
device_location: '',
device_description: '',
ip_address: '',
scheduler_date: '',
listen_channel: '',
};
@@ -41,6 +46,7 @@ const DetailDevice = (props) => {
{ field: 'device_name', label: 'Device Name', required: true },
{ field: 'ip_address', label: 'Ip Address', required: true, ip: true },
{ field: 'brand_id', label: 'Brand Device', required: true },
{ field: 'scheduler_date', label: 'Tanggaln(Scheduler)', required: true },
];
if (
@@ -67,32 +73,35 @@ const DetailDevice = (props) => {
ip_address: formData.ip_address,
brand_id: formData.brand_id,
listen_channel: formData.listen_channel,
scheduler_date: toApiDateFormatter(formData.scheduler_date)
};
const response = formData.device_id
? await updateDevice(formData.device_id, payload)
: await createDevice(payload);
console.log(payload);
// Check if response is successful
if (response && (response.statusCode === 200 || response.statusCode === 201)) {
const deviceName = response.data?.device_name || formData.device_name;
// const response = formData.device_id
// ? await updateDevice(formData.device_id, payload)
// : await createDevice(payload);
NotifOk({
icon: 'success',
title: 'Berhasil',
message: `Data Device "${deviceName}" berhasil ${
formData.device_id ? 'diubah' : 'ditambahkan'
}.`,
});
// // Check if response is successful
// if (response && (response.statusCode === 200 || response.statusCode === 201)) {
// const deviceName = response.data?.device_name || formData.device_name;
props.setActionMode('list');
} else {
NotifAlert({
icon: 'error',
title: 'Gagal',
message: response?.message || 'Terjadi kesalahan saat menyimpan data.',
});
}
// NotifOk({
// icon: 'success',
// title: 'Berhasil',
// message: `Data Device "${deviceName}" berhasil ${
// formData.device_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 Device Error:', error);
NotifAlert({
@@ -128,6 +137,13 @@ const DetailDevice = (props) => {
});
};
const handleDateChange = (field, value) => {
setFormData({
...formData,
[field]: value,
});
};
// Fungsi untuk mengambil daftar brand
const fetchBrands = async () => {
setLoadingBrands(true);
@@ -218,9 +234,10 @@ const DetailDevice = (props) => {
</React.Fragment>,
]}
>
<Divider/>
{formData && (
<div>
<div>
<div style={{ marginBottom: 12 }}>
<div>
<Text strong>Device Status</Text>
</div>
@@ -247,7 +264,7 @@ const DetailDevice = (props) => {
</div>
</div>
</div>
<Divider style={{ margin: '12px 0' }} />
{/* <Divider style={{ margin: '12px 0' }} /> */}
<div hidden>
<Text strong>Device ID</Text>
<Input
@@ -340,6 +357,17 @@ const DetailDevice = (props) => {
readOnly={props.readOnly}
/>
</div>
<div style={{ marginBottom: 12 }}>
<Text strong>Scheduler Date</Text>
<DatePicker
value={formData.scheduler_date ? dayjs(formData.scheduler_date, 'DD-MM-YYYY') : ''}
onChange={(date, dateString) =>
handleDateChange("scheduler_date", dateString)
}
format="DD-MM-YYYY"
style={{ width: '100%', marginTop: '4px' }}
/>
</div>
<div style={{ marginBottom: 12 }}>
<Text strong>Device Description</Text>
<TextArea

View File

@@ -11,6 +11,7 @@ import {
Row,
Col,
Image,
Checkbox
} from 'antd';
import { PlusOutlined, EyeOutlined, DeleteOutlined } from '@ant-design/icons';
import { NotifAlert, NotifOk } from '../../../../components/Global/ToastNotif';
@@ -37,9 +38,15 @@ const DetailSparepart = (props) => {
const [previewTitle, setPreviewTitle] = useState('');
const [isHovering, setIsHovering] = useState(false);
const options = ['1 Year', '2 Year', '3 Year', '4 Year', '5 Year', '6 Year'];
const [checkedList, setCheckedList] = useState([]);
const [checkAll, setCheckAll] = useState(false);
const [indeterminate, setIndeterminate] = useState(false);
const defaultData = {
sparepart_id: '',
sparepart_name: '',
sparepart_number: '',
sparepart_description: '',
sparepart_model: '',
sparepart_item_type: null,
@@ -75,6 +82,16 @@ const DetailSparepart = (props) => {
setFileList([]);
};
const chekboxValue = () => {
const result = {};
options.forEach((item, index) => {
const key = `is_${index + 1}th`;
result[key] = checkedList.includes(item);
});
return result;
};
const handleSave = async () => {
setConfirmLoading(true);
@@ -273,6 +290,11 @@ const DetailSparepart = (props) => {
setConfirmLoading(false);
};
// const handleSave = () => {
// const val = chekboxValue();
// console.log(val);
// };
const handleInputChange = (e) => {
const { name, value } = e.target;
setFormData({ ...formData, [name]: value });
@@ -282,6 +304,21 @@ const DetailSparepart = (props) => {
setFormData({ ...formData, [name]: value });
};
const onChangeCheckbox = (list) => {
setCheckedList(list);
setIndeterminate(!!list.length && list.length < options.length);
setCheckAll(list.length === options.length);
};
const onCheckAllChange = (e) => {
const checked = e.target.checked;
setCheckedList(checked ? options : []);
setIndeterminate(false);
setCheckAll(checked);
};
useEffect(() => {
if (props.selectedData) {
setFormData(props.selectedData);
@@ -321,6 +358,9 @@ const DetailSparepart = (props) => {
} else {
setFormData(defaultData);
setFileList([]);
setIndeterminate(false);
setCheckedList([]);
setCheckAll(false);
}
}, [props.showModal, props.selectedData, props.actionMode]);
@@ -333,6 +373,7 @@ const DetailSparepart = (props) => {
return (
<Modal
width='40rem'
title={`${
props.actionMode === 'add'
? 'Tambah'
@@ -463,7 +504,7 @@ const DetailSparepart = (props) => {
<div
style={{
width: '180px', // Fixed width for square
height: '180px',
height: '240px',
border: '1px dashed #d9d9d9',
borderRadius: '8px',
display: 'flex',
@@ -485,6 +526,17 @@ const DetailSparepart = (props) => {
{/* Kolom untuk field lainnya */}
<Col span={14}>
<Row gutter={[16, 16]}>
<Col span={24}>
<Text strong>Part Number</Text>
<Text style={{ color: 'red' }}> *</Text>
<Input
name="sparepart_number"
value={formData.sparepart_number}
onChange={handleInputChange}
placeholder="Enter Sparepart Number"
readOnly={props.readOnly}
/>
</Col>
<Col span={24}>
<Text strong>Sparepart Name</Text>
<Text style={{ color: 'red' }}> *</Text>
@@ -560,7 +612,44 @@ const DetailSparepart = (props) => {
/>
</Col>
</Row>
<ConfigProvider
theme={{
token: {
colorPrimary: '#23A55A',
},
}}
>
<Row style={{ marginTop: 16 }}>
<Col>
<Checkbox
indeterminate={indeterminate}
onChange={onCheckAllChange}
checked={checkAll}
>
{checkAll ? 'Unselect All Years' : 'Select All Years'}
</Checkbox>
</Col>
</Row>
<Row style={{ marginTop: 10 }}>
<Col span={24}>
<Checkbox.Group
value={checkedList}
onChange={onChangeCheckbox}
style={{
width: '100%',
display: 'flex',
justifyContent: 'space-between',
}}
>
{options.map((item) => (
<Checkbox key={item} value={item}>
{item}
</Checkbox>
))}
</Checkbox.Group>
</Col>
</Row>
</ConfigProvider>
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
<Col span={24}>
<Text strong>Description</Text>

View File

@@ -277,8 +277,8 @@ const ListSparepart = memo(function ListSparepart(props) {
onStockUpdate={doFilter}
onGetData={(data) => {
if(data && data.length > 0) {
console.log('Sample sparepart data from API:', data[0]);
console.log('Available fields:', Object.keys(data[0] || {}));
// console.log('Sample sparepart data from API:', data[0]);
// console.log('Available fields:', Object.keys(data[0] || {}));
}
}} // Log untuk debugging field-field yang tersedia
/>