Untitled
unknown
plain_text
a year ago
7.9 kB
7
Indexable
import React, { useRef, useState } from 'react';
import { SimpleFileUpload, Label, Button, Group, Section, ListItem, List } from '@d-lift/uxcomponents';
import * as XLSX from 'xlsx';
const ExcelUpload = () => {
const [status, setStatus] = useState('initial');
const [uploadedFiles, setUploadedFiles] = useState([]);
const [errors, setErrors] = useState([]);
const fileInputRef = useRef(null);
const [selectedFile, setSelectedFile] = useState(null);
const handleFileChange = (e) => {
if (Array.isArray(e) && e.length > 0) {
const newFile = e[0];
setSelectedFile(newFile);
handleUpload(newFile);
} else {
console.log('No file selected');
}
};
const handleUpload = async (file) => {
try {
if (!file) {
console.error('No file selected');
setStatus('fail');
return;
}
console.log('Processing file:', file);
const reader = new FileReader();
reader.onload = (event) => {
const data = new Uint8Array(event.target.result);
const workbook = XLSX.read(data, { type: 'array' });
const firstSheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[firstSheetName];
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
const validationResult = validateData(jsonData);
if (validationResult.isValid) {
convertToJSONAndUpload(jsonData);
} else {
setErrors(validationResult.errors);
setStatus('fail');
}
};
reader.readAsArrayBuffer(file);
setUploadedFiles((prevFiles) => [
...prevFiles,
{
id: Math.random() * 100 + 1,
name: file.name,
},
]);
setStatus('success');
} catch (error) {
console.error(error);
setStatus('fail');
}
};
const validateData = (data) => {
let isValid = true;
let errors = [];
const headers = data[0];
const requiredFields = ["RFI Title", "RFI desc", "requesting as", "needed by", "offering"];
const questionFields = ["response", "respond as"];
// Check mandatory headers
requiredFields.forEach((field) => {
if (!headers.includes(field)) {
isValid = false;
errors.push(`Missing mandatory field: ${field}`);
}
});
// Validate each row
data.slice(1).forEach((row, rowIndex) => {
// Check mandatory fields
requiredFields.forEach((field) => {
const fieldIndex = headers.indexOf(field);
if (row[fieldIndex] === '' || row[fieldIndex] === undefined) {
isValid = false;
errors.push(`Error in row ${rowIndex + 2}: ${field} is mandatory`);
}
if (field === "needed by") {
const date = new Date(row[fieldIndex]);
if (date < new Date()) {
isValid = false;
errors.push(`Error in row ${rowIndex + 2}: ${field} date should not be in the past`);
}
}
});
// Check questions fields
let questionSection = false;
row.forEach((cell, cellIndex) => {
if (questionFields.includes(headers[cellIndex])) {
questionSection = true;
if (cell === '' || cell === undefined) {
isValid = false;
errors.push(`Error in row ${rowIndex + 2}, cell ${cellIndex + 1}: ${headers[cellIndex]} is mandatory`);
}
}
});
if (questionSection && (row[headers.indexOf("response")] === '' || row[headers.indexOf("response")] === undefined)) {
isValid = false;
errors.push(`Error in row ${rowIndex + 2}: response is mandatory for questions`);
}
if (questionSection && (row[headers.indexOf("respond as")] === '' || row[headers.indexOf("respond as")] === undefined)) {
isValid = false;
errors.push(`Error in row ${rowIndex + 2}: respond as is mandatory for questions`);
}
});
return { isValid, errors };
};
const convertToJSONAndUpload = (data) => {
const jsonData = data.slice(1).map((row, index) => {
const rowData = {};
data[0].forEach((header, i) => {
rowData[header] = row[i];
});
return rowData;
});
callAPIToInsertData(jsonData);
};
const callAPIToInsertData = async (data) => {
try {
const response = await fetch('YOUR_API_ENDPOINT', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
if (response.ok) {
console.log('Data successfully inserted');
} else {
console.error('Failed to insert data');
}
} catch (error) {
console.error('Error during API call:', error);
}
};
return (
<>
<div className="ux-rfi-attachment-container ux-rfi-green-border">
<Label className="mb-0" model="AddAttachments.fileList" labelKey="attachments"></Label>
<Section className="pt-4">
<List>
{uploadedFiles.length > 0 ? (
uploadedFiles.map((file) => (
<ListItem key={file.id} iconKey={null}>
{file.name}
</ListItem>
))
) : (
<ListItem iconKey={null} labelKey="empty_err"></ListItem>
)}
</List>
{errors.length > 0 && (
<Section className="pt-4">
<Label className="mb-0" model="AddAttachments.errorList" labelKey="errors"></Label>
<List>
{errors.map((error, index) => (
<ListItem key={index} iconKey={null}>
{error}
</ListItem>
))}
</List>
</Section>
)}
<SimpleFileUpload
model="AddAttachments.uploadedFiles"
allowDragAndDrop={false}
inputDisplayType="custom"
ref={fileInputRef}
style={{ display: 'none' }}
onDropAccepted={handleFileChange}
accept=".xls,.xlsx">
<Button
size="small"
click={() => fileInputRef.current && fileInputRef.current.click()}
className="ux-rfi-green-button">
<Group width="1,10">
<i className="fa fa-plus" aria-hidden="true"></i>Add Attachment
</Group>
</Button>
</SimpleFileUpload>
</Section>
</div>
</>
);
};
export default ExcelUpload;
Editor is loading...
Leave a Comment