From 8770c8441ec8c33595d927af8a8efc072d0e7490 Mon Sep 17 00:00:00 2001 From: gokul-00 <62957549+gokul-00@users.noreply.github.com> Date: Wed, 20 Jan 2021 16:25:16 +0530 Subject: [PATCH] Frontend v2 updated (#93) * Admin backend integ (#78) * Backend integ of missions * updated fetching routes * Mission page backend integ * Delete App.js * Updated App.js * Updated admin navigation * Frontend auth navigation (#86) * added admin navigation * added admin navigation * auth navigation added * Admin backend integ (#85) * updated fetching routes * Updated admin navigation * Updated new mission form with new field names * Added back buttons * Added integ for admin mission list * Backend integ for editing and deleting missions * Fix: Rendering of mission detail with mission id * Auth routes added * scoreboard added * navigation change * client side notification setup Co-authored-by: saisandhya01 <55455466+saisandhya01@users.noreply.github.com> --- frontend/package-lock.json | 110 +++++++ frontend/package.json | 2 + frontend/src/AdminLogin.jsx | 98 ------- frontend/src/App.js | 19 +- frontend/src/UserRegistration.jsx | 113 -------- frontend/src/admin/AdminMission.jsx | 32 ++- frontend/src/admin/AdminMissionListItem.jsx | 69 ++++- frontend/src/admin/Drawer.jsx | 20 +- frontend/src/admin/DrawerHeader.jsx | 128 +++++++++ frontend/src/admin/EditMission.jsx | 228 +++++++++++++++ frontend/src/admin/Mission.jsx | 40 +-- frontend/src/admin/MissionCard.jsx | 22 +- frontend/src/admin/MissionDetail.jsx | 75 +++-- frontend/src/admin/MissionListItem.jsx | 2 +- frontend/src/admin/NewMission.jsx | 268 +++++++++++------- frontend/src/api/auth.js | 2 +- frontend/src/api/authContext.js | 68 ++++- frontend/src/api/client.js | 3 +- frontend/src/api/scoreBoard.js | 3 + frontend/src/api/storage.js | 5 - frontend/src/api/team.js | 6 + .../animations/animation_640_kk23yswy.gif | Bin 0 -> 168177 bytes frontend/src/assets/animations/loader.json | 1 + .../assets/animations/success_animation.json | 1 + frontend/src/components/LoadingPage.jsx | 33 +++ frontend/src/components/MessageBot.jsx | 18 ++ frontend/src/components/SuccessAnimation.jsx | 23 ++ frontend/src/hooks/useAuth.js | 22 -- frontend/src/hooks/useScript.js | 6 +- frontend/src/index.js | 6 +- frontend/src/navigation/AdminNavigation.jsx | 231 ++++++--------- frontend/src/navigation/UserNavigation.jsx | 178 ++++++------ frontend/src/navigation/userNavigation.jsx | 178 ++++++------ frontend/src/user/CreateTeam.jsx | 27 +- frontend/src/user/GameIntro.jsx | 16 +- frontend/src/user/JoinTeam.jsx | 14 +- frontend/src/user/Leaderbaord.jsx | 51 ++-- frontend/src/user/ProfilePage.jsx | 16 +- frontend/src/user/UserLogin.jsx | 39 ++- frontend/src/user/UserProfile.jsx | 50 ---- frontend/src/user/UserRegistration.jsx | 20 +- frontend/src/user/VerificationEmail.jsx | 43 ++- frontend/src/utils/routes.js | 5 +- frontend/src/utils/socketio.js | 15 + 44 files changed, 1404 insertions(+), 902 deletions(-) delete mode 100644 frontend/src/AdminLogin.jsx delete mode 100644 frontend/src/UserRegistration.jsx create mode 100644 frontend/src/admin/DrawerHeader.jsx create mode 100644 frontend/src/admin/EditMission.jsx create mode 100644 frontend/src/api/scoreBoard.js delete mode 100644 frontend/src/api/storage.js create mode 100644 frontend/src/api/team.js create mode 100644 frontend/src/assets/animations/animation_640_kk23yswy.gif create mode 100644 frontend/src/assets/animations/loader.json create mode 100644 frontend/src/assets/animations/success_animation.json create mode 100644 frontend/src/components/LoadingPage.jsx create mode 100644 frontend/src/components/MessageBot.jsx create mode 100644 frontend/src/components/SuccessAnimation.jsx delete mode 100644 frontend/src/hooks/useAuth.js delete mode 100644 frontend/src/user/UserProfile.jsx create mode 100644 frontend/src/utils/socketio.js diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 68c8eb8..ee3deba 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -2106,6 +2106,11 @@ "@babel/types": "^7.3.0" } }, + "@types/component-emitter": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", + "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==" + }, "@types/eslint": { "version": "7.2.6", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz", @@ -3334,6 +3339,11 @@ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -3389,6 +3399,11 @@ } } }, + "base64-arraybuffer": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=" + }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -5250,6 +5265,38 @@ "once": "^1.4.0" } }, + "engine.io-client": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-4.1.0.tgz", + "integrity": "sha512-OUmn4m71/lW3ixICv4h3DuBRuh3ri0w3cDuepjsrINSbbqbni4Xw1shTFiKhl0v58lEtNpwJTpSKJJ3fondu5Q==", + "requires": { + "base64-arraybuffer": "0.1.4", + "component-emitter": "~1.3.0", + "debug": "~4.3.1", + "engine.io-parser": "~4.0.1", + "has-cors": "1.1.0", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~7.4.2", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "ws": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", + "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==" + } + } + }, + "engine.io-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", + "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", + "requires": { + "base64-arraybuffer": "0.1.4" + } + }, "enhanced-resolve": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", @@ -6932,6 +6979,11 @@ "function-bind": "^1.1.1" } }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -9260,6 +9312,11 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "lottie-web": { + "version": "5.7.6", + "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.7.6.tgz", + "integrity": "sha512-qn/KYMI4QQvFDhtoxs0RPkn9uZKhDB9keE5BKgbJlSRfNEZpRiDlwBE9ibYz4nPhbyE+NUlt8IRIVR7g5OSX3w==" + }, "lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -10286,6 +10343,16 @@ "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" }, + "parseqs": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" + }, + "parseuri": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -12026,6 +12093,15 @@ "resolved": "https://registry.npmjs.org/react-layout-effect/-/react-layout-effect-1.0.5.tgz", "integrity": "sha512-zdRXHuch+OBHU6bvjTelOGUCM+UDr/iCY+c0wXLEAc+G4/FlcJruD/hUOzlKH5XgO90Y/BUJPNhI/g9kl+VAsA==" }, + "react-lottie": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/react-lottie/-/react-lottie-1.2.3.tgz", + "integrity": "sha512-qLCERxUr8M+4mm1LU0Ruxw5Y5Fn/OmYkGfnA+JDM/dZb3oKwVAJCjwnjkj9TMHtzR2U6sMEUD3ZZ1RaHagM7kA==", + "requires": { + "babel-runtime": "^6.26.0", + "lottie-web": "^5.1.3" + } + }, "react-refresh": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", @@ -13579,6 +13655,30 @@ } } }, + "socket.io-client": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-3.1.0.tgz", + "integrity": "sha512-T4qPOL80KnoBwkdR70zMpiR6aH6zv3ZqLNriofHqsO9wvQllNTOez0mpV4GdVqo1Y55Z+h8YOlBo7c8pOxDlHw==", + "requires": { + "@types/component-emitter": "^1.2.10", + "backo2": "~1.0.2", + "component-emitter": "~1.3.0", + "debug": "~4.3.1", + "engine.io-client": "~4.1.0", + "parseuri": "0.0.6", + "socket.io-parser": "~4.0.4" + } + }, + "socket.io-parser": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", + "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", + "requires": { + "@types/component-emitter": "^1.2.10", + "component-emitter": "~1.3.0", + "debug": "~4.3.1" + } + }, "sockjs": { "version": "0.3.20", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", @@ -16369,6 +16469,11 @@ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -16423,6 +16528,11 @@ } } }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index ffae583..3139c87 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,11 +19,13 @@ "react": "^17.0.1", "react-dom": "^17.0.1", "react-html5-camera-photo": "^1.5.4", + "react-lottie": "^1.2.3", "react-router-dom": "^5.2.0", "react-scripts": "4.0.1", "react-social": "^1.10.0", "react-swipeable-views": "^0.13.9", "react-webcam": "^5.2.2", + "socket.io-client": "^3.1.0", "web-vitals": "^0.2.4", "yup": "^0.32.8" }, diff --git a/frontend/src/AdminLogin.jsx b/frontend/src/AdminLogin.jsx deleted file mode 100644 index 8f2dc66..0000000 --- a/frontend/src/AdminLogin.jsx +++ /dev/null @@ -1,98 +0,0 @@ -import React from 'react'; -import { ArrowForward } from '@material-ui/icons'; -import { Formik, Form } from 'formik'; -import * as Yup from "yup"; -import { Grid, TextField, Container, makeStyles, CssBaseline, Button, Typography, Avatar } from '@material-ui/core'; - -import ErrorMessage from './components/ErrorMessage'; - - -const validationSchema = Yup.object().shape({ - email: Yup.string().required().email().label("Email"), - password: Yup.string().required().label("Password"), -}); - -const useStyles = makeStyles((theme) => ({ - paper: { - marginTop: theme.spacing(8), - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - }, - avatar: { - backgroundColor: theme.palette.secondary.main, - color: 'white', - margin: 20, - width: theme.spacing(7), - height: theme.spacing(7), - }, - form: { - justifyContent: 'center', - width: '100%', - }, - submit: { - margin: theme.spacing(3, 0, 2), - }, - TextField: { - width: '100%', - marginTop: 10, - backgroundColor: '#fafafa', - }, -})); - -export default function AdminLogin() { - const classes = useStyles(); - - return ( - - -
- - - - - Login - - console.log(values)} - > - {({ setFieldValue, errors, touched, values }) => ( -
- - - setFieldValue("email", e.target.value)} - className={classes.TextField} - /> - - - - setFieldValue("password", e.target.value)} - className={classes.TextField} - /> - - - - -
- )} -
-
-
- ); -} diff --git a/frontend/src/App.js b/frontend/src/App.js index b5529d7..74459a0 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -1,18 +1,21 @@ -import React, { useState } from "react"; +import React from "react"; import "./App.css"; -import UserNav from "./navigation/userNavigation"; -import AdminNav from "./navigation/AdminNavigation"; -import AuthContext from "./api/authContext"; +import AppNavigation from "./navigation/userNavigation"; +import { AuthProvider } from "./api/authContext"; +import { BrowserRouter, Switch } from "react-router-dom"; function App() { - const [user, setUser] = useState(); return ( - +
- + + + + +
-
+ ); } diff --git a/frontend/src/UserRegistration.jsx b/frontend/src/UserRegistration.jsx deleted file mode 100644 index 4b8d2bf..0000000 --- a/frontend/src/UserRegistration.jsx +++ /dev/null @@ -1,113 +0,0 @@ -import React from 'react'; -import { LockOutlined } from '@material-ui/icons'; -import { Formik, Form } from 'formik'; -import * as Yup from "yup"; -import { Grid, TextField, Container, makeStyles, CssBaseline, Button, Typography } from '@material-ui/core'; - -import ErrorMessage from './components/ErrorMessage'; - -const validationSchema = Yup.object().shape({ - username: Yup.string().required().label("User name"), - email: Yup.string().required().email().label("Email"), - age: Yup.number().min(18).required().label("Age"), -}); - -const useStyles = makeStyles((theme) => ({ - paper: { - marginTop: theme.spacing(8), - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - }, - avatar: { - backgroundColor: theme.palette.secondary.main, - padding: 10, - color: 'white', - borderRadius: 30, - margin: 20, - }, - form: { - justifyContent: 'center', - padding: 10, - alignItems: 'center', - }, - submit: { - margin: theme.spacing(3, 0, 2), - }, - error: { - fontSize: 14, - color: 'red', - }, - TextField: { - width: '100%', - backgroundColor: '#fafafa', - } -})); - -export default function UserRegistration() { - - const classes = useStyles(); - - return ( - - -
-
- -
- - Register - - console.log(values)} - > - {({ setFieldValue, errors, touched }) => ( -
- - - setFieldValue( "username", e.target.value)} - className={classes.TextField} - /> - - - - setFieldValue("email", e.target.value)} - className={classes.TextField} - /> - - - - setFieldValue( "age", e.target.value)} - className={classes.TextField} - /> - - - - -
- )} -
-
-
- ); -} diff --git a/frontend/src/admin/AdminMission.jsx b/frontend/src/admin/AdminMission.jsx index 820db53..33a56b6 100644 --- a/frontend/src/admin/AdminMission.jsx +++ b/frontend/src/admin/AdminMission.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { makeStyles } from '@material-ui/core/styles'; import List from '@material-ui/core/List'; import AdminMissionListItem from './AdminMissionListItem'; @@ -6,6 +6,8 @@ import AddIcon from '@material-ui/icons/Add'; import Fab from '@material-ui/core/Fab'; import colors from '../utils/colors'; import Routes from '../utils/routes' +import { withRouter } from 'react-router-dom' +import client from '../api/client'; const useStyles = makeStyles((theme) => ({ root: { @@ -28,7 +30,15 @@ const useStyles = makeStyles((theme) => ({ function AdminMission(props) { const { history } = props; const classes = useStyles(); - const [dense, setDense] = React.useState(false); + const [dense, setDense] = useState(false); + const [data, setData] = useState([]); + useEffect(() => { + const fetchData = async () => { + const result = await client.get('api/admin/mission') + setData(result.data.Missions); + } + fetchData(); + }, []); return (
- - - - - - - - - + {data.map((mission, index) => ( + + ))}
@@ -61,4 +67,4 @@ function AdminMission(props) { ) } -export default AdminMission; \ No newline at end of file +export default withRouter(AdminMission); \ No newline at end of file diff --git a/frontend/src/admin/AdminMissionListItem.jsx b/frontend/src/admin/AdminMissionListItem.jsx index 15b3994..a455863 100644 --- a/frontend/src/admin/AdminMissionListItem.jsx +++ b/frontend/src/admin/AdminMissionListItem.jsx @@ -11,40 +11,85 @@ import LocationOnIcon from '@material-ui/icons/LocationOn'; import TextFormatIcon from '@material-ui/icons/TextFormat'; import EditIcon from '@material-ui/icons/Edit'; import colors from '../utils/colors'; +import Dialog from '@material-ui/core/Dialog'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogContent from '@material-ui/core/DialogContent'; +import DialogContentText from '@material-ui/core/DialogContentText'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import Button from '@material-ui/core/Button'; +import client from '../api/client'; +import { withRouter } from 'react-router-dom'; function AdminMissionListItem(props) { const [secondary, setSecondary] = React.useState(false); - const renderType = (type) => { - if (type === "1") { - return (); + const [open, setOpen] = React.useState(false); + const { history } = props; + const handleClickOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + }; + const handleDeleteConfirm = () => { + setOpen(false); + const confirmDelete = async () => { + const response = await client.delete(`api/admin/mission/delete/${props.values._id}`); + console.log(response); } - else if (type === "2") { - return (); + confirmDelete(); + } + const renderType = (type) => { + const object = { + 'Picture': , + 'Text': , + 'Picture and Location': , + 'Video': } - else - return (); + return object[type]; } return ( - {renderType(props.type)} + {renderType(props.values.Category)} - + { history.push(`edit/${props.values._id}`) }}> - + + + {"DELETE MISSION"} + + + Are you sure you want to delete this Mission ? + + + + + + + ) } -export default AdminMissionListItem; \ No newline at end of file +export default withRouter(AdminMissionListItem); \ No newline at end of file diff --git a/frontend/src/admin/Drawer.jsx b/frontend/src/admin/Drawer.jsx index ac386ba..2f68583 100644 --- a/frontend/src/admin/Drawer.jsx +++ b/frontend/src/admin/Drawer.jsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useContext } from "react"; import { Drawer as MUIDrawer, ListItem, @@ -19,6 +19,7 @@ import Avatar from '@material-ui/core/Avatar'; import { deepOrange } from '@material-ui/core/colors'; import colors from '../utils/colors'; import Routes from '../utils/routes'; +import { AuthContext } from "../api/authContext"; const useStyles = makeStyles((theme) => ({ drawer: { @@ -39,13 +40,13 @@ const useStyles = makeStyles((theme) => ({ const Drawer = props => { const { history } = props; + const authContext = useContext(AuthContext); const classes = useStyles(); const itemsList = [ { text: "Mission", icon: , onClick: () => { - props.onTitleChange('Missions') history.push(Routes.ADMIN_MISSIONS); } }, @@ -53,7 +54,6 @@ const Drawer = props => { text: "Activity", icon: , onClick: () => { - props.onTitleChange('Activity feed') history.push(Routes.ADMIN_ACTIVITY_FEED); } }, @@ -61,14 +61,16 @@ const Drawer = props => { text: "Score Board", icon: , onClick: () => { - props.onTitleChange('Score Board') history.push(Routes.ADMIN_LEADERBOARD) } }, { text: "Logout", icon: , - onClick: () => history.push("/logout") + onClick: () => { + authContext.logout(); + history.push(Routes.USER_LOGIN); + } } ]; const adminList = [ @@ -76,7 +78,6 @@ const Drawer = props => { text: "Admin List", icon: , onClick: () => { - props.onTitleChange('Admin List'); history.push(Routes.ADMIN_LIST); } }, @@ -84,8 +85,7 @@ const Drawer = props => { text: "Missions", icon: , onClick: () => { - props.onTitleChange('Missions'); - history.push(Routes.ADMIN_MISSION_EDIT); + history.push(Routes.ADMIN_MISSION_UPDATE); } } ] @@ -111,6 +111,8 @@ const Drawer = props => { ); })} + {authContext.isSuperAdmin() && ( + <>

{ ); })} + + )} ); }; diff --git a/frontend/src/admin/DrawerHeader.jsx b/frontend/src/admin/DrawerHeader.jsx new file mode 100644 index 0000000..55db995 --- /dev/null +++ b/frontend/src/admin/DrawerHeader.jsx @@ -0,0 +1,128 @@ +import React from 'react'; +import CssBaseline from '@material-ui/core/CssBaseline'; +import clsx from 'clsx'; +import AppBar from '@material-ui/core/AppBar'; +import Toolbar from '@material-ui/core/Toolbar'; +import IconButton from '@material-ui/core/IconButton'; +import Typography from '@material-ui/core/Typography'; +import Badge from '@material-ui/core/Badge'; +import MenuIcon from '@material-ui/icons/Menu'; +import NotificationsActiveIcon from '@material-ui/icons/NotificationsActive'; +import { makeStyles } from "@material-ui/core/styles"; + +const drawerWidth = 190; + +const useStyles = makeStyles((theme) => ({ + root: { + display: "flex" + }, + toolbar: { + paddingRight: 24, + }, + toolbarIcon: { + display: 'flex', + alignItems: 'center', + justifyContent: 'flex-end', + padding: '0 8px', + ...theme.mixins.toolbar, + }, + appBar: { + zIndex: theme.zIndex.drawer + 1, + transition: theme.transitions.create(['width', 'margin'], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + }, + appBarShift: { + marginLeft: drawerWidth, + width: `calc(100% - ${drawerWidth}px)`, + transition: theme.transitions.create(['width', 'margin'], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }, + menuButton: { + marginRight: 36, + }, + menuButtonHidden: { + display: 'none', + }, + title: { + flexGrow: 1, + }, + drawerPaper: { + position: 'relative', + whiteSpace: 'nowrap', + width: drawerWidth, + transition: theme.transitions.create('width', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }, + drawerPaperClose: { + overflowX: 'hidden', + transition: theme.transitions.create('width', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + width: theme.spacing(7), + [theme.breakpoints.up('sm')]: { + width: theme.spacing(9), + }, + }, + appBarSpacer: theme.mixins.toolbar, + content: { + flexGrow: 1, + height: '100vh', + overflow: 'auto', + }, + container: { + paddingTop: theme.spacing(4), + paddingBottom: theme.spacing(4), + }, + paper: { + padding: theme.spacing(2), + display: 'flex', + overflow: 'auto', + flexDirection: 'column', + }, + fixedHeight: { + height: 240, + }, +})); + +const DrawerHeader = (props) => { + const classes = useStyles(); + const [open, setOpen] = React.useState(true); + const handleDrawerOpen = () => { + setOpen(true); + }; + return ( +
+ + + + + + + + {props.title} + + + + + + + + +
+ ) +} + +export default DrawerHeader; \ No newline at end of file diff --git a/frontend/src/admin/EditMission.jsx b/frontend/src/admin/EditMission.jsx new file mode 100644 index 0000000..6f57168 --- /dev/null +++ b/frontend/src/admin/EditMission.jsx @@ -0,0 +1,228 @@ +import React, { useEffect, useState } from 'react'; +import { useFormik } from 'formik'; +import ArrowBackIcon from '@material-ui/icons/ArrowBack'; +import Button from '@material-ui/core/Button'; +import TextField from '@material-ui/core/TextField'; +import Select from '@material-ui/core/Select'; +import client from '../api/client'; +import { withRouter } from 'react-router-dom'; + +const dummyData = { + "id": "5ff7bac89b8b6a46c011b200", + "Category": "Picture", + "clue": "uhugyfytfytfyfyfyfug jgyfyfddtd gfgugufigi vugfyfyfy", + "answer_Type": "Picture", + "answer": ["base64string"], + "Location": { + "Lat": "12.334543656", + "Long": "34.56456756" + }, + "Other_Info": "vdhvdsvfdvfhdsvfjdvfvdvdsjvadv bjdvdsvdsv vcvdhcvjdsvcdsv", + "Feed": "true", + "ServerEvaluation": "false", + "maxPoints": "100", + "MissionName": "IESFHORIG", + "Hints": [ + { + "Content": "hfbfrbfrfrfgrfbrjbfjrbgjrbgbr", + "MaxPoints": "123" + }, { + "Content": "hfbfrbfrfrfgrfbrjbfjrbgjrbgbr", + "MaxPoints": "123" + }, { + "Content": "hfbfrbfrfrfgrfbrjbfjrbgjrbgbr", + "MaxPoints": "123" + }, + { + "Content": "hfbfrbfrfrfgrfbrjbfjrbgjrbgbr", + "MaxPoints": "123" + } + ] +}; + +const EditMission = (props) => { + const { history } = props; + const [data, setData] = useState(dummyData); + const formik = useFormik({ + initialValues: { + Category: data['Category'], + clue: data['clue'], + answer: data['answer'].join(','), + Other_Info: data['Other_Info'], + answer_Type: '', + maxPoints: data['maxPoints'], + Lat: data.Location.Lat, + Long: data.Location.Long, + MissionName: data['Category'] + }, + enableReinitialize: true, + onSubmit: async (values) => { + const { Category, clue, answer, answer_Type, Other_Info, Lat, Long, maxPoints, MissionName } = values; + const answerArray = []; + answerArray.push(answer); + const object = { + id: props.match.params.id, + Category, + clue, + answer: answerArray, + answer_Type, + Other_Info, + Location: { + Lat, + Long + }, + MissionName, + Feed: true, + ServerEvaluation: false, + maxPoints, + Hints: [ + { + Content: "hfbfrbfrfrfgrfbrjbfjrbgjrbgbr", + MaxPoints: 123 + }, { + Content: "hfbfrbfrfrfgrfbrjbfjrbgjrbgbr", + MaxPoints: 123 + }, { + Content: "hfbfrbfrfrfgrfbrjbfjrbgjrbgbr", + MaxPoints: 123 + } + ] + }; + const response = await client.patch('api/admin/mission/update', object); + console.log(response); + }, + }); + useEffect(() => { + const fetchData = async () => { + const result = await client.get(`api/mission/${props.match.params.id}`); + setData(result.data); + } + fetchData() + }, []); + return ( +
+
history.push('/admin/mission/update')}> + +
+
+

Edit

+
+ + + + + + + + + + + +
+
+ ); +}; + + +export default withRouter(EditMission); + diff --git a/frontend/src/admin/Mission.jsx b/frontend/src/admin/Mission.jsx index 7197ad6..940744e 100644 --- a/frontend/src/admin/Mission.jsx +++ b/frontend/src/admin/Mission.jsx @@ -1,34 +1,22 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import MissionCard from './MissionCard' +import client from '../api/client'; +import { Link } from 'react-router-dom'; const Mission = () => { + const [data, setData] = useState([]); + useEffect(() => { + const fetchData = async () => { + const result = await client.get('api/admin/mission') + setData(result.data.Missions); + } + fetchData(); + }, []); return (
- - - - - - - - - - - - - - - - - - - - - - - - - + {data.map((mission, index) => ( + + ))}
); } diff --git a/frontend/src/admin/MissionCard.jsx b/frontend/src/admin/MissionCard.jsx index c237897..bf1ec93 100644 --- a/frontend/src/admin/MissionCard.jsx +++ b/frontend/src/admin/MissionCard.jsx @@ -4,29 +4,25 @@ import LocationOnIcon from '@material-ui/icons/LocationOn'; import TextFormatIcon from '@material-ui/icons/TextFormat'; import { withRouter } from 'react-router-dom' import './admin.css' -import Routes from '../utils/routes' - const MissionCard = (props) => { const { history } = props; const renderType = (type) => { - if (type === "1") { - return (); - } - else if (type === "2") { - return (); - } - else { - return (); + const object = { + 'Picture': , + 'Text': , + 'Picture and Location': , + 'Video': } + return object[type]; } return ( -
{ history.push(Routes.ADMIN_MISSION_DETAILS) }}> +
- {renderType(props.type)} + {renderType(props.values.Category)}
-

Mission 1

+

{`Mission ${props.index}`}

); diff --git a/frontend/src/admin/MissionDetail.jsx b/frontend/src/admin/MissionDetail.jsx index 47b76c1..0845223 100644 --- a/frontend/src/admin/MissionDetail.jsx +++ b/frontend/src/admin/MissionDetail.jsx @@ -1,7 +1,8 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { makeStyles } from "@material-ui/core/styles"; import MissionListItem from './MissionListItem' -import CameraAltIcon from '@material-ui/icons/CameraAlt'; +import ArrowBackIcon from '@material-ui/icons/ArrowBack'; +import client from '../api/client'; const useStyles = makeStyles((theme) => ({ root: { @@ -17,33 +18,61 @@ const useStyles = makeStyles((theme) => ({ }, })) +const dummyData = { + Location: { Lat: 23, Long: 24 }, + Category: 'Picture and Location', + clue: 'I am clueless yaaar', + answer_Type: 'Picture and Location', + answer: ['orange', 'apple', 'mango'], + Other_Info: 'I am orange' +} function MissionDetail(props) { const classes = useStyles(); + const [data, setData] = useState(dummyData); + const { history } = props; + useEffect(() => { + const fetchData = async () => { + const result = await client.get(`api/mission/${props.match.params.id}`); + console.log(result.data); + setData(result.data); + } + fetchData(); + }, [props.match.params.id]); return ( -
+
-

Mission 1

+ position: 'absolute', + left: '28%', + top: '20%', + cursor: 'pointer', + }} onClick={() => history.push('/admin')}> +
-
-
- - - - - - +
+
+

Mission

+
+
+
+ + + + + + +
diff --git a/frontend/src/admin/MissionListItem.jsx b/frontend/src/admin/MissionListItem.jsx index c29ba7e..9f43ff6 100644 --- a/frontend/src/admin/MissionListItem.jsx +++ b/frontend/src/admin/MissionListItem.jsx @@ -15,7 +15,7 @@ function MissionListItem(props) { const classes = useStyles(); return (
-

{props.title} Lorem ipsum dolor sit amet, consectetur adipis

+

{props.title} {props.value}

) } diff --git a/frontend/src/admin/NewMission.jsx b/frontend/src/admin/NewMission.jsx index 3adccfb..a5add8a 100644 --- a/frontend/src/admin/NewMission.jsx +++ b/frontend/src/admin/NewMission.jsx @@ -1,131 +1,183 @@ import React from 'react'; import { useFormik } from 'formik'; - +import ArrowBackIcon from '@material-ui/icons/ArrowBack'; import Button from '@material-ui/core/Button'; import TextField from '@material-ui/core/TextField'; import Select from '@material-ui/core/Select'; +import client from '../api/client'; +import { withRouter } from 'react-router-dom'; - -const NewMission = () => { +const NewMission = (props) => { + const { history } = props; const formik = useFormik({ initialValues: { - category: '', + Category: '', clue: '', - password: '', answer: '', - otherinfo: '', - answertype: '', + Other_Info: '', + answer_Type: '', }, - onSubmit: (values) => { - console.log(values); + onSubmit: async (values) => { + const { Category, clue, answer, answer_Type, Other_Info, Lat, Long, maxPoints, MissionName } = values; + const answerArray = []; + answerArray.push(answer); + const object = { + Category, + clue, + answer: answerArray, + answer_Type, + Other_Info, + Location: { + Lat, + Long + }, + MissionName, + Feed: true, + ServerEvaluation: false, + maxPoints, + Hints: [ + { + Content: "hfbfrbfrfrfgrfbrjbfjrbgjrbgbr", + MaxPoints: 123 + }, { + Content: "hfbfrbfrfrfgrfbrjbfjrbgjrbgbr", + MaxPoints: 123 + }, { + Content: "hfbfrbfrfrfgrfbrjbfjrbgjrbgbr", + MaxPoints: 123 + } + ] + }; + const response = await client.post('api/admin/mission/add', object); + console.log(response); }, }); return ( -
-

Add a Mission

-
- - - - - - - - - - + +
); }; -export default NewMission; +export default withRouter(NewMission); diff --git a/frontend/src/api/auth.js b/frontend/src/api/auth.js index ba82985..fffcd75 100644 --- a/frontend/src/api/auth.js +++ b/frontend/src/api/auth.js @@ -9,4 +9,4 @@ export const userMobileNoVerify = (body) => export const userLogin = (body) => client.post("/auth/login", body); export const AdminRegister = (email) => - client.post("/auth/create_admin", { emailId: email }); + client.post("/api/admin/createAdmin", { emailId: email }); diff --git a/frontend/src/api/authContext.js b/frontend/src/api/authContext.js index 4294f09..07dbeea 100644 --- a/frontend/src/api/authContext.js +++ b/frontend/src/api/authContext.js @@ -1,5 +1,67 @@ -import React from "react"; +import React, { createContext, useState } from "react"; -const AuthContext = React.createContext(); +const AuthContext = createContext(); +const { Provider } = AuthContext; -export default AuthContext; +const AuthProvider = ({ children }) => { + const token = localStorage.getItem("token"); + const userInfo = localStorage.getItem("userInfo"); + const expiresAt = localStorage.getItem("expiresAt"); + + const [authState, setAuthState] = useState({ + token, + expiresAt, + userInfo: userInfo ? JSON.parse(userInfo) : {}, + }); + + const setAuthInfo = ({ token, userInfo, expiresAt }) => { + localStorage.setItem("token", token); + localStorage.setItem("userInfo", JSON.stringify(userInfo)); + localStorage.setItem("expiresAt", expiresAt); + + setAuthState({ + token, + userInfo, + expiresAt, + }); + }; + + const logout = () => { + localStorage.removeItem("token"); + localStorage.removeItem("userInfo"); + localStorage.removeItem("expiresAt"); + setAuthState({}); + }; + + const isAuthenticated = () => { + if (!authState.token || !authState.expiresAt) { + return false; + } + return new Date().getTime() / 1000 < authState.expiresAt; + }; + + const isAdmin = () => { + const adminRoles = ["Admin", "SuperAdmin"]; + return adminRoles.includes(authState.userInfo.Role); + }; + + const isSuperAdmin = () => { + return authState.userInfo.Role === "SuperAdmin"; + }; + + return ( + setAuthInfo(authInfo), + logout, + isAuthenticated, + isAdmin, + isSuperAdmin, + }}> + {children} + + ); +}; + +export { AuthContext, AuthProvider }; diff --git a/frontend/src/api/client.js b/frontend/src/api/client.js index 4cfadfa..723c2f0 100644 --- a/frontend/src/api/client.js +++ b/frontend/src/api/client.js @@ -1,12 +1,11 @@ import apisauce from "apisauce"; -import { getToken } from "./storage"; const client = apisauce.create({ baseURL: "http://localhost:3000/", }); client.addAsyncRequestTransform(async (request) => { - const authToken = await getToken(); + const authToken = await localStorage.getItem("token"); if (!authToken) return; request.headers["token"] = authToken; }); diff --git a/frontend/src/api/scoreBoard.js b/frontend/src/api/scoreBoard.js new file mode 100644 index 0000000..7dc5e2a --- /dev/null +++ b/frontend/src/api/scoreBoard.js @@ -0,0 +1,3 @@ +import client from "./client"; + +export const scoreboard = () => client.get("/api/scoreboard"); diff --git a/frontend/src/api/storage.js b/frontend/src/api/storage.js deleted file mode 100644 index 4c7732e..0000000 --- a/frontend/src/api/storage.js +++ /dev/null @@ -1,5 +0,0 @@ -export const setToken = (token) => localStorage.setItem("token", token); - -export const getToken = () => localStorage.getItem("token"); - -export const removeToken = () => localStorage.removeItem("token"); diff --git a/frontend/src/api/team.js b/frontend/src/api/team.js new file mode 100644 index 0000000..b17108b --- /dev/null +++ b/frontend/src/api/team.js @@ -0,0 +1,6 @@ +import client from "./client"; + +export const teamRegister = (body) => client.post("/api/team/create", body); + +export const joinTeam = (teamID) => + client.get(`/api/team/join?teamid=${teamID}`); diff --git a/frontend/src/assets/animations/animation_640_kk23yswy.gif b/frontend/src/assets/animations/animation_640_kk23yswy.gif new file mode 100644 index 0000000000000000000000000000000000000000..e343aa5d9d56e121dfe9ae2e7128a82cfe29f6be GIT binary patch literal 168177 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%0D}{NM^DGQEtTH?01S@w>idck!H_YhU@}zHIi-Y) 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 literal 0 HcmV?d00001 diff --git a/frontend/src/assets/animations/loader.json b/frontend/src/assets/animations/loader.json new file mode 100644 index 0000000..c7de61b --- /dev/null +++ b/frontend/src/assets/animations/loader.json @@ -0,0 +1 @@ +{"assets":[],"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"形状图层 5","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":8,"s":[100],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":24,"s":[30],"e":[100]},{"t":40}]},"r":{"k":0},"p":{"k":[187.875,77.125,0]},"a":{"k":[-76.375,-2.875,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":8,"s":[100,100,100],"e":[200,200,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":24,"s":[200,200,100],"e":[100,100,100]},{"t":40}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[18,18]},"p":{"k":[0,0]},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0.87,0.42,0.56,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-76.482,-3.482],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":40,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"形状图层 4","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":6,"s":[100],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":22,"s":[30],"e":[100]},{"t":36}]},"r":{"k":0},"p":{"k":[162.125,76.625,0]},"a":{"k":[-76.375,-2.875,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":6,"s":[100,100,100],"e":[200,200,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":22,"s":[200,200,100],"e":[100,100,100]},{"t":36}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[18,18]},"p":{"k":[0,0]},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0.81,0.55,0.82,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-76.482,-3.482],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":40,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"形状图层 3","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":4,"s":[100],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":20,"s":[30],"e":[100]},{"t":32}]},"r":{"k":0},"p":{"k":[135.625,76.625,0]},"a":{"k":[-76.375,-2.875,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":4,"s":[100,100,100],"e":[200,200,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":20,"s":[200,200,100],"e":[100,100,100]},{"t":32}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[18,18]},"p":{"k":[0,0]},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0.47,0.31,0.62,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-76.482,-3.482],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":40,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"形状图层 2","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":2,"s":[100],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":16,"s":[30],"e":[100]},{"t":28}]},"r":{"k":0},"p":{"k":[109.375,76.625,0]},"a":{"k":[-76.625,-3.125,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":2,"s":[100,100,100],"e":[200,200,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":16,"s":[200,200,100],"e":[100,100,100]},{"t":28}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[18,18]},"p":{"k":[0,0]},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0.54,0.81,0.89,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-76.482,-3.482],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":40,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":4,"ty":4,"nm":"形状图层 1","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":0,"s":[100],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":12,"s":[30],"e":[100]},{"t":24}]},"r":{"k":0},"p":{"k":[82.625,76.625,0]},"a":{"k":[-76.625,-3.375,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":0,"s":[100,100,100],"e":[200,200,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":12,"s":[200,200,100],"e":[100,100,100]},{"t":24}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[18,18]},"p":{"k":[0,0]},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0.34,0.45,0.78,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-76.482,-3.482],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":40,"st":0,"bm":0,"sr":1}],"v":"4.5.4","ddd":0,"ip":0,"op":40,"fr":24,"w":280,"h":160} \ No newline at end of file diff --git a/frontend/src/assets/animations/success_animation.json b/frontend/src/assets/animations/success_animation.json new file mode 100644 index 0000000..7fea758 --- /dev/null +++ b/frontend/src/assets/animations/success_animation.json @@ -0,0 +1 @@ +{"v":"5.0.4","fr":30,"ip":0,"op":90,"w":50,"h":50,"nm":"Success_tick","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"tick","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":69,"s":[0],"e":[100]},{"t":78}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[23.75,25.125,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-13,1],[-4.625,10.5],[14.5,-9.25]],"c":false},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":28,"s":[0],"e":[100]},{"t":49}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Raccorder les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":69,"op":90,"st":13,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"circle","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":69,"s":[0],"e":[100]},{"t":78}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[24.259,25.634,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[43.732,43.732],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Tracé d'ellipse 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.286274509804,0.721568627451,0.282352941176,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.741,-0.634],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13,"s":[0],"e":[100]},{"t":33}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Raccorder les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":69,"op":90,"st":13,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Calque de forme 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[23.75,25.125,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-13,1],[-4.625,10.5],[14.5,-9.25]],"c":false},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.153552650003,0.565732230392,0.149839333927,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":48,"s":[0],"e":[100]},{"t":68}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Raccorder les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":47,"op":70,"st":15,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Calque de forme 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[23.75,25.125,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-13,1],[-4.625,10.5],[14.5,-9.25]],"c":false},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.277887920305,0.759528186275,0.273548799403,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":43,"s":[0],"e":[100]},{"t":63}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Raccorder les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":42,"op":68,"st":10,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Calque de forme 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[23.75,25.125,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-13,1],[-4.625,10.5],[14.5,-9.25]],"c":false},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.390696387197,0.889353553922,0.386203960344,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":38,"s":[0],"e":[100]},{"t":58}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Raccorder les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":37,"op":67,"st":5,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Calque de forme 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[23.75,25.125,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-13,1],[-4.625,10.5],[14.5,-9.25]],"c":false},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.542909450157,0.90612745098,0.539637187883,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Forme 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":32,"s":[0],"e":[100]},{"t":52}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Raccorder les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":31,"op":65,"st":-1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Calque de forme 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[24.259,25.634,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[43.732,43.732],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Tracé d'ellipse 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.286274509804,0.721568627451,0.282352941176,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.741,-0.634],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[0],"e":[100]},{"t":30}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Raccorder les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":150,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/frontend/src/components/LoadingPage.jsx b/frontend/src/components/LoadingPage.jsx new file mode 100644 index 0000000..011b071 --- /dev/null +++ b/frontend/src/components/LoadingPage.jsx @@ -0,0 +1,33 @@ +import { makeStyles } from '@material-ui/core'; +import React from 'react'; +import Lottie from 'react-lottie' +import animationData from '../assets/animations/loader.json'; + +const useStyles = makeStyles(() => ({ + animation: { + justifyContent: 'center', + alignItems: 'center', + } +})) + +function LoadingPage(props) { + const styles = useStyles(); + const defaultOptions = { + loop: true, + autoplay: true, + animationData: animationData, + rendererSettings: { + preserveAspectRatio: 'xMidYMid slice' + } + }; + return ( +
+ +
+ ); +} + +export default LoadingPage; \ No newline at end of file diff --git a/frontend/src/components/MessageBot.jsx b/frontend/src/components/MessageBot.jsx new file mode 100644 index 0000000..ef4a35e --- /dev/null +++ b/frontend/src/components/MessageBot.jsx @@ -0,0 +1,18 @@ +import React from 'react'; +import useScript from '../hooks/useScript'; + +function MessageBot(props) { + useScript( + "https://embed.tawk.to/5ffc4538c31c9117cb6d70dc/1eromsq55", + "user", + { + key: "crossorigin", + value: "*", + } + ); + return ( +
+ ); +} + +export default MessageBot; \ No newline at end of file diff --git a/frontend/src/components/SuccessAnimation.jsx b/frontend/src/components/SuccessAnimation.jsx new file mode 100644 index 0000000..2b07818 --- /dev/null +++ b/frontend/src/components/SuccessAnimation.jsx @@ -0,0 +1,23 @@ +import React from 'react'; +import Lottie from 'react-lottie' +import animationData from '../assets/animations/success_animation.json'; + +function SuccessAnimation(props) { + const defaultOptions = { + loop: false, + autoplay: true, + animationData: animationData, + rendererSettings: { + preserveAspectRatio: 'xMidYMid slice' + } + }; + return ( + + ); +} + +export default SuccessAnimation; \ No newline at end of file diff --git a/frontend/src/hooks/useAuth.js b/frontend/src/hooks/useAuth.js deleted file mode 100644 index c35a321..0000000 --- a/frontend/src/hooks/useAuth.js +++ /dev/null @@ -1,22 +0,0 @@ -import { useContext } from "react"; -import jwtDecode from "jwt-decode"; -import AuthContext from "../api/authContext"; -import { setToken, removeToken } from "../api/storage"; - -export default function useAuth() { - const { user, setUser } = useContext(AuthContext); - - const logIn = (authToken) => { - const user = jwtDecode(authToken); - setUser(user); - console.log(user); - setToken(authToken); - }; - - const logOut = () => { - setUser(null); - removeToken(); - }; - - return { user, logIn, logOut }; -} diff --git a/frontend/src/hooks/useScript.js b/frontend/src/hooks/useScript.js index 89affbe..8fd0be4 100644 --- a/frontend/src/hooks/useScript.js +++ b/frontend/src/hooks/useScript.js @@ -9,9 +9,9 @@ const useScript = (url, classElement, attribute) => { script.setAttribute(attribute.key, attribute.value); document.getElementsByClassName(classElement)[0].appendChild(script); - return () => { - document.getElementsByClassName(classElement)[0].removeChild(script); - }; + // return () => { + // document.getElementsByClassName(classElement)[0].removeChild(script); + // }; }, [attribute.key, attribute.value, classElement, url]); }; diff --git a/frontend/src/index.js b/frontend/src/index.js index fb35d14..a054b14 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -3,7 +3,9 @@ import ReactDOM from "react-dom"; // import AdminMembers from "./AdminMembers"; // import AdminRegistration from "./AdminRegistration"; import App from "./App"; -import PaymentPage from "./user/PaymentPage"; +// import LoadingPage from "./components/LoadingPage"; +// import SuccessAnimation from "./components/SuccessAnimation"; +// import PaymentPage from "./user/PaymentPage"; // import ProfilePage from "./user/ProfilePage"; // import UserLogin from "./UserLogin"; // import GameIntro from "./user/GameIntro"; @@ -14,4 +16,4 @@ import PaymentPage from "./user/PaymentPage"; // import AdminRegistration from "./AdminRegistration"; // import Template from "./user/Template"; -ReactDOM.render(, document.getElementById("root")); +ReactDOM.render(, document.getElementById("root")); diff --git a/frontend/src/navigation/AdminNavigation.jsx b/frontend/src/navigation/AdminNavigation.jsx index 72e4dad..8bfe621 100644 --- a/frontend/src/navigation/AdminNavigation.jsx +++ b/frontend/src/navigation/AdminNavigation.jsx @@ -1,11 +1,7 @@ -import React from "react"; -import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; -import CssBaseline from '@material-ui/core/CssBaseline'; -import clsx from 'clsx'; -import AppBar from '@material-ui/core/AppBar'; -import Toolbar from '@material-ui/core/Toolbar'; -import IconButton from '@material-ui/core/IconButton'; +import React, { useContext } from "react"; +import { BrowserRouter as Router, Redirect, Route, Switch } from "react-router-dom"; import Drawer from "../admin/Drawer"; +import DrawerHeader from '../admin/DrawerHeader'; import Mission from '../admin/Mission' import Activity from '../admin/Activity.jsx' import ScoreBoard from '../admin/ScoreBoard' @@ -14,147 +10,96 @@ import AdminMission from '../admin/AdminMission'; import Notification from '../admin/Notifications'; import MissionDetail from '../admin/MissionDetail' import NewMission from '../admin/NewMission'; -import { makeStyles } from "@material-ui/core/styles"; -import Typography from '@material-ui/core/Typography'; -import Badge from '@material-ui/core/Badge'; -import MenuIcon from '@material-ui/icons/Menu'; -import { ChatBubble } from '@material-ui/icons'; -import NotificationsActiveIcon from '@material-ui/icons/NotificationsActive'; +import EditMission from '../admin/EditMission'; import Routes from "../utils/routes"; +import UserLogin from "../user/UserLogin"; +import GameIntro from "../user/GameIntro"; +import { AuthContext } from "../api/authContext"; -const drawerWidth = 190; - -const useStyles = makeStyles((theme) => ({ - root: { - display: "flex" - }, - toolbar: { - paddingRight: 24, - }, - toolbarIcon: { - display: 'flex', - alignItems: 'center', - justifyContent: 'flex-end', - padding: '0 8px', - ...theme.mixins.toolbar, - }, - appBar: { - zIndex: theme.zIndex.drawer + 1, - transition: theme.transitions.create(['width', 'margin'], { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.leavingScreen, - }), - }, - appBarShift: { - marginLeft: drawerWidth, - width: `calc(100% - ${drawerWidth}px)`, - transition: theme.transitions.create(['width', 'margin'], { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.enteringScreen, - }), - }, - menuButton: { - marginRight: 36, - }, - menuButtonHidden: { - display: 'none', - }, - title: { - flexGrow: 1, - }, - drawerPaper: { - position: 'relative', - whiteSpace: 'nowrap', - width: drawerWidth, - transition: theme.transitions.create('width', { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.enteringScreen, - }), - }, - drawerPaperClose: { - overflowX: 'hidden', - transition: theme.transitions.create('width', { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.leavingScreen, - }), - width: theme.spacing(7), - [theme.breakpoints.up('sm')]: { - width: theme.spacing(9), - }, - }, - appBarSpacer: theme.mixins.toolbar, - content: { - flexGrow: 1, - height: '100vh', - overflow: 'auto', - }, - container: { - paddingTop: theme.spacing(4), - paddingBottom: theme.spacing(4), - }, - paper: { - padding: theme.spacing(2), - display: 'flex', - overflow: 'auto', - flexDirection: 'column', - }, - fixedHeight: { - height: 240, - }, -})); +const AdminRoute = ({ children, ...rest }) => { + const auth = useContext(AuthContext); + return ( + + auth.isAuthenticated() && auth.isAdmin() ? ( + <>{children} + ) : ( + + ) + } + > + ); +}; export default function AdminNav() { - const classes = useStyles(); - const [open, setOpen] = React.useState(true); - const [title, setTitle] = React.useState('Missions'); - const handleDrawerOpen = () => { - setOpen(true); - }; - const onTitleChange = (title) => { - setTitle(title); - } + const auth = useContext(AuthContext); return ( - -
- - - - - - - - {title} - - - - - - - - - - - - - - - - } /> - } /> - } /> - } /> - } /> - } /> - - - + <> + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + ( + auth.isAuthenticated() && auth.isAdmin() ? ( +
+ + + +
) : () + )} /> + + + + + + + + + + + + + + + + ( + auth.isAuthenticated() && auth.isAdmin() ? ( +
+ + +
- + ) : () + )} /> +
+ ); } \ No newline at end of file diff --git a/frontend/src/navigation/UserNavigation.jsx b/frontend/src/navigation/UserNavigation.jsx index 4712be6..95e9b9f 100644 --- a/frontend/src/navigation/UserNavigation.jsx +++ b/frontend/src/navigation/UserNavigation.jsx @@ -1,7 +1,6 @@ import React, { useContext } from "react"; -import { BrowserRouter as Router, Switch, Route, Redirect } from 'react-router-dom' +import { Switch, Route, Redirect } from 'react-router-dom' import Home from "../user/Home"; -import UserRegistration from "../user/UserRegistration"; import TopNav from "../user/TopNav"; import NavBar from "../user/NavBar"; import { Container } from "@material-ui/core"; @@ -16,99 +15,110 @@ import TextClues from '../user/TextClues'; import LocationClues from '../user/LocationClues'; import Capture from '../user/Photogragh'; -import VerificationEmail from "../user/VerificationEmail"; -import UserLogin from "../user/UserLogin"; import ClueTabs from "../user/ClueTabs"; import Routes from "../utils/routes"; import ProfilePage from "../user/ProfilePage"; import JoinTeam from "../user/JoinTeam"; -import AuthContext from "../api/authContext"; -import { getToken } from "../api/storage"; -import useScript from "../hooks/useScript"; +import UserRegistration from "../user/UserRegistration"; +import UserLogin from "../user/UserLogin"; +import VerificationEmail from "../user/VerificationEmail"; +import { AuthContext } from "../api/authContext"; +import AdminNav from "./AdminNavigation"; +import MessageBot from "../components/MessageBot"; + +const UserAuthenticatedRoute = ({ children, ...rest }) => { + const authContext = useContext(AuthContext); + return ( + + authContext.isAuthenticated() ? ( + <> + {children} + + + ) : ( + + ) + } + > + ); +}; function UserNav() { - useScript( - "https://embed.tawk.to/5ffc4538c31c9117cb6d70dc/1eromsq55", - "user", - { - key: "crossorigin", - value: "*" - } - ); - const authContext = useContext(AuthContext); - console.log(authContext) - return ( - -
- - - - - - {getToken() ? ( + return ( + <> + + + + + + + + + + ( <> - - - - - - - - -
- -
-
- - -
- -
- -
- - - - - - - - -
- - - -
- - -
- -
- -
-
- - -
- - - -
- - - - - - + + - ) : } -
-
-
+ )} /> + + + + + + + + + + + + +
+ +
+
+ + +
+ +
+
+ + +
+ + + +
+ + +
+ +
+ +
+
+ + +
+ + + +
+ + + + + + + + + ) - } export default UserNav; diff --git a/frontend/src/navigation/userNavigation.jsx b/frontend/src/navigation/userNavigation.jsx index 4712be6..95e9b9f 100644 --- a/frontend/src/navigation/userNavigation.jsx +++ b/frontend/src/navigation/userNavigation.jsx @@ -1,7 +1,6 @@ import React, { useContext } from "react"; -import { BrowserRouter as Router, Switch, Route, Redirect } from 'react-router-dom' +import { Switch, Route, Redirect } from 'react-router-dom' import Home from "../user/Home"; -import UserRegistration from "../user/UserRegistration"; import TopNav from "../user/TopNav"; import NavBar from "../user/NavBar"; import { Container } from "@material-ui/core"; @@ -16,99 +15,110 @@ import TextClues from '../user/TextClues'; import LocationClues from '../user/LocationClues'; import Capture from '../user/Photogragh'; -import VerificationEmail from "../user/VerificationEmail"; -import UserLogin from "../user/UserLogin"; import ClueTabs from "../user/ClueTabs"; import Routes from "../utils/routes"; import ProfilePage from "../user/ProfilePage"; import JoinTeam from "../user/JoinTeam"; -import AuthContext from "../api/authContext"; -import { getToken } from "../api/storage"; -import useScript from "../hooks/useScript"; +import UserRegistration from "../user/UserRegistration"; +import UserLogin from "../user/UserLogin"; +import VerificationEmail from "../user/VerificationEmail"; +import { AuthContext } from "../api/authContext"; +import AdminNav from "./AdminNavigation"; +import MessageBot from "../components/MessageBot"; + +const UserAuthenticatedRoute = ({ children, ...rest }) => { + const authContext = useContext(AuthContext); + return ( + + authContext.isAuthenticated() ? ( + <> + {children} + + + ) : ( + + ) + } + > + ); +}; function UserNav() { - useScript( - "https://embed.tawk.to/5ffc4538c31c9117cb6d70dc/1eromsq55", - "user", - { - key: "crossorigin", - value: "*" - } - ); - const authContext = useContext(AuthContext); - console.log(authContext) - return ( - -
- - - - - - {getToken() ? ( + return ( + <> + + + + + + + + + + ( <> - - - - - - - - -
- -
-
- - -
- -
- -
- - - - - - - - -
- - - -
- - -
- -
- -
-
- - -
- - - -
- - - - - - + + - ) : } -
-
-
+ )} /> + + + + + + + + + + + + +
+ +
+
+ + +
+ +
+
+ + +
+ + + +
+ + +
+ +
+ +
+
+ + +
+ + + +
+ + + + + + + + + ) - } export default UserNav; diff --git a/frontend/src/user/CreateTeam.jsx b/frontend/src/user/CreateTeam.jsx index 7d5ab90..76e4e0c 100644 --- a/frontend/src/user/CreateTeam.jsx +++ b/frontend/src/user/CreateTeam.jsx @@ -1,10 +1,14 @@ -import React from 'react'; +import React, { useContext } from 'react'; import { Formik, Form } from 'formik'; import * as Yup from "yup"; import { TextField, Container, makeStyles, CssBaseline, Button, Typography } from '@material-ui/core'; import ErrorMessage from '../components/ErrorMessage'; import team from '../assets/animations/team.gif'; +import { teamRegister } from '../api/team'; +import { useHistory } from 'react-router'; +import Routes from '../utils/routes'; +import { AuthContext } from '../api/authContext'; const validationSchema = Yup.object().shape({ teamName: Yup.string().required().label("Team Name"), @@ -37,6 +41,23 @@ const useStyles = makeStyles((theme) => ({ function CreateTeam(props) { const classes = useStyles(); + const History = useHistory(); + const handleSubmit = async({ teamName }, { resetForm }) => { + const response = await teamRegister({ + teamName: teamName + }); + if(!response.ok){ + console.log(response.status ,response.originalError, response.problem); + return; + }; + console.log(response.data); + const userInfo = JSON.parse(localStorage.getItem("userInfo")); + localStorage.setItem("userInfo", JSON.stringify({...userInfo, teamID: response.data.TeamId})); + resetForm(); + setTimeout(() => { + History.push(Routes.USER_PROFILE); + }, 500); + } return ( @@ -49,7 +70,7 @@ function CreateTeam(props) { console.log(values)} + onSubmit={handleSubmit} > {({ setFieldValue, errors, touched }) => (
@@ -63,7 +84,7 @@ function CreateTeam(props) { /> )} diff --git a/frontend/src/user/GameIntro.jsx b/frontend/src/user/GameIntro.jsx index 61da8fb..a219ea9 100644 --- a/frontend/src/user/GameIntro.jsx +++ b/frontend/src/user/GameIntro.jsx @@ -1,8 +1,10 @@ -import React from 'react'; +import React, { useContext } from 'react'; import { makeStyles } from '@material-ui/core/styles'; import Button from '@material-ui/core/Button'; import { Typography } from '@material-ui/core'; import Routes from '../utils/routes'; +import {AuthContext} from '../api/authContext'; +import { useHistory } from 'react-router'; const useStyles = makeStyles((theme) => ({ root: { @@ -14,8 +16,16 @@ const useStyles = makeStyles((theme) => ({ })); export default function GameIntro() { + const auth = useContext(AuthContext); const classes = useStyles(); - + const history = useHistory(); + const handleLogin = () => { + if(auth.isAuthenticated()){ + auth.isAdmin() ? history.push(Routes.ADMIN_MISSIONS) : history.push(Routes.HOME); + }else{ + history.push(Routes.USER_LOGIN); + } + } return (
@@ -25,7 +35,7 @@ export default function GameIntro() { Register
-
diff --git a/frontend/src/user/JoinTeam.jsx b/frontend/src/user/JoinTeam.jsx index 549b9ee..c968aa0 100644 --- a/frontend/src/user/JoinTeam.jsx +++ b/frontend/src/user/JoinTeam.jsx @@ -6,6 +6,7 @@ import ErrorMessage from '../components/ErrorMessage'; import * as Yup from "yup"; import { userMobileNoVerify } from '../api/auth'; import Routes from '../utils/routes'; +import { joinTeam } from '../api/team'; const validationSchema = Yup.object().shape({ teamId: Yup.string().required().label("Team ID"), @@ -40,18 +41,15 @@ const useStyles = makeStyles((theme) => ({ function JoinTeam(props) { const styles = useStyles(); const handleSubmit = async({teamId}, { resetForm }) => { - const body = { - teamId:teamId - } - const response = await userMobileNoVerify(body); + const response = await joinTeam(teamId); if(!response.ok){ - console.log(response.problem); - console.log(response.data); - return; + console.log(response.problem); + console.log(response); + return; } console.log(response.data); resetForm(); - props.history.push(Routes.USER_PROFILE); + // props.history.push(Routes.USER_PROFILE); } return ( diff --git a/frontend/src/user/Leaderbaord.jsx b/frontend/src/user/Leaderbaord.jsx index 1a00ce6..647aec9 100644 --- a/frontend/src/user/Leaderbaord.jsx +++ b/frontend/src/user/Leaderbaord.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import { makeStyles, useTheme } from '@material-ui/core/styles'; import Table from '@material-ui/core/Table'; @@ -14,6 +14,7 @@ import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft'; import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight'; import LastPageIcon from '@material-ui/icons/LastPage'; import { Container, TableHead } from '@material-ui/core'; +import { scoreboard } from '../api/scoreBoard'; const useStyles1 = makeStyles((theme) => ({ root: { @@ -79,26 +80,6 @@ TablePaginationActions.propTypes = { rowsPerPage: PropTypes.number.isRequired, }; -function createData(name, points) { - return { name, points }; -} - -const rows = [ - createData('Cupcake', 300), - createData('Donut', 400), - createData('Eclair', 200), - createData('Frozen yoghurt', 150), - createData('Gingerbread', 350), - createData('Honeycomb', 400), - createData('Ice cream sandwich', 230), - createData('Jelly Bean', 370), - createData('KitKat', 510), - createData('Lollipop', 390), - createData('Marshmallow', 310), - createData('Nougat', 360), - createData('Oreo', 430), -].sort((a, b) => (a.points > b.points ? -1 : 1)); - const useStyles2 = makeStyles(theme => ({ root: { width: "100%", @@ -120,8 +101,20 @@ export default function CustomPaginationActionsTable() { const classes = useStyles2(); const [page, setPage] = React.useState(0); const [rowsPerPage, setRowsPerPage] = React.useState(10); + const [ scores, setScores ] = useState([]) + const fetchScore = async() => { + const response = await scoreboard(); + if(!response.ok){ + console.log(response.status, response.originalError, response.problem); + return; + } + setScores(response.data); + } + useEffect(() => { + fetchScore(); + },[]) - const emptyRows = rowsPerPage - Math.min(rowsPerPage, rows.length - page * rowsPerPage); + const emptyRows = rowsPerPage - Math.min(rowsPerPage, scores.length - page * rowsPerPage); const handleChangePage = (event, newPage) => { setPage(newPage); @@ -141,21 +134,21 @@ export default function CustomPaginationActionsTable() { Team Name - + points {(rowsPerPage > 0 - ? rows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) - : rows + ? scores.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + : scores ).map((row) => ( - {row.name} + {row.teamName} - + {row.points} @@ -163,7 +156,7 @@ export default function CustomPaginationActionsTable() { {emptyRows > 0 && ( - + )} @@ -172,7 +165,7 @@ export default function CustomPaginationActionsTable() { ({ root: { @@ -31,8 +30,13 @@ const useStyles = makeStyles((theme) => ({ })) function ProfilePage(props) { - const { logOut } = useAuth(); + const authContext = useContext(AuthContext) const classes = useStyles(); + const history = useHistory(); + const handleLogout = () => { + authContext.logout(); + history.push(Routes.USER_LOGIN); + } return (
@@ -87,11 +91,11 @@ function ProfilePage(props) { - + - + diff --git a/frontend/src/user/UserLogin.jsx b/frontend/src/user/UserLogin.jsx index aa8f90d..e848b69 100644 --- a/frontend/src/user/UserLogin.jsx +++ b/frontend/src/user/UserLogin.jsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useContext, useState } from 'react'; import { ArrowForward } from '@material-ui/icons'; import { Formik, Form } from 'formik'; import * as Yup from "yup"; @@ -8,9 +8,11 @@ import ErrorMessage from '../components/ErrorMessage'; import { userLogin } from '../api/auth'; import AlertMessage from '../components/AlertMessage'; import Routes from '../utils/routes'; -import { withRouter } from 'react-router'; -import useAuth from '../hooks/useAuth'; - +import { useHistory } from 'react-router'; +import { AuthContext } from '../api/authContext'; +import jwtDecode from 'jwt-decode'; +import LoadingPage from '../components/LoadingPage'; +import SuccessAnimation from '../components/SuccessAnimation'; const validationSchema = Yup.object().shape({ email: Yup.string().required().email().label("Email"), @@ -47,9 +49,13 @@ const useStyles = makeStyles((theme) => ({ export default function UserLogin(props) { const [info, setInfo] = useState(''); - const { logIn } = useAuth(); + const [loading, setLoading] = useState(false); + const [successLogin, setSuccessLogin] = useState(false); + const authContext = useContext(AuthContext); const classes = useStyles(); + const History = useHistory(); const handleSubmit = async({ email, password },{ resetForm }) => { + setLoading(true); const body = { emailId:email, password:password @@ -60,15 +66,28 @@ export default function UserLogin(props) { console.log(response.data); return; } - logIn(response.data.token); + setLoading(false); + setSuccessLogin(true); + const {exp} = await jwtDecode(response.data.token) + const data = { + token: response.data.token, + expiresAt: exp, + userInfo: response.data.user + } + await authContext.setAuthState(data); resetForm(); - response.data.user.Role === "Player" ? props.history.push(Routes.HOME) : props.history.push(Routes.ADMIN_MISSIONS); + const adminRoles = ["Admin", "SuperAdmin"]; + setTimeout(() => { + adminRoles.includes(data.userInfo.Role) ? History.push(Routes.ADMIN_MISSIONS) : History.push(Routes.HOME); + }, 2000); } return ( + {loading && } + {successLogin && } {info && } -
+ {(!loading && !successLogin) &&
@@ -114,9 +133,7 @@ export default function UserLogin(props) { )} -
+
}
); } - -const UserLoginRoute = withRouter(UserLogin); \ No newline at end of file diff --git a/frontend/src/user/UserProfile.jsx b/frontend/src/user/UserProfile.jsx deleted file mode 100644 index 6330eb5..0000000 --- a/frontend/src/user/UserProfile.jsx +++ /dev/null @@ -1,50 +0,0 @@ -import React from 'react'; -import Box from '@material-ui/core/Box'; -import AccountBoxTwoToneIcon from '@material-ui/icons/AccountBoxTwoTone'; -import { makeStyles } from '@material-ui/core/styles'; -import{ Link } from '@material-ui/core'; -import CssBaseline from '@material-ui/core/CssBaseline'; - -function Profile(props) { - const classes= useStyles(); - return ( -
- - -
-

User Name

-

Email :

-

Team :

-
- My posts - Logout - -
- - ); -} - -const useStyles= makeStyles( - { - box:{ - position: 'absolute', left: '50%', top: '50%', - transform: 'translate(-50%, -50%)' - }, - icon:{ - fontSize:70, - color:"navy" - }, - link:{ - fontSize:16, - fontStyle:"italic", - padding:15 - }, - post:{ - fontSize:16, - fontStyle:"italic", - padding:15 - } - } -) - -export default Profile; \ No newline at end of file diff --git a/frontend/src/user/UserRegistration.jsx b/frontend/src/user/UserRegistration.jsx index e072e16..a6970a2 100644 --- a/frontend/src/user/UserRegistration.jsx +++ b/frontend/src/user/UserRegistration.jsx @@ -7,8 +7,9 @@ import { Grid, TextField, Container, makeStyles, CssBaseline, Button, Typography import ErrorMessage from '../components/ErrorMessage'; import { userRegister } from '../api/auth'; import AlertMessage from '../components/AlertMessage'; -import { withRouter } from 'react-router-dom'; +import { useHistory, withRouter } from 'react-router-dom'; import Routes from '../utils/routes'; +import LoadingPage from '../components/LoadingPage'; const validationSchema = Yup.object().shape({ @@ -52,9 +53,12 @@ const useStyles = makeStyles((theme) => ({ export default function UserRegistration(props) { const [info, setInfo] = useState(''); + const [loading, setLoading] = useState(false); const classes = useStyles(); + const history = useHistory(); const handleSubmit = async ({ username, email, phoneNo, password },{ resetForm }) => { + setLoading(true); const body = { name:username, emailId:email, @@ -64,21 +68,23 @@ export default function UserRegistration(props) { const response = await userRegister(body); if(!response.ok){ console.log(response.problem); - console.log(response.data.message); setInfo(response.data.message); + setLoading(false); return; } - console.log(response.data.message); - setInfo(response.data.message); resetForm(); - props.history.push(`${Routes.USER_VERIFY}?mobileNo=${phoneNo}`); + setTimeout(() => { + setLoading(false); + history.push(`${Routes.USER_VERIFY}?mobileNo=${phoneNo}`); + }, 500); } return ( + {loading && } {info && } -
+ {!loading &&
@@ -148,7 +154,7 @@ export default function UserRegistration(props) { )} -
+
}
); } diff --git a/frontend/src/user/VerificationEmail.jsx b/frontend/src/user/VerificationEmail.jsx index 5fb31c7..dfe64e6 100644 --- a/frontend/src/user/VerificationEmail.jsx +++ b/frontend/src/user/VerificationEmail.jsx @@ -1,12 +1,15 @@ -import { Button, Container, Grid, Link, makeStyles, TextField, Typography } from '@material-ui/core'; +import { Button, Container, CssBaseline, Grid, Link, makeStyles, TextField, Typography } from '@material-ui/core'; import { MessageOutlined } from '@material-ui/icons'; import { Form, Formik } from 'formik'; -import React from 'react'; +import React, { useContext, useState } from 'react'; import ErrorMessage from '../components/ErrorMessage'; import * as Yup from "yup"; import { userMobileNoVerify } from '../api/auth'; import Routes from '../utils/routes'; -import useAuth from '../hooks/useAuth'; +import jwtDecode from 'jwt-decode'; +import { AuthContext } from '../api/authContext'; +import LoadingPage from '../components/LoadingPage'; +import SuccessAnimation from '../components/SuccessAnimation'; const queryString = require('query-string'); const validationSchema = Yup.object().shape({ @@ -41,26 +44,43 @@ const useStyles = makeStyles((theme) => ({ function VerificationEmail(props) { const styles = useStyles(); - const { logIn } = useAuth(); + const [loading, setLoading] = useState(false); + const [successVerify, setSuccessVerify] = useState(false); + const auth = useContext(AuthContext); const parsed = queryString.parse(props.location.search); const handleSubmit = async({otp}, { resetForm }) => { + setLoading(true); const body = { mobileNo:parsed.mobileNo, otp:otp } const response = await userMobileNoVerify(body); if(!response.ok){ - console.log(response.problem); - console.log(response.data); - return; + console.log(response.problem); + console.log(response.data); + setLoading(false); + return; } - console.log(response.data); - logIn(response.data.token); + setLoading(false); + setSuccessVerify(true); + const {exp} = await jwtDecode(response.data.token) + const data = { + token: response.data.token, + expiresAt: exp, + userInfo: response.data.result + } + await auth.setAuthState(data); resetForm(); - props.history.push(Routes.HOME); + setTimeout(() => { + props.history.push(Routes.HOME); + }, 2000); } return ( - + + + {loading && } + {successVerify && } + {(!loading && !successVerify) &&
@@ -103,6 +123,7 @@ function VerificationEmail(props) { > resend OTP +
}
); } diff --git a/frontend/src/utils/routes.js b/frontend/src/utils/routes.js index cb590d7..24fddfe 100644 --- a/frontend/src/utils/routes.js +++ b/frontend/src/utils/routes.js @@ -14,13 +14,14 @@ const Routes = { ADMIN_LOGIN: "/admin/login", ADMIN_ADD: "/admin/add-admin", ADMIN_MISSIONS: "/admin", - ADMIN_MISSION_DETAILS: "/admin/missiondetail", + ADMIN_MISSION_DETAILS: "/admin/missiondetail/:id", ADMIN_LEADERBOARD: "/admin/scoreboard", ADMIN_LIST: "/admin/list", - ADMIN_MISSION_EDIT: "/admin/mission/edit", + ADMIN_MISSION_UPDATE: "/admin/mission/update", ADMIN_NOTIFICATION: "/admin/notification", ADMIN_NEW_MISSION: "/admin/mission/new", ADMIN_ACTIVITY_FEED: "/admin/activity", + ADMIN_EDIT_MISSION: "/admin/mission/edit/:id", }; export default Routes; diff --git a/frontend/src/utils/socketio.js b/frontend/src/utils/socketio.js new file mode 100644 index 0000000..2886b53 --- /dev/null +++ b/frontend/src/utils/socketio.js @@ -0,0 +1,15 @@ +import { io } from "socket.io-client"; + +const socket = io("http://localhost:3000/"); + +socket.on("connect", () => { + console.log(socket.id); +}); + +const listener = (...args) => { + console.log(args); +}; + +const teamID = "abcd123"; + +socket.on(`Notification ${teamID}`, listener);