Compare commits
4 Commits
7063865a7b
...
lavoce
| Author | SHA1 | Date | |
|---|---|---|---|
| 276a75f13f | |||
| 51e2fa46bf | |||
| c22000437b | |||
| 1f5678f435 |
@@ -35,8 +35,11 @@ const DetailDevice = (props) => {
|
||||
device_location: '',
|
||||
device_description: '',
|
||||
ip_address: '',
|
||||
reminder_at: null,
|
||||
listen_channel: null,
|
||||
reminder_at: null,
|
||||
reminder_at_monthly: null,
|
||||
start_date: null,
|
||||
end_date: null,
|
||||
};
|
||||
|
||||
const [formData, setFormData] = useState(defaultData);
|
||||
@@ -82,6 +85,9 @@ const DetailDevice = (props) => {
|
||||
listen_channel: formData.listen_channel,
|
||||
listen_channel_reminder: formData.listen_channel_reminder,
|
||||
reminder_at: formData.reminder_at,
|
||||
reminder_at_monthly: formData.reminder_at_monthly,
|
||||
start_date: formData.start_date,
|
||||
end_date: formData.end_date,
|
||||
};
|
||||
|
||||
console.log(payload);
|
||||
@@ -172,6 +178,57 @@ const DetailDevice = (props) => {
|
||||
}
|
||||
};
|
||||
|
||||
const [period, setPeriod] = useState({
|
||||
period: undefined,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (formData.start_date && formData.end_date) {
|
||||
const start = dayjs(formData.start_date);
|
||||
const end = dayjs(formData.end_date);
|
||||
|
||||
let periodValue = 'custom';
|
||||
|
||||
if (end.isSame(start.add(1, 'month').subtract(1, 'day'), 'day')) {
|
||||
periodValue = '1';
|
||||
} else if (end.isSame(start.add(3, 'month').subtract(1, 'day'), 'day')) {
|
||||
periodValue = '3';
|
||||
} else if (end.isSame(start.add(6, 'month').subtract(1, 'day'), 'day')) {
|
||||
periodValue = '6';
|
||||
}
|
||||
|
||||
setPeriod({
|
||||
period: periodValue,
|
||||
});
|
||||
}
|
||||
}, [formData.start_date, formData.end_date]);
|
||||
|
||||
const handleMonthly = (field, value) => {
|
||||
setPeriod((prev) => ({
|
||||
...prev,
|
||||
[field]: value,
|
||||
}));
|
||||
|
||||
if (value !== 'custom') {
|
||||
const months = Number(value);
|
||||
|
||||
const startDate = dayjs().startOf('day');
|
||||
const endDate = startDate.add(months, 'month').subtract(1, 'day').endOf('day');
|
||||
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
start_date: startDate.toISOString(),
|
||||
end_date: endDate.toISOString(),
|
||||
}));
|
||||
} else {
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
start_date: null,
|
||||
end_date: null,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (props.showModal && (props.actionMode === 'add' || props.actionMode === 'edit')) {
|
||||
fetchBrands();
|
||||
@@ -381,7 +438,7 @@ const DetailDevice = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ marginBottom: 12 }}>
|
||||
<Text strong>Reminder At</Text>
|
||||
<Text strong>Reminder At(Yearly)</Text>
|
||||
<div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
|
||||
<DatePicker
|
||||
value={
|
||||
@@ -413,6 +470,92 @@ const DetailDevice = (props) => {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ marginBottom: 12 }}>
|
||||
<Text strong>Period</Text>
|
||||
<Text style={{ color: 'red' }}> *</Text>
|
||||
|
||||
<Select
|
||||
value={period.period}
|
||||
onChange={(value) => handleMonthly('period', value)}
|
||||
placeholder="Select Period"
|
||||
style={{ width: '100%' }}
|
||||
>
|
||||
<Select.Option value="1">1 Monthly</Select.Option>
|
||||
<Select.Option value="3">3 Monthly</Select.Option>
|
||||
<Select.Option value="6">6 Monthly</Select.Option>
|
||||
<Select.Option value="custom">Custom</Select.Option>
|
||||
</Select>
|
||||
</div>
|
||||
{period.period === 'custom' && (
|
||||
<div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>
|
||||
<DatePicker
|
||||
placeholder="Start Date"
|
||||
value={formData.start_date ? dayjs(formData.start_date) : null}
|
||||
onChange={(date) =>
|
||||
handleDateChange('start_date', date ? date.toISOString() : null)
|
||||
}
|
||||
disabledDate={(current) =>
|
||||
formData.end_date &&
|
||||
current &&
|
||||
current.isAfter(dayjs(formData.end_date), 'day')
|
||||
}
|
||||
format="DD-MM-YYYY HH:mm"
|
||||
showTime={{ format: 'HH:mm' }}
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
|
||||
<DatePicker
|
||||
placeholder="End Date"
|
||||
value={formData.end_date ? dayjs(formData.end_date) : null}
|
||||
onChange={(date) =>
|
||||
handleDateChange('end_date', date ? date.toISOString() : null)
|
||||
}
|
||||
disabledDate={(current) =>
|
||||
formData.start_date &&
|
||||
current &&
|
||||
current.isBefore(dayjs(formData.start_date), 'day')
|
||||
}
|
||||
format="DD-MM-YYYY HH:mm"
|
||||
showTime={{ format: 'HH:mm' }}
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div style={{ marginBottom: 12 }}>
|
||||
<Text strong>Reminder At(Monthly)</Text>
|
||||
<div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
|
||||
<DatePicker
|
||||
disabled={period.period === 'custom'}
|
||||
value={
|
||||
formData.reminder_at_monthly
|
||||
? dayjs(formData.reminder_at_monthly) // ✅ langsung parse ISO
|
||||
: null
|
||||
}
|
||||
onChange={(date) =>
|
||||
handleDateChange(
|
||||
'reminder_at_monthly',
|
||||
date ? date.toISOString() : null
|
||||
)
|
||||
}
|
||||
format="DD-MM-YYYY HH:mm"
|
||||
showTime={{ format: 'HH:mm' }}
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
|
||||
<Button
|
||||
disabled={period.period === 'custom'}
|
||||
danger
|
||||
onClick={() =>
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
reminder_at_monthly: null,
|
||||
}))
|
||||
}
|
||||
>
|
||||
Clear
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ marginBottom: 12 }}>
|
||||
<Text strong>Device Description</Text>
|
||||
<TextArea
|
||||
|
||||
@@ -38,6 +38,24 @@ const DetailSparepart = (props) => {
|
||||
const [previewTitle, setPreviewTitle] = useState('');
|
||||
const [isHovering, setIsHovering] = useState(false);
|
||||
|
||||
const optionsMonthly = [
|
||||
{
|
||||
key: 1,
|
||||
value: 1,
|
||||
text: '1 Month',
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
value: 3,
|
||||
text: '3 Month',
|
||||
},
|
||||
{
|
||||
key: 6,
|
||||
value: 6,
|
||||
text: '6 Month',
|
||||
},
|
||||
];
|
||||
|
||||
const optionsYearly = [
|
||||
{
|
||||
key: 1,
|
||||
@@ -70,6 +88,10 @@ const DetailSparepart = (props) => {
|
||||
text: '6 Year',
|
||||
},
|
||||
];
|
||||
const [checkedListM, setCheckedListM] = useState([]);
|
||||
const [checkAllM, setCheckAllM] = useState(false);
|
||||
const [indeterminateM, setIndeterminateM] = useState(false);
|
||||
|
||||
const [checkedList, setCheckedList] = useState([]);
|
||||
const [checkAll, setCheckAll] = useState(false);
|
||||
const [indeterminate, setIndeterminate] = useState(false);
|
||||
@@ -276,6 +298,7 @@ const DetailSparepart = (props) => {
|
||||
|
||||
payload.sparepart_number = formData.sparepart_number;
|
||||
payload.sparepart_yearly = checkedList;
|
||||
payload.sparepart_monthly = checkedListM;
|
||||
|
||||
// console.log('Sending payload:', payload);
|
||||
|
||||
@@ -323,6 +346,21 @@ const DetailSparepart = (props) => {
|
||||
setFormData({ ...formData, [name]: value });
|
||||
};
|
||||
|
||||
const onChangeCheckboxM = (list) => {
|
||||
setCheckedListM(list);
|
||||
|
||||
setIndeterminateM(!!list.length && list.length < optionsMonthly.length);
|
||||
setCheckAllM(list.length === optionsMonthly.length);
|
||||
};
|
||||
|
||||
const onCheckAllChangeM = (e) => {
|
||||
const checked = e.target.checked;
|
||||
|
||||
setCheckedListM(checked ? optionsMonthly.map((item) => item.value) : []);
|
||||
setIndeterminateM(false);
|
||||
setCheckAllM(checked);
|
||||
};
|
||||
|
||||
const onChangeCheckbox = (list) => {
|
||||
setCheckedList(list);
|
||||
|
||||
@@ -374,10 +412,16 @@ const DetailSparepart = (props) => {
|
||||
} else {
|
||||
setFileList([]);
|
||||
}
|
||||
setCheckedListM(JSON.parse(props.selectedData.sparepart_monthly));
|
||||
setCheckedList(JSON.parse(props.selectedData.sparepart_yearly));
|
||||
} else {
|
||||
setFormData(defaultData);
|
||||
setFileList([]);
|
||||
|
||||
setIndeterminateM(false);
|
||||
setCheckedListM([]);
|
||||
setCheckAllM(false);
|
||||
|
||||
setIndeterminate(false);
|
||||
setCheckedList([]);
|
||||
setCheckAll(false);
|
||||
@@ -639,6 +683,8 @@ const DetailSparepart = (props) => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
|
||||
{/* Yearly */}
|
||||
<Row style={{ marginTop: 16 }}>
|
||||
<Col>
|
||||
<Checkbox
|
||||
@@ -669,6 +715,38 @@ const DetailSparepart = (props) => {
|
||||
</Checkbox.Group>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/* Monthly */}
|
||||
<Row style={{ marginTop: 16 }}>
|
||||
<Col>
|
||||
<Checkbox
|
||||
indeterminate={indeterminateM}
|
||||
onChange={onCheckAllChangeM}
|
||||
checked={checkAllM}
|
||||
>
|
||||
{checkAllM ? 'Unselect All Months' : 'Select All Months'}
|
||||
</Checkbox>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{ marginTop: 10 }}>
|
||||
<Col span={24}>
|
||||
<Checkbox.Group
|
||||
value={checkedListM}
|
||||
onChange={onChangeCheckboxM}
|
||||
style={{
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
{optionsMonthly.map((item) => (
|
||||
<Checkbox key={item.key} value={item.value}>
|
||||
{item.text}
|
||||
</Checkbox>
|
||||
))}
|
||||
</Checkbox.Group>
|
||||
</Col>
|
||||
</Row>
|
||||
</ConfigProvider>
|
||||
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
|
||||
<Col span={24}>
|
||||
|
||||
Reference in New Issue
Block a user