diff --git a/src/containers/App.js b/src/containers/App.js index 7fb7b7fdc6ac5b84a7528de03da04c4cc583e198..88746a88f70a48c447e2fedae87d7e88103cc469 100644 --- a/src/containers/App.js +++ b/src/containers/App.js @@ -1,25 +1,56 @@ -import React from 'react'; +import React, { useState, useEffect } from "react"; -import { - BrowserRouter as Router, - Switch, - Route, - Link -} from "react-router-dom"; +import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; -import '../styles/App.css'; -import Header from './header' -import ListAnnonce from './list-annonces'; -import CreateAnnonce from './createAnnonce'; -import DetailAnnonce from './detail-annonce'; +import "../styles/App.css"; +import Header from "./header"; +import ListAnnonce from "./list-annonces"; +import CreateAnnonce from "./createAnnonce"; +import DetailAnnonce from "./detail-annonce"; -import SignIn from './../containers/SignIn'; -import Register from './../containers/Register'; +import SignIn from "./../containers/SignIn"; +import Register from "./../containers/Register"; + +import { AuthContext } from "./../contexts/AuthContext"; function App() { + const [loggedIn, setLoggedIn] = useState(false); + const [token, setToken] = useState(null); + const [tokenExpirationTime, setTokenExpirationTime] = useState(); + + const login = (token, expirationTime) => { + setLoggedIn(true); + setToken(token); + + const expiration = + expirationTime || new Date(new Date().getTime() + 1000 * 60 * 60); + + setTokenExpirationTime(expiration); + localStorage.setItem("token", token); + }; + + const logout = () => { + setLoggedIn(false); + setToken(null); + + localStorage.removeItem("token"); + }; + + useEffect(() => { + const storedData = JSON.parse(localStorage.getItem("userData")); + if ( + storedData && + storedData.token && + new Date(storedData.expirationTime) > new Date() + ) { + login(storedData.token, new Date(storedData.expirationTime)); + } + }, [login]); return ( - <> +
@@ -46,7 +77,7 @@ function App() {
- + ); } diff --git a/src/containers/SignIn.js b/src/containers/SignIn.js index 83404b15eb289118ce390f8f688a4b8639259530..4b232cdba7c0fb168fa049595637e5a2b2f59cc9 100644 --- a/src/containers/SignIn.js +++ b/src/containers/SignIn.js @@ -1,101 +1,117 @@ -import React, { useState } from "react"; +import React, { useState, useContext } from "react"; import { useMutation, gql } from "@apollo/client"; import { useHistory } from "react-router-dom"; -import Logo from './iwocs.png'; +import Logo from "./iwocs.png"; import "./../styles/sign-in.css"; +import { AuthContext } from "./../contexts/AuthContext"; + const SignIn = () => { - let history = useHistory(); - const LOGIN_MUTATION = gql` - mutation login($credentials: LoginInput!) { - login(credentials: $credentials) { - userId - token - tokenExpiration - } - } - `; + let history = useHistory(); + const authContext = useContext(AuthContext); + + const LOGIN_MUTATION = gql` + mutation login($credentials: LoginInput!) { + login(credentials: $credentials) { + userId + token + tokenExpiration + } + } + `; + + const defaultCredentials = { + email: "", + password: "", + }; + const [credentials, setCredentials] = useState({ ...defaultCredentials }); + const [ + login, + { loading: mutationLoading, error: mutationError, data }, + ] = useMutation(LOGIN_MUTATION, { + errorPolicy: "all", + }); + + const onChange = (e) => { + e.preventDefault(); + const target = e.target; + const field = target.name; - const defaultCredentials = { - email: '', - password: '' - }; - const [credentials, setCredentials] = useState({ ...defaultCredentials }); - const [login, { - loading: mutationLoading, - error: mutationError, - data - }] = useMutation(LOGIN_MUTATION, { - errorPolicy: 'all' + credentials[`${field}`] = target.value; + setCredentials({ + ...credentials, }); + }; - const onChange = (e) => { - e.preventDefault(); - const target = e.target; - const field = target.name; - - credentials[`${field}`] = target.value; - setCredentials({ - ...credentials - }); - } + const onSubmit = (e) => { + e.preventDefault(); + login({ variables: { credentials: credentials } }).then(({ data }) => { + authContext.login(data.login.token, data.login.tokenExpiration); + navigateToAnnonce(); + }).catch(err => { + console.log(err); + }); + }; - const onSubmit = (e) => { - e.preventDefault(); - login({ variables: { credentials: credentials }}); - navigateToAnnonce(); - } - - const navigateToAnnonce = () => { - history.push('/'); - } + const navigateToAnnonce = () => { + history.push("/"); + }; - return ( -
-
-

Connexion

- logo iwocs - - - - {mutationError && ( -
- {mutationError.graphQLErrors[0].message} -
- )} - -

M2 IWOCS 2020-2021

-
-
+ return ( +
+
+

Connexion

+ logo iwocs + + + + {mutationError && ( +
+ {mutationError.graphQLErrors[0].message} +
+ )} + +

M2 IWOCS 2020-2021

+
+
); }; diff --git a/src/containers/header.js b/src/containers/header.js index 301284acec758af5dbad1996b4d46e9362a1f1a8..921869596847827939d1a56cbc761e5b353d5818 100644 --- a/src/containers/header.js +++ b/src/containers/header.js @@ -1,21 +1,41 @@ -import React from 'react'; -import { Link } from 'react-router-dom'; +import React, { useContext } from 'react'; + +import { AuthContext } from "./../contexts/AuthContext"; function Header() { + const authContext = useContext(AuthContext); + + const logoutHandler = (e) => { + e.preventDefault(); + authContext.logout(); + } return (
- M2 Iwocs -
- - - Sign up - + + {!authContext.isLoggedIn && ( + <> + + + Sign up + + + )} + {authContext.isLoggedIn && ( + + )}
); } diff --git a/src/containers/list-annonces.js b/src/containers/list-annonces.js index e743c5d4c43b33dd49f4969fc1434c990f8bde24..b73eb3f382be64cd3603a1dd8e54d3f443088b00 100644 --- a/src/containers/list-annonces.js +++ b/src/containers/list-annonces.js @@ -1,10 +1,11 @@ -import React, { useState } from 'react'; +import React, { useState, useContext } from 'react'; import { gql, useQuery, useMutation } from "@apollo/client"; import { useHistory } from "react-router-dom"; import { GraphQLID } from 'graphql'; import ListAnnonceItem from '../components/list-annonce-item'; import { API_URL } from './../constants'; +import { AuthContext } from "./../contexts/AuthContext"; const GET_ANNONCES_QUERY = gql` query getAnnonces { @@ -49,6 +50,7 @@ const DELETE_ANNONCE_MUTATION = gql` const ListAnnonce = () => { let history = useHistory(); + const authContext = useContext(AuthContext); const { loading, error, data, updateQuery } = useQuery(GET_ANNONCES_QUERY); @@ -93,12 +95,14 @@ const ListAnnonce = () => { return (
+ {authContext.isLoggedIn && + }
{data.annonces.map((annonce, index) => { return ( @@ -107,7 +111,7 @@ const ListAnnonce = () => { annonce={annonce} onClick={(e) => navigateToDetail(annonce)} /> - ); + ); })}
{selectedAnnonce && ( diff --git a/src/contexts/AuthContext.js b/src/contexts/AuthContext.js new file mode 100644 index 0000000000000000000000000000000000000000..c0e7885968cc0fc113eb287d479cbd649e36af68 --- /dev/null +++ b/src/contexts/AuthContext.js @@ -0,0 +1,10 @@ +import React from 'react'; + +export const AuthContext = React.createContext({ + isLoggedIn: false, + token: null, + login: () => { + + }, + logout: () => {} +});