Upload Project

This commit is contained in:
louai98 2023-11-20 15:21:28 +01:00
parent c1933dccfa
commit 7b5ede438a
18 changed files with 418 additions and 57 deletions

264
package-lock.json generated
View File

@ -22,6 +22,8 @@
"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",
"html-react-parser": "^4.2.2",
"interweave": "^13.1.0",
"js-file-download": "^0.4.12", "js-file-download": "^0.4.12",
"react": "^18.2.0", "react": "^18.2.0",
"react-bootstrap": "^2.7.4", "react-bootstrap": "^2.7.4",
@ -30,6 +32,7 @@
"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",
"sbd": "^1.0.19",
"web-vitals": "^2.1.4", "web-vitals": "^2.1.4",
"worker-loader": "^3.0.8" "worker-loader": "^3.0.8"
} }
@ -10136,6 +10139,84 @@
"resolved": "https://registry.npmjs.org/hsl-to-rgb-for-reals/-/hsl-to-rgb-for-reals-1.1.1.tgz", "resolved": "https://registry.npmjs.org/hsl-to-rgb-for-reals/-/hsl-to-rgb-for-reals-1.1.1.tgz",
"integrity": "sha512-LgOWAkrN0rFaQpfdWBQlv/VhkOxb5AsBjk6NQVx4yEzWS923T07X0M1Y0VNko2H52HeSpZrZNNMJ0aFqsdVzQg==" "integrity": "sha512-LgOWAkrN0rFaQpfdWBQlv/VhkOxb5AsBjk6NQVx4yEzWS923T07X0M1Y0VNko2H52HeSpZrZNNMJ0aFqsdVzQg=="
}, },
"node_modules/html-dom-parser": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-4.0.0.tgz",
"integrity": "sha512-TUa3wIwi80f5NF8CVWzkopBVqVAtlawUzJoLwVLHns0XSJGynss4jiY0mTWpiDOsuyw+afP+ujjMgRh9CoZcXw==",
"dependencies": {
"domhandler": "5.0.3",
"htmlparser2": "9.0.0"
}
},
"node_modules/html-dom-parser/node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/html-dom-parser/node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/html-dom-parser/node_modules/domutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/html-dom-parser/node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/html-dom-parser/node_modules/htmlparser2": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.0.0.tgz",
"integrity": "sha512-uxbSI98wmFT/G4P2zXx4OVx04qWUmyFPrD2/CNepa2Zo3GPNaCaaxElDgwUrwYWkK1nr9fft0Ya8dws8coDLLQ==",
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3",
"domutils": "^3.1.0",
"entities": "^4.5.0"
}
},
"node_modules/html-encoding-sniffer": { "node_modules/html-encoding-sniffer": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
@ -10177,6 +10258,34 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/html-react-parser": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-4.2.2.tgz",
"integrity": "sha512-lh0wEGISnFZEAmvQqK4xc0duFMUh/m9YYyAhFursWxdtNv+hCZge0kj1y4wep6qPB5Zm33L+2/P6TcGWAJJbjA==",
"dependencies": {
"domhandler": "5.0.3",
"html-dom-parser": "4.0.0",
"react-property": "2.0.0",
"style-to-js": "1.1.4"
},
"peerDependencies": {
"react": "0.14 || 15 || 16 || 17 || 18"
}
},
"node_modules/html-react-parser/node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/html-webpack-plugin": { "node_modules/html-webpack-plugin": {
"version": "5.5.1", "version": "5.5.1",
"resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.1.tgz", "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.1.tgz",
@ -10447,6 +10556,11 @@
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
}, },
"node_modules/inline-style-parser": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz",
"integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q=="
},
"node_modules/internal-slot": { "node_modules/internal-slot": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz",
@ -10468,6 +10582,21 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/interweave": {
"version": "13.1.0",
"resolved": "https://registry.npmjs.org/interweave/-/interweave-13.1.0.tgz",
"integrity": "sha512-JIDq0+2NYg0cgL7AB26fBcV0yZdiJvPDBp+aF6k8gq6Cr1kH5Gd2/Xqn7j8z+TGb8jCWZn739jzalCz+nPYwcA==",
"dependencies": {
"escape-html": "^1.0.3"
},
"funding": {
"type": "ko-fi",
"url": "https://ko-fi.com/milesjohnson"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/invariant": { "node_modules/invariant": {
"version": "2.2.4", "version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
@ -10712,6 +10841,14 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-potential-custom-element-name": { "node_modules/is-potential-custom-element-name": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
@ -14020,6 +14157,11 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/parse-srcset": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
"integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q=="
},
"node_modules/parse-svg-path": { "node_modules/parse-svg-path": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz", "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
@ -16048,6 +16190,11 @@
} }
} }
}, },
"node_modules/react-property": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/react-property/-/react-property-2.0.0.tgz",
"integrity": "sha512-kzmNjIgU32mO4mmH5+iUyrqlpFQhF8K2k7eZ4fdLSOPFrD1XgEuSBv9LDEgxRXTMBqMd8ppT0x6TIzqE5pdGdw=="
},
"node_modules/react-refresh": { "node_modules/react-refresh": {
"version": "0.11.0", "version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@ -16653,6 +16800,99 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
}, },
"node_modules/sanitize-html": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.11.0.tgz",
"integrity": "sha512-BG68EDHRaGKqlsNjJ2xUB7gpInPA8gVx/mvjO743hZaeMCZ2DwzW7xvsqZ+KNU4QKwj86HJ3uu2liISf2qBBUA==",
"dependencies": {
"deepmerge": "^4.2.2",
"escape-string-regexp": "^4.0.0",
"htmlparser2": "^8.0.0",
"is-plain-object": "^5.0.0",
"parse-srcset": "^1.0.2",
"postcss": "^8.3.11"
}
},
"node_modules/sanitize-html/node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/sanitize-html/node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/sanitize-html/node_modules/domutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/sanitize-html/node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/sanitize-html/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/sanitize-html/node_modules/htmlparser2": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
"integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3",
"domutils": "^3.0.1",
"entities": "^4.4.0"
}
},
"node_modules/sanitize.css": { "node_modules/sanitize.css": {
"version": "13.0.0", "version": "13.0.0",
"resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz",
@ -16711,6 +16951,14 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/sbd": {
"version": "1.0.19",
"resolved": "https://registry.npmjs.org/sbd/-/sbd-1.0.19.tgz",
"integrity": "sha512-b5RyZMGSrFuIB4AHdbv12uYHS8YGEJ36gtuvG3RflbJGY+T0dXmAL0E4vZjQqT2RsX0v+ZwVqhV2zsGr5aFK9w==",
"dependencies": {
"sanitize-html": "^2.3.2"
}
},
"node_modules/scheduler": { "node_modules/scheduler": {
"version": "0.23.0", "version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
@ -17318,6 +17566,22 @@
"webpack": "^5.0.0" "webpack": "^5.0.0"
} }
}, },
"node_modules/style-to-js": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.4.tgz",
"integrity": "sha512-zEeU3vy9xL/hdLBFmzqjhm+2vJ1Y35V0ctDeB2sddsvN1856OdMZUCOOfKUn3nOjjEKr6uLhOnY4CrX6gLDRrA==",
"dependencies": {
"style-to-object": "0.4.2"
}
},
"node_modules/style-to-object": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.2.tgz",
"integrity": "sha512-1JGpfPB3lo42ZX8cuPrheZbfQ6kqPPnPHlKMyeRYtfKD+0jG+QsXgXN57O/dvJlzlB2elI6dGmrPnl5VPQFPaA==",
"dependencies": {
"inline-style-parser": "0.1.1"
}
},
"node_modules/stylehacks": { "node_modules/stylehacks": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz",

View File

@ -17,6 +17,8 @@
"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",
"html-react-parser": "^4.2.2",
"interweave": "^13.1.0",
"js-file-download": "^0.4.12", "js-file-download": "^0.4.12",
"react": "^18.2.0", "react": "^18.2.0",
"react-bootstrap": "^2.7.4", "react-bootstrap": "^2.7.4",
@ -25,6 +27,7 @@
"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",
"sbd": "^1.0.19",
"web-vitals": "^2.1.4", "web-vitals": "^2.1.4",
"worker-loader": "^3.0.8" "worker-loader": "^3.0.8"
}, },

View File

@ -6,9 +6,9 @@ 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 Logos from "./Components/Layout/Logos/Logos";
import IddrsImg from "./Imgs/IDDRS.png";
import axios from "axios"; import axios from "axios";
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";
@ -27,6 +27,11 @@ function App() {
const [filtersComplaince, setFiltersComplaince] = useState([]); const [filtersComplaince, setFiltersComplaince] = useState([]);
const [filtersStandards, setFiltersStandards] = useState([]); const [filtersStandards, setFiltersStandards] = useState([]);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [currentPage, setCurrentPage] = useState(1);
const [standardsFilter, setStandardsFilter] = useState([]);
const [score, setScore] = useState(8);
// 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
@ -40,14 +45,19 @@ function App() {
const handleSubmit = (event) => { const handleSubmit = (event) => {
event.preventDefault(); event.preventDefault();
setLoading(true); setLoading(true);
setFiltersStandards([]);
setFiltersComplaince([]);
setCurrentPage(1) //test
// 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[0]); // The recived data from this api is a tuple of (results, min_score), thats why we used [0]
setShowResults(true); setShowResults(true);
setFilteredResults(response.data.results); setFilteredResults(response.data.results[0]);// The recived data from this api is a tuple of (results, min_score), thats why we used [0]
setScore(response.data.results[1]) // The recived data from this api is a tuple of (results, min_score), thats why we used [1]
setLoading(false); setLoading(false);
}) })
.catch((error) => { .catch((error) => {
@ -58,6 +68,7 @@ function App() {
const handleSubmit_ = (value) => { const handleSubmit_ = (value) => {
setLoading(true); setLoading(true);
setCurrentPage(1) //test
// Send the input value to Django // Send the input value to Django
axios axios
.post("http://localhost:8000/client_api/get_input/", { .post("http://localhost:8000/client_api/get_input/", {
@ -66,8 +77,9 @@ function App() {
.then((response) => { .then((response) => {
setPhrase(value); setPhrase(value);
setShowResults(true); setShowResults(true);
setResults(response.data.results); setResults(response.data.results[0]);// The recived data from this api is a tuple of (results, min_score), thats why we used [0]
setFilteredResults(response.data.results); setFilteredResults(response.data.results[0]);// The recived data from this api is a tuple of (results, min_score), thats why we used [0]
setScore(response.data.results[1])// The recived data from this api is a tuple of (results, min_score), thats why we used [1]
setLoading(false); setLoading(false);
}) })
.catch((error) => { .catch((error) => {
@ -85,7 +97,7 @@ function App() {
// Apply the Standards filter if it is provided, Array#some method checks if at least one // Apply the Standards filter if it is provided, Array#some method checks if at least one
// element in filter1 matches the result.Title value. // element in filter1 matches the result.Title value.
if (filter1.length > 0) { if (filter1.length > 0) {
console.log("filter1");
filteredResults__ = filteredResults__.filter((result) => { filteredResults__ = filteredResults__.filter((result) => {
return filter1.some((filter) => filter == result.Title); return filter1.some((filter) => filter == result.Title);
}); });
@ -93,7 +105,7 @@ function App() {
// Apply the second filter if it is provided // Apply the second filter if it is provided
if (filter2.length > 0) { if (filter2.length > 0) {
console.log("filter2");
filteredResults__ = filteredResults__.filter((result) => { filteredResults__ = filteredResults__.filter((result) => {
return filter2.every((filter) => result[filter]); return filter2.every((filter) => result[filter]);
}); });
@ -113,6 +125,7 @@ function App() {
// apply the standards filter on the results and then send the new results to the // apply the standards filter on the results and then send the new results to the
// results component // results component
function handleStandardsFilterChange(StandardsFilterValue) { function handleStandardsFilterChange(StandardsFilterValue) {
setCurrentPage(1) //test
setFiltersStandards(StandardsFilterValue); setFiltersStandards(StandardsFilterValue);
} }
//################################################################################ //################################################################################
@ -148,18 +161,24 @@ function App() {
} }
}; };
//###########################################################################################
const handleClearFilter = () =>{
setFiltersStandards([]);
setStandardsFilter([]);
}
return ( return (
<main> <main>
<Container> <Container>
<Image className="mt-5" src={IddrsImg} alt="IDDRS" fluid /> <Image className="mt-5" src={IddrsImg} alt="IDDRS" fluid />
<Search onSubmit={handleSubmit} onChange={handleChange} /> <Search onSubmit={handleSubmit} onChange={handleChange} />
{showResults && <Filter onFilterChange={handleStandardsFilterChange} />} {showResults && <Filter onFilterChange={handleStandardsFilterChange} standardsFilter={standardsFilter} setStandardsFilter={setStandardsFilter}/>}
{showResults && ( {showResults && (
<ComplainceFilter onFilterChange={handleComplainceFilterChange} /> <ComplainceFilter onFilterChange={handleComplainceFilterChange} />
)} )}
{filtersStandards.length > 0 && ( {filtersStandards.length > 0 && (
<AppliedFilters standards={filtersStandards} /> <AppliedFilters standards={filtersStandards} clearFilter={handleClearFilter}/>
)} )}
{showResults && ( {showResults && (
<Button onClick={handleExportPDF}>Export | PDF</Button> <Button onClick={handleExportPDF}>Export | PDF</Button>
@ -169,12 +188,16 @@ function App() {
results={filteredResults} results={filteredResults}
complainceFilter={filtersComplaince} complainceFilter={filtersComplaince}
searchedPhrase={phrase} searchedPhrase={phrase}
currentPage = {currentPage} //test
setCurrentPage = {setCurrentPage} //test
score = {score}
/> />
)} )}
<Stack className="mt-5" direction="horizontal" gap={2}> <Stack className="mt-5" direction="horizontal" gap={5}>
<FeaturedQuestions handleButtonClick={handleSubmit_} /> {/* <FeaturedQuestions handleButtonClick={handleSubmit_} /> */}
<WordCloud_ handleButtonClick={handleSubmit_} /> <WordCloud_ handleButtonClick={handleSubmit_} />
<Logos />
</Stack> </Stack>
{loading && ( {loading && (

View File

@ -2,6 +2,7 @@ import React from "react";
import Stack from "react-bootstrap/esm/Stack"; import Stack from "react-bootstrap/esm/Stack";
import Accordion from "react-bootstrap/Accordion"; import Accordion from "react-bootstrap/Accordion";
const AppliedFilters = (props) => { const AppliedFilters = (props) => {
return ( return (
<div className="mt-5"> <div className="mt-5">
<Accordion defaultActiveKey="0"> <Accordion defaultActiveKey="0">
@ -14,7 +15,9 @@ const AppliedFilters = (props) => {
{standard} {standard}
</h6> </h6>
))} ))}
<span role="button" onClick={props.clearFilter}><h6>Clear filter</h6></span>
</Stack> </Stack>
</Accordion.Body> </Accordion.Body>
</Accordion.Item> </Accordion.Item>
</Accordion> </Accordion>

View File

@ -5,7 +5,6 @@ import classes from "./FeaturedQuestions.module.css"
const FeaturedQuestions = ({ handleButtonClick }) => { const FeaturedQuestions = ({ handleButtonClick }) => {
const handleClick = (value) => { const handleClick = (value) => {
//console.log(event.target.value)
handleButtonClick(value); handleButtonClick(value);
}; };

View File

@ -13,7 +13,7 @@ const Filter = ({ onFilterChange }) => {
function handelOnFilterChange(newFilters){ function handelOnFilterChange(newFilters){
setStandardsFilter(newFilters) setStandardsFilter(newFilters)
onFilterChange(newFilters) onFilterChange(newFilters)
//console.log(newFilters)
} }
useEffect(() => { useEffect(() => {

View File

@ -7,16 +7,19 @@ import filterClasses from "./Filter.module.css";
import axios from "axios"; import axios from "axios";
const Filter = ({ onFilterChange }) => { const Filter = (props) => {
const [levels, setLevels] = useState([]); const [levels, setLevels] = useState([]);
const [standards, setStandards] = useState([]); const [standards, setStandards] = useState([]);
const [standardsFilter, setStandardsFilter] = useState([]);
// Function to clear selected standards
const clearSelectedStandards = () => {
props.setStandardsFilter([]); // Set standardsFilter to an empty array
};
// get the filters values to this component // get the filters values to this component
const handelOnFilterChange = (val) => { const handelOnFilterChange = (val) => {
// console.log(val); props.setStandardsFilter(val);
setStandardsFilter(val); props.onFilterChange(val);
onFilterChange(val);
}; };
useEffect(() => { useEffect(() => {
@ -50,7 +53,7 @@ const Filter = ({ onFilterChange }) => {
<Dropdown.Menu className="w-100"> <Dropdown.Menu className="w-100">
<ToggleButtonGroup <ToggleButtonGroup
type="checkbox" type="checkbox"
value={standardsFilter} value={props.standardsFilter}
onChange={handelOnFilterChange} onChange={handelOnFilterChange}
vertical vertical
name={level.levelNumber} name={level.levelNumber}

View File

@ -0,0 +1,34 @@
import React from "react";
import BICC from "../../../Imgs/BICC.png";
import Fenix from "../../../Imgs/Fenix.png";
import Image from "react-bootstrap/esm/Image";
import Stack from "react-bootstrap/esm/Stack";
/**
* Logos component - Renders logos for BICC and Fenix Insight.
*/
const Logos = () => {
return (
<div className="border rounded mt-5 p-3 w-50 mx-auto">
<Stack>
<h6 className="text-md-center">
Developed for the UN by{" "}
<a href="https://bicc.de" target="_blank">
BICC
</a>{" "}
in colaboration with{" "}
<a href="https://www.fenix-insight.online/" target="_blank">
Fenix Insight
</a>
.
</h6>
<Stack className="mt-5 d-flex flex-column flex-md-row " direction="horizontal" gap={5}>
<Image src={BICC} alt="Bonn International Centre for Conflict Studies" style={{width:150}} srcset="" id="image-section" className="img-fluid"/>
<Image src={Fenix} alt="Fenix Insight" srcset="" id="image-section" style={{width:150}} className="img-fluid"/>
</Stack>
</Stack>
</div>
);
};
export default Logos;

View File

@ -0,0 +1,11 @@
@media screen and (max-width: 320px) {
#image-section {
width: 100%;
height: auto;
}
.imgBox {
max-width: 400px;
min-width: 200px;
}
}

View File

@ -4,19 +4,20 @@ 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 OverlayTrigger from "react-bootstrap/OverlayTrigger";
import Tooltip from "react-bootstrap/Tooltip";
const Results = (props) => { const Results = (props) => {
const [showModal, setShowModal] = useState(false); const [showModal, setShowModal] = useState(false);
const [selectedResult, setSelectedResult] = useState(null); const [selectedResult, setSelectedResult] = useState(null);
const [currentPage, setCurrentPage] = useState(1);
// eslint-disable-next-line // eslint-disable-next-line
const [postsPerPage, setPostsPerPage] = useState(10); const [postsPerPage, setPostsPerPage] = useState(10);
const lastPostIndex = currentPage * postsPerPage; const lastPostIndex = props.currentPage * postsPerPage;
const firstPostIndex = lastPostIndex - postsPerPage; const firstPostIndex = lastPostIndex - postsPerPage;
const currentPost = props.results.slice(firstPostIndex, lastPostIndex); const currentPost = props.results.slice(firstPostIndex, lastPostIndex);
const resultsLength = props.results.length;
const handleShowModal = (result) => { const handleShowModal = (result) => {
setSelectedResult(result); setSelectedResult(result);
@ -28,13 +29,33 @@ const Results = (props) => {
setSelectedResult(null); setSelectedResult(null);
}; };
const Link = ({ id, children, title }) => (
<OverlayTrigger overlay={<Tooltip id={id}>{title}</Tooltip>}>
<span>{children}</span>
</OverlayTrigger>
);
return ( return (
<div className="mt-5 mb-5"> <div className="mt-5 mb-5">
{/* <PDFGenerator results={props.results} /> */}
<Card className="secondary p-1"> <Card className="secondary p-1">
<h2 className="text-secondary text-center">{props.searchedPhrase}</h2> <h2 className="text-secondary text-center">{props.searchedPhrase}</h2>
<blockquote class="blockquote">
<p class="mb-3">
Search Results: <strong>{resultsLength}</strong> Results Found at
Score <strong>{props.score}</strong>{" "}
<Link title="Our search tool uses a scoring system that starts at 8. If no results are found, the score may decrease and the search will be reattempted. A lower score can result in more diverse results, some of which may be less relevant." id="t-1">
( ? )
</Link>
</p>
<footer class="blockquote-footer">
<a href="http://" target="_blank" rel="noopener noreferrer">
Learn more
</a>{" "}
about the scoring system
</footer>
</blockquote>
<Stack gap={3} className="mt-3"> <Stack gap={3} className="mt-3">
{currentPost.map((result) => ( {currentPost.map((result) => (
<ResultsItem <ResultsItem
@ -44,21 +65,19 @@ const Results = (props) => {
title={result.Title} title={result.Title}
heading1={result.Heading1} heading1={result.Heading1}
paragraph={result.Paragraph} paragraph={result.Paragraph}
complainceFilter = {props.complainceFilter} complainceFilter={props.complainceFilter}
pageNumber = {result.PageNum} pageNumber={result.PageNum}
></ResultsItem> ></ResultsItem>
))} ))}
</Stack> </Stack>
<ResultsPagination <ResultsPagination
totalPosts={props.results.length} totalPosts={props.results.length}
postsPerPage={postsPerPage} postsPerPage={postsPerPage}
setCurrentPage={setCurrentPage} setCurrentPage={props.setCurrentPage}
currentPage={currentPage} currentPage={props.currentPage}
></ResultsPagination> ></ResultsPagination>
</Card> </Card>
<ResultModal <ResultModal
show={showModal} show={showModal}
handleClose={handleCloseModal} handleClose={handleCloseModal}
@ -71,9 +90,8 @@ const Results = (props) => {
pageNumber={selectedResult ? selectedResult.PageNum : ""} pageNumber={selectedResult ? selectedResult.PageNum : ""}
paragraph={selectedResult ? selectedResult.Paragraph : ""} paragraph={selectedResult ? selectedResult.Paragraph : ""}
sentence={selectedResult ? selectedResult.Sentence : ""} sentence={selectedResult ? selectedResult.Sentence : ""}
highlight={selectedResult ? selectedResult.Highlight : ""}
></ResultModal> ></ResultModal>
</div> </div>
); );
}; };

View File

@ -89,7 +89,6 @@ const data = [
const WordCloud_ = ({handleButtonClick}) => { const WordCloud_ = ({handleButtonClick}) => {
const handleClick = (value) => { const handleClick = (value) => {
//console.log(event.target.value)
handleButtonClick(value); handleButtonClick(value);
}; };
@ -112,7 +111,6 @@ const WordCloud_ = ({handleButtonClick}) => {
padding={2} padding={2}
onWordMouseOver = {classes.pointer} onWordMouseOver = {classes.pointer}
onWordClick={(event, d) => { onWordClick={(event, d) => {
console.log(`onWordClick: ${d.text}`);
handleClick(d.text) handleClick(d.text)
}} }}
/> />

View File

@ -3,7 +3,6 @@ import WordCloud from "react-d3-cloud";
import Card from "react-bootstrap/Card"; import Card from "react-bootstrap/Card";
import classes from "./WordCloud_.module.css"; import classes from "./WordCloud_.module.css";
const data = [ const data = [
{ text: "Disarmament", value: 1000 },
{ {
text: "Disarmament", text: "Disarmament",
value: 68.0, value: 68.0,
@ -88,18 +87,17 @@ const data = [
const WordCloud_ = ({ handleButtonClick }) => { const WordCloud_ = ({ handleButtonClick }) => {
const handleClick = (value) => { const handleClick = (value) => {
//console.log(event.target.value)
handleButtonClick(value); handleButtonClick(value);
}; };
return ( return (
<Card className="w-50"> <Card className="w-50">
<h4 className="text-decoration-underline text-center"> <h4 className="text-decoration-underline text-center">
Most Frequent Key-Phrases Optional Search Terms
</h4> </h4>
<div className={classes.pointer}> <div className={classes.pointer}>
<WordCloud <WordCloud
//width={200} width={600}
data={data} data={data}
font="Times" font="Times"
fontStyle="italic" fontStyle="italic"
@ -111,7 +109,7 @@ const WordCloud_ = ({ handleButtonClick }) => {
fill="gray" fill="gray"
padding={2} padding={2}
onWordClick={(event, d) => { onWordClick={(event, d) => {
console.log(`onWordClick: ${d.text}`);
handleClick(d.text); handleClick(d.text);
}} }}
/> />

View File

@ -17,7 +17,7 @@ const Dropdown_ = (props) => {
})); }));
props.onFilterChange(filterValues) props.onFilterChange(filterValues)
//console.log(filterValues);
}; };
return ( return (

View File

@ -2,29 +2,33 @@ import React, { useState } from "react";
import Modal from "react-bootstrap/Modal"; import Modal from "react-bootstrap/Modal";
import Button from "react-bootstrap/esm/Button"; import Button from "react-bootstrap/esm/Button";
import classes from "../../../Static/styles.module.css"; import classes from "../../../Static/styles.module.css";
import sbd from 'sbd';
import { Interweave } from 'interweave';
import parse from 'html-react-parser';
const ResultModal = (props) => { const ResultModal = (props) => {
const test_text = "This is a <strong>test text</strong>"
const HighlightSubstring = ({ text, substring }) => { const HighlightSubstring = ({ text, substring }) => {
const highlightStyle = { const highlightStyle = {
backgroundColor: "yellow", backgroundColor: "yellow",
fontWeight: "bold", fontWeight: "bold",
}; };
// Split the text into parts based on the substring // Split the text into sentences based on the substring
const parts = text.split(new RegExp(`(${substring})`, "gi")); const sentences = sbd.sentences(text);
console.log(parts)
// Wrap the matching sentences with a span and apply the highlight style
// Wrap the matching parts with a span and apply the highlight style const highlightedText = sentences.map((sentence, index) => {
const highlightedText = parts.map((part, index) => { if (sentence == substring) {
if (part == substring) {
return ( return (
<span key={index} style={highlightStyle}> <span key={index} style={highlightStyle}>
{part} {sentence}
</span> </span>
); );
} }
return part; return sentence;
}); });
return highlightedText; return highlightedText;
}; };
@ -50,9 +54,11 @@ const ResultModal = (props) => {
</Modal.Title> </Modal.Title>
</Modal.Header> </Modal.Header>
<Modal.Body> <Modal.Body>
<p className="fs-6 fw-light"><HighlightSubstring text={props.paragraph} substring={props.sentence} /></p>
<Interweave content={props.highlight} />
<div className="fs-5 fw-light mt-4"> <div className="fs-5 fw-light mt-4">
<p class="text-end">Page: {props.pageNumber}</p> <p className="text-end">Page: {props.pageNumber}</p>
</div> </div>
</Modal.Body> </Modal.Body>
<Modal.Footer> <Modal.Footer>

View File

@ -8,10 +8,11 @@ const ResultsPagination = ({
setCurrentPage, setCurrentPage,
currentPage, currentPage,
}) => { }) => {
const [pageNumberLimit, setpageNumberLimit] = useState(5); const [pageNumberLimit, setpageNumberLimit] = useState(5);
const [maxPageNumberLimit, setmaxPageNumberLimit] = useState(5); const [maxPageNumberLimit, setmaxPageNumberLimit] = useState(5);
const [minPageNumberLimit, setminPageNumberLimit] = useState(0); const [minPageNumberLimit, setminPageNumberLimit] = useState(0);
//console.log(maxPageNumberLimit, minPageNumberLimit);
let pages = []; let pages = [];
for (let i = 1; i <= Math.ceil(totalPosts / postsPerPage); i++) { for (let i = 1; i <= Math.ceil(totalPosts / postsPerPage); i++) {
pages.push(i); pages.push(i);
@ -39,13 +40,13 @@ const ResultsPagination = ({
setCurrentPage(1); setCurrentPage(1);
setmaxPageNumberLimit(5); setmaxPageNumberLimit(5);
setminPageNumberLimit(0); setminPageNumberLimit(0);
}; };
const handleLastbtn = () => { const handleLastbtn = () => {
setCurrentPage(pages.slice(-1)); setCurrentPage(pages.slice(-1));
setmaxPageNumberLimit(Math.floor(pages.slice(-1) / 5) * 5); setmaxPageNumberLimit(Math.floor(pages.slice(-1) / 5) * 5);
setminPageNumberLimit(Math.floor(pages.slice(-1) / 5) * 5 - 5); setminPageNumberLimit(Math.floor(pages.slice(-1) / 5) * 5 - 5);
console.log(currentPage)
}; };
let pageIncrementBtn = null; let pageIncrementBtn = null;

BIN
src/Imgs/BICC.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

BIN
src/Imgs/Fenix.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 69 KiB