From 5a26ec7ee1f2f951eb661e913bc88b312a76e6cf Mon Sep 17 00:00:00 2001 From: Kwizera Pacifique Date: Mon, 7 Aug 2023 15:22:54 +0200 Subject: [PATCH] bg(): fixed export csv/pdf button --- package.json | 3 + src/components/PDFexport.tsx | 75 +++++++++++++++++ src/helpers/exportTocsv.ts | 151 ++++++++++++++++++++++++++++++++++ src/pages/TrainneeDetails.tsx | 29 ++++++- src/redux/actions/trainnee.ts | 1 - webpack.config.js | 2 +- 6 files changed, 255 insertions(+), 6 deletions(-) create mode 100644 src/components/PDFexport.tsx create mode 100644 src/helpers/exportTocsv.ts diff --git a/package.json b/package.json index 96d2d93b..06b83ba7 100755 --- a/package.json +++ b/package.json @@ -77,9 +77,11 @@ "@hookform/resolvers": "^3.3.0", "@mui/material": "^5.10.11", "@mui/x-date-pickers": "^5.0.6", + "@react-pdf/renderer": "^3.1.12", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@tinymce/tinymce-react": "^4.2.0", + "@types/file-saver": "^2.0.5", "@types/react-i18next": "^8.1.0", "@types/react-router": "^5.1.19", "@types/react-router-dom": "^5.3.3", @@ -88,6 +90,7 @@ "browser": "^0.2.6", "date-fns": "^2.29.3", "dotenv": "^16.0.3", + "file-saver": "^2.0.5", "flowbite": "^1.5.3", "formik": "^2.4.3", "googleapis": "^126.0.1", diff --git a/src/components/PDFexport.tsx b/src/components/PDFexport.tsx new file mode 100644 index 00000000..605ea018 --- /dev/null +++ b/src/components/PDFexport.tsx @@ -0,0 +1,75 @@ +import React from "react"; +import { + PDFViewer, + PDFDownloadLink, + Document, + Page, + View, + Text, + StyleSheet, +} from "@react-pdf/renderer"; +import { saveAs } from "file-saver"; + +const styles = StyleSheet.create({ + page: { + flexDirection: "row", + }, + section: { + margin: 10, + padding: 2, + flexGrow: 1, + }, + group: { + flexDirection: "column", + gap: 10, + }, +}); + +const PDFExport = ({ obj1, obj2 }) => ( + + + + + First name: {obj2.firstName} + Gender: {obj1.gender} + Address: {obj1.Address} + Phone number: {obj1.phone} + Field of study: {obj1.field_of_study} + Education level: {obj1.education_level} + Is employed: {obj1.isEmployed ? "true" : "false"} + Email: {obj2.email} + + + + + Province: {obj1.province} + District: {obj1.district} + Sector: {obj1.sector} + Is student: {obj1.isStudent ? "true" : "false"} + Hackerrank score: {obj1.Hackerrank_score} + English score: {obj1.english_score} + + + + + } + fileName={"export-doc.pdf"} + > + {({ blob, url, loading, error }) => ( + + )} + +); + +export default PDFExport; diff --git a/src/helpers/exportTocsv.ts b/src/helpers/exportTocsv.ts new file mode 100644 index 00000000..bfd0c7dc --- /dev/null +++ b/src/helpers/exportTocsv.ts @@ -0,0 +1,151 @@ +export const dataTocsv = ( + obj1: { + _id: string; + gender: string; + Address: string; + birth_date: string; + phone: string; + field_of_study: string; + education_level: string; + province: string; + district: string; + sector: string; + isEmployed: boolean; + haveLaptop: boolean; + isStudent: boolean; + Hackerrank_score: any; + english_score: any; + interview_decision: any; + past_andela_programs: any; + }, + obj2: { + lastName: string; + firstName: string; + _id: string; + email: string; + } +) => { + let allObjects: any = []; + let dataList: { + _id: string; + gender: string; + Address: string; + birth_date: string; + phone: string; + field_of_study: string; + education_level: string; + province: string; + district: string; + sector: string; + isEmployed: boolean; + haveLaptop: boolean; + isStudent: boolean; + Hackerrank_score: any; + english_score: any; + interview_decision: any; + past_andela_programs: any; + lastName: string; + firstName: string; + email: string; + }[] = []; + let traineeObj = Object.assign(obj1, obj2); + + dataList.push(traineeObj); + let headers: string[] = [ + "First name,last name,email,gender,Address,birth date,phone,field of study,education level,province,district,sector,isEmployed,haveLaptop,isStudent,Hackerrank score,english score,interview decision,past andela programs", + ]; + for (const item of dataList) { + let arr: any[] = []; + arr.push(item.firstName); + arr.push(item.lastName); + arr.push(item.email); + arr.push(item.gender); + arr.push(item.Address); + arr.push(item.birth_date); + arr.push(item.phone); + arr.push(item.field_of_study); + arr.push(item.education_level); + arr.push(item.province); + arr.push(item.district); + arr.push(item.sector); + arr.push(item.isEmployed); + arr.push(item.haveLaptop); + arr.push(item.isStudent); + arr.push(item.Hackerrank_score); + arr.push(item.english_score); + arr.push(item.interview_decision); + arr.push(item.past_andela_programs); + + allObjects.push(arr); + } + + let traineeCsv = dataList.reduce((acc: any, trainee) => { + const { + _id, + gender, + Address, + birth_date, + phone, + field_of_study, + education_level, + province, + district, + sector, + isEmployed, + haveLaptop, + isStudent, + Hackerrank_score, + english_score, + interview_decision, + past_andela_programs, + lastName, + firstName, + email, + } = trainee; + acc.push( + [ + firstName, + lastName, + email, + gender, + Address, + birth_date, + phone, + field_of_study, + education_level, + province, + district, + sector, + isEmployed, + haveLaptop, + isStudent, + Hackerrank_score, + english_score, + interview_decision, + past_andela_programs, + ].join(",") + ); + return acc; + }, []); + + downloadFile({ + data: [...headers, ...traineeCsv].join("\n"), + fileName: `trainee_${traineeObj.firstName}`, + fileType: "text/csv", + }); +}; + +const downloadFile = ({ data, fileName, fileType }) => { + const blob = new Blob([data], { type: fileType }); + + const a = document.createElement("a"); + a.download = fileName; + a.href = window.URL.createObjectURL(blob); + const clickEvt = new MouseEvent("click", { + view: window, + bubbles: true, + cancelable: true, + }); + a.dispatchEvent(clickEvt); + a.remove(); +}; diff --git a/src/pages/TrainneeDetails.tsx b/src/pages/TrainneeDetails.tsx index 4908f84e..aea441ac 100644 --- a/src/pages/TrainneeDetails.tsx +++ b/src/pages/TrainneeDetails.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useRef } from "react"; import { BsEnvelope } from "react-icons/bs"; import { TiExportOutline } from "react-icons/ti"; import { FcApproval } from "react-icons/fc"; @@ -15,6 +15,10 @@ import { updateManyScoreValues, } from "../redux/actions/scoreValueActions"; import { toast } from "react-toastify"; +import { Link } from "react-router-dom"; +import { dataTocsv } from "../helpers/exportTocsv"; + +import PDFExport from "../components/PDFexport"; const TrainneeDetails = (props: any) => { const params = useParams(); @@ -83,6 +87,8 @@ const TrainneeDetails = (props: any) => { props.updateManyScoreValues(tsabus); }; + const divRef = useRef(null); + return ( <> @@ -90,7 +96,10 @@ const TrainneeDetails = (props: any) => { {/*
*/}
{traineeDetails && ( -
+

@@ -299,9 +308,21 @@ const TrainneeDetails = (props: any) => { {open && (
  • - Export to PDF + {/* + Export to PDF + */} + +
  • +
  • + + dataTocsv(traineeDetails, traineeDetails.trainee_id) + } + > + Export to CSV +
  • -
  • Export to CSV
)} diff --git a/src/redux/actions/trainnee.ts b/src/redux/actions/trainnee.ts index cfbe882a..2fe37ceb 100644 --- a/src/redux/actions/trainnee.ts +++ b/src/redux/actions/trainnee.ts @@ -50,7 +50,6 @@ export const getOneTraineeAllDetails = }); const response = await datas.data.data.getOneTraineeAllDetails; - // console.log( response) dispatch(creator(GET_ONE_TRAINEES_ALL_DETAILS, response)); } catch (error) { if (error) { diff --git a/webpack.config.js b/webpack.config.js index 3a42e5ae..a60df0ab 100755 --- a/webpack.config.js +++ b/webpack.config.js @@ -64,7 +64,7 @@ module.exports = () => { "process.env": JSON.stringify(process.env), }), new webpack.ProvidePlugin({ - process: "process/browser", + process: 'process/browser', }), ], };