152 lines
6.5 KiB
JavaScript
152 lines
6.5 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import { Form, Select, Button, Switch, Typography, Space, Input, message } from 'antd';
|
|
import { DeleteOutlined } from '@ant-design/icons';
|
|
import { getAllSparepart } from '../../../../api/sparepart';
|
|
|
|
const { Text } = Typography;
|
|
|
|
const SparepartField = ({
|
|
fieldKey,
|
|
fieldName,
|
|
index,
|
|
sparepartType,
|
|
sparepartStatus,
|
|
isReadOnly = false,
|
|
canRemove = true,
|
|
onRemove,
|
|
spareparts = [],
|
|
onSparepartChange
|
|
}) => {
|
|
const [currentStatus, setCurrentStatus] = useState(sparepartStatus ?? true);
|
|
const [sparepartList, setSparepartList] = useState([]);
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
useEffect(() => {
|
|
setCurrentStatus(sparepartStatus ?? true);
|
|
loadSpareparts();
|
|
}, [sparepartStatus]);
|
|
|
|
const loadSpareparts = async () => {
|
|
setLoading(true);
|
|
try {
|
|
// Get all spareparts from the API
|
|
const params = new URLSearchParams();
|
|
params.set('limit', '100'); // Get all spareparts
|
|
|
|
const response = await getAllSparepart(params);
|
|
// Response structure should have { data: [...], statusCode: 200 }
|
|
if (response && (response.statusCode === 200 || response.data)) {
|
|
// If response has data array directly
|
|
const sparepartData = response.data?.data || response.data || [];
|
|
setSparepartList(sparepartData);
|
|
if (onSparepartChange) {
|
|
onSparepartChange(sparepartData);
|
|
}
|
|
} else {
|
|
// For demo purposes, use mock data if API fails
|
|
setSparepartList([
|
|
{ brand_sparepart_id: 1, sparepart_name: 'Compressor Oil Filter', brand_sparepart_description: 'Oil filter for compressor' },
|
|
{ brand_sparepart_id: 2, sparepart_name: 'Air Intake Filter', brand_sparepart_description: 'Air intake filter' },
|
|
{ brand_sparepart_id: 3, sparepart_name: 'Cooling Fan Motor', brand_sparepart_description: 'Motor for cooling fan' },
|
|
]);
|
|
if (onSparepartChange) {
|
|
onSparepartChange([
|
|
{ brand_sparepart_id: 1, sparepart_name: 'Compressor Oil Filter', brand_sparepart_description: 'Oil filter for compressor' },
|
|
{ brand_sparepart_id: 2, sparepart_name: 'Air Intake Filter', brand_sparepart_description: 'Air intake filter' },
|
|
{ brand_sparepart_id: 3, sparepart_name: 'Cooling Fan Motor', brand_sparepart_description: 'Motor for cooling fan' },
|
|
]);
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Error loading spareparts:', error);
|
|
// Default mock data
|
|
const mockSpareparts = [
|
|
{ brand_sparepart_id: 1, sparepart_name: 'Compressor Oil Filter', brand_sparepart_description: 'Oil filter for compressor' },
|
|
{ brand_sparepart_id: 2, sparepart_name: 'Air Intake Filter', brand_sparepart_description: 'Air intake filter' },
|
|
{ brand_sparepart_id: 3, sparepart_name: 'Cooling Fan Motor', brand_sparepart_description: 'Motor for cooling fan' },
|
|
];
|
|
setSparepartList(mockSpareparts);
|
|
if (onSparepartChange) {
|
|
onSparepartChange(mockSpareparts);
|
|
}
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const sparepartOptions = sparepartList.map(sparepart => ({
|
|
label: sparepart.sparepart_name || sparepart.sparepart_name || `Sparepart ${sparepart.sparepart_id || sparepart.brand_sparepart_id}`,
|
|
value: sparepart.sparepart_id || sparepart.brand_sparepart_id,
|
|
description: sparepart.sparepart_description
|
|
}));
|
|
|
|
return (
|
|
<div style={{
|
|
border: '1px solid #d9d9d9',
|
|
borderRadius: 8,
|
|
padding: 16,
|
|
marginBottom: 16,
|
|
backgroundColor: isReadOnly ? '#f5f5f5' : 'white'
|
|
}}>
|
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
|
|
<Text strong>Sparepart #{index + 1}</Text>
|
|
<Space>
|
|
<Form.Item
|
|
name={[fieldName, 'sparepart_id']}
|
|
rules={[{ required: false, message: 'Sparepart wajib dipilih!' }]} /* Making it optional since sparepart is optional */
|
|
style={{ margin: 0, width: 200 }}
|
|
>
|
|
<Select
|
|
placeholder="Pilih sparepart"
|
|
loading={loading}
|
|
disabled={isReadOnly}
|
|
options={sparepartOptions}
|
|
showSearch
|
|
optionFilterProp="label"
|
|
/>
|
|
</Form.Item>
|
|
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
|
|
<Form.Item name={[fieldName, 'status']} valuePropName="checked" noStyle>
|
|
<Switch
|
|
disabled={isReadOnly}
|
|
onChange={(checked) => {
|
|
setCurrentStatus(checked);
|
|
}}
|
|
style={{
|
|
backgroundColor: currentStatus ? '#23A55A' : '#bfbfbf'
|
|
}}
|
|
/>
|
|
</Form.Item>
|
|
<Text style={{ fontSize: 12, color: '#666' }}>
|
|
{currentStatus ? 'Active' : 'Inactive'}
|
|
</Text>
|
|
</div>
|
|
|
|
{canRemove && !isReadOnly && (
|
|
<Button
|
|
type="text"
|
|
danger
|
|
icon={<DeleteOutlined />}
|
|
onClick={onRemove}
|
|
/>
|
|
)}
|
|
</Space>
|
|
</div>
|
|
|
|
{/* Sparepart Description */}
|
|
<Form.Item
|
|
name={[fieldName, 'description']}
|
|
label="Deskripsi"
|
|
>
|
|
<Input.TextArea
|
|
placeholder="Deskripsi sparepart"
|
|
rows={2}
|
|
disabled={isReadOnly}
|
|
/>
|
|
</Form.Item>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default SparepartField; |