Android_Retail/src/Pages/CommonMaster/ConfigExcelUpload.jsx

1002 lines
28 KiB
JavaScript

import React, { useRef, useEffect, useState, useContext } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Table, Form, Input, Tooltip, Modal } from 'antd';
// import { read, utils } from 'xlsx';
import ExcelJS from 'exceljs';
import {
emptyExcelData,
excelDataSelector,
excelFileSelector,
excelFileErrorSelector,
fileInputRefSelector,
uploadExcel,
} from '../../Features/ExcelUploadPage/ExcelUploadPage.js';
import '../../Components/Forms/main.scss';
import { RadioGrpButton } from '../../Components/Forms/RadioGroup.jsx';
import { AiFillDelete } from 'react-icons/ai';
import upldimg from '../../Images/upldimg.png';
import { FiDelete, FiDownload } from 'react-icons/fi';
import { downloadFile } from '../../utils/downloadFile.js';
const allowedExcelTypes = [
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
'application/vnd.ms-excel', // .xls
];
const ConfigExcel = ({ handleSubmit, CategoryNames, SubCatData }) => {
const dispatch = useDispatch();
const fileInputRef = useRef(fileInputRefSelector);
const excelData = useSelector(excelDataSelector);
const excelFile = useSelector(excelFileSelector);
const excelFileError = useSelector(excelFileErrorSelector);
const [worksheet1, setWorksheet1] = useState(null);
const [editdelete, seteditdelete] = useState('');
const [Datas, setDatas] = useState();
const [currentPage, setCurrentPage] = useState(1);
const [radioValue, setRadioValue] = useState('Category Name');
const [parcolumns, setparcolumns] = useState();
useEffect(() => {
if (radioValue === 'Category Name') {
setparcolumns([
{
title: 'CATEGORY Name',
dataIndex: 'CategoryName',
key: 'CategoryName',
editable: true,
},
]);
} else if (radioValue === 'Sub-Category Name') {
setparcolumns([
{
title: 'CATEGORY Name',
dataIndex: 'CategoryName',
key: 'CategoryName',
editable: true,
},
{
title: 'SUB-CATEGORY Name',
dataIndex: 'SubCategoryName',
key: 'SubCategoryName',
editable: true,
},
]);
} else if (radioValue === 'Brand Name') {
setparcolumns([
{
title: 'SUB-CATEGORY Name',
dataIndex: 'SubCategoryName',
key: 'SubCategoryName',
editable: true,
},
{
title: 'BRAND Name',
dataIndex: 'BrandName',
key: 'BrandName',
editable: true,
},
]);
}
}, [radioValue]);
const handleTableChange = (pagination, filters, sorter) => {
setCurrentPage(pagination.current);
};
useEffect(() => {
if (excelData && excelData?.length > 0) {
let ExecelToJsConvertion = [];
let slicedData = excelData?.slice(1);
slicedData?.map((item, index) => {
let convertedItem = {
key: index,
CategoryName: item?.['0'],
TypeName: 'Product Category',
};
if (radioValue === 'Category Name') {
convertedItem = { ...convertedItem };
} else if (radioValue === 'Sub-Category Name') {
convertedItem = {
...convertedItem,
SubCategoryName: item?.['1'],
TypeName: 'Product Sub-Category',
};
} else if (radioValue === 'Brand Name') {
convertedItem = {
...convertedItem,
SubCategoryName: item?.['0'],
BrandName: item?.['1'],
TypeName: 'Product Brand',
};
}
ExecelToJsConvertion.push(convertedItem);
});
setDatas(ExecelToJsConvertion);
}
}, [excelData, radioValue]);
useEffect(() => {
if (Datas) {
handleSubmit(Datas);
}
}, [Datas, handleSubmit]);
const handleFileUpload = (e) => {
const file = e.target.files[0];
if (file) {
const isAllowed = allowedExcelTypes.includes(file.type);
if (!isAllowed) {
Modal.error({
title: 'Invalid File Type',
content: 'Only Excel files (.xls, .xlsx) are allowed.',
});
handleCancelData();
} else {
uploadAndProcessExcel(file);
}
} else {
dispatch(emptyExcelData());
}
};
const handleClick = () => {
// Programmatically trigger the file input click event
fileInputRef.current.click();
};
const uploadAndProcessExcel = (file) => {
const reader = new FileReader();
reader.onload = async (e) => {
try {
const buffer = e.target.result;
const workbook = new ExcelJS.Workbook();
await workbook.xlsx.load(buffer);
const worksheet = workbook.worksheets[0];
const jsonData = [];
worksheet.eachRow((row) => {
const rowData = [];
row.eachCell({ includeEmpty: true }, (cell) => {
let value = cell.value;
// handle different ExcelJS value types
if (value && typeof value === 'object') {
if (value.text) value = value.text;
else if (value.result) value = value.result;
else if (value.richText) {
value = value.richText.map((t) => t.text).join('');
}
}
rowData.push(value ?? '');
});
jsonData.push(rowData);
});
// remove empty rows (same as before)
const nonEmptyRows = jsonData.filter((row) =>
row.some((cell) => cell !== '')
);
const header = nonEmptyRows[0];
const rows = nonEmptyRows.slice(1);
const dateFields = ['Manufacture Date', 'Expire Date', 'Stock Date'];
const convertToDisplayFormat = (dateString) => {
const date = new Date(dateString);
if (isNaN(date)) return '';
return `${String(date.getDate()).padStart(2, '0')}-${String(
date.getMonth() + 1
).padStart(2, '0')}-${date.getFullYear()}`;
};
const formattedData = rows.map((row) => {
return header.reduce((acc, col, index) => {
if (dateFields.includes(col)) {
acc[col] = convertToDisplayFormat(row[index]);
} else {
acc[col] = row[index];
}
return acc;
}, {});
});
// SAME AS BEFORE (no break)
dispatch(uploadExcel({ file, jsonData: nonEmptyRows }));
setDatas(formattedData);
} catch (err) {
console.error(err);
Modal.error({
title: 'Error',
content: 'Failed to process Excel file',
});
}
};
reader.readAsArrayBuffer(file);
};
// const uploadAndProcessExcel = (file) => {
// const reader = new FileReader();
// reader.onload = (e) => {
// const data = new Uint8Array(e.target.result);
// const workbook = read(data, { type: 'array' });
// const worksheet = workbook.Sheets[workbook.SheetNames[0]];
// const jsonData = utils.sheet_to_json(worksheet, {
// header: 1,
// raw: false,
// dateNF: 'DD/MM/YY',
// });
// const nonEmptyRows = jsonData.filter((row) =>
// row.some((cell) => cell !== '')
// );
// const header = nonEmptyRows[0];
// const rows = nonEmptyRows.slice(1);
// const dateFields = ['Manufacture Date', 'Expire Date', 'Stock Date'];
// function convertToDisplayFormat(dateString) {
// const date = new Date(dateString);
// const day = date.getDate().toString().padStart(2, '0');
// const month = (date.getMonth() + 1).toString().padStart(2, '0');
// const year = date.getFullYear().toString();
// return `${day}-${month}-${year}`;
// }
// const formattedData = rows.map((row) => {
// let rowData = header.reduce((acc, col, columnIndex) => {
// if (dateFields.includes(col)) {
// acc[col] = convertToDisplayFormat(row[columnIndex]);
// } else {
// acc[col] = row[columnIndex];
// }
// return acc;
// }, {});
// return rowData;
// });
// dispatch(uploadExcel({ file, jsonData: nonEmptyRows }));
// setWorksheet1(worksheet1);
// setDatas(formattedData);
// };
// reader.readAsArrayBuffer(file);
// };
const handleDownload = async () => {
const workbook = new ExcelJS.Workbook();
const worksheet = workbook.addWorksheet('Sheet1');
const headerStyle = {
font: { bold: true },
border: {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' },
},
alignment: { horizontal: 'center', vertical: 'middle' },
};
worksheet.columns = [
{
header: 'CATEGORY NAME',
key: 'CATEGORY',
width: 40,
style: {
...headerStyle,
font: { bold: true, color: { argb: '#000000' } },
},
},
];
// const ProductNameHeaderCell = worksheet.getCell("A1");
// ProductNameHeaderCell.style = {...headerStyle,fill: { type: "pattern", pattern: "solid", fgColor: { argb: "FF2929" } }};
const CategoryNameHeaderCell = worksheet.getCell('A1');
CategoryNameHeaderCell.style = {
...headerStyle,
fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF2929' } },
};
const buffer = await workbook.xlsx.writeBuffer();
const blob = new Blob([buffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
});
const filename = 'CategoryDatas.xlsx';
if (typeof window !== 'undefined') {
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
// For IE browser
window.navigator.msSaveOrOpenBlob(blob, filename);
} else {
// For other browsers
downloadFile(
buffer,
"CategoryDatas.xlsx",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
(success) => {
if (!success) {
console.error("error occured while downloading")
}
}
);
}
}
};
const handleDownload1 = async () => {
const workbook = new ExcelJS.Workbook();
const worksheet = workbook.addWorksheet('Sheet1');
const headerStyle = {
font: { bold: true },
border: {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' },
},
alignment: { horizontal: 'center', vertical: 'middle' },
};
worksheet.columns = [
{
header: 'CATEGORY NAME',
key: 'CATEGORY',
width: 40,
style: {
...headerStyle,
font: { bold: true, color: { argb: '#000000' } },
},
},
{
header: 'Sub-Category NAME',
key: 'Sub',
width: 40,
style: {
...headerStyle,
font: { bold: true, color: { argb: '#000000' } },
},
},
];
for (let i = 1; i <= 1000; i++) {
worksheet.addRow({});
}
const CategoryNameHeaderCell = worksheet.getCell('A1');
CategoryNameHeaderCell.style = {
...headerStyle,
fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF2929' } },
};
worksheet
.getColumn('A')
.eachCell({ includeEmpty: true }, function (cell, rowNumber) {
if (rowNumber > 1) {
const dynamicValidValues = '"' + CategoryNames.join(',') + '"';
cell.dataValidation = {
type: 'list',
allowBlank: true,
formulae: [dynamicValidValues],
};
}
});
const SubCategoryNameHeaderCell = worksheet.getCell('B1');
SubCategoryNameHeaderCell.style = {
...headerStyle,
fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF2929' } },
};
const buffer = await workbook.xlsx.writeBuffer();
const blob = new Blob([buffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
});
const filename = 'SubcatagoryDatas.xlsx';
if (typeof window !== 'undefined') {
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
// For IE browser
window.navigator.msSaveOrOpenBlob(blob, filename);
} else {
// For other browsers
downloadFile(
buffer,
"SubcatagoryDatas.xlsx",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
(success) => {
if (!success) {
console.error("Failed to download the file. Please try again.")
}
}
);
}
}
};
const handleDownload2 = async () => {
const workbook = new ExcelJS.Workbook();
const worksheet = workbook.addWorksheet('Sheet1');
// const hiddenWorksheet = workbook.addWorksheet('HiddenData');
// const dropdownDataSheet = workbook.addWorksheet('DropdownData');
const headerStyle = {
font: { bold: true },
border: {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' },
},
alignment: { horizontal: 'center', vertical: 'middle' },
};
worksheet.columns = [
{
header: 'Sub-Category Name',
key: 'SubCategory',
width: 40,
style: {
...headerStyle,
font: { bold: true, color: { argb: '#000000' } },
},
},
{
header: 'Brand Name',
key: 'Brand',
width: 40,
style: {
...headerStyle,
font: { bold: true, color: { argb: '#000000' } },
},
},
];
let sssss = [
"2,1,Hydserabadi 1s,Biryani2 ,ggie3,Natti4,Hybrid5,99 Dosa's6,super7,juice8,Hyderabadi Biryani9,iryaninks10,Non-ggie11, Clate12,American13,Natti14,Hybrid15,99 Dosa's16,superjuice17,superj18,uicesuperju19,icesuperj20,uice21,Hyderabadi22,Biryani23,iryaninks124",
];
for (let i = 1; i <= 100; i++) {
worksheet.addRow();
}
const SubCategoryNameHeaderCell = worksheet.getCell('A1');
SubCategoryNameHeaderCell.style = {
...headerStyle,
fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF2929' } },
};
for (let i = 0; i < 100; i++) {
worksheet.getCell(`A${i + 2}`).value = SubCatData[i];
}
const dynamicValidValues = `'Sheet1'!$A$2:$A$101`; // Adjust range according to the length of your dropdown data array
// Set data validation for each cell in column A (excluding header)
worksheet
.getColumn('A')
.eachCell({ includeEmpty: true }, function (cell, rowNumber) {
if (rowNumber > 1) {
cell.dataValidation = {
type: 'list',
allowBlank: true,
formulae: [dynamicValidValues],
};
}
});
// SubCatData.forEach((value, index) => {
// dropdownDataSheet.getCell(`A${index + 1}`).value = value;
// });
// const dataValidationRange = `'DropdownData'!$A$1:$A$${SubCatData.length}`; // Reference new sheet
// worksheet.getColumn('A').eachCell((cell, rowNumber) => {
// if (rowNumber > 1) { // Skip header
// cell.dataValidation = {
// type: 'list',
// formulae: [dataValidationRange],
// allowBlank: true
// };
// }
// });
const BrandNameHeaderCell = worksheet.getCell('B1');
BrandNameHeaderCell.style = {
...headerStyle,
fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF2929' } },
};
const buffer = await workbook.xlsx.writeBuffer();
const blob = new Blob([buffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
});
const filename = 'BrandDatas.xlsx';
if (typeof window !== 'undefined') {
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
// For IE browser
window.navigator.msSaveOrOpenBlob(blob, filename);
} else {
// For other browsers
downloadFile(
buffer,
"BrandDatas.xlsx",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
(success) => {
if (!success) {
console.error("Failed to download the file. Please try again.")
}
}
);
}
}
};
// for (let i = 0; i < SubCatData.length; i++) {
// worksheet.getCell(`A${i + 2}`).value = SubCatData[i];
// }
// const dynamicValidValues = `'Sheet1'!$A$2:$A$${SubCatData.length + 1}`;
// console.log(dynamicValidValues,"dynamicValidValuesdynamicValidValuesdynamicValidValues")
// worksheet.getColumn("A").eachCell({ includeEmpty: true }, function (cell, rowNumber) {
// if (rowNumber > 1) {
// cell.dataValidation = {
// type: "list",
// allowBlank: true,
// formulae: [dynamicValidValues],
// };
// }
// });
//-------------------------------------------------------------------------------------------------------
// worksheet.getColumn("A").eachCell({ includeEmpty: true }, function (cell, rowNumber) {
// if (rowNumber > 1) {
// const dynamicValidValues = '"' + sssss.join(",") + '"';
// console.log(dynamicValidValues,"dynamicValidValuesdynamicValidValuesdynamicValidValuesdynamicValidValues")
// cell.dataValidation = {
// type: "list",
// allowBlank: true,
// formulae: [dynamicValidValues],
// };
// }
// });
//-------------------------------------------------------------------------------------------------------------------
// for (let i = 1; i <= 1000; i++) {
// worksheet.addRow();
// }
// worksheet.getColumn("A").eachCell({ includeEmpty: true }, function (cell, rowNumber) {
// if (rowNumber > 1) {
// const dynamicValidValues = '"' + SubCatData.join(",") + '"';
// cell.dataValidation = {
// type: "list",
// allowBlank: true,
// formulae: [dynamicValidValues],
// };
// }
// });
//21 dataa with this dataaa
// File upload submit handler
const handleFileSubmit = (e) => {
e.preventDefault();
if (excelFile === null) {
excelFileError('Please select an Excel file.');
} else {
handleSubmit(Datas);
}
};
const handleCancelData = () => {
dispatch(emptyExcelData());
if (fileInputRef.current) {
fileInputRef.current.value = '';
}
};
const column = parcolumns?.map((col) => {
if (!col.editable) {
return col;
}
let onClickHandler = null;
if (editdelete === 'Delete') {
onClickHandler = (record) => removeFromTable(record);
}
return {
...col,
onCell: (record) => ({
record,
editable: col.editable,
dataIndex: col.dataIndex,
title: col.title,
handleSave,
onClick: () => onClickHandler(record),
}),
};
});
const EditableContext = React.createContext(null);
const EditableRow = ({ index, dataIndex, ...props }) => {
const [form] = Form.useForm();
return (
<Form form={form} component={false}>
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
</Form>
);
};
const EditableCell = ({
title,
editable,
children,
dataIndex,
record,
handleSave,
...restProps
}) => {
const [editing, setEditing] = useState(false);
const inputRef = useRef(null);
const form = useContext(EditableContext);
useEffect(() => {
if (editing) {
inputRef?.current?.focus();
}
}, [editing]);
const toggleEdit = () => {
setEditing(!editing);
form.setFieldsValue({
[dataIndex]: record[dataIndex],
});
};
const save = async () => {
try {
const values = await form.validateFields();
toggleEdit();
handleSave({
...record,
...values,
});
} catch (errInfo) { }
};
let childNode = children;
if (editable) {
childNode = editing ? (
<Form.Item
style={{
margin: 0,
}}
name={dataIndex}
>
<Input ref={inputRef} onPressEnter={save} onBlur={save} />
</Form.Item>
) : (
<div
className="editable-cell-value-wrap"
style={{
paddingRight: 24,
}}
onClick={toggleEdit}
>
{children}
</div>
);
}
return <td {...restProps}>{childNode}</td>;
};
const components = {
body: {
row: EditableRow,
cell: EditableCell,
},
};
const handleSave = (row) => {
const newDatas = [...Datas];
const item = newDatas.filter((item) => item.key === row.key);
const UpdatedData = {
CategoryName: row?.CategoryName,
SubCategoryName: row?.SubCategoryName,
BrandName: row?.BrandName,
};
newDatas.splice(item?.[0]?.key, 1, {
...item?.[0],
...UpdatedData,
});
setDatas(newDatas);
};
const handlechange22 = (index) => {
if (editdelete === 'Delete') {
seteditdelete('');
} else {
seteditdelete('Delete');
}
};
const removeFromTable = (record) => {
const indexToRemove = Datas.findIndex((item) => item.key === record.key);
if (indexToRemove !== -1) {
const updatedDataSource = [...Datas];
updatedDataSource.splice(indexToRemove, 1);
setDatas(updatedDataSource);
}
};
const handleRadioChange = (value) => {
setRadioValue(value);
};
return (
<div className="container">
<div className="form">
<form
className="form-group"
autoComplete="off"
onSubmit={handleFileSubmit}
>
<div>
<RadioGrpButton
content={[
{ value: 'Category Name', label: 'Category Name' },
{ value: 'Sub-Category Name', label: 'Sub-Category Name' },
{ value: 'Brand Name', label: 'Brand Name' },
]}
defaultSelect={radioValue}
onSelectFuntion={(value) => {
handleRadioChange(value);
}}
/>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<label>
<h3>UPLOAD YOUR EXCEL</h3>
</label>
{excelData?.length > 0 && excelData && (
<div>
<Tooltip title="Delete">
<AiFillDelete
onClick={handlechange22}
style={{
fontSize: '23px',
color: editdelete ? '#52c41a' : '#1292ee',
}}
/>
</Tooltip>
</div>
)}
</div>
<br />
{(!excelData || excelData?.length === 0) && (
<>
<div style={{ display: 'flex', alignItems: 'center' }}>
<div style={{ position: 'relative', display: 'inline-block' }}>
{/* <Imageupload size="2x" /> */}
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<img
src={upldimg}
width={'80px'}
style={{ cursor: 'pointer' }}
onClick={handleClick}
/>
<input
type="file"
className="form-control"
onChange={handleFileUpload}
ref={fileInputRef}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
opacity: 0,
cursor: 'pointer',
}}
/>
<a style={{ color: '#000' }}> Upload File </a>
</div>
</div>
</div>
</>
)}
{/* {radioValue === 'Category Name' && (
<button id="Category Name" className="download-link" onClick={handleDownload}>
Download File
</button>
)}
{radioValue === 'Sub-Category Name' && (
<button id ="Sub-Category Name" className="download-link" onClick={handleDownload1}>
Download File
</button>
)}
{radioValue === 'Brand Name' && (
<button id ="Brand Name" className="download-link" onClick={handleDownload2}>
Download File
</button>
)}
<button
className="cancel-link"
onClick={handleCancelData}
style={{ marginLeft: "140px" }}
>
<span role="img" aria-label="cancel-symbol">
&#10060;
</span>
Remove File
</button> */}
{excelFileError && (
<div className="text-danger" style={{ marginTop: '5px' }}>
{excelFileError}
</div>
)}
</form>
</div>
<div
className="viewerExcelupload"
style={{ maxHeight: '500px', width: '600px' }}
>
{excelData && excelData.length > 0 ? (
<Table
columns={column}
components={components}
bordered
dataSource={Datas}
onChange={handleTableChange}
></Table>
) : (
<p></p>
)}
</div>
<div
style={{
display: 'flex',
alignItems: 'center',
width: '100%',
gap: '2rem',
margin: '1rem 0rem',
}}
>
{radioValue === 'Category Name' && (
<Tooltip title="Format Sheet" placement="bottom">
<div
className="download-link"
onClick={handleDownload}
style={{
display: 'flex',
alignItems: 'center',
gap: '.5rem',
padding: '0.3rem 0.4rem',
borderRadius: '6px',
backgroundColor: 'ghostwhite',
}}
>
<FiDownload style={{ fontSize: '20px' }} />
<a style={{ color: '#000' }}> Download</a>
</div>
</Tooltip>
)}
{radioValue === 'Sub-Category Name' && (
<Tooltip title="Format Sheet" placement="bottom">
<div
className="download-link"
onClick={handleDownload1}
style={{
display: 'flex',
alignItems: 'center',
gap: '.5rem',
padding: '0.3rem 0.4rem',
borderRadius: '6px',
backgroundColor: 'ghostwhite',
}}
>
<FiDownload style={{ fontSize: '20px' }} />
<a style={{ color: '#000' }}> Download</a>
</div>
</Tooltip>
)}
{radioValue === 'Brand Name' && (
<Tooltip title="Format Sheet" placement="bottom">
<div
className="download-link"
onClick={handleDownload2}
style={{
display: 'flex',
alignItems: 'center',
gap: '.5rem',
padding: '0.3rem 0.4rem',
borderRadius: '6px',
backgroundColor: 'ghostwhite',
}}
>
<FiDownload style={{ fontSize: '20px' }} />
<a style={{ color: '#000' }}> Download</a>
</div>
</Tooltip>
)}
{excelData && excelData?.length > 0 && (
<div
className="cancel-link"
onClick={handleCancelData}
style={{
display: 'flex',
alignItems: 'center',
gap: '.5rem',
padding: '0.3rem 0.4rem',
borderRadius: '6px',
backgroundColor: 'ghostwhite',
}}
>
<FiDelete style={{ fontSize: '20px', color: '#1292EE' }} />
<a style={{ color: '#000' }}> Remove File</a>
</div>
)}
</div>
</div>
);
};
export default ConfigExcel;