Merge branch 'feature/auth' into 'dev'
Feature/auth See merge request sae-but2/2025-26/gestion-benevoles-association/Frontend!21
This commit is contained in:
@@ -1,47 +1,22 @@
|
||||
/*import { useState } from "react";
|
||||
import login from "../../utils/login.js";
|
||||
import getUser from "../../utils/getUser.js";
|
||||
import styles from "./form.module.css";
|
||||
function LoginForm({ className }) {
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
await login(email, password);
|
||||
getUser();
|
||||
}
|
||||
return (
|
||||
<div className={`${className} ${"glassCard"}`}>
|
||||
<div className={styles.formgroup}>
|
||||
<input type="email" id="email" value={email} placeholder="Adresse mail" onChange={e => setEmail(e.target.value)} required/>
|
||||
</div>
|
||||
import { useState, useContext } from "react";
|
||||
import styles from "./loginForm.module.css";
|
||||
import Button from "../ui/button/button.jsx";
|
||||
import Input from "../ui/input/input.jsx";
|
||||
import { useNavigate } from "react-router";
|
||||
import { AuthContext } from "../../contexts/auth/AuthContext.js";
|
||||
|
||||
<div className={styles.formgroup}>
|
||||
<input type="password" id="password" value={password} placeholder="Mot de passe" onChange={e => setPassword(e.target.value)} required/>
|
||||
<br/>
|
||||
</div>
|
||||
<div className={styles.logButton} >
|
||||
<button className={styles.loginButton} onClick={e => handleSubmit(e)}>Se connecter</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default LoginForm;*/
|
||||
|
||||
import { useState } from "react";
|
||||
import login from "../../utils/login.js";
|
||||
import getUser from "../../utils/getUser.js";
|
||||
import styles from "./form.module.css";
|
||||
|
||||
function LoginForm({ className }) {
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
let navigate = useNavigate();
|
||||
const { login } = useContext(AuthContext);
|
||||
|
||||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
await login(email, password);
|
||||
getUser();
|
||||
navigate("/");
|
||||
}
|
||||
|
||||
const toggleShowPassword = () => {
|
||||
@@ -51,27 +26,22 @@ function LoginForm({ className }) {
|
||||
return (
|
||||
<div className={`${className} ${"glassCard"}`}>
|
||||
<div className={styles.formgroup}>
|
||||
<input
|
||||
<Input
|
||||
type="email"
|
||||
id="email"
|
||||
className={styles.input}
|
||||
value={email}
|
||||
placeholder="Adresse mail"
|
||||
onChange={e => setEmail(e.target.value)}
|
||||
required
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.formgroup}>
|
||||
<div style={{ position: 'relative', width: '100%' }}>
|
||||
<input
|
||||
<Input
|
||||
type={showPassword ? "text" : "password"}
|
||||
id="password"
|
||||
className={styles.input}
|
||||
value={password}
|
||||
placeholder="Mot de passe"
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
required
|
||||
style={{ width: '100%', paddingRight: '40px' }}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
@@ -92,8 +62,9 @@ function LoginForm({ className }) {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.logButton}>
|
||||
<button className={styles.loginButton} onClick={handleSubmit}>Se connecter</button>
|
||||
<Button onClick={handleSubmit} variant={"default"}> Se connecter </Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -0,0 +1,3 @@
|
||||
import { createContext } from "react";
|
||||
|
||||
export const AuthContext = createContext(null);
|
||||
@@ -0,0 +1,37 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import loginFunction from "../../utils/login.js";
|
||||
import getUser from "../../utils/getUser.js";
|
||||
import { AuthContext } from "./AuthContext";
|
||||
|
||||
|
||||
export function AuthProvider({ children }) {
|
||||
const [user, setUser] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const u = await getUser();
|
||||
setUser(u);
|
||||
setLoading(false);
|
||||
})();
|
||||
}, []);
|
||||
|
||||
const login = async (email, password) => {
|
||||
const res = await loginFunction(email, password);
|
||||
if (!res || res.status !== 200) throw new Error("Login error");
|
||||
const u = await getUser();
|
||||
setUser(u);
|
||||
return res;
|
||||
};
|
||||
|
||||
const logout = async () => {
|
||||
// TODO: Appeller fonction logout
|
||||
setUser(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{ user, loading, login, logout }}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
}
|
||||
@@ -2,10 +2,18 @@ import { Outlet } from "react-router";
|
||||
import Footer from "./components/Footer/Footer.jsx"
|
||||
import Header from "./components/Header/Header.jsx";
|
||||
import Background from "./components/background/background.jsx";
|
||||
import { Navigate } from "react-router";
|
||||
import { useContext} from "react";
|
||||
import { AuthContext } from "./contexts/auth/AuthContext.js";
|
||||
|
||||
|
||||
function Layout(){
|
||||
|
||||
const { user, loading } = useContext(AuthContext);
|
||||
|
||||
if (loading) return <p>Loading</p>;
|
||||
if (!user) return <Navigate to="/login" />;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Background>
|
||||
|
||||
+4
-1
@@ -3,10 +3,13 @@ import { createRoot } from 'react-dom/client'
|
||||
import './index.css'
|
||||
import { RouterProvider } from "react-router";
|
||||
import router from './router';
|
||||
import { AuthProvider } from "./contexts/auth/authProvider.jsx";
|
||||
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<StrictMode>
|
||||
<RouterProvider router={router} />
|
||||
<AuthProvider>
|
||||
<RouterProvider router={router} />
|
||||
</AuthProvider>
|
||||
</StrictMode>,
|
||||
)
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import styles from "./LoginPage.module.css";
|
||||
import LoginForm from "../../components/form/form.jsx";
|
||||
import LoginForm from "../../components/loginform/loginForm.jsx";
|
||||
import Background from "../../components/background/background.jsx";
|
||||
|
||||
function LoginPage() {
|
||||
return (
|
||||
return <Background>
|
||||
|
||||
<div className={styles.container}>
|
||||
<LoginForm />
|
||||
<LoginForm />
|
||||
</div>
|
||||
);
|
||||
|
||||
</Background>
|
||||
}
|
||||
|
||||
export default LoginPage;
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
import styles from "./RegisterPage.module.css";
|
||||
import Background from "../../components/background/background.jsx";
|
||||
import Input from "../../components/ui/input/input.jsx";
|
||||
import Button from "../../components/ui/button/button.jsx";
|
||||
import { useState } from "react";
|
||||
import register from "../../utils/register.js";
|
||||
import { useNavigate } from "react-router";
|
||||
|
||||
|
||||
function RegisterPage() {
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [name, setName] = useState("");
|
||||
const [lastName, setLastName] = useState("");
|
||||
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
|
||||
|
||||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
const res = await register(email, password, name, lastName);
|
||||
if (!res || res.status !== 200) throw new Error("Register error");
|
||||
navigate("/login");
|
||||
}
|
||||
|
||||
return <Background>
|
||||
|
||||
<div className={styles.container}>
|
||||
|
||||
<div className={"glassCard"}>
|
||||
|
||||
<h1>Créer un compte</h1>
|
||||
|
||||
<div className={styles.formGroup}>
|
||||
<Input
|
||||
value={name}
|
||||
placeholder="Prénom"
|
||||
onChange={e => setName(e.target.value)}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.formGroup}>
|
||||
<Input
|
||||
value={lastName}
|
||||
placeholder="Nom"
|
||||
onChange={e => setLastName(e.target.value)}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.formGroup}>
|
||||
<Input
|
||||
type="email"
|
||||
value={email}
|
||||
placeholder="Adresse mail"
|
||||
onChange={e => setEmail(e.target.value)}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.formGroup}>
|
||||
<div style={{ position: 'relative', width: '100%' }}>
|
||||
<Input
|
||||
type={showPassword ? "text" : "password"}
|
||||
value={password}
|
||||
placeholder="Mot de passe"
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowPassword(!showPassword)}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
width: '30px',
|
||||
right: '10px',
|
||||
top: '50%',
|
||||
transform: 'translateY(-50%)',
|
||||
background: 'none',
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
fontSize: '16px',
|
||||
}}
|
||||
>
|
||||
{showPassword ? '👁️' : '🔒'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.logButton}>
|
||||
<Button variant={"transparent"} onClick={() => navigate("/login")}>Vous avez déjà un compte ?</Button>
|
||||
<Button variant={"default"} onClick={handleSubmit}> Se connecter </Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</Background>
|
||||
}
|
||||
|
||||
export default RegisterPage;
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
.container {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
width: 30%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
border-radius:12px;
|
||||
}
|
||||
|
||||
:global(.glassCard) {
|
||||
--glass-bg: #ffffff9f;
|
||||
}
|
||||
.logButton{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.formGroup{
|
||||
margin-top:23px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
overflow: visible;
|
||||
text-align: center;
|
||||
}
|
||||
+9
-1
@@ -2,12 +2,20 @@ import { createBrowserRouter } from "react-router";
|
||||
import Layout from "./layout.jsx";
|
||||
import HomePage from "./pages/Home/HomePage";
|
||||
import LoginPage from "./pages/Login/LoginPage";
|
||||
import RegisterPage from "./pages/Register/RegisterPage.jsx";
|
||||
import VolunteersPage from "./pages/Volunteers/VolunteersPage";
|
||||
import ProfilePage from "./pages/Profile/ProfilePage";
|
||||
import EventsPage from "./pages/Events/EventsPage.jsx";
|
||||
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
path: "/login",
|
||||
Component: LoginPage,
|
||||
},
|
||||
{
|
||||
path: "/register",
|
||||
Component: RegisterPage,
|
||||
},
|
||||
{
|
||||
path: "/",
|
||||
Component: Layout,
|
||||
|
||||
+19
-10
@@ -1,12 +1,21 @@
|
||||
export default async function getUser() {
|
||||
await fetch('http://localhost:8000/api/me', {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
try {
|
||||
const res = await fetch('http://localhost:8000/api/me', {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`Erreur serveur : ${res.status}`);
|
||||
}
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => console.log('Utilisateur connecté :', data))
|
||||
.catch(err => console.error('Erreur :', err));
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
return data;
|
||||
} catch (err) {
|
||||
console.error('Erreur :', err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+25
-27
@@ -3,31 +3,29 @@ import getXSRFToken from "./getXSRF.js";
|
||||
export default async function login(email, password) {
|
||||
const csrfToken = await getXSRFToken();
|
||||
|
||||
|
||||
await fetch('http://localhost:8000/api/users/login', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-XSRF-TOKEN': csrfToken,
|
||||
'Accept': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: email,
|
||||
password: password
|
||||
})
|
||||
})
|
||||
.then(response => {
|
||||
console.log('Code HTTP :', response.status);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Erreur HTTP ${response.status}`);
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
console.log('Connexion réussie ! Données utilisateur :', data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Erreur lors de la connexion :', error.message);
|
||||
try {
|
||||
const response = await fetch('http://localhost:8000/api/users/login', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-XSRF-TOKEN': csrfToken,
|
||||
'Accept': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ email, password })
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Code HTTP :', response.status);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Erreur HTTP ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('Connexion réussie ! Données utilisateur :', data);
|
||||
|
||||
return { status: response.status, data };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import getXSRFToken from "./getXSRF.js";
|
||||
|
||||
export default async function register(email, password, name, lastname) {
|
||||
const csrfToken = await getXSRFToken();
|
||||
|
||||
try {
|
||||
const response = await fetch('http://localhost:8000/api/users/register', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-XSRF-TOKEN': csrfToken,
|
||||
'Accept': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ email, password, name, lastname }),
|
||||
});
|
||||
|
||||
console.log('Code HTTP :', response.status);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Erreur HTTP ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
return { status: response.status, data };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user