Updated version

This commit is contained in:
louai98 2023-07-31 09:59:28 +02:00
parent 9cb8fe4f73
commit c1933dccfa
7 changed files with 124 additions and 65 deletions

28
package-lock.json generated
View File

@ -22,6 +22,7 @@
"d3": "^7.8.4", "d3": "^7.8.4",
"d3-cloud": "^1.2.5", "d3-cloud": "^1.2.5",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"js-file-download": "^0.4.12",
"react": "^18.2.0", "react": "^18.2.0",
"react-bootstrap": "^2.7.4", "react-bootstrap": "^2.7.4",
"react-d3-cloud": "^1.0.6", "react-d3-cloud": "^1.0.6",
@ -29,7 +30,8 @@
"react-pdf": "^6.2.2", "react-pdf": "^6.2.2",
"react-scripts": "^5.0.1", "react-scripts": "^5.0.1",
"react-spinners": "^0.13.8", "react-spinners": "^0.13.8",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4",
"worker-loader": "^3.0.8"
} }
}, },
"node_modules/@adobe/css-tools": { "node_modules/@adobe/css-tools": {
@ -12904,6 +12906,11 @@
"jiti": "bin/jiti.js" "jiti": "bin/jiti.js"
} }
}, },
"node_modules/js-file-download": {
"version": "0.4.12",
"resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz",
"integrity": "sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg=="
},
"node_modules/js-sdsl": { "node_modules/js-sdsl": {
"version": "4.4.0", "version": "4.4.0",
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz",
@ -19040,6 +19047,25 @@
"workbox-core": "6.5.4" "workbox-core": "6.5.4"
} }
}, },
"node_modules/worker-loader": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-3.0.8.tgz",
"integrity": "sha512-XQyQkIFeRVC7f7uRhFdNMe/iJOdO6zxAaR3EWbDp45v3mDhrTi+++oswKNxShUNjPC/1xUp5DB29YKLhFo129g==",
"dependencies": {
"loader-utils": "^2.0.0",
"schema-utils": "^3.0.0"
},
"engines": {
"node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"webpack": "^4.0.0 || ^5.0.0"
}
},
"node_modules/wrap-ansi": { "node_modules/wrap-ansi": {
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",

View File

@ -17,6 +17,7 @@
"d3": "^7.8.4", "d3": "^7.8.4",
"d3-cloud": "^1.2.5", "d3-cloud": "^1.2.5",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"js-file-download": "^0.4.12",
"react": "^18.2.0", "react": "^18.2.0",
"react-bootstrap": "^2.7.4", "react-bootstrap": "^2.7.4",
"react-d3-cloud": "^1.0.6", "react-d3-cloud": "^1.0.6",
@ -24,7 +25,8 @@
"react-pdf": "^6.2.2", "react-pdf": "^6.2.2",
"react-scripts": "^5.0.1", "react-scripts": "^5.0.1",
"react-spinners": "^0.13.8", "react-spinners": "^0.13.8",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4",
"worker-loader": "^3.0.8"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",

View File

@ -6,13 +6,17 @@ import Filter from "./Components/Layout/Filter/Filter";
import ComplainceFilter from "./Components/Layout/Filter/ComplainceFilter"; import ComplainceFilter from "./Components/Layout/Filter/ComplainceFilter";
import Results from "./Components/Layout/Results/Results"; import Results from "./Components/Layout/Results/Results";
import AppliedFilters from "./Components/Layout/AppliedFilters/AppliedFilters"; import AppliedFilters from "./Components/Layout/AppliedFilters/AppliedFilters";
import IddrsImg from "./Static/Imgs/IDDRS.png" import IddrsImg from "./Static/Imgs/IDDRS.png";
import axios from "axios"; import axios from "axios";
import FeaturedQuestions from "./Components/Layout/FeaturedQuestions/FeaturedQuestions"; import FeaturedQuestions from "./Components/Layout/FeaturedQuestions/FeaturedQuestions";
import WordCloud_ from "./Components/Layout/WordCloud_/WordCloud_"; import WordCloud_ from "./Components/Layout/WordCloud_/WordCloud_";
import Stack from "react-bootstrap/esm/Stack"; import Stack from "react-bootstrap/esm/Stack";
import Container from "react-bootstrap/esm/Container"; import Container from "react-bootstrap/esm/Container";
import Image from 'react-bootstrap/Image'; import Image from "react-bootstrap/Image";
import Button from "react-bootstrap/esm/Button";
import { saveAs } from 'file-saver';
import ClipLoader from "react-spinners/ClipLoader";
import Classes from "./App.module.css";
function App() { function App() {
const [data, setData] = useState(""); const [data, setData] = useState("");
@ -22,6 +26,7 @@ function App() {
const [filteredResults, setFilteredResults] = useState([]); const [filteredResults, setFilteredResults] = useState([]);
const [filtersComplaince, setFiltersComplaince] = useState([]); const [filtersComplaince, setFiltersComplaince] = useState([]);
const [filtersStandards, setFiltersStandards] = useState([]); const [filtersStandards, setFiltersStandards] = useState([]);
const [loading, setLoading] = useState(false);
// the useEffect hook is used to apply filters whenever the results, // the useEffect hook is used to apply filters whenever the results,
// filtersStandards, or filtersComplaince values change // filtersStandards, or filtersComplaince values change
@ -34,31 +39,40 @@ function App() {
//################################################################################ //################################################################################
const handleSubmit = (event) => { const handleSubmit = (event) => {
event.preventDefault(); event.preventDefault();
setLoading(true);
// Send the input value to Django // Send the input value to Django
axios axios
.post("http://localhost:8000/client_api/get_input/", { data }) .post("http://localhost:8000/client_api/get_input/", { data })
.then((response) => { .then((response) => {
setPhrase(data['phrase']) setPhrase(data["phrase"]);
setResults(response.data.results); setResults(response.data.results);
setShowResults(true) setShowResults(true);
setFilteredResults(response.data.results); setFilteredResults(response.data.results);
setLoading(false);
}) })
.catch((error) => { .catch((error) => {
console.log(error); console.log(error);
setLoading(false);
}); });
}; };
const handleSubmit_ = (value) => { const handleSubmit_ = (value) => {
setLoading(true);
// Send the input value to Django // Send the input value to Django
axios axios
.post("http://localhost:8000/client_api/get_input/", { data: { phrase: value } }) .post("http://localhost:8000/client_api/get_input/", {
data: { phrase: value },
})
.then((response) => { .then((response) => {
setPhrase(value);
setShowResults(true); setShowResults(true);
setResults(response.data.results); setResults(response.data.results);
setFilteredResults(response.data.results); setFilteredResults(response.data.results);
setLoading(false);
}) })
.catch((error) => { .catch((error) => {
console.log(error); console.log(error);
setLoading(false);
}); });
}; };
@ -112,6 +126,28 @@ function App() {
}); });
}; };
//#################################################################################
// function to export the results as a pdf file
const handleExportPDF = async () => {
setLoading(true);
try {
const response = await axios.post("http://localhost:8000/client_api/exportPDF/", {
params: {
filteredResults: filteredResults, // Replace with the actual filtered results data
phrase: phrase, // Replace with the actual phrase data
},
});
// The response will contain the PDF file data, and you can use it as needed (e.g., to display or download the PDF)
const blob = new Blob([response.data], { type: 'application/pdf' });
saveAs(blob, 'output.pdf');
setLoading(false);
} catch (error) {
console.error('Error exporting PDF:', error);
setLoading(false);
}
};
return ( return (
<main> <main>
<Container> <Container>
@ -122,20 +158,36 @@ function App() {
<ComplainceFilter onFilterChange={handleComplainceFilterChange} /> <ComplainceFilter onFilterChange={handleComplainceFilterChange} />
)} )}
{filtersStandards.length > 0 && <AppliedFilters standards={filtersStandards} />} {filtersStandards.length > 0 && (
<AppliedFilters standards={filtersStandards} />
)}
{showResults && (
<Button onClick={handleExportPDF}>Export | PDF</Button>
)}
{showResults && ( {showResults && (
<Results <Results
results={filteredResults} results={filteredResults}
complainceFilter={filtersComplaince} complainceFilter={filtersComplaince}
searchedPhrase = {phrase} searchedPhrase={phrase}
/> />
)} )}
<Stack className="mt-5" direction="horizontal" gap={2}> <Stack className="mt-5" direction="horizontal" gap={2}>
<FeaturedQuestions handleButtonClick={handleSubmit_} /> <FeaturedQuestions handleButtonClick={handleSubmit_} />
<WordCloud_ handleButtonClick={handleSubmit_}/> <WordCloud_ handleButtonClick={handleSubmit_} />
</Stack> </Stack>
{loading && (
<div
className={`d-flex justify-content-center align-items-center ${Classes.overlay}`}
>
<ClipLoader
size={150}
color="#ffffff"
aria-label="Loading Spinner"
></ClipLoader>
</div>
)}
</Container> </Container>
</main> </main>
); );

9
src/App.module.css Normal file
View File

@ -0,0 +1,9 @@
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5); /* Adjust the opacity as needed */
z-index: 9999;
}

View File

@ -4,7 +4,7 @@ import Stack from "react-bootstrap/Stack";
import ResultsItem from "./ResultsItem"; import ResultsItem from "./ResultsItem";
import ResultModal from "../../UI/ResultModal/ResultModal"; import ResultModal from "../../UI/ResultModal/ResultModal";
import ResultsPagination from "../../UI/ResultsPagination/ResultsPagination"; import ResultsPagination from "../../UI/ResultsPagination/ResultsPagination";
//import PDFGenerator from "../../PDFGenerator/PDFGenerator"; import PDFGenerator from "../../PDFGenerator/PDFGenerator";
const Results = (props) => { const Results = (props) => {
const [showModal, setShowModal] = useState(false); const [showModal, setShowModal] = useState(false);

View File

@ -7,13 +7,11 @@ import {
View, View,
StyleSheet, StyleSheet,
Font, Font,
pdf,createWorker pdf,
} from "@react-pdf/renderer"; } from "@react-pdf/renderer";
import { saveAs } from "file-saver"; import { saveAs } from "file-saver";
import { css } from "@emotion/react";
import ClipLoader from "react-spinners/ClipLoader";
//import { createWorker } from "@react-pdf-viewer/core"; // Import the createWorker function
// Register font
Font.register({ family: "Times-Roman" }); Font.register({ family: "Times-Roman" });
const styles = StyleSheet.create({ const styles = StyleSheet.create({
@ -38,48 +36,32 @@ const PDFGenerator = (props) => {
setIsLoading(true); setIsLoading(true);
try { try {
const worker = createWorker(); // Create a new web worker const views = props.results.map((result, index) => (
<Fragment key={index}>
await worker.load(); // Load the worker <Text style={[styles.text, styles.title]}>
await worker.setFont("path/to/font/Times-Roman.ttf"); // Set the font path Level {result.LevelName}
</Text>
worker.onRenderError(() => { <Text style={[styles.text, styles.title]}>
console.error("Error generating PDF"); IDDRS - {result.Module}
setIsLoading(false); </Text>
}); <Text style={styles.text}>{result.Heading1}</Text>
<Text style={styles.text}>{result.Heading2}</Text>
worker.onRenderProgress((percent) => { <Text style={styles.text}>{result.Heading3}</Text>
console.log(`PDF rendering progress: ${percent}%`); <Text style={styles.text}>{result.Heading4}</Text>
}); <Text style={styles.text}>{result.Paragraph}</Text>
<Text style={styles.text}>{result.PageNum}</Text>
</Fragment>
));
const pdfContent = ( const pdfContent = (
<Document> <Document>
<Page size="A4" style={styles.page}> <Page size="A4" style={styles.page}>
<View style={styles.content}> <View style={styles.content}>{views}</View>
{props.results.map((result, index) => (
<Fragment key={index}>
<Text style={[styles.text, styles.title]}>
Level {result.LevelName}
</Text>
<Text style={[styles.text, styles.title]}>
IDDRS - {result.Module}
</Text>
<Text style={styles.text}>{result.Heading1}</Text>
<Text style={styles.text}>{result.Heading2}</Text>
<Text style={styles.text}>{result.Heading3}</Text>
<Text style={styles.text}>{result.Heading4}</Text>
<Text style={styles.text}>{result.Paragraph}</Text>
<Text style={styles.text}>{result.PageNum}</Text>
</Fragment>
))}
</View>
</Page> </Page>
</Document> </Document>
); );
const result = await worker.renderToString(pdfContent); // Render the PDF content using the web worker const pdfBlob = await pdf(pdfContent).toBlob();
const pdfBlob = new Blob([result], { type: "application/pdf" });
saveAs(pdfBlob, "IDDRS.pdf"); saveAs(pdfBlob, "IDDRS.pdf");
} catch (error) { } catch (error) {
console.error("Error generating PDF:", error); console.error("Error generating PDF:", error);
@ -91,22 +73,10 @@ const PDFGenerator = (props) => {
return ( return (
<div> <div>
<Button onClick={handleDownload} disabled={isLoading}> <Button onClick={handleDownload} disabled={isLoading}>
{isLoading ? ( {isLoading ? "Generating PDF..." : "Generate and Download PDF"}
<ClipLoader
css={css`
display: block;
margin: 0 auto;
border-color: red;
`}
size={20}
color={"#ffffff"}
loading={isLoading}
/>
) : (
"Generate and Download PDF"
)}
</Button> </Button>
</div> </div>
); );
}; };
export default PDFGenerator; export default PDFGenerator;