auth context

This commit is contained in:
Tyrel Souza 2022-09-23 12:14:21 -04:00
parent 9149538440
commit 884a4dbea5
No known key found for this signature in database
GPG Key ID: F3614B02ACBE438E
9 changed files with 137 additions and 78 deletions

View File

@ -1 +1 @@
[{"/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/index.js":"1","/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/App.js":"2","/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/components/Home/Home.js":"3","/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/components/Login/Login.js":"4","/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/components/MainHeader/MainHeader.js":"5","/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/components/MainHeader/Navigation.js":"6","/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/components/UI/Card/Card.js":"7","/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/components/UI/Button/Button.js":"8"},{"size":206,"mtime":1648532752000,"results":"9","hashOfConfig":"10"},{"size":1093,"mtime":1616593928000,"results":"11","hashOfConfig":"10"},{"size":250,"mtime":1616593928000,"results":"12","hashOfConfig":"10"},{"size":3876,"mtime":1663871762917,"results":"13","hashOfConfig":"10"},{"size":368,"mtime":1616593928000,"results":"14","hashOfConfig":"10"},{"size":571,"mtime":1616593928000,"results":"15","hashOfConfig":"10"},{"size":218,"mtime":1616593928000,"results":"16","hashOfConfig":"10"},{"size":353,"mtime":1616593928000,"results":"17","hashOfConfig":"10"},{"filePath":"18","messages":"19","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"4a8obe",{"filePath":"20","messages":"21","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"22","messages":"23","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"24","messages":"25","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"26","messages":"27","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"28","messages":"29","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"30","messages":"31","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"32","messages":"33","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"34"},"/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/index.js",[],"/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/App.js",[],"/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/components/Home/Home.js",[],"/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/components/Login/Login.js",[],"/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/components/MainHeader/MainHeader.js",[],"/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/components/MainHeader/Navigation.js",[],"/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/components/UI/Card/Card.js",[],"/Users/tyrel.souza/code/udemy/react-course/usereducer-starting-project/src/components/UI/Button/Button.js",[],["35","36"],{"ruleId":"37","replacedBy":"38"},{"ruleId":"39","replacedBy":"40"},"no-native-reassign",["41"],"no-negated-in-lhs",["42"],"no-global-assign","no-unsafe-negation"] [{"/code/gitea/udemy-react-course/usereducer-starting-project/src/index.js":"1","/code/gitea/udemy-react-course/usereducer-starting-project/src/App.js":"2","/code/gitea/udemy-react-course/usereducer-starting-project/src/components/Home/Home.js":"3","/code/gitea/udemy-react-course/usereducer-starting-project/src/components/MainHeader/MainHeader.js":"4","/code/gitea/udemy-react-course/usereducer-starting-project/src/components/Login/Login.js":"5","/code/gitea/udemy-react-course/usereducer-starting-project/src/components/MainHeader/Navigation.js":"6","/code/gitea/udemy-react-course/usereducer-starting-project/src/components/UI/Card/Card.js":"7","/code/gitea/udemy-react-course/usereducer-starting-project/src/components/UI/Button/Button.js":"8","/code/gitea/udemy-react-course/usereducer-starting-project/src/store/auth-context.js":"9"},{"size":322,"mtime":1663949419058,"results":"10","hashOfConfig":"11"},{"size":514,"mtime":1663949472127,"results":"12","hashOfConfig":"11"},{"size":458,"mtime":1663949557069,"results":"13","hashOfConfig":"11"},{"size":333,"mtime":1663948682144,"results":"14","hashOfConfig":"11"},{"size":3985,"mtime":1663949653304,"results":"15","hashOfConfig":"11"},{"size":828,"mtime":1663949120275,"results":"16","hashOfConfig":"11"},{"size":218,"mtime":1663942019122,"results":"17","hashOfConfig":"11"},{"size":353,"mtime":1663942019122,"results":"18","hashOfConfig":"11"},{"size":1036,"mtime":1663949348496,"results":"19","hashOfConfig":"11"},{"filePath":"20","messages":"21","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"s4xwqj",{"filePath":"22","messages":"23","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"24","messages":"25","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"26","messages":"27","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"28"},{"filePath":"29","messages":"30","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"31","messages":"32","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"28"},{"filePath":"33","messages":"34","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"28"},{"filePath":"35","messages":"36","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"28"},{"filePath":"37","messages":"38","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"28"},"/code/gitea/udemy-react-course/usereducer-starting-project/src/index.js",[],"/code/gitea/udemy-react-course/usereducer-starting-project/src/App.js",[],"/code/gitea/udemy-react-course/usereducer-starting-project/src/components/Home/Home.js",[],"/code/gitea/udemy-react-course/usereducer-starting-project/src/components/MainHeader/MainHeader.js",[],["39","40"],"/code/gitea/udemy-react-course/usereducer-starting-project/src/components/Login/Login.js",[],"/code/gitea/udemy-react-course/usereducer-starting-project/src/components/MainHeader/Navigation.js",[],"/code/gitea/udemy-react-course/usereducer-starting-project/src/components/UI/Card/Card.js",[],"/code/gitea/udemy-react-course/usereducer-starting-project/src/components/UI/Button/Button.js",[],"/code/gitea/udemy-react-course/usereducer-starting-project/src/store/auth-context.js",[],{"ruleId":"41","replacedBy":"42"},{"ruleId":"43","replacedBy":"44"},"no-native-reassign",["45"],"no-negated-in-lhs",["46"],"no-global-assign","no-unsafe-negation"]

View File

@ -4222,6 +4222,17 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/ansi-escapes/node_modules/type-fest": {
"version": "0.21.3",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/ansi-html": { "node_modules/ansi-html": {
"version": "0.0.7", "version": "0.0.7",
"resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
@ -19209,9 +19220,11 @@
} }
}, },
"node_modules/type-fest": { "node_modules/type-fest": {
"version": "0.21.3", "version": "0.13.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": ">=10" "node": ">=10"
}, },
@ -24599,6 +24612,13 @@
"integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
"requires": { "requires": {
"type-fest": "^0.21.3" "type-fest": "^0.21.3"
},
"dependencies": {
"type-fest": {
"version": "0.21.3",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="
}
} }
}, },
"ansi-html": { "ansi-html": {
@ -36309,9 +36329,11 @@
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="
}, },
"type-fest": { "type-fest": {
"version": "0.21.3", "version": "0.13.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
"optional": true,
"peer": true
}, },
"type-is": { "type-is": {
"version": "1.6.18", "version": "1.6.18",

View File

@ -1,41 +1,22 @@
import React, { useState, useEffect } from 'react'; import React, {useContext} from "react"
import Login from './components/Login/Login'; import Login from "./components/Login/Login"
import Home from './components/Home/Home'; import Home from "./components/Home/Home"
import MainHeader from './components/MainHeader/MainHeader'; import MainHeader from "./components/MainHeader/MainHeader"
import AuthContext from "./store/auth-context"
function App() { function App() {
const [isLoggedIn, setIsLoggedIn] = useState(false); const ctx = useContext(AuthContext)
useEffect(() => { return (
const storedUserLoggedInInformation = localStorage.getItem('isLoggedIn'); <>
<MainHeader />
if (storedUserLoggedInInformation === '1') { <main>
setIsLoggedIn(true); {!ctx.isLoggedIn && <Login />}
} {ctx.isLoggedIn && <Home />}
}, []); </main>
</>
const loginHandler = (email, password) => { )
// We should of course check email and password
// But it's just a dummy/ demo anyways
localStorage.setItem('isLoggedIn', '1');
setIsLoggedIn(true);
};
const logoutHandler = () => {
localStorage.removeItem('isLoggedIn');
setIsLoggedIn(false);
};
return (
<React.Fragment>
<MainHeader isAuthenticated={isLoggedIn} onLogout={logoutHandler} />
<main>
{!isLoggedIn && <Login onLogin={loginHandler} />}
{isLoggedIn && <Home onLogout={logoutHandler} />}
</main>
</React.Fragment>
);
} }
export default App; export default App

View File

@ -1,12 +1,17 @@
import React from 'react'; import React, {useContext} from 'react';
import Card from '../UI/Card/Card'; import Card from '../UI/Card/Card';
import Button from '../UI/Button/Button';
import classes from './Home.module.css'; import classes from './Home.module.css';
import AuthContext from '../../store/auth-context';
const Home = (props) => { const Home = (props) => {
const authCtx = useContext(AuthContext)
return ( return (
<Card className={classes.home}> <Card className={classes.home}>
<h1>Welcome back!</h1> <h1>Welcome back!</h1>
<Button onClick={authCtx.onLogout}>Logout</Button>
</Card> </Card>
); );
}; };

View File

@ -1,8 +1,9 @@
import React, { useState, useEffect, useReducer } from "react" import React, { useState, useEffect, useReducer, useContext } from "react"
import Card from "../UI/Card/Card" import Card from "../UI/Card/Card"
import classes from "./Login.module.css" import classes from "./Login.module.css"
import Button from "../UI/Button/Button" import Button from "../UI/Button/Button"
import AuthContext from "../../store/auth-context"
const emailReducer = (state, action) => { const emailReducer = (state, action) => {
if (action.type === "USER_INPUT") { if (action.type === "USER_INPUT") {
@ -26,6 +27,7 @@ const passwordReducer = (state, action) => {
const Login = (props) => { const Login = (props) => {
const [formIsValid, setFormIsValid] = useState(false) const [formIsValid, setFormIsValid] = useState(false)
const authCtx = useContext(AuthContext)
const [emailState, dispatchEmail] = useReducer(emailReducer, { const [emailState, dispatchEmail] = useReducer(emailReducer, {
value: "", value: "",
@ -73,7 +75,7 @@ const Login = (props) => {
const submitHandler = (event) => { const submitHandler = (event) => {
event.preventDefault() event.preventDefault()
props.onLogin(emailState.value, passwordState.value) authCtx.onLogin(emailState.value, passwordState.value)
} }
return ( return (

View File

@ -7,7 +7,7 @@ const MainHeader = (props) => {
return ( return (
<header className={classes['main-header']}> <header className={classes['main-header']}>
<h1>A Typical Page</h1> <h1>A Typical Page</h1>
<Navigation isLoggedIn={props.isAuthenticated} onLogout={props.onLogout} /> <Navigation onLogout={props.onLogout} />
</header> </header>
); );
}; };

View File

@ -1,29 +1,31 @@
import React from 'react'; import React, { useContext } from "react"
import AuthContext from "../../store/auth-context"
import classes from './Navigation.module.css'; import classes from "./Navigation.module.css"
const Navigation = (props) => { const Navigation = () => {
return ( const ctx = useContext(AuthContext)
<nav className={classes.nav}> return (
<ul> <nav className={classes.nav}>
{props.isLoggedIn && ( <ul>
<li> {ctx.isLoggedIn && (
<a href="/">Users</a> <li>
</li> <a href="/">Users</a>
)} </li>
{props.isLoggedIn && ( )}
<li> {ctx.isLoggedIn && (
<a href="/">Admin</a> <li>
</li> <a href="/">Admin</a>
)} </li>
{props.isLoggedIn && ( )}
<li> {ctx.isLoggedIn && (
<button onClick={props.onLogout}>Logout</button> <li>
</li> <button onClick={ctx.onLogout}>Logout</button>
)} </li>
</ul> )}
</nav> </ul>
); </nav>
}; )
}
export default Navigation; export default Navigation

View File

@ -1,8 +1,13 @@
import React from 'react'; import React from "react"
import ReactDOM from 'react-dom/client'; import ReactDOM from "react-dom/client"
import './index.css'; import "./index.css"
import App from './App'; import App from "./App"
import { AuthContextProvider } from "./store/auth-context"
const root = ReactDOM.createRoot(document.getElementById('root')); const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<App />); root.render(
<AuthContextProvider>
<App />
</AuthContextProvider>
)

View File

@ -0,0 +1,42 @@
import React, { useState, useEffect } from "react"
const AuthContext = React.createContext({
isLoggedIn: false,
onLogout: () => {},
onLogin: (email, password) => {},
})
export const AuthContextProvider = (props) => {
const [isLoggedIn, setIsLoggedIn] = useState(false)
useEffect(() => {
const storedUserLoggedInInformation = localStorage.getItem("isLoggedIn")
if (storedUserLoggedInInformation === "1") {
setIsLoggedIn(true)
}
}, [])
const logoutHandler = () => {
localStorage.removeItem("isLoggedIn")
setIsLoggedIn(false)
}
const loginHandler = () => {
localStorage.setItem("isLoggedIn", "1")
setIsLoggedIn(true)
}
return (
<AuthContext.Provider
value={{
isLoggedIn: isLoggedIn,
onLogin: loginHandler,
onLogout: logoutHandler,
}}
>
{props.children}
</AuthContext.Provider>
)
}
export default AuthContext