diff --git a/src/components/form/form.jsx b/src/components/loginform/loginForm.jsx similarity index 52% rename from src/components/form/form.jsx rename to src/components/loginform/loginForm.jsx index fc46bcd..edc6c55 100644 --- a/src/components/form/form.jsx +++ b/src/components/loginform/loginForm.jsx @@ -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 ( -
-
- setEmail(e.target.value)} required/> -
+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"; -
- setPassword(e.target.value)} required/> -
-
-
- -
-
- ); -} -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 (
- setEmail(e.target.value)} - required + style={{ width: '100%' }} />
- setPassword(e.target.value)} - required - style={{ width: '100%', paddingRight: '40px' }} + style={{ width: '100%' }} />
+
- +
); diff --git a/src/components/form/form.module.css b/src/components/loginform/loginForm.module.css similarity index 100% rename from src/components/form/form.module.css rename to src/components/loginform/loginForm.module.css diff --git a/src/contexts/auth/AuthContext.js b/src/contexts/auth/AuthContext.js new file mode 100644 index 0000000..885fd0e --- /dev/null +++ b/src/contexts/auth/AuthContext.js @@ -0,0 +1,3 @@ +import { createContext } from "react"; + +export const AuthContext = createContext(null); diff --git a/src/contexts/auth/authProvider.jsx b/src/contexts/auth/authProvider.jsx new file mode 100644 index 0000000..7151a96 --- /dev/null +++ b/src/contexts/auth/authProvider.jsx @@ -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 ( + + {children} + + ); +} diff --git a/src/layout.jsx b/src/layout.jsx index b159981..4689a4e 100644 --- a/src/layout.jsx +++ b/src/layout.jsx @@ -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

Loading

; + if (!user) return ; + return (
diff --git a/src/main.jsx b/src/main.jsx index 088afa5..6b79e8c 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -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( - + + + , ) diff --git a/src/pages/Login/LoginPage.jsx b/src/pages/Login/LoginPage.jsx index 95a194a..fcea9bb 100644 --- a/src/pages/Login/LoginPage.jsx +++ b/src/pages/Login/LoginPage.jsx @@ -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 +
- +
- ); + +
} export default LoginPage; diff --git a/src/pages/Register/RegisterPage.jsx b/src/pages/Register/RegisterPage.jsx new file mode 100644 index 0000000..489858d --- /dev/null +++ b/src/pages/Register/RegisterPage.jsx @@ -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 + +
+ +
+ +

Créer un compte

+ +
+ setName(e.target.value)} + style={{ width: '100%' }} + /> +
+ +
+ setLastName(e.target.value)} + style={{ width: '100%' }} + /> +
+ +
+ setEmail(e.target.value)} + style={{ width: '100%' }} + /> +
+
+
+ setPassword(e.target.value)} + style={{ width: '100%' }} + /> + +
+
+ +
+ + +
+
+
+ +
+} + +export default RegisterPage; + + diff --git a/src/pages/Register/RegisterPage.module.css b/src/pages/Register/RegisterPage.module.css new file mode 100644 index 0000000..7a379ee --- /dev/null +++ b/src/pages/Register/RegisterPage.module.css @@ -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; +} \ No newline at end of file diff --git a/src/router.js b/src/router.js index 5a4e1aa..49775e1 100644 --- a/src/router.js +++ b/src/router.js @@ -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, diff --git a/src/utils/getUser.js b/src/utils/getUser.js index 5345926..6826525 100644 --- a/src/utils/getUser.js +++ b/src/utils/getUser.js @@ -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)); -} \ No newline at end of file + + const data = await res.json(); + return data; + } catch (err) { + console.error('Erreur :', err); + return null; + } +} diff --git a/src/utils/login.js b/src/utils/login.js index 529d27c..a08151b 100644 --- a/src/utils/login.js +++ b/src/utils/login.js @@ -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 }) }); -} \ No newline at end of file + + 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; + } +} diff --git a/src/utils/register.js b/src/utils/register.js new file mode 100644 index 0000000..1612bf8 --- /dev/null +++ b/src/utils/register.js @@ -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; + } +}