Skip to content
Snippets Groups Projects
Commit e72946b0 authored by YAHYAOUI Firas's avatar YAHYAOUI Firas
Browse files

add: authentication with local storage

parent 5f2a2d9b
No related branches found
No related tags found
1 merge request!24Dev/client
......@@ -9,9 +9,13 @@ import {
import "../../App.css";
import { Link, NavLink, useNavigate } from "react-router-dom";
import { useAppDispatch, useAppSelector } from "../../redux/hooks";
import { logout } from "../../redux/slices/authSlice";
const CustomNavbar = () => {
const navigate = useNavigate();
const { isAuthenticated, username } = useAppSelector((state) => state.auth);
const dispatch = useAppDispatch();
return (
<Navbar bg="light" expand="lg" className="flex-column">
<Container>
......@@ -42,19 +46,28 @@ const CustomNavbar = () => {
</NavLink>
<NavDropdown
className="mx-1"
title="Utilisateur"
title={isAuthenticated ? username : "Utilisateur"}
id="navbarScrollingDropdown"
>
<NavDropdown.Item onClick={() => navigate("/myevents")}>
Mes évènements
</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item onClick={() => navigate("/login")}>
Se connecter
</NavDropdown.Item>
<NavDropdown.Item onClick={() => navigate("/register")}>
Créer un compte
</NavDropdown.Item>
{!isAuthenticated && (
<>
<NavDropdown.Item onClick={() => navigate("/login")}>
Se connecter
</NavDropdown.Item>
<NavDropdown.Item onClick={() => navigate("/register")}>
Créer un compte
</NavDropdown.Item>
</>
)}
{isAuthenticated && (
<NavDropdown.Item onClick={() => dispatch(logout())}>
Se déconnecter
</NavDropdown.Item>
)}
</NavDropdown>
</Nav>
</Navbar.Collapse>
......
......@@ -7,6 +7,8 @@ import { RouterProvider, createBrowserRouter } from "react-router-dom";
import HomePage from "./pages/HomePage.tsx";
import EventsPage from "./pages/EventsPage.tsx";
import EventPage from "./pages/EventPage.tsx";
import LoginPage from "./pages/LoginPage.tsx";
import RegisterPage from "./pages/RegisterPage.tsx";
const router = createBrowserRouter([
{
......@@ -35,19 +37,11 @@ const router = createBrowserRouter([
},
{
path: "/login",
element: (
<>
<h1>Se connecter</h1>
</>
),
element: <LoginPage />,
},
{
path: "/register",
element: (
<>
<h1>Créer un compte</h1>
</>
),
element: <RegisterPage />,
},
{
path: "/myevents",
......
import { useState } from "react";
import { Button, Form } from "react-bootstrap";
import { Link, useNavigate } from "react-router-dom";
import { useAppDispatch, useAppSelector } from "../redux/hooks";
import { login } from "../redux/slices/authSlice";
export default function LoginPage() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const users = useAppSelector((state) => state.users);
const dispatch = useAppDispatch();
const navigate = useNavigate();
const handleLogin = () => {
if (users.map((user) => user.username).includes(username)) {
const user = users.find((_user) => _user.username === username);
if (user?.password === password) {
dispatch(login(username));
navigate('/events')
}
}
};
return (
<div className="p-5">
<h1 className="text-center">Se connecter</h1>
<Form>
<Form.Group controlId="formBasicUsername">
<Form.Label>Username</Form.Label>
<Form.Control
type="text"
placeholder="Enter username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
placeholder="Enter password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</Form.Group>
<Button variant="primary" onClick={handleLogin} className="mt-3">
Login
</Button>
<p className="mt-1">
Pas de compte? Cliquer <Link to={"/register"}>Ici</Link>
</p>
</Form>
</div>
);
}
import { useState } from "react";
import { Button, Form } from "react-bootstrap";
import { Link, useNavigate } from "react-router-dom";
import { useAppDispatch } from "../redux/hooks";
import { addUser } from "../redux/slices/usersSlice";
export default function RegisterPage() {
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [email, setEmail] = useState("");
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [communityCode, setCommunityCode] = useState("");
const navigate = useNavigate();
const dispatch = useAppDispatch();
const handleRegister = () => {
dispatch(
addUser({
firstname: firstName,
lastname: lastName,
email,
username,
password,
community: communityCode,
})
);
navigate('/login')
};
return (
<div className="p-5">
<h1 className="text-center">Créer un compte</h1>
<Form>
<Form.Group controlId="formBasicFirstName">
<Form.Label>First Name</Form.Label>
<Form.Control
type="text"
placeholder="Enter first name"
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
/>
</Form.Group>
<Form.Group controlId="formBasicLastName">
<Form.Label>Last Name</Form.Label>
<Form.Control
type="text"
placeholder="Enter last name"
value={lastName}
onChange={(e) => setLastName(e.target.value)}
/>
</Form.Group>
<Form.Group controlId="formBasicEmail">
<Form.Label>Email</Form.Label>
<Form.Control
type="email"
placeholder="Enter email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</Form.Group>
<Form.Group controlId="formBasicUsername">
<Form.Label>Username</Form.Label>
<Form.Control
type="text"
placeholder="Enter username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
placeholder="Enter password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</Form.Group>
<Form.Group controlId="formBasicCommunityCode">
<Form.Label>Community Code</Form.Label>
<Form.Control
type="text"
placeholder="Enter community code"
value={communityCode}
onChange={(e) => setCommunityCode(e.target.value)}
/>
</Form.Group>
<Button variant="primary" onClick={handleRegister} className="mt-3">
Register
</Button>
<p className="mt-1">
Vous avez déja un compte? Cliquer <Link to={"/login"}>Ici</Link>
</p>
</Form>
</div>
);
}
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
export type Auth = {
isAuthenticated: boolean,
username?: string
}
const initialState: Auth = {
isAuthenticated: false
}
const initiateStateFromLocalStorage = (): Auth => {
return localStorage.getItem('username') ? {
isAuthenticated: true,
username: localStorage.getItem('username') ?? ""
} : initialState;
}
export const authSlice = createSlice({
name: 'auth',
initialState: initiateStateFromLocalStorage(),
reducers: {
login: (state, action: PayloadAction<string>) => {
state.isAuthenticated = true;
state.username = action.payload;
localStorage.setItem('username', action.payload);
},
logout: (state) => {
state.isAuthenticated = false;
state.username = undefined;
localStorage.removeItem('username')
}
}
})
export const { login, logout } = authSlice.actions;
export default authSlice.reducer;
\ No newline at end of file
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
export type User = {
firstname: string,
lastname: string,
email: string,
password: string,
username: string,
community: string
}
const initialState: User[] = []
const initiateStateFromLocalStorage = () => {
const users = JSON.parse(localStorage.getItem('users') ?? JSON.stringify(initialState));
return users as User[]
}
export const usersSlice = createSlice({
name: 'users',
initialState: initiateStateFromLocalStorage(),
reducers: {
addUser: (state, action: PayloadAction<User>) => {
if (!state.map(user => user.username).includes(action.payload.username)) {
state.push(action.payload)
localStorage.setItem("users", JSON.stringify(state))
}
}
}
})
export const { addUser } = usersSlice.actions;
export default usersSlice.reducer;
\ No newline at end of file
import { configureStore } from "@reduxjs/toolkit";
import selectionReducer from "./slices/selectionSlice";
import usersReducer from "./slices/usersSlice";
import authReducer from "./slices/authSlice";
export const store = configureStore({
reducer: {
selection: selectionReducer
selection: selectionReducer,
users: usersReducer,
auth: authReducer
}
})
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment