feat: enhance DetailSparepart component with image upload and preview functionality

This commit is contained in:
2025-12-02 13:48:56 +07:00
parent 1797058526
commit 2e98dc168a

View File

@@ -12,7 +12,7 @@ import {
Col,
Image,
} from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { PlusOutlined, EyeOutlined, DeleteOutlined } from '@ant-design/icons';
import { NotifAlert, NotifOk } from '../../../../components/Global/ToastNotif';
import { createSparepart, updateSparepart } from '../../../../api/sparepart';
import { uploadFile } from '../../../../api/file-uploads';
@@ -35,13 +35,14 @@ const DetailSparepart = (props) => {
const [previewOpen, setPreviewOpen] = useState(false);
const [previewImage, setPreviewImage] = useState('');
const [previewTitle, setPreviewTitle] = useState('');
const [isHovering, setIsHovering] = useState(false);
const defaultData = {
sparepart_id: '',
sparepart_name: '',
sparepart_description: '',
sparepart_model: '',
sparepart_item_type: '',
sparepart_item_type: null,
sparepart_unit: '',
sparepart_merk: '',
sparepart_stok: '0',
@@ -69,6 +70,10 @@ const DetailSparepart = (props) => {
const handleChange = ({ fileList: newFileList }) => setFileList(newFileList);
const handleRemove = () => {
setFileList([]);
};
const handleSave = async () => {
setConfirmLoading(true);
@@ -364,85 +369,158 @@ const DetailSparepart = (props) => {
{formData && (
<div>
<Row gutter={[16, 16]}>
<Col span={12}>
<Text strong>Sparepart Name</Text>
<Text style={{ color: 'red' }}> *</Text>
<Input
name="sparepart_name"
value={formData.sparepart_name}
onChange={handleInputChange}
placeholder="Enter Sparepart Name"
readOnly={props.readOnly}
/>
</Col>
<Col span={12}>
<Text strong>Item Type</Text>
<Select
name="sparepart_item_type"
value={formData.sparepart_item_type}
onChange={(value) =>
handleSelectChange('sparepart_item_type', value)
}
placeholder="Select Item Type"
disabled={props.readOnly}
style={{ width: '100%' }}
>
<Select.Option value="Air Dryer">Air Dryer</Select.Option>
<Select.Option value="Compressor">Compressor</Select.Option>
</Select>
</Col>
</Row>
<Row gutter={[16, 16]}>
<Col span={12}>
<Text strong>Stock</Text>
<Input
name="sparepart_stok"
value={formData.sparepart_stok}
onChange={handleInputChange}
placeholder="Initial stock quantity"
readOnly={props.readOnly}
type="number"
/>
</Col>
<Col span={12}>
<Text strong>Unit</Text>
<Input
name="sparepart_unit"
value={formData.sparepart_unit}
onChange={handleInputChange}
placeholder="e.g., pcs, box, roll"
readOnly={props.readOnly}
/>
</Col>
</Row>
<Row gutter={[16, 16]}>
<Col span={24}>
{/* Kolom untuk foto */}
<Col span={10} style={{ display: 'flex', flexDirection: 'column' }}>
<Text strong>Foto</Text>
<Upload
listType="picture-card"
fileList={fileList}
onPreview={handlePreview}
onChange={handleChange}
beforeUpload={() => false}
maxCount={1}
disabled={props.readOnly}
<div
style={{
flexGrow: 1,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
}}
>
{fileList.length >= 1 ? null : uploadButton}
</Upload>
<Modal
open={previewOpen}
title={previewTitle}
footer={null}
onCancel={handlePreviewCancel}
>
<img alt="preview" style={{ width: '100%' }} src={previewImage} />
</Modal>
{fileList.length > 0 ? (
<div
onMouseEnter={() => setIsHovering(true)}
onMouseLeave={() => setIsHovering(false)}
style={{
position: 'relative',
width: '180px', // Fixed width for square
height: '180px', // Fixed height
border: '1px solid #d9d9d9',
borderRadius: '8px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Image
src={fileList[0].url || fileList[0].thumbUrl}
alt="preview"
style={{
maxWidth: '100%',
maxHeight: '100%',
objectFit: 'contain',
}}
preview={false} // Disable default preview
/>
{isHovering && !props.readOnly && (
<div
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
background: 'rgba(0, 0, 0, 0.5)',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
color: 'white',
gap: '16px',
fontSize: '20px',
borderRadius: '8px',
cursor: 'pointer',
}}
>
<EyeOutlined
onClick={() => handlePreview(fileList[0])}
/>
<DeleteOutlined onClick={handleRemove} />
</div>
)}
</div>
) : (
<Upload
name="file"
multiple={false}
fileList={fileList}
onChange={handleChange}
beforeUpload={() => false}
maxCount={1}
disabled={props.readOnly}
showUploadList={false}
>
<div
style={{
width: '180px', // Fixed width for square
height: '180px',
border: '1px dashed #d9d9d9',
borderRadius: '8px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
cursor: 'pointer',
gap: '8px',
}}
>
<PlusOutlined />
<div>Upload</div>
</div>
</Upload>
)}
</div>
</Col>
{/* Kolom untuk field lainnya */}
<Col span={14}>
<Row gutter={[16, 16]}>
<Col span={24}>
<Text strong>Sparepart Name</Text>
<Text style={{ color: 'red' }}> *</Text>
<Input
name="sparepart_name"
value={formData.sparepart_name}
onChange={handleInputChange}
placeholder="Enter Sparepart Name"
readOnly={props.readOnly}
/>
</Col>
<Col span={24}>
<Text strong>Item Type</Text>
<Select
name="sparepart_item_type"
value={formData.sparepart_item_type}
onChange={(value) =>
handleSelectChange('sparepart_item_type', value)
}
placeholder="Enter Item Type"
disabled={props.readOnly}
style={{ width: '100%' }}
>
<Select.Option value="Air Dryer">Air Dryer</Select.Option>
<Select.Option value="Compressor">Compressor</Select.Option>
</Select>
</Col>
<Col span={12}>
<Text strong>Stock</Text>
<Input
name="sparepart_stok"
value={formData.sparepart_stok}
onChange={handleInputChange}
placeholder="Initial stock"
readOnly={props.readOnly}
type="number"
/>
</Col>
<Col span={12}>
<Text strong>Unit</Text>
<Input
name="sparepart_unit"
value={formData.sparepart_unit}
onChange={handleInputChange}
placeholder="e.g., pcs"
readOnly={props.readOnly}
/>
</Col>
</Row>
</Col>
</Row>
<Row gutter={[16, 16]}>
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
<Col span={12}>
<Text strong>Brand</Text>
<Input
@@ -465,7 +543,7 @@ const DetailSparepart = (props) => {
</Col>
</Row>
<Row gutter={[16, 16]}>
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
<Col span={24}>
<Text strong>Description</Text>
<TextArea
@@ -480,6 +558,9 @@ const DetailSparepart = (props) => {
</Row>
</div>
)}
<Modal open={previewOpen} title={previewTitle} footer={null} onCancel={handlePreviewCancel}>
<img alt="preview" style={{ width: '100%' }} src={previewImage} />
</Modal>
</Modal>
);
};