diff --git a/CHANGELOG.md b/CHANGELOG.md index b5a7ca29231ef0e63000639174e9be3c7eacae3a..32d0ecb94d32a5a485034d9270ed4e1a0b927378 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - [feat] front / back: added stats view and frontend deps needed for the view - [feat] Create a custom admin site containing a view to run cron tasks manually. - [feat] back: add functions and tests to compute daily stats about the contributions +- [feat] front: add select component for lastVisitedUniversities ## v2.6.0 diff --git a/frontend/src/components/app/App.jsx b/frontend/src/components/app/App.jsx index 92006b5328559f5135f15a1e39538e11b633a6e5..c9f00a6206f2b74e4c10f47e8f1db6e235a3d875 100644 --- a/frontend/src/components/app/App.jsx +++ b/frontend/src/components/app/App.jsx @@ -6,6 +6,7 @@ import { compose } from "recompose"; import { Route, Switch } from "react-router-dom"; import { withErrorBoundary } from "../common/ErrorBoundary"; +import LastVisitedUniversity from "./LastVisitedUniversity"; import PageMap from "../pages/PageMap"; import PageHome from "../pages/PageHome"; import PageUniversity from "../pages/PageUniversity"; @@ -90,6 +91,7 @@ function App() { + ); diff --git a/frontend/src/components/app/LastVisitedUniversity.jsx b/frontend/src/components/app/LastVisitedUniversity.jsx new file mode 100644 index 0000000000000000000000000000000000000000..998db69a0c017a2f18911ba13a314cdc30b42662 --- /dev/null +++ b/frontend/src/components/app/LastVisitedUniversity.jsx @@ -0,0 +1,100 @@ +import React from "react"; +import { compose } from "recompose"; +import { makeStyles } from "@material-ui/styles"; +import InputLabel from "@material-ui/core/InputLabel"; +import FormControl from "@material-ui/core/FormControl"; +import Select from "@material-ui/core/Select"; +import MenuItem from "@material-ui/core/MenuItem"; +import Box from "@material-ui/core/Box"; +import PropTypes from "prop-types"; +import { withRouter } from "react-router-dom"; +import APP_ROUTES from "../../config/appRoutes"; +import withNetworkWrapper, { NetWrapParam } from "../../hoc/withNetworkWrapper"; +import UniversityService from "../../services/data/UniversityService"; +import NavigationService from "../../services/NavigationService"; +import LicenseNotice from "../common/LicenseNotice"; + +const useStyles = makeStyles((theme) => ({ + formControl: { + marginLeft: "auto", + marginRight: theme.spacing(2), + padding: theme.spacing(1), + maxWidth: "80%", + position: "sticky", + bottom: theme.spacing(2), + border: "solid", + borderWidth: 2, + borderRadius: theme.shape.borderRadius, + borderColor: theme.palette.primary.main, + borderStyle: "dashed", + backgroundColor: theme.palette.background.paper, + zIndex: 1000, + }, +})); + +function LastVisitedUniversity({ location, lastVisitedUniversities }) { + const classes = useStyles(); + + if ( + location.pathname === APP_ROUTES.themeSettings || + location.pathname === APP_ROUTES.myExchanges || + location.pathname === APP_ROUTES.editPreviousExchangeWithParams || + location.pathname === APP_ROUTES.userWithParams || + location.pathname === APP_ROUTES.aboutProject || + location.pathname === APP_ROUTES.aboutRgpd || + location.pathname === APP_ROUTES.aboutCgu || + location.pathname === APP_ROUTES.aboutUnlinkedPartners || + location.pathname === APP_ROUTES.logout + ) { + return <>; + } + + const handleChange = (event) => { + const univId = event.target.value; + if (univId !== "") NavigationService.goToUniversity(univId); + }; + + return ( + + + + Dernières universités visitées + + + + + + ); +} + +LastVisitedUniversity.propTypes = { + location: PropTypes.shape({ + pathname: PropTypes.string.isRequired, + }).isRequired, + lastVisitedUniversities: PropTypes.arrayOf( + PropTypes.shape({ + university: PropTypes.number.isRequired, + ts: PropTypes.string.isRequired, + }).isRequired + ).isRequired, +}; + +export default compose( + withNetworkWrapper([ + new NetWrapParam("lastVisitedUniversities", "all", { + addDataToProp: "lastVisitedUniversities", + }), + ]), + withRouter +)(LastVisitedUniversity); diff --git a/frontend/src/components/common/LicenseNotice.jsx b/frontend/src/components/common/LicenseNotice.jsx index 8d1b0696cc23cb884678790ba20c0177110f7468..b0fc8d943411c2514fef9f7d90e215d3ca37d688 100644 --- a/frontend/src/components/common/LicenseNotice.jsx +++ b/frontend/src/components/common/LicenseNotice.jsx @@ -21,17 +21,23 @@ function LicenseNotice(props) { return ( <> - Ce contenu est sous license   - {props.variant}. Plus d'informations à ce propos sont disponibles  + Ce contenu est sous license  + {props.variant}.
+ Plus d'informations à ce propos sont disponibles  ici.
-
+ {props.spacer &&
} ); } LicenseNotice.propTypes = { variant: PropTypes.oneOf(["REX-DRI—PRIVATE", "REX-DRI—BY"]).isRequired, + spacer: PropTypes.bool, +}; + +LicenseNotice.defaultProps = { + spacer: true, }; export default LicenseNotice; diff --git a/frontend/src/components/pages/PageUniversity.jsx b/frontend/src/components/pages/PageUniversity.jsx index 2a4a0a67033429b6970381fefadd35d830445d46..d345c74d2cff04d512272fa751d52974826bae40 100644 --- a/frontend/src/components/pages/PageUniversity.jsx +++ b/frontend/src/components/pages/PageUniversity.jsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useEffect } from "react"; import PropTypes from "prop-types"; import Dialog from "@material-ui/core/Dialog"; import DialogActions from "@material-ui/core/DialogActions"; @@ -11,6 +11,7 @@ import { withErrorBoundary } from "../common/ErrorBoundary"; import APP_ROUTES from "../../config/appRoutes"; import CustomNavLink from "../common/CustomNavLink"; import UniversityService from "../../services/data/UniversityService"; +import { useApiCreate } from "../../hooks/wrappers/api"; function UniversityNotFound() { return ( @@ -34,13 +35,25 @@ function UniversityNotFound() { ); } +let lastVisitedUniv = -1; + /** * Component holding the page with the university details */ function PageUniversity({ match }) { const { univId, tabName } = match.params; + const createLastVisited = useApiCreate("lastVisitedUniversities"); + + useEffect(() => { + if (lastVisitedUniv !== univId) + createLastVisited({ university: univId }, () => { + lastVisitedUniv = univId; + }); + }, [univId]); + const parsedUnivId = parseInt(univId, 10); + if (UniversityService.hasUniversity(parsedUnivId)) { return (