finished Protected Routes
This commit is contained in:
parent
a20c839324
commit
686c8fe008
@ -2,11 +2,13 @@ import React, { useState } from "react";
|
|||||||
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
|
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
|
||||||
import "./styles.css";
|
import "./styles.css";
|
||||||
|
|
||||||
|
import Login from "./components/login/Login";
|
||||||
import Home from "./components/home/Home";
|
import Home from "./components/home/Home";
|
||||||
import Contacts from "./components/contacts/Contacts";
|
import Contacts from "./components/contacts/Contacts";
|
||||||
import Calendar from "./components/calendar/Calendar";
|
import Calendar from "./components/calendar/Calendar";
|
||||||
import Navbar from "./components/navbar/Navbar";
|
import Navbar from "./components/navbar/Navbar";
|
||||||
import { ThemeProvider } from "@emotion/react";
|
import { ThemeProvider } from "@emotion/react";
|
||||||
|
import ProtectedRoute from "./ProtectedRoute";
|
||||||
|
|
||||||
import Theme from "./Theme";
|
import Theme from "./Theme";
|
||||||
|
|
||||||
@ -47,9 +49,12 @@ const App: React.FC = () => {
|
|||||||
<Router>
|
<Router>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<Routes>
|
<Routes>
|
||||||
|
<Route path="/login" element={<Login />} />
|
||||||
|
<Route element={<ProtectedRoute />}>
|
||||||
<Route path="/" element={<Home />} />
|
<Route path="/" element={<Home />} />
|
||||||
<Route path="/contacts" element={<Contacts />} />
|
<Route path="/contacts" element={<Contacts />} />
|
||||||
<Route path="/calendar" element={<Calendar />} />
|
<Route path="/calendar" element={<Calendar />} />
|
||||||
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
</Router>
|
</Router>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
|||||||
12
src/ProtectedRoute.tsx
Normal file
12
src/ProtectedRoute.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { useLocation, Outlet, Navigate } from "react-router-dom";
|
||||||
|
import useAuth from "./hooks/useAuth";
|
||||||
|
|
||||||
|
const ProtectedRoute = () => {
|
||||||
|
const { auth }: any = useAuth();
|
||||||
|
const location = useLocation();
|
||||||
|
return (
|
||||||
|
auth?.isLoggedIn ? <Outlet /> : <Navigate to="/login" state={{ from: location }} replace />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProtectedRoute;
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { useRef, useState, useEffect, useContext } from 'react';
|
||||||
|
import { useLocation, Link, useNavigate } from "react-router-dom";
|
||||||
import { Stack } from "@mui/material";
|
import { Stack } from "@mui/material";
|
||||||
import Container from "@mui/material/Container";
|
import Container from "@mui/material/Container";
|
||||||
import TextField from "@mui/material/TextField";
|
import TextField from "@mui/material/TextField";
|
||||||
@ -5,17 +7,50 @@ import Button from "@mui/material/Button";
|
|||||||
import hsbcLogo from "../../assets/logo-png.png";
|
import hsbcLogo from "../../assets/logo-png.png";
|
||||||
import zoomLogo from "../../assets/zoom.png";
|
import zoomLogo from "../../assets/zoom.png";
|
||||||
import LoginIcon from '@mui/icons-material/Login';
|
import LoginIcon from '@mui/icons-material/Login';
|
||||||
|
import useAuth from "../../hooks/useAuth";
|
||||||
|
|
||||||
const Login: React.FC = () => {
|
const Login: React.FC = () => {
|
||||||
|
|
||||||
|
const { setAuth }: any = useAuth();
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const location: any = useLocation();
|
||||||
|
const from = location.state?.from?.pathname || "/";
|
||||||
|
|
||||||
|
const [username, setUsername] = useState('');
|
||||||
|
const [password, setPassword] = useState('');
|
||||||
|
// const [errMsg, setErrMsg] = useState('');
|
||||||
|
|
||||||
|
// const userRef = useRef();
|
||||||
|
// const errRef = useRef();
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// userRef.current.focus();
|
||||||
|
// }, [])
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// setErrMsg('');
|
||||||
|
// }, [user, pwd])
|
||||||
|
|
||||||
|
const handleLogin = () => {
|
||||||
|
if (username === "" && password === "") {
|
||||||
|
setAuth({username: username, isLoggedIn: true});
|
||||||
|
navigate(from, {replace: true});
|
||||||
|
}
|
||||||
|
setUsername("");
|
||||||
|
setPassword("");
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container className="login">
|
<Container className="login">
|
||||||
<Stack className="grid-container" spacing={2}>
|
<Stack className="grid-container" spacing={2}>
|
||||||
<img className="login-logo" src={hsbcLogo} alt="HSBC Logo"/>
|
<img className="login-logo" src={hsbcLogo} alt="HSBC Logo"/>
|
||||||
<TextField className="username-input" id="outlined-basic" label="Username" variant="outlined" placeholder="Username"/>
|
{/* <p ref={errRef} className={errMsg ? "errmsg" : "offscreen"} aria-live="assertive">{errMsg}</p> */}
|
||||||
<TextField className="password-input" id="outlined-basic" label="Password" variant="outlined" placeholder="Password"/>
|
<TextField className="username-input" id="outlined-basic" label="Username" variant="outlined" placeholder="Username" onChange={(event) => {setUsername(event.target.value)}}/>
|
||||||
|
<TextField className="password-input" id="outlined-basic" label="Password" variant="outlined" placeholder="Password" type="password" onChange={(event) => {setPassword(event.target.value)}}/>
|
||||||
<Stack direction="row" justifyContent="space-between" spacing={2}>
|
<Stack direction="row" justifyContent="space-between" spacing={2}>
|
||||||
<a className="register-btn" href="#">Forgotten Your Password?</a>
|
<a className="register-btn" href="#">Forgotten Your Password?</a>
|
||||||
<Button endIcon={<LoginIcon />} className="login-btn" href="#" variant="contained">Login</Button>
|
<Button endIcon={<LoginIcon />} className="login-btn" variant="contained" type="submit" onClick={handleLogin}>Login</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack direction="row" justifyContent="space-between" spacing={2}>
|
<Stack direction="row" justifyContent="space-between" spacing={2}>
|
||||||
<label>Login with</label>
|
<label>Login with</label>
|
||||||
|
|||||||
15
src/context/AuthProvider.tsx
Normal file
15
src/context/AuthProvider.tsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { createContext, useState } from "react";
|
||||||
|
|
||||||
|
const AuthContext = createContext({});
|
||||||
|
|
||||||
|
export const AuthProvider = ({ children }: {children: any}) => {
|
||||||
|
const [auth, setAuth] = useState({});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AuthContext.Provider value={{ auth, setAuth }}>
|
||||||
|
{children}
|
||||||
|
</AuthContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AuthContext;
|
||||||
8
src/hooks/useAuth.tsx
Normal file
8
src/hooks/useAuth.tsx
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { useContext } from "react";
|
||||||
|
import AuthContext from "../context/AuthProvider";
|
||||||
|
|
||||||
|
const useAuth = () => {
|
||||||
|
return useContext(AuthContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useAuth;
|
||||||
@ -1,9 +1,14 @@
|
|||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
import "./style/App.css";
|
import "./style/App.css";
|
||||||
|
import { AuthProvider } from './context/AuthProvider';
|
||||||
|
|
||||||
const Index:React.FC = () => {
|
const Index:React.FC = () => {
|
||||||
return <App />;
|
return (
|
||||||
|
<AuthProvider>
|
||||||
|
<App />
|
||||||
|
</AuthProvider>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
ReactDOM.render(<Index />, document.getElementById("root"));
|
ReactDOM.render(<Index />, document.getElementById("root"));
|
||||||
|
|||||||
Reference in New Issue
Block a user