diff --git a/src/App.js b/src/App.js
index 7a13708..c08e629 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,24 +1,33 @@
-import logo from './logo.svg';
-import './App.css';
-import Dashboard from './pages/Dashboard'
-import Categories from './pages/Categories'
-import Products from './pages/Products'
-import Login from './pages/Login'
-import {Navigate, Route, Routes} from 'react-router-dom'
-import {useEffect,useState} from 'react'
-import Drawer from './components/Drawer'
+import "./App.css";
+import routes, { renderRoutes } from "./routes";
+import { Router } from "react-router-dom";
+import { AuthProvider } from "./contexts/AuthContext";
+import { createBrowserHistory } from "history";
+import { createTheme } from "./theme";
+import { create } from "jss";
+import rtl from "jss-rtl";
+import { useContext } from "react";
+import { jssPreset, StylesProvider, ThemeProvider } from "@material-ui/core";
+import SettingsContext from './contexts/SettingsContext'
+const history = createBrowserHistory();
+const jss = create({ plugins: [...jssPreset().plugins, rtl()] });
-
-function App(props) {
-
-
- return
- }/>
- }/>
- }/>
- }/>
-
-
+function App() {
+ const { settings } = useContext(SettingsContext);
+ const theme = createTheme({
+ direction: settings.direction,
+ responsiveFontSizes: settings.responsiveFontSizes,
+ theme: settings.theme,
+ });
+ return (
+
+
+
+ {renderRoutes(routes)}
+
+
+
+ );
}
export default App;
diff --git a/src/assets/images/1.jpg b/src/assets/images/1.jpg
deleted file mode 100644
index 00e8755..0000000
Binary files a/src/assets/images/1.jpg and /dev/null differ
diff --git a/src/common/Constants.js b/src/common/Constants.js
new file mode 100644
index 0000000..0c33a95
--- /dev/null
+++ b/src/common/Constants.js
@@ -0,0 +1,8 @@
+export const SESSION_KEY = "CompUserData";
+export const BASE_URL = "https://website-backend.computiq.tech";
+
+export const THEMES = {
+ LIGHT: 'LIGHT',
+ ONE_DARK: 'ONE_DARK'
+ };
+
\ No newline at end of file
diff --git a/src/components/Avatar.jsx b/src/components/Avatar.jsx
deleted file mode 100644
index 5b87d0b..0000000
--- a/src/components/Avatar.jsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import * as React from 'react';
-import Avatar from '@mui/material/Avatar';
-import Stack from '@mui/material/Stack';
-
-export default function ImageAvatars() {
- return (
-
-
-
- );
-}
diff --git a/src/components/BoardItems.jsx b/src/components/BoardItems.jsx
new file mode 100644
index 0000000..2571708
--- /dev/null
+++ b/src/components/BoardItems.jsx
@@ -0,0 +1,47 @@
+import React from 'react'
+import { Box,makeStyles, Typography } from '@material-ui/core';
+
+
+const useStyles = makeStyles(()=>({
+ flx:{
+ color: '#575756',
+ display: 'flex',
+ justifyContent: 'space-between',
+ alignItems:'center'
+ },
+
+ box: {
+ display: 'flex',
+ alignItems:'center'
+ },
+
+ img: {
+ fontSize: 35,
+ marginLeft: 5
+ }
+
+}))
+
+
+export default function BoardItems(props) {
+ const classes = useStyles()
+ return (
+ <>
+ SCORE BOARD
+ {
+ props.dataP.map((item,i)=>{
+ return (
+
+
+ #{props.data.findIndex((data)=> (data.user__first_name+' '+data.user__last_name)===(item.user__first_name+' '+item.user__last_name) )}
+ {item.user__score_profile__photo}
+
+ {item.user__first_name+' '+item.user__last_name}
+ {item.total_score} points
+
+ )
+ })
+ }
+ >
+ )
+}
diff --git a/src/components/Drawer.jsx b/src/components/Drawer.jsx
deleted file mode 100644
index 9e615f1..0000000
--- a/src/components/Drawer.jsx
+++ /dev/null
@@ -1,240 +0,0 @@
-import * as React from 'react';
-import { useEffect } from 'react'
-import { styled, useTheme } from '@mui/material/styles';
-import Box from '@mui/material/Box';
-import Drawer from '@mui/material/Drawer';
-import CssBaseline from '@mui/material/CssBaseline';
-import MuiAppBar from '@mui/material/AppBar';
-import Toolbar from '@mui/material/Toolbar';
-import List from '@mui/material/List';
-import Typography from '@mui/material/Typography';
-import Divider from '@mui/material/Divider';
-import IconButton from '@mui/material/IconButton';
-import MenuIcon from '@mui/icons-material/Menu';
-import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
-import ChevronRightIcon from '@mui/icons-material/ChevronRight';
-import ListItem from '@mui/material/ListItem';
-import ListItemIcon from '@mui/material/ListItemIcon';
-import ListItemText from '@mui/material/ListItemText';
-import InboxIcon from '@mui/icons-material/MoveToInbox';
-import MailIcon from '@mui/icons-material/Mail';
-import { Routes, Link, Route, useLocation, useNavigate } from 'react-router-dom'
-import Dashboard from '../pages/Dashboard'
-import Categories from '../pages/Categories'
-import Products from '../pages/Products'
-import LogoutIcon from '@mui/icons-material/Logout';
-import GridViewIcon from '@mui/icons-material/GridView';
-import CategoryIcon from '@mui/icons-material/Category';
-import ProductionQuantityLimitsIcon from '@mui/icons-material/ProductionQuantityLimits';
-import Login from '../pages/Login'
-import Avatar from './Avatar'
-import MenuItem from '@mui/material/MenuItem';
-import Menu from '@mui/material/Menu';
-import Tooltip from '@mui/material/Tooltip';
-import {navigate} from 'react-router-dom'
-import {TOKEN_KEY} from '../utils/Constants'
-
-const drawerWidth = 240;
-
-
-
-const Main = styled('main', { shouldForwardProp: (prop) => prop !== 'open' })(
- ({ theme, open }) => ({
- flexGrow: 1,
- padding: theme.spacing(3),
- transition: theme.transitions.create('margin', {
- easing: theme.transitions.easing.sharp,
- duration: theme.transitions.duration.leavingScreen,
- }),
- marginLeft: `-${drawerWidth}px`,
- ...(open && {
- transition: theme.transitions.create('margin', {
- easing: theme.transitions.easing.easeOut,
- duration: theme.transitions.duration.enteringScreen,
- }),
- marginLeft: 0,
- }),
- }),
-);
-
-const AppBar = styled(MuiAppBar, {
- shouldForwardProp: (prop) => prop !== 'open',
-})(({ theme, open }) => ({
- transition: theme.transitions.create(['margin', 'width'], {
- easing: theme.transitions.easing.sharp,
- duration: theme.transitions.duration.leavingScreen,
- }),
- ...(open && {
- width: `calc(100% - ${drawerWidth}px)`,
- marginLeft: `${drawerWidth}px`,
- transition: theme.transitions.create(['margin', 'width'], {
- easing: theme.transitions.easing.easeOut,
- duration: theme.transitions.duration.enteringScreen,
- }),
- }),
-}));
-
-const DrawerHeader = styled('div')(({ theme }) => ({
- display: 'flex',
- alignItems: 'center',
- padding: theme.spacing(0, 1),
- // necessary for content to be below app bar
- ...theme.mixins.toolbar,
- justifyContent: 'flex-end',
-}));
-
-function PersistentDrawerLeft(props) {
- const location = useLocation()
- const navigate = useNavigate()
- const theme = useTheme();
- const [open, setOpen] = React.useState(false);
-
- const [anchorElUser, setAnchorElUser] = React.useState(null);
-
- const handleDrawerOpen = () => {
- setOpen(true);
- };
-
- const handleDrawerClose = () => {
- setOpen(false);
- };
-
- const logout = () => {
- localStorage.removeItem(TOKEN_KEY)
- navigate('/login')
- handleCloseUserMenu()
- }
- useEffect(() => {
-
- }, [])
- const renderContent = (routeName) => {
- console.log(routeName)
- switch (routeName) {
- case '/login':
- return
- case '/products':
- return
- case '/dashboard':
- return
- case '/categories':
- return
- }
- }
- const handleOpenUserMenu = (event) => {
- setAnchorElUser(event.currentTarget);
- };
- const handleCloseUserMenu = () => {
- setAnchorElUser(null);
- };
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {theme.direction === 'ltr' ? : }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {renderContent(location.pathname)}
-
-
- );
-}
-
-export default PersistentDrawerLeft
\ No newline at end of file
diff --git a/src/components/LoadingScreen.jsx b/src/components/LoadingScreen.jsx
new file mode 100644
index 0000000..f72b4c8
--- /dev/null
+++ b/src/components/LoadingScreen.jsx
@@ -0,0 +1,11 @@
+import React from 'react';
+
+function LoadingScreen(props) {
+ return (
+
+ LoadingScreen
+
+ );
+}
+
+export default LoadingScreen;
\ No newline at end of file
diff --git a/src/components/TaskItem.jsx b/src/components/TaskItem.jsx
new file mode 100644
index 0000000..9ba62dd
--- /dev/null
+++ b/src/components/TaskItem.jsx
@@ -0,0 +1,43 @@
+import React from 'react'
+import parse from 'html-react-parser';
+
+import { Box , makeStyles} from '@material-ui/core';
+import Collapse from '@mui/material/Collapse';
+import ExpandLess from '@mui/icons-material/ExpandLess';
+import ExpandMore from '@mui/icons-material/ExpandMore';
+
+const useStyles = makeStyles(()=>({
+ flx:{
+ color: '#575756',
+ display: 'flex',
+ justifyContent: 'space-between',
+ alignItems:'center'
+ },
+
+ box: {
+ backgroundColor: 'white',
+ padding: 20,
+ borderRadius: 20,
+ border: '1px solid #c6c6c6',
+ color: '#575756',
+ marginBottom: 20,
+ cursor: 'pointer'
+ },
+
+}))
+
+export default function TaskItem(props) {
+ const classes = useStyles()
+ const [open, setOpen] = React.useState(false);
+
+ return (
+ setOpen(!open)} className={classes.box}>
+
+ {props.title} {open ? : }
+
+
+ { parse(props.desc) }
+
+
+ )
+}
diff --git a/src/components/TaskItems.jsx b/src/components/TaskItems.jsx
new file mode 100644
index 0000000..89a5e97
--- /dev/null
+++ b/src/components/TaskItems.jsx
@@ -0,0 +1,13 @@
+import React from 'react'
+import TaskItem from './TaskItem'
+
+
+export default function TaskItems(props) {
+ return (
+ <>
+ {
+ props.tasks.map((task,i)=> )
+ }
+ >
+ )
+}
diff --git a/src/components/Users.jsx b/src/components/Users.jsx
deleted file mode 100644
index 5b3b0d7..0000000
--- a/src/components/Users.jsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react';
-
-function Users(props) {
- return (
-
- );
-}
-
-export default Users;
\ No newline at end of file
diff --git a/src/components/guards/AuthGuard.jsx b/src/components/guards/AuthGuard.jsx
new file mode 100644
index 0000000..0f9fa2c
--- /dev/null
+++ b/src/components/guards/AuthGuard.jsx
@@ -0,0 +1,24 @@
+import React from 'react';
+import { Redirect } from 'react-router-dom';
+import PropTypes from 'prop-types';
+import useAuth from '../../hooks/useAuth';
+
+const AuthGuard = ({ children }) => {
+ const { isAuthenticated } = useAuth();
+
+ if (!isAuthenticated) {
+ return ;
+ }
+
+ return (
+ <>
+ {children}
+ >
+ );
+};
+
+AuthGuard.propTypes = {
+ children: PropTypes.node
+};
+
+export default AuthGuard;
diff --git a/src/components/guards/GuestGuard.jsx b/src/components/guards/GuestGuard.jsx
new file mode 100644
index 0000000..1a5917d
--- /dev/null
+++ b/src/components/guards/GuestGuard.jsx
@@ -0,0 +1,24 @@
+import React from 'react';
+import { Redirect } from 'react-router-dom';
+import PropTypes from 'prop-types';
+import useAuth from '../../hooks/useAuth';
+
+const GuestGuard = ({ children }) => {
+ const { isAuthenticated } = useAuth();
+
+ if (isAuthenticated) {
+ return ;
+ }
+
+ return (
+ <>
+ {children}
+ >
+ );
+};
+
+GuestGuard.propTypes = {
+ children: PropTypes.node
+};
+
+export default GuestGuard;
diff --git a/src/contexts/AuthContext.js b/src/contexts/AuthContext.js
new file mode 100644
index 0000000..2e94f6c
--- /dev/null
+++ b/src/contexts/AuthContext.js
@@ -0,0 +1,255 @@
+import React, {
+ createContext,
+ useEffect,
+ useReducer
+ } from 'react';
+ import jwtDecode from 'jwt-decode';
+ import LoadingScreen from '../components/LoadingScreen';
+ import axios from '../utils/axios';
+ import { LoginService } from '../services/Http/LoginService';
+ import { handleResponse } from '../utils/responseHandler';
+ import {SESSION_KEY} from '../common/Constants'
+ const initialAuthState = {
+ isAuthenticated: false,
+ isInitialised: false,
+ user: null,
+ error:null
+ };
+
+ const isValidToken = (tokenObj) => {
+ console.log(tokenObj)
+ if (!tokenObj) {
+ return false;
+ }
+ const decoded = jwtDecode(tokenObj.access_token);
+ const currentTime = Date.now() / 1000;
+ return decoded.exp > currentTime;
+ };
+
+
+ const setSessionData = (data) => {
+ if (data) {
+ localStorage.setItem(SESSION_KEY, JSON.stringify(data));
+ axios.defaults.headers.common.Authorization = `Bearer ${data.token.access_token}`;
+ } else {
+ localStorage.removeItem(SESSION_KEY);
+ delete axios.defaults.headers.common.Authorization;
+ }
+ };
+ const reducer = (state, action) => {
+
+ switch (action.type) {
+ case 'INITIALISE': {
+ const { isAuthenticated, user } = action.payload;
+
+ return {
+ ...state,
+ isAuthenticated,
+ isInitialised: true,
+ user,
+ error:null
+ };
+ }
+ case 'LOGIN': {
+ const { data } = action.payload;
+ const user = data;
+ console.log('in login reducer, user fetched is: ' )
+ console.log(data,user)
+ return {
+ ...state,
+ isAuthenticated: true,
+ user,
+ error:null
+ };
+ }
+ case 'LOGOUT': {
+ return {
+ ...state,
+ isAuthenticated: false,
+ user: null,
+ error:null
+ };
+ }
+
+ case 'ERROR': {
+ const errorMSG = action.payload;
+
+ console.log('error dispatched')
+ console.log(errorMSG)
+ return {
+ ...state,
+ isAuthenticated: false,
+ error:errorMSG.error.message
+ };
+ }
+ default: {
+ return { ...state };
+ }
+ }
+ };
+
+ const AuthContext = createContext({
+ ...initialAuthState,
+ method: 'JWT',
+ login: () => Promise.resolve(),
+ logout: () => { }
+ });
+
+ export const AuthProvider = ({ children }) => {
+ const [state, dispatch] = useReducer(reducer, initialAuthState);
+
+ const login = (email, password) =>{
+ (new LoginService).login({
+ email:email,
+ password:password
+ })
+ .then((res)=>{
+ console.log('response is: ',res)
+ if(res.status == '200')
+ {
+ const data = res.data;
+ // // origin
+ setSessionData(data)
+ // setSession(data);
+ console.log('after set session data,',data)
+ dispatch({
+ type: 'LOGIN',
+ payload: {
+ data
+ }
+ });
+ }
+ else{ // 404, 400,
+ let resp = handleResponse(res)
+ console.log('error of resp handler is : ')
+ console.log(resp)
+ dispatch({
+ type: 'ERROR',
+ payload: {
+ error:resp
+ }
+ });
+ }
+
+ })
+ .catch((err)=>{
+ let resp = handleResponse(err)
+ console.log('error caught: ',err)
+ dispatch({
+ type:'ERROR',
+ payload:{
+ error:resp
+ }
+ })
+ })
+ }
+ // const login = async (email, password) => {
+
+ // try{
+ // const response = await (new LoginService).login({email,password});
+ // console.log('response is',response)
+ // if(!response.data)
+ // return response
+ // const data = response.data;
+ // // origin
+ // setSessionData(data)
+ // // setSession(data);
+ // console.log('after set session data,',data)
+ // dispatch({
+ // type: 'LOGIN',
+ // payload: {
+ // data
+ // }
+ // });
+
+
+ // return response;
+ // }
+ // catch(err)
+ // {
+ // console.log('error caught',err)
+ // dispatch({
+ // type: 'ERROR',
+ // payload: {
+ // err
+ // }
+ // });
+ // }
+
+
+
+
+
+ // };
+
+ const logout = () => {
+ setSessionData(null);
+ dispatch({ type: 'LOGOUT' });
+ };
+
+
+ useEffect(() => {
+ const initialise = async () => {
+ try {
+ console.log('try to load userData from localstaorage')
+ // const accessToken = window.localStorage.getItem('accessToken');
+ let user = window.localStorage.getItem(SESSION_KEY);
+ if(user)
+ {
+ user = JSON.parse(user);
+ }
+ console.log(user)
+ if (user && user.token && isValidToken(user.token)) {
+ setSessionData(user);
+ dispatch({
+ type: 'INITIALISE',
+ payload: {
+ isAuthenticated: true,
+ user
+ }
+ });
+ } else {
+ console.log('user data not found or expired')
+ dispatch({
+ type: 'INITIALISE',
+ payload: {
+ isAuthenticated: false,
+ user: null
+ }
+ });
+ }
+ } catch (err) {
+ let resp = handleResponse(err)
+ dispatch({
+ type: 'INITIALISE',
+ payload: {
+ isAuthenticated: false,
+ user: null
+ }
+ });
+ }
+ };
+
+ initialise();
+ }, []);
+ if (!state.isInitialised) {
+ return ;
+ }
+
+ return (
+
+ {children}
+
+ );
+ };
+
+ export default AuthContext;
\ No newline at end of file
diff --git a/src/contexts/SettingsContext.js b/src/contexts/SettingsContext.js
new file mode 100644
index 0000000..67cf25c
--- /dev/null
+++ b/src/contexts/SettingsContext.js
@@ -0,0 +1,78 @@
+import React, {
+ createContext,
+ useEffect,
+ useState
+} from 'react';
+import _ from 'lodash';
+import { THEMES } from '../common/Constants';
+// 1
+const defaultSettings = {
+ direction: 'ltr',
+ responsiveFontSizes: true,
+ theme: THEMES.LIGHT
+};
+
+export const restoreSettings = () => {
+ let settings = null;
+
+ try {
+ const storedData = window.localStorage.getItem('settings');
+
+ if (storedData) {
+ settings = JSON.parse(storedData);
+ }
+ } catch (err) {
+ console.error(err);
+ // If stored data is not a strigified JSON this will fail,
+ // that's why we catch the error
+ }
+
+ return settings;
+};
+
+export const storeSettings = (settings) => {
+ window.localStorage.setItem('settings', JSON.stringify(settings));
+};
+// 2
+const SettingsContext = createContext({
+ settings: defaultSettings,
+ saveSettings: () => { }
+});
+
+export const SettingsProvider = ({ settings, children }) => {
+ const [currentSettings, setCurrentSettings] = useState(settings || defaultSettings);
+
+ const handleSaveSettings = (update = {}) => {
+ const mergedSettings = _.merge({}, currentSettings, update);
+
+ setCurrentSettings(mergedSettings);
+ storeSettings(mergedSettings);
+ };
+
+ useEffect(() => {
+ const restoredSettings = restoreSettings();
+
+ if (restoredSettings) {
+ setCurrentSettings(restoredSettings);
+ }
+ }, []);
+
+ useEffect(() => {
+ document.dir = currentSettings.direction;
+ }, [currentSettings]);
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const SettingsConsumer = SettingsContext.Consumer;
+
+export default SettingsContext;
diff --git a/src/hooks/useAuth.js b/src/hooks/useAuth.js
new file mode 100644
index 0000000..a5b69fd
--- /dev/null
+++ b/src/hooks/useAuth.js
@@ -0,0 +1,6 @@
+import { useContext } from 'react';
+import AuthContext from '../contexts/AuthContext';
+
+const useAuth = () => useContext(AuthContext);
+
+export default useAuth;
diff --git a/src/hooks/useSettings.js b/src/hooks/useSettings.js
new file mode 100644
index 0000000..fe0fb11
--- /dev/null
+++ b/src/hooks/useSettings.js
@@ -0,0 +1,6 @@
+import { useContext } from 'react';
+import SettingsContext from '../contexts/SettingsContext';
+
+const useSettings = () => useContext(SettingsContext);
+
+export default useSettings;
diff --git a/src/index.css b/src/index.css
index ec2585e..17c3491 100644
--- a/src/index.css
+++ b/src/index.css
@@ -11,3 +11,7 @@ code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
+
+.MuiPagination-ul {
+ justify-content: space-around;
+}
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index bb29a24..9a5b6c0 100644
--- a/src/index.js
+++ b/src/index.js
@@ -3,30 +3,16 @@ import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
-import {BrowserRouter} from 'react-router-dom'
-import Drawer from './components/Drawer'
-import { createTheme, ThemeProvider, styled } from '@mui/material/styles';
-
-const theme = createTheme({
-
- palette: {
- type: 'light',
- primary: {
- main: '#000000',
- },
- secondary: {
- main: '#f50057',
- },
- },
-})
-
+import { SnackbarProvider } from 'notistack';
+import {SettingsProvider} from './contexts/SettingsContext'
ReactDOM.render(
-
-
-
-
-
+
+
+
+
+
+
,
document.getElementById('root')
);
diff --git a/src/layouts/DashboardLayout/NavBar/NavItem.js b/src/layouts/DashboardLayout/NavBar/NavItem.js
new file mode 100644
index 0000000..1300812
--- /dev/null
+++ b/src/layouts/DashboardLayout/NavBar/NavItem.js
@@ -0,0 +1,168 @@
+import React, { useState } from 'react';
+import { NavLink as RouterLink } from 'react-router-dom';
+import clsx from 'clsx';
+import PropTypes from 'prop-types';
+import {
+ Button,
+ Collapse,
+ ListItem,
+ makeStyles
+} from '@material-ui/core';
+import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
+import ExpandLessIcon from '@mui/icons-material/ExpandLess';
+
+const useStyles = makeStyles((theme) => ({
+ item: {
+ display: 'block',
+ paddingTop: 0,
+ paddingBottom: 0
+ },
+ itemLeaf: {
+ display: 'flex',
+ paddingTop: 0,
+ paddingBottom: 0
+ },
+ button: {
+ color: theme.palette.text.secondary,
+ padding: '10px 8px',
+ justifyContent: 'flex-start',
+ textTransform: 'none',
+ letterSpacing: 0,
+ width: '100%'
+ },
+ buttonLeaf: {
+ color: theme.palette.text.secondary,
+ padding: '10px 8px',
+ justifyContent: 'flex-start',
+ textTransform: 'none',
+ letterSpacing: 0,
+ width: '100%',
+ fontWeight: theme.typography.fontWeightRegular,
+ '&.depth-0': {
+ '& $title': {
+ fontWeight: theme.typography.fontWeightMedium
+ }
+ }
+ },
+ icon: {
+ display: 'flex',
+ alignItems: 'center',
+ marginRight: theme.spacing(1)
+ },
+ title: {
+ marginRight: 'auto'
+ },
+ active: {
+ color: theme.palette.secondary.main,
+ '& $title': {
+ fontWeight: theme.typography.fontWeightMedium
+ },
+ '& $icon': {
+ color: theme.palette.secondary.main
+ }
+ }
+}));
+
+const NavItem = ({
+ children,
+ className,
+ depth,
+ href,
+ icon: Icon,
+ info: Info,
+ open: openProp,
+ title,
+ ...rest
+}) => {
+ const classes = useStyles();
+ const [open, setOpen] = useState(openProp);
+
+ const handleToggle = () => {
+ setOpen((prevOpen) => !prevOpen);
+ };
+
+ let paddingLeft = 8;
+
+ if (depth > 0) {
+ paddingLeft = 32 + 8 * depth;
+ }
+
+ const style = { paddingLeft };
+
+ if (children) {
+ return (
+
+
+
+ {children}
+
+
+ );
+ }
+
+ return (
+
+
+
+ );
+};
+
+NavItem.propTypes = {
+ children: PropTypes.node,
+ className: PropTypes.string,
+ depth: PropTypes.number.isRequired,
+ href: PropTypes.string,
+ icon: PropTypes.elementType,
+ info: PropTypes.elementType,
+ open: PropTypes.bool,
+ title: PropTypes.string.isRequired
+};
+
+NavItem.defaultProps = {
+ open: false
+};
+
+export default NavItem;
diff --git a/src/layouts/DashboardLayout/NavBar/index.js b/src/layouts/DashboardLayout/NavBar/index.js
new file mode 100644
index 0000000..3e6e530
--- /dev/null
+++ b/src/layouts/DashboardLayout/NavBar/index.js
@@ -0,0 +1,96 @@
+/* eslint-disable no-use-before-define */
+import React, { useEffect } from 'react';
+import { useLocation, matchPath } from 'react-router-dom';
+import PropTypes from 'prop-types';
+import {
+ Box,
+ Drawer,
+ Hidden,
+ makeStyles
+} from '@material-ui/core';
+import useAuth from '../../../hooks/useAuth';
+
+
+
+function renderNavItems({
+ items,
+ pathname,
+ depth = 0
+}) {
+ return (
+
+ );
+}
+
+
+const useStyles = makeStyles(() => ({
+ mobileDrawer: {
+ width: 256
+ },
+ desktopDrawer: {
+ width: 256,
+ top: 64,
+ height: 'calc(100% - 64px)'
+ },
+ avatar: {
+ cursor: 'pointer',
+ width: 64,
+ height: 64
+ }
+}));
+
+const NavBar = ({ onMobileClose, openMobile }) => {
+ const classes = useStyles();
+ const location = useLocation();
+ const { user } = useAuth();
+
+ useEffect(() => {
+ if (openMobile && onMobileClose) {
+ onMobileClose();
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [location.pathname]);
+
+ const content = (
+
+
+
+ );
+
+ return (
+ <>
+
+
+ {content}
+
+
+
+
+ {content}
+
+
+ >
+ );
+};
+
+NavBar.propTypes = {
+ onMobileClose: PropTypes.func,
+ openMobile: PropTypes.bool
+};
+
+export default NavBar;
diff --git a/src/layouts/DashboardLayout/TopBar/Account.js b/src/layouts/DashboardLayout/TopBar/Account.js
new file mode 100644
index 0000000..dd0d1db
--- /dev/null
+++ b/src/layouts/DashboardLayout/TopBar/Account.js
@@ -0,0 +1,114 @@
+import React, {
+ useRef,
+ useState
+} from 'react';
+import { Link as RouterLink } from 'react-router-dom';
+import { useHistory } from 'react-router-dom';
+import { useSnackbar } from 'notistack';
+import {
+ Avatar,
+ Box,
+ ButtonBase,
+ Hidden,
+ Menu,
+ MenuItem,
+ Typography,
+ makeStyles
+} from '@material-ui/core';
+import useAuth from '../../../hooks/useAuth';
+
+const useStyles = makeStyles((theme) => ({
+ avatar: {
+ height: 32,
+ width: 32,
+ marginRight: theme.spacing(1)
+ },
+ popover: {
+ width: 200
+ }
+}));
+
+const Account = () => {
+ const classes = useStyles();
+ const history = useHistory();
+ const ref = useRef(null);
+ const { user, logout} = useAuth();
+
+ const { enqueueSnackbar } = useSnackbar();
+ const [isOpen, setOpen] = useState(false);
+
+ const handleOpen = () => {
+ setOpen(true);
+ };
+
+ const handleClose = () => {
+ setOpen(false);
+ };
+
+ const handleLogout = async () => {
+ try {
+ handleClose();
+ await logout();
+ history.push('/login');
+ } catch (err) {
+ enqueueSnackbar('Unable to logout', {
+ variant: 'error'
+ });
+ }
+ };
+ return (
+ <>
+
+
+
+
+ {user.profile.user.first_name}
+
+
+
+
+ >
+ );
+}
+
+export default Account;
diff --git a/src/layouts/DashboardLayout/TopBar/Settings.js b/src/layouts/DashboardLayout/TopBar/Settings.js
new file mode 100644
index 0000000..c0cd85e
--- /dev/null
+++ b/src/layouts/DashboardLayout/TopBar/Settings.js
@@ -0,0 +1,172 @@
+import React, {
+ useState,
+ useRef
+} from 'react';
+import { capitalCase } from 'change-case';
+import {
+ Badge,
+ Box,
+ Button,
+ FormControlLabel,
+ IconButton,
+ Popover,
+ SvgIcon,
+ Switch,
+ TextField,
+ Tooltip,
+ Typography,
+ makeStyles
+} from '@material-ui/core';
+import { Settings as SettingsIcon } from 'react-feather';
+import useSettings from '../../../hooks/useSettings';
+import { THEMES } from '../../../common/Constants';
+
+const useStyles = makeStyles((theme) => ({
+ badge: {
+ height: 10,
+ width: 10,
+ borderRadius: 5,
+ marginTop: 10,
+ marginRight: 5
+ },
+ popover: {
+ width: 320,
+ padding: theme.spacing(2)
+ }
+}));
+
+const Settings = () => {
+ const classes = useStyles();
+ const ref = useRef(null);
+ const { settings, saveSettings } = useSettings();
+ const [isOpen, setOpen] = useState(false);
+ const [values, setValues] = useState({
+ direction: settings.direction,
+ responsiveFontSizes: settings.responsiveFontSizes,
+ theme: settings.theme
+ });
+
+ const handleOpen = () => {
+ setOpen(true);
+ };
+
+ const handleClose = () => {
+ setOpen(false);
+ };
+
+ const handleChange = (field, value) => {
+ setValues({
+ ...values,
+ [field]: value
+ });
+ };
+
+ const handleSave = () => {
+ saveSettings(values);
+ setOpen(false);
+ };
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+ Settings
+
+
+ handleChange('direction', event.target.checked ? 'rtl' : 'ltr')}
+ />
+ )}
+ label="RTL"
+ />
+
+
+ handleChange('responsiveFontSizes', event.target.checked)}
+ />
+ )}
+ label="Responsive font sizes"
+ />
+
+
+ handleChange('theme', event.target.value)}
+ select
+ SelectProps={{ native: true }}
+ value={values.theme}
+ variant="outlined"
+ >
+ {Object.keys(THEMES).map((theme) => (
+
+ ))}
+
+
+
+
+
+
+ >
+ );
+}
+
+export default Settings;
diff --git a/src/layouts/DashboardLayout/TopBar/index.js b/src/layouts/DashboardLayout/TopBar/index.js
new file mode 100644
index 0000000..5f467fb
--- /dev/null
+++ b/src/layouts/DashboardLayout/TopBar/index.js
@@ -0,0 +1,85 @@
+import React from 'react';
+import { Link as RouterLink } from 'react-router-dom';
+import PropTypes from 'prop-types';
+import clsx from 'clsx';
+import {
+ AppBar,
+ Box,
+ Hidden,
+ IconButton,
+ Toolbar,
+ makeStyles,
+ SvgIcon
+} from '@material-ui/core';
+import { Menu as MenuIcon } from 'react-feather';
+import { THEMES } from '../../../common/Constants';
+import Account from './Account';
+import Settings from './Settings';
+
+const useStyles = makeStyles((theme) => ({
+ root: {
+ ...theme.name === THEMES.LIGHT ? {
+ boxShadow: 'none',
+ backgroundColor: theme.palette.primary.main
+ } : {},
+ ...theme.name === THEMES.ONE_DARK ? {
+ backgroundColor: theme.palette.background.default
+ } : {}
+ },
+ toolbar: {
+ minHeight: 64
+ },
+ logo:{
+ maxHeight:'40px',
+ maxWidth:'40px'
+ }
+}));
+
+const TopBar = ({
+ className,
+ onMobileNavOpen,
+ ...rest
+}) => {
+ const classes = useStyles();
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+TopBar.propTypes = {
+ className: PropTypes.string,
+ onMobileNavOpen: PropTypes.func
+};
+
+TopBar.defaultProps = {
+ onMobileNavOpen: () => {}
+};
+
+export default TopBar;
diff --git a/src/layouts/DashboardLayout/index.js b/src/layouts/DashboardLayout/index.js
new file mode 100644
index 0000000..cd647c7
--- /dev/null
+++ b/src/layouts/DashboardLayout/index.js
@@ -0,0 +1,62 @@
+import React, { useState } from 'react';
+import PropTypes from 'prop-types';
+import { makeStyles } from '@material-ui/core';
+import NavBar from './NavBar';
+import TopBar from './TopBar';
+
+const useStyles = makeStyles((theme) => ({
+ root: {
+ backgroundColor: theme.palette.background.dark,
+ display: 'flex',
+ height: '100%',
+ overflow: 'hidden',
+ width: '100%'
+ },
+ wrapper: {
+ display: 'flex',
+ flex: '1 1 auto',
+ overflow: 'hidden',
+ paddingTop: 64,
+ // [theme.breakpoints.up('lg')]: {
+ // paddingLeft: 256
+ // }
+ },
+ contentContainer: {
+ display: 'flex',
+ flex: '1 1 auto',
+ overflow: 'hidden'
+ },
+ content: {
+ flex: '1 1 auto',
+ height: '100%',
+ overflow: 'auto'
+ }
+}));
+
+const DashboardLayout = ({ children }) => {
+ const classes = useStyles();
+ const [isMobileNavOpen, setMobileNavOpen] = useState(false);
+
+ return (
+
+
setMobileNavOpen(true)} />
+ {/* setMobileNavOpen(false)}
+ openMobile={isMobileNavOpen}
+ /> */}
+
+
+ );
+};
+
+DashboardLayout.propTypes = {
+ children: PropTypes.node
+};
+
+export default DashboardLayout;
diff --git a/src/pages/Categories.jsx b/src/pages/Categories.jsx
deleted file mode 100644
index 0e9ce54..0000000
--- a/src/pages/Categories.jsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import React, { useEffect } from 'react';
-
-function Categories(props) {
- console.log(props)
- useEffect(()=>{
- console.log('use effect')
- let userData = JSON.parse(localStorage.getItem('myData'))
- console.log(userData)
- },[])
- return (
-
- Categories
-
- );
-}
-
-export default Categories;
\ No newline at end of file
diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx
deleted file mode 100644
index 3c13707..0000000
--- a/src/pages/Dashboard.jsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import React, { useEffect, useState } from 'react';
-import {Navigate} from 'react-router-dom'
-function Dashboard(props) {
- const [isLogged, setIsLogged] = React.useState(true)
- useEffect(()=>{
- console.log('1')
- let token;
- try {
- token = JSON.parse(localStorage.getItem('token'))
- console.log('2')
- if(!token)
- setIsLogged(false)
-
- } catch (error) {
- console.log(error)
- setIsLogged(false)
- }
-
- },[])
- console.log('3')
-
- if(!isLogged)
- return
-
- return (
-
- Dashboard
-
- );
-}
-
-export default Dashboard;
\ No newline at end of file
diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx
deleted file mode 100644
index cf8b851..0000000
--- a/src/pages/Login.jsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import React from 'react';
-import { useNavigate } from 'react-router-dom';
-import axios from '../utils/axios'
-import {TOKEN_KEY} from '../utils/Constants'
-function Login(props) {
- const navigate = useNavigate()
- const [email, setEmail] = React.useState('')
- const [password, setPassword] = React.useState('')
-
- const login = (e)=>{
- e.preventDefault()
- axios.post('/api/academy/auth/login',
- {
- email:email,
- password:password
- }
- )
- .then((response)=>{
- console.log(response)
- let token = response.data.token.access_token;
- let data = response.data;
- localStorage.setItem(TOKEN_KEY, JSON.stringify(data))
- navigate('/dashboard')
- })
- .catch((err)=>{
- console.log(err)
- })
- }
- return (
-
-
-
- );
-}
-
-export default Login;
\ No newline at end of file
diff --git a/src/pages/Products.jsx b/src/pages/Products.jsx
deleted file mode 100644
index e3fcba4..0000000
--- a/src/pages/Products.jsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import React, { useEffect } from 'react';
-
-function Products(props) {
-
- return (
-
- Products
-
- );
-}
-
-export default Products;
\ No newline at end of file
diff --git a/src/routes.js b/src/routes.js
new file mode 100644
index 0000000..72a91e2
--- /dev/null
+++ b/src/routes.js
@@ -0,0 +1,66 @@
+import React, {
+ Suspense,
+ Fragment,
+ lazy
+} from 'react';
+import {
+ Switch,
+ Redirect,
+ Route
+} from 'react-router-dom';
+import DashboardLayout from './layouts/DashboardLayout';
+import LoadingScreen from './components/LoadingScreen';
+import AuthGuard from './components/guards/AuthGuard';
+import GuestGuard from './components/guards/GuestGuard';
+
+export const renderRoutes = (routes = []) => (
+ }>
+
+ {routes.map((route, i) => {
+ const Guard = route.guard || Fragment;
+ const Layout = route.layout || Fragment;
+ const Component = route.component;
+
+ return (
+ (
+
+
+
+
+
+
+
+ )}
+ />
+ );
+ })}
+
+
+);
+
+export const routes = [
+ {
+ exact: true,
+ path: '/404',
+ component: lazy(() => import('./views/NotFoundView'))
+ },
+ {
+ exact: true,
+ guard: GuestGuard,
+ path: '/login',
+ component: lazy(() => import('./views/LoginView'))
+ },
+ {
+ exact: true,
+ guard: AuthGuard,
+ path: '/board',
+ layout:DashboardLayout,
+ component: lazy(() => import('./views/BoardView'))
+ }
+];
+
+export default routes;
diff --git a/src/services/Http/DashoardService.js b/src/services/Http/DashoardService.js
new file mode 100644
index 0000000..333f479
--- /dev/null
+++ b/src/services/Http/DashoardService.js
@@ -0,0 +1,10 @@
+import { BaseService } from "../../utils/classes/BaseHttp"
+
+export class DashboradService extends BaseService {
+ constructor() {
+ super('')
+ }
+ async loadPoints(){
+ return await this.http.get("api/score/data/5")
+ }
+}
\ No newline at end of file
diff --git a/src/services/Http/LoginService.js b/src/services/Http/LoginService.js
new file mode 100644
index 0000000..c86883f
--- /dev/null
+++ b/src/services/Http/LoginService.js
@@ -0,0 +1,10 @@
+import { BaseService } from "../../utils/classes/BaseHttp"
+
+export class LoginService extends BaseService {
+ constructor() {
+ super('')
+ }
+ async login(body){
+ return await this.http.post("/api/score/auth/login",body)
+ }
+}
\ No newline at end of file
diff --git a/src/theme/index.js b/src/theme/index.js
new file mode 100644
index 0000000..c00e818
--- /dev/null
+++ b/src/theme/index.js
@@ -0,0 +1,128 @@
+
+
+import _ from 'lodash'
+import {THEMES} from '../common/Constants'
+import {
+ colors,
+ createMuiTheme,
+ responsiveFontSizes
+} from '@material-ui/core';
+const themesOptions = [
+ {
+ name: THEMES.LIGHT,
+ overrides: {
+ MuiInputBase: {
+ input: {
+ '&::placeholder': {
+ opacity: 1,
+ color: colors.blueGrey[600]
+ }
+ }
+ }
+ },
+ palette: {
+ type: 'light',
+ action: {
+ active: colors.blueGrey[600]
+ },
+ background: {
+ default: colors.common.white,
+ dark: colors.common.white,
+ paper: colors.common.white
+ },
+ primary: {
+ main: '#00bbf0'//ex: top bar
+ },
+ secondary: {
+ main: '#fdb44b' //
+ },
+ text: {
+ primary: colors.blueGrey[900],
+ secondary: colors.blueGrey[600]
+ }
+ }
+ },
+ {
+ name: THEMES.ONE_DARK,
+ palette: {
+ type: 'dark',
+ action: {
+ active: 'rgba(255, 255, 255, 0.54)',
+ hover: 'rgba(255, 255, 255, 0.04)',
+ selected: 'rgba(255, 255, 255, 0.08)',
+ disabled: 'rgba(255, 255, 255, 0.26)',
+ disabledBackground: 'rgba(255, 255, 255, 0.12)',
+ focus: 'rgba(255, 255, 255, 0.12)'
+ },
+ background: {
+ default: '#005792',
+ dark:'#f0f0f0',
+ paper: colors.common.white
+ },
+ primary: {
+ main: '#00204a'
+ },
+ secondary: {
+ main: '#fdb44b'
+ },
+ text: {
+ primary: '#2d2d2e',
+ secondary: '#8a8a8a'
+ }
+ }
+ },
+ {
+ name: THEMES.UNICORN,
+ palette: {
+ type: 'dark',
+ action: {
+ active: 'rgba(255, 255, 255, 0.54)',
+ hover: 'rgba(255, 255, 255, 0.04)',
+ selected: 'rgba(255, 255, 255, 0.08)',
+ disabled: 'rgba(255, 255, 255, 0.26)',
+ disabledBackground: 'rgba(255, 255, 255, 0.12)',
+ focus: 'rgba(255, 255, 255, 0.12)'
+ },
+ background: {
+ default: '#2a2d3d',
+ dark: '#00204a',
+ paper: '#005792'
+ },
+ primary: {
+ main: '#00bbf0'
+ },
+ secondary: {
+ main: '#fdb44b'
+ },
+ text: {
+ primary: '#f6f5f8',
+ secondary: '#9699a4'
+ }
+ }
+ }
+];
+
+const baseOptions = {
+ direction:'ltr'
+}
+export const createTheme = (config = {}) => {
+ let themeOptions = themesOptions.find((theme) => theme.name === config.theme);
+ console.log('selected theme is ', themeOptions)
+ if (!themeOptions) {
+ console.warn(new Error(`The theme ${config.theme} is not valid`));
+ [themeOptions] = themesOptions;
+ }
+ console.log('theme before update,' , themeOptions)
+ let theme = createMuiTheme(
+ _.merge(
+ {},
+ baseOptions,
+ themeOptions,
+ { direction: config.direction }
+ )
+ );
+
+ console.log('last theme object: ',theme)
+ return theme;
+ }
+
\ No newline at end of file
diff --git a/src/utils/Constants.js b/src/utils/Constants.js
deleted file mode 100644
index 1574da1..0000000
--- a/src/utils/Constants.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export const TOKEN_KEY = 'token'
-export const BASE_URL = 'https://website-backend.computiq.tech'
\ No newline at end of file
diff --git a/src/utils/axios.js b/src/utils/axios.js
new file mode 100644
index 0000000..8ae7635
--- /dev/null
+++ b/src/utils/axios.js
@@ -0,0 +1,29 @@
+import axios from 'axios';
+import { SESSION_KEY, BASE_URL} from "../common/Constants";
+
+const axiosInstance = axios.create();
+axiosInstance.defaults.baseURL=BASE_URL;
+axiosInstance.interceptors.response.use(
+ (response) => response
+ // ,(error) => Promise.reject((error.response && error.response.data) || 'Something went wrong')
+);
+
+function getSession() {
+ let session = localStorage.getItem(SESSION_KEY)
+ if (session) {
+ return JSON.parse(session)
+ }
+ return session
+}
+function checkSession() {
+ return localStorage.getItem(SESSION_KEY) !== null
+}
+
+if (checkSession()) {
+ let sessionData = getSession();
+ console.log('local storage: ',sessionData)
+ let apiToken = sessionData.token.access_token
+ console.log(apiToken)
+ axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${apiToken}`;
+}
+export default axiosInstance;
diff --git a/src/utils/axios.jsx b/src/utils/axios.jsx
deleted file mode 100644
index 5610218..0000000
--- a/src/utils/axios.jsx
+++ /dev/null
@@ -1,4 +0,0 @@
-import axios from 'axios'
-import {BASE_URL} from './Constants'
-axios.defaults.baseURL = BASE_URL;
-export default axios
\ No newline at end of file
diff --git a/src/utils/classes/BaseHttp.js b/src/utils/classes/BaseHttp.js
new file mode 100644
index 0000000..ffda785
--- /dev/null
+++ b/src/utils/classes/BaseHttp.js
@@ -0,0 +1,30 @@
+import { HttpService } from "./HttpHelper";
+
+export class BaseService {
+
+ http
+
+ constructor(url_prefix = "") {
+ this.http = (new HttpService(url_prefix))
+ }
+
+ async getAll() {
+ return await this.http.get(``)
+ }
+
+ async get(id) {
+ return await this.http.get(`/${id}`)
+ }
+
+ async create(body) {
+ return await this.http.post(``, body)
+ }
+
+ async update(id, body) {
+ return await this.http.put(`/${id}`, body)
+ }
+
+ async delete(id) {
+ return await this.http.remove(`/${id}`)
+ }
+}
\ No newline at end of file
diff --git a/src/utils/classes/HttpHelper.js b/src/utils/classes/HttpHelper.js
new file mode 100644
index 0000000..c730d97
--- /dev/null
+++ b/src/utils/classes/HttpHelper.js
@@ -0,0 +1,92 @@
+import axios from '../axios'
+
+
+export class HttpService {
+
+ headers = {
+
+ }
+
+ constructor(url_prefix = "") {
+ this.url_prefix = url_prefix
+ this.getHeaders()
+ }
+
+ async get(url, queryParams) {
+ try {
+ let response = await axios.get(this.getUrl(url) + this.mapQueryParams(queryParams), {
+ headers: this.headers
+ })
+
+ return response
+ } catch (error) {
+ console.log(error)
+ return error
+ }
+ }
+
+ async post(url, body, queryParams = null) {
+ try {
+ let response = await axios.post(this.getUrl(url) + this.mapQueryParams(queryParams),body ,{
+ method: "POST",
+ headers: this.headers
+ })
+
+ return response
+ } catch (error) {
+ // console.log('error in response of axios is',error)
+ // let res = handleResponse(error)
+ return error; // null or object of msg
+ }
+
+ }
+
+ async put(url, body, queryParams = null) {
+ try {
+ let response = await fetch(this.getUrl(url) + this.mapQueryParams(queryParams), {
+ method: "PUT",
+ headers: this.headers,
+ body: JSON.stringify(body)
+ })
+
+ return response
+ } catch (error) {
+ console.log(error);
+ return null
+ }
+ }
+
+ async remove(url, queryParams = null) {
+ try {
+ let response = await fetch(this.getUrl(url) + this.mapQueryParams(queryParams), {
+ method: "DELETE",
+ headers: this.headers
+ })
+
+ return response
+ } catch (error) {
+ console.log(error)
+ return null
+ }
+ }
+
+ getUrl(url) {
+ return this.url_prefix + url
+ }
+
+ getHeaders() {
+ this.headers = {
+ 'Content-Type': 'application/json',
+ 'Accept': 'application/json',
+ 'Access-Control-Allow-Origin': '*'
+ }
+ }
+
+ mapQueryParams(queryParams) {
+ return queryParams
+ ? Object.keys(queryParams).map(function (key) {
+ return key + '=' + queryParams[key]
+ }).join('&')
+ : ""
+ }
+}
\ No newline at end of file
diff --git a/src/utils/responseHandler.js b/src/utils/responseHandler.js
new file mode 100644
index 0000000..ed803d7
--- /dev/null
+++ b/src/utils/responseHandler.js
@@ -0,0 +1,60 @@
+export const handleResponse = (err) => {
+ let resp = null
+ if(err.response)
+ {
+ resp = {}
+
+ switch(err.response.status)
+ {
+ case 401:
+ resp = {
+ message:err.response.data.message,
+ statusCode:err.response.status
+ }
+ console.log(resp)
+ // window.location.href='/login'
+ break;
+ case 422:
+ let msg = '';
+ console.log('err object: ',err.response)
+ let details = err.response.data.detail
+ if(details)
+ {
+ details.map((m)=>{
+ msg = msg + ", "+m.msg
+ })
+ }
+ resp = {
+ message:msg,
+ statusCode:err.response.status
+ }
+ console.log('object created: ',resp)
+ // window.location.href='/login'
+ break;
+
+ case 404:
+ resp ={
+ message:err.response.data.message,
+ statusCode:err.response.status
+ }
+ break;
+
+ }
+
+ }
+ else if(err.request)
+ {
+ console.log(err.status)
+ console.log("Error in the client side at request")
+
+ }
+ else{
+ resp = {
+ message:'Unknown error!',
+ statusCode:-1
+ }
+ }
+ console.log('respo in handler is: ',resp)
+ return resp;
+
+}
\ No newline at end of file
diff --git a/src/views/BoardView.jsx b/src/views/BoardView.jsx
new file mode 100644
index 0000000..2ea6f22
--- /dev/null
+++ b/src/views/BoardView.jsx
@@ -0,0 +1,76 @@
+import { makeStyles, Typography, Box} from '@material-ui/core';
+import React, { useEffect, useState} from 'react';
+import { DashboradService } from '../services/Http/DashoardService';
+import Pagination from '@mui/material/Pagination';
+import BoardItems from '../components/BoardItems';
+import Container from '@mui/material/Container';
+import Grid from '@mui/material/Grid';
+import TaskItems from '../components/TaskItems'
+import CircularProgress from '@mui/material/CircularProgress';
+
+const useStyles = makeStyles((theme)=>({
+ bg:{
+ backgroundColor: 'white',
+ borderRadius: 20,
+ boxSizing: 'border-box',
+ padding: 20,
+ border: '1px #1a8cf7 solid',
+ boxShadow: '5px 5px 0 #1a8cf7',
+ },
+
+
+}))
+function BoardView(props) {
+ const classes = useStyles()
+ let perPage = 10
+ const [data, setData] = useState([])
+ const [page, setPage] = useState(1)
+ const [pages, setPages] = useState(1)
+ const [dataPaginate, setDataPaginate] = useState([])
+ const [tasks, setTasks] = useState([])
+
+ const handleClick = (event, value)=> {
+ let fromRecord = perPage * (value - 1)
+ let toRecord = ((fromRecord + perPage) <= data.length) ? (fromRecord + perPage) : (data.length % perPage) + fromRecord
+ setPage(value)
+ setDataPaginate(data.slice(fromRecord,toRecord))
+ }
+
+
+ useEffect(()=>{
+
+ (new DashboradService).loadPoints().then((res)=> {
+ let dataRes = res.data
+ let boardData = dataRes.data
+ let tasksData = dataRes.program.tasks
+
+ setTasks(tasksData)
+ setData([...boardData])
+ setPages(Math.ceil(boardData.length/perPage))
+ setDataPaginate(boardData.slice(0,10))
+ }).catch((err)=> console.log(err))
+
+ },[])
+
+ return (
+
+ {dataPaginate.length==0? :
+
+
+ Computiq Score Board
+ Full-Stack Development Bootcamp
+
+
+
+
+
+
+
+
+
+ }
+
+ );
+}
+
+export default BoardView;
\ No newline at end of file
diff --git a/src/views/LoginView.jsx b/src/views/LoginView.jsx
new file mode 100644
index 0000000..2b32ed5
--- /dev/null
+++ b/src/views/LoginView.jsx
@@ -0,0 +1,82 @@
+import React, { useState } from 'react';
+// import { makeStyles } from '@mui/styles';
+import { Box,makeStyles } from '@material-ui/core';
+import TextField from '@mui/material/TextField';
+import Button from '@mui/material/Button';
+import useAuth from '../hooks/useAuth';
+import Snackbar from '@mui/material/Snackbar';
+import MuiAlert from '@mui/material/Alert';
+
+
+const Alert = React.forwardRef(function Alert(props, ref) {
+ return ;
+ });
+
+const useStyles = makeStyles(()=>({
+ root:{
+ display:'flex',
+ flexGrow:1,
+ justifyContent:'center',
+ alignItems:'center',
+ backgroundColor:'#e0e0e0',
+ height:'100vh'
+ },
+ loginBox:{
+ width:'400px',
+ height:'250px',
+ backgroundColor:'white',
+ borderRadius:'5px'
+ },
+ form:{
+ width:'75%',
+ margin:'auto',
+ paddingTop:'15px',
+ paddingBottom:'15px',
+ boxSizing:'border-box',
+ display:'flex',
+ flexDirection:'column',
+ justifyContent:'space-between',
+ height:'100%'
+ },
+
+ field:{
+ width:'100%'
+ }
+
+}))
+function LoginView(props) {
+ const classes = useStyles()
+ const {login,error} = useAuth()
+ console.log(' error is ',error)
+ const [email,setEmail] = useState('')
+ const [password,setPassword] = useState('')
+ const auth = (e)=>{
+ e.preventDefault();
+ login(email, password);
+
+
+ }
+ return (
+
+
+
+
+ {
+ error && {error}
+ }
+
+ );
+}
+
+export default LoginView;
\ No newline at end of file
diff --git a/src/views/NotFoundView.jsx b/src/views/NotFoundView.jsx
new file mode 100644
index 0000000..1e19bd9
--- /dev/null
+++ b/src/views/NotFoundView.jsx
@@ -0,0 +1,11 @@
+import React from 'react';
+
+function ViewNotFound(props) {
+ return (
+
+ 404 Not Found
+
+ );
+}
+
+export default ViewNotFound;
\ No newline at end of file