repair: add edit brand device
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Form, Input, Button, Switch, Radio, Upload, Typography, Space } from 'antd';
|
||||
import { DeleteOutlined, UploadOutlined, EyeOutlined } from '@ant-design/icons';
|
||||
import { uploadFile, getFolderFromFileType } from '../../../../api/file-uploads';
|
||||
import React, { useState } from 'react';
|
||||
import { Form, Input, Button, Switch, Radio, Typography, Space } from 'antd';
|
||||
import { DeleteOutlined } from '@ant-design/icons';
|
||||
import FileUploadHandler from './FileUploadHandler';
|
||||
import { NotifAlert } from '../../../../components/Global/ToastNotif';
|
||||
|
||||
const { Text } = Typography;
|
||||
@@ -22,64 +22,43 @@ const SolutionFieldNew = ({
|
||||
onFileView,
|
||||
fileList = []
|
||||
}) => {
|
||||
const handleFileUpload = async (file) => {
|
||||
try {
|
||||
const isAllowedType = [
|
||||
'application/pdf',
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/gif',
|
||||
].includes(file.type);
|
||||
const form = Form.useFormInstance();
|
||||
const existingFile = Form.useWatch([`solution_items,${fieldKey}`, 'fileUpload'], form) ||
|
||||
Form.useWatch([`solution_items,${fieldKey}`, 'file'], form);
|
||||
|
||||
if (!isAllowedType) {
|
||||
NotifAlert({
|
||||
icon: 'error',
|
||||
title: 'Error',
|
||||
message: `${file.name} bukan file PDF atau gambar yang diizinkan.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Get form values for debugging and file data extraction
|
||||
const allFormValues = form.getFieldsValue(true);
|
||||
const solutionData = allFormValues[`solution_items,${fieldKey}`] || {};
|
||||
|
||||
const fileExtension = file.name.split('.').pop().toLowerCase();
|
||||
const isImage = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'].includes(fileExtension);
|
||||
const fileType = isImage ? 'image' : 'pdf';
|
||||
const folder = getFolderFromFileType(fileType);
|
||||
|
||||
const uploadResponse = await uploadFile(file, folder);
|
||||
const actualPath = uploadResponse.data?.path_solution || '';
|
||||
|
||||
if (actualPath) {
|
||||
// Store the file info with the solution field
|
||||
file.uploadPath = actualPath;
|
||||
file.solutionId = fieldKey;
|
||||
file.type_solution = fileType;
|
||||
onFileUpload(file);
|
||||
NotifAlert({
|
||||
icon: 'success',
|
||||
title: 'Berhasil',
|
||||
message: `${file.name} berhasil diupload!`,
|
||||
});
|
||||
} else {
|
||||
NotifAlert({
|
||||
icon: 'error',
|
||||
title: 'Gagal',
|
||||
message: `Gagal mengupload ${file.name}`,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
NotifAlert({
|
||||
icon: 'error',
|
||||
title: 'Error',
|
||||
message: `Gagal mengupload ${file.name}. Silakan coba lagi.`,
|
||||
});
|
||||
// Extract file data from form values for preview
|
||||
const getFileFromFormValues = () => {
|
||||
if (solutionData.fileUpload && typeof solutionData.fileUpload === 'object' && Object.keys(solutionData.fileUpload).length > 0) {
|
||||
return solutionData.fileUpload;
|
||||
}
|
||||
if (solutionData.file && typeof solutionData.file === 'object' && Object.keys(solutionData.file).length > 0) {
|
||||
return solutionData.file;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const fileFromForm = getFileFromFormValues();
|
||||
const displayFile = existingFile || fileFromForm;
|
||||
|
||||
console.log(`🔍 SolutionField ${fieldKey}:`, {
|
||||
solutionType,
|
||||
hasPathSolution: !!solutionData.path_solution,
|
||||
pathSolution: solutionData.path_solution,
|
||||
fileFromForm,
|
||||
existingFile,
|
||||
displayFile,
|
||||
shouldRenderPreview: !!displayFile
|
||||
});
|
||||
|
||||
const renderSolutionContent = () => {
|
||||
if (solutionType === 'text') {
|
||||
return (
|
||||
<Form.Item
|
||||
name={[fieldName, 'text']}
|
||||
name={[`solution_items,${fieldKey}`, 'text']}
|
||||
rules={[{ required: true, message: 'Text solution wajib diisi!' }]}
|
||||
>
|
||||
<TextArea
|
||||
@@ -93,59 +72,44 @@ const SolutionFieldNew = ({
|
||||
}
|
||||
|
||||
if (solutionType === 'file') {
|
||||
const currentFiles = fileList.filter(file => file.solutionId === fieldKey);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Form.Item
|
||||
name={[fieldName, 'file']}
|
||||
rules={[{ required: true, message: 'File solution wajib diupload!' }]}
|
||||
>
|
||||
<Upload
|
||||
beforeUpload={handleFileUpload}
|
||||
showUploadList={false}
|
||||
accept=".pdf,.jpg,.jpeg,.png,.gif"
|
||||
disabled={isReadOnly}
|
||||
>
|
||||
<Button
|
||||
icon={<UploadOutlined />}
|
||||
disabled={isReadOnly}
|
||||
size="small"
|
||||
style={{ width: '100%', fontSize: 12 }}
|
||||
>
|
||||
Upload File
|
||||
</Button>
|
||||
</Upload>
|
||||
</Form.Item>
|
||||
<FileUploadHandler
|
||||
type="solution"
|
||||
existingFile={displayFile}
|
||||
onFileUpload={(fileObject) => {
|
||||
const fileWithKey = {
|
||||
...fileObject,
|
||||
solutionId: fieldKey
|
||||
};
|
||||
|
||||
{currentFiles.length > 0 && (
|
||||
<div style={{ marginTop: 8 }}>
|
||||
{currentFiles.map((file, index) => (
|
||||
<div key={index} style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
padding: '4px 8px',
|
||||
border: '1px solid #d9d9d9',
|
||||
borderRadius: 4,
|
||||
marginBottom: 4
|
||||
}}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<Text style={{ fontSize: 12 }}>{file.name}</Text>
|
||||
<Text type="secondary" style={{ fontSize: 10 }}>
|
||||
({(file.size / 1024).toFixed(1)} KB)
|
||||
</Text>
|
||||
</div>
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<EyeOutlined />}
|
||||
onClick={() => onFileView(file.uploadPath, file.type_solution)}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
if (onFileUpload && typeof onFileUpload === 'function') {
|
||||
onFileUpload(fileWithKey);
|
||||
}
|
||||
|
||||
form.setFieldValue([`solution_items,${fieldKey}`, 'fileUpload'], fileWithKey);
|
||||
form.setFieldValue([`solution_items,${fieldKey}`, 'file'], fileWithKey);
|
||||
form.setFieldValue([`solution_items,${fieldKey}`, 'type'], 'file');
|
||||
}}
|
||||
onFileRemove={() => {
|
||||
console.log(`🗑️ Removing file from solution ${fieldKey}`);
|
||||
|
||||
// Clear file form values only, keep type as file and status active
|
||||
form.setFieldValue([`solution_items,${fieldKey}`, 'fileUpload'], null);
|
||||
form.setFieldValue([`solution_items,${fieldKey}`, 'file'], null);
|
||||
|
||||
// Call parent callback if exists
|
||||
if (onFileUpload && typeof onFileUpload === 'function') {
|
||||
onFileUpload(null);
|
||||
}
|
||||
|
||||
console.log(`✅ File removed from solution ${fieldKey} - type and status preserved`);
|
||||
}}
|
||||
disabled={isReadOnly}
|
||||
buttonText={displayFile ? 'Replace File' : 'Upload File'}
|
||||
buttonStyle={{ width: '100%', fontSize: 12 }}
|
||||
uploadText="Upload solution file"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -176,15 +140,16 @@ const SolutionFieldNew = ({
|
||||
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
|
||||
<Form.Item name={[fieldName, 'status']} valuePropName="checked" noStyle>
|
||||
<Form.Item name={[`solution_items,${fieldKey}`, 'status']} valuePropName="checked" noStyle>
|
||||
<Switch
|
||||
size="small"
|
||||
disabled={isReadOnly}
|
||||
onChange={(checked) => {
|
||||
onStatusChange(fieldKey, checked);
|
||||
}}
|
||||
defaultChecked={solutionStatus !== false}
|
||||
style={{
|
||||
backgroundColor: solutionStatus ? '#23A55A' : '#bfbfbf'
|
||||
backgroundColor: solutionStatus !== false ? '#23A55A' : '#bfbfbf'
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
@@ -193,7 +158,7 @@ const SolutionFieldNew = ({
|
||||
color: '#666',
|
||||
whiteSpace: 'nowrap'
|
||||
}}>
|
||||
{solutionStatus ? 'Active' : 'Inactive'}
|
||||
{solutionStatus !== false ? 'Active' : 'Inactive'}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
@@ -215,7 +180,7 @@ const SolutionFieldNew = ({
|
||||
</div>
|
||||
|
||||
<Form.Item
|
||||
name={[fieldName, 'name']}
|
||||
name={[`solution_items,${fieldKey}`, 'name']}
|
||||
rules={[{ required: true, message: 'Solution name wajib diisi!' }]}
|
||||
style={{ margin: 0 }}
|
||||
>
|
||||
@@ -226,10 +191,11 @@ const SolutionFieldNew = ({
|
||||
style={{ fontSize: 13 }}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<Form.Item
|
||||
name={[fieldName, 'type']}
|
||||
name={[`solution_items,${fieldKey}`, 'type']}
|
||||
rules={[{ required: true, message: 'Solution type wajib diisi!' }]}
|
||||
style={{ marginBottom: 8 }}
|
||||
initialValue={solutionType || 'text'}
|
||||
@@ -238,13 +204,20 @@ const SolutionFieldNew = ({
|
||||
onChange={(e) => onTypeChange(fieldKey, e.target.value)}
|
||||
disabled={isReadOnly}
|
||||
size="small"
|
||||
defaultValue={solutionType || 'text'}
|
||||
>
|
||||
<Radio value="text" style={{ fontSize: 12 }}>Text</Radio>
|
||||
<Radio value="file" style={{ fontSize: 12 }}>File</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[`solution_items,${fieldKey}`, 'status']}
|
||||
initialValue={solutionStatus !== false ? true : false}
|
||||
noStyle
|
||||
>
|
||||
<input type="hidden" />
|
||||
</Form.Item>
|
||||
|
||||
{renderSolutionContent()}
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user