Merge branch 'main' of github.com:Charles40130/Projet-Dev-Web-Ing1
This commit is contained in:
commit
6499123131
@ -30,8 +30,9 @@ public class AuthHandler {
|
|||||||
String email = body.getString("email");
|
String email = body.getString("email");
|
||||||
String gender = body.getString("gender");
|
String gender = body.getString("gender");
|
||||||
String password = body.getString("password");
|
String password = body.getString("password");
|
||||||
|
String pseudo = body.getString("pseudo");
|
||||||
|
|
||||||
if (name == null || surname == null || email == null || gender == null || password == null) {
|
if (name == null || surname == null || email == null || gender == null || password == null || pseudo == null) {
|
||||||
context.response()
|
context.response()
|
||||||
.setStatusCode(400)
|
.setStatusCode(400)
|
||||||
.end(new JsonObject().put("error", "Tous les champs sont requis").encode());
|
.end(new JsonObject().put("error", "Tous les champs sont requis").encode());
|
||||||
@ -41,8 +42,8 @@ public class AuthHandler {
|
|||||||
String hashedPassword = BCrypt.withDefaults().hashToString(12, password.toCharArray());
|
String hashedPassword = BCrypt.withDefaults().hashToString(12, password.toCharArray());
|
||||||
|
|
||||||
databaseService.pool
|
databaseService.pool
|
||||||
.preparedQuery("INSERT INTO users (name, surname, email, gender, password) VALUES (?, ?, ?, ?, ?)")
|
.preparedQuery("INSERT INTO users (name, surname, email, gender, password, pseudo) VALUES (?, ?, ?, ?, ?, ?)")
|
||||||
.execute(Tuple.of(name, surname, email, gender, hashedPassword))
|
.execute(Tuple.of(name, surname, email, gender, hashedPassword,pseudo))
|
||||||
.onSuccess(result -> {
|
.onSuccess(result -> {
|
||||||
context.response()
|
context.response()
|
||||||
.setStatusCode(201)
|
.setStatusCode(201)
|
||||||
|
|||||||
@ -56,12 +56,16 @@ public class MainVerticle extends AbstractVerticle {
|
|||||||
router.post("/modifRangeData").handler(setWeatherData::setRangeData);
|
router.post("/modifRangeData").handler(setWeatherData::setRangeData);
|
||||||
router.post("/deleteObject").handler(setObjects::deleteObject);
|
router.post("/deleteObject").handler(setObjects::deleteObject);
|
||||||
router.get("/users").handler(queryUsers::getUsers);
|
router.get("/users").handler(queryUsers::getUsers);
|
||||||
|
router.post("/user").handler(queryUsers::getUser);
|
||||||
router.post("/setUserPoints").handler(setUser::setUserPoints);
|
router.post("/setUserPoints").handler(setUser::setUserPoints);
|
||||||
router.post("/deleteUser").handler(setUser::deleteUser);
|
router.post("/deleteUser").handler(setUser::deleteUser);
|
||||||
|
router.post("/updateProfil").handler(setUser::updateUserProfile);
|
||||||
|
router.post("/changePassword").handler(setUser::changeUserPassword);
|
||||||
|
|
||||||
// Routes d'authentification
|
// Routes d'authentification
|
||||||
router.post("/signup").handler(authHandler::handleSignup);
|
router.post("/signup").handler(authHandler::handleSignup);
|
||||||
router.post("/login").handler(authHandler::handleLogin);
|
router.post("/login").handler(authHandler::handleLogin);
|
||||||
|
|
||||||
|
|
||||||
// Création du serveur HTTP
|
// Création du serveur HTTP
|
||||||
vertx.createHttpServer()
|
vertx.createHttpServer()
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import io.vertx.core.json.JsonArray;
|
|||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import io.vertx.sqlclient.Row;
|
import io.vertx.sqlclient.Row;
|
||||||
|
import io.vertx.sqlclient.Tuple;
|
||||||
|
|
||||||
public class QueryUsers {
|
public class QueryUsers {
|
||||||
private DatabaseService databaseService;
|
private DatabaseService databaseService;
|
||||||
@ -25,19 +26,20 @@ public class QueryUsers {
|
|||||||
.onSuccess(rows -> {
|
.onSuccess(rows -> {
|
||||||
JsonArray users = new JsonArray();
|
JsonArray users = new JsonArray();
|
||||||
for (Row row : rows) {
|
for (Row row : rows) {
|
||||||
int points=row.getInteger("points");
|
int points = row.getInteger("points");
|
||||||
JsonObject user = new JsonObject()
|
JsonObject user = new JsonObject()
|
||||||
.put("id", row.getInteger("id"))
|
.put("id", row.getInteger("id"))
|
||||||
.put("name", row.getString("name"))
|
.put("name", row.getString("name"))
|
||||||
.put("surname", row.getString("surname"))
|
.put("surname", row.getString("surname"))
|
||||||
.put("email", row.getString("email"))
|
.put("email", row.getString("email"))
|
||||||
.put("gender", row.getString("gender"))
|
.put("gender", row.getString("gender"))
|
||||||
.put("points",points);
|
.put("pseudo",row.getString("pseudo"))
|
||||||
if(points<=60){
|
.put("points", points);
|
||||||
|
if (points <= 60) {
|
||||||
user.put("role", "user");
|
user.put("role", "user");
|
||||||
}else if(points<=100){
|
} else if (points <= 100) {
|
||||||
user.put("role", "complexe");
|
user.put("role", "complexe");
|
||||||
}else if(points>=200){
|
} else if (points >= 200) {
|
||||||
user.put("role", "admin");
|
user.put("role", "admin");
|
||||||
}
|
}
|
||||||
users.add(user);
|
users.add(user);
|
||||||
@ -48,4 +50,56 @@ public class QueryUsers {
|
|||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getUser(RoutingContext context) {
|
||||||
|
JsonObject body = context.body().asJsonObject();
|
||||||
|
if (body == null) {
|
||||||
|
context.response()
|
||||||
|
.setStatusCode(400)
|
||||||
|
.end(new JsonObject().put("error", "Corps de la requête manquant").encode());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Integer idUser = body.getInteger("idUser");
|
||||||
|
Integer idUser = 4;
|
||||||
|
databaseService.pool
|
||||||
|
.preparedQuery("SELECT * FROM users WHERE id=?;")
|
||||||
|
.execute(Tuple.of(idUser))
|
||||||
|
.onFailure(e -> {
|
||||||
|
System.err.println("Erreur de récupération de la BDD :" + e.getMessage());
|
||||||
|
context.response()
|
||||||
|
.setStatusCode(500)
|
||||||
|
.end(new JsonObject().put("error", "Erreur de récupération de la BDD").encode());
|
||||||
|
})
|
||||||
|
.onSuccess(rows -> {
|
||||||
|
if (rows.size() == 0) {
|
||||||
|
context.response()
|
||||||
|
.setStatusCode(404)
|
||||||
|
.end(new JsonObject().put("error", "Utilisateur non trouvé").encode());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Row row = rows.iterator().next();
|
||||||
|
int points = row.getInteger("points");
|
||||||
|
JsonObject user = new JsonObject()
|
||||||
|
.put("id", row.getInteger("id"))
|
||||||
|
.put("name", row.getString("name"))
|
||||||
|
.put("surname", row.getString("surname"))
|
||||||
|
.put("email", row.getString("email"))
|
||||||
|
.put("gender", row.getString("gender"))
|
||||||
|
.put("pseudo",row.getString("pseudo"))
|
||||||
|
.put("points", points);
|
||||||
|
|
||||||
|
if (points <= 60) {
|
||||||
|
user.put("role", "user");
|
||||||
|
} else if (points <= 100) {
|
||||||
|
user.put("role", "complexe");
|
||||||
|
} else if (points >= 200) {
|
||||||
|
user.put("role", "admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
context.response()
|
||||||
|
.putHeader("content-type", "application/json; charset=UTF-8")
|
||||||
|
.end(user.encode());
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package com.example.starter;
|
package com.example.starter;
|
||||||
|
|
||||||
|
import at.favre.lib.crypto.bcrypt.BCrypt;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import io.vertx.sqlclient.Tuple;
|
import io.vertx.sqlclient.Tuple;
|
||||||
@ -10,6 +11,7 @@ public class SetUser {
|
|||||||
public SetUser(DatabaseService ddbs) {
|
public SetUser(DatabaseService ddbs) {
|
||||||
this.databaseService = ddbs;
|
this.databaseService = ddbs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateUserPoints(Integer userId, Integer points) {
|
public void updateUserPoints(Integer userId, Integer points) {
|
||||||
databaseService.pool
|
databaseService.pool
|
||||||
.preparedQuery("UPDATE users SET points=points+? WHERE id=?")
|
.preparedQuery("UPDATE users SET points=points+? WHERE id=?")
|
||||||
@ -25,6 +27,105 @@ public class SetUser {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void changeUserPassword(RoutingContext context) {
|
||||||
|
JsonObject body = context.body().asJsonObject();
|
||||||
|
if (body == null) {
|
||||||
|
context.response()
|
||||||
|
.setStatusCode(400)
|
||||||
|
.end(new JsonObject().put("error", "Corps de la requête manquant").encode());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Integer id = body.getInteger("id");
|
||||||
|
String oldPassword = body.getString("oldPassword");
|
||||||
|
String newPassword = body.getString("newPassword");
|
||||||
|
|
||||||
|
databaseService.pool
|
||||||
|
.preparedQuery("SELECT password FROM users WHERE id=?")
|
||||||
|
.execute(Tuple.of(id))
|
||||||
|
.onFailure(e -> {
|
||||||
|
System.err.println("Erreur de récupération de la BDD :" + e.getMessage());
|
||||||
|
context.response()
|
||||||
|
.setStatusCode(500)
|
||||||
|
.end(new JsonObject().put("error", "Erreur de récupération de la BDD").encode());
|
||||||
|
})
|
||||||
|
.onSuccess(rows -> {
|
||||||
|
if (rows.rowCount() == 0) {
|
||||||
|
context.response()
|
||||||
|
.setStatusCode(404)
|
||||||
|
.end(new JsonObject().put("error", "Utilisateur non trouvé").encode());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String currentPassword = rows.iterator().next().getString("password");
|
||||||
|
BCrypt.Result verification = BCrypt.verifyer().verify(oldPassword.toCharArray(), currentPassword);
|
||||||
|
|
||||||
|
if (!verification.verified) {
|
||||||
|
context.response()
|
||||||
|
.setStatusCode(401)
|
||||||
|
.end(new JsonObject().put("error", "Ancien mot de passe incorrect").encode());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String hashedPassword = BCrypt.withDefaults().hashToString(12, newPassword.toCharArray());
|
||||||
|
|
||||||
|
databaseService.pool
|
||||||
|
.preparedQuery("UPDATE users SET password=? WHERE id=?")
|
||||||
|
.execute(Tuple.of(hashedPassword, id))
|
||||||
|
.onFailure(e -> {
|
||||||
|
System.err.println("Erreur lors de la mise à jour du mot de passe :" + e.getMessage());
|
||||||
|
context.response()
|
||||||
|
.setStatusCode(500)
|
||||||
|
.end(new JsonObject()
|
||||||
|
.put("error", "Erreur lors de la mise à jour du mot de passe")
|
||||||
|
.encode());
|
||||||
|
})
|
||||||
|
.onSuccess(updateRows -> {
|
||||||
|
context.response()
|
||||||
|
.putHeader("content-type", "application/json: charset=UTF-8")
|
||||||
|
.end(new JsonObject().put("success", "Le mot de passe a bien été mis à jour")
|
||||||
|
.encode());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateUserProfile(RoutingContext context) {
|
||||||
|
JsonObject body = context.body().asJsonObject();
|
||||||
|
if (body == null) {
|
||||||
|
context.response()
|
||||||
|
.setStatusCode(400)
|
||||||
|
.end(new JsonObject().put("error", "Corps de la requête manquant").encode());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Integer id = body.getInteger("id");
|
||||||
|
String name = body.getString("name");
|
||||||
|
String surname = body.getString("surname");
|
||||||
|
String pseudo = body.getString("pseudo");
|
||||||
|
|
||||||
|
databaseService.pool
|
||||||
|
.preparedQuery("UPDATE users SET name=?, surname=?, pseudo=? WHERE id=?")
|
||||||
|
.execute(Tuple.of(name, surname,pseudo, id))
|
||||||
|
.onFailure(e -> {
|
||||||
|
System.err.println("Erreur de récupération de la BDD :" + e.getMessage());
|
||||||
|
context.response()
|
||||||
|
.setStatusCode(500)
|
||||||
|
.end(new JsonObject().put("error", "Erreur de récupération de la BDD").encode());
|
||||||
|
})
|
||||||
|
.onSuccess(rows -> {
|
||||||
|
if (rows.rowCount() == 0) {
|
||||||
|
context.response()
|
||||||
|
.setStatusCode(404)
|
||||||
|
.end(new JsonObject().put("error", "Utilisateur non trouvé").encode());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
context.response()
|
||||||
|
.putHeader("content-type", "application/json: charset=UTF-8")
|
||||||
|
.end(new JsonObject()
|
||||||
|
.put("success", "Les informations de l'utilisateur ont bien été mises à jour")
|
||||||
|
.encode());
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void setUserPoints(RoutingContext context) {
|
public void setUserPoints(RoutingContext context) {
|
||||||
JsonObject body = context.body().asJsonObject();
|
JsonObject body = context.body().asJsonObject();
|
||||||
if (body == null) {
|
if (body == null) {
|
||||||
@ -59,36 +160,37 @@ public class SetUser {
|
|||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public void deleteUser(RoutingContext context){
|
|
||||||
|
public void deleteUser(RoutingContext context) {
|
||||||
JsonObject body = context.body().asJsonObject();
|
JsonObject body = context.body().asJsonObject();
|
||||||
if(body== null){
|
if (body == null) {
|
||||||
context.response()
|
context.response()
|
||||||
.setStatusCode(400)
|
.setStatusCode(400)
|
||||||
.end(new JsonObject().put("error","Corps de la requête manquant").encode());
|
.end(new JsonObject().put("error", "Corps de la requête manquant").encode());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Integer id = body.getInteger("id");
|
Integer id = body.getInteger("id");
|
||||||
databaseService.pool
|
databaseService.pool
|
||||||
.preparedQuery("DELETE FROM users WHERE id=?")
|
.preparedQuery("DELETE FROM users WHERE id=?")
|
||||||
.execute(Tuple.of(id))
|
.execute(Tuple.of(id))
|
||||||
.onFailure(e->{
|
.onFailure(e -> {
|
||||||
System.err.println("Erreur de récupération de la BDD :"+e.getMessage());
|
System.err.println("Erreur de récupération de la BDD :" + e.getMessage());
|
||||||
context.response()
|
|
||||||
.setStatusCode(500)
|
|
||||||
.end(new JsonObject().put("error","Erreur de récupération de la BDD").encode());
|
|
||||||
})
|
|
||||||
.onSuccess(rows -> {
|
|
||||||
if(rows.rowCount()==0){
|
|
||||||
context.response()
|
context.response()
|
||||||
|
.setStatusCode(500)
|
||||||
|
.end(new JsonObject().put("error", "Erreur de récupération de la BDD").encode());
|
||||||
|
})
|
||||||
|
.onSuccess(rows -> {
|
||||||
|
if (rows.rowCount() == 0) {
|
||||||
|
context.response()
|
||||||
.setStatusCode(404)
|
.setStatusCode(404)
|
||||||
.end(new JsonObject().put("error", "Utilisateur non trouvé").encode());
|
.end(new JsonObject().put("error", "Utilisateur non trouvé").encode());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
context.response()
|
context.response()
|
||||||
.putHeader("content-type","application/json: charset=UTF-8")
|
.putHeader("content-type", "application/json: charset=UTF-8")
|
||||||
.end(new JsonObject().put("success", "L'utilisateur à bien été supprimé").encode());
|
.end(new JsonObject().put("success", "L'utilisateur à bien été supprimé").encode());
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import Objet from "./pages/Gestion/Objet.jsx";
|
|||||||
import AddObject from "./pages/Gestion/AddObject.jsx";
|
import AddObject from "./pages/Gestion/AddObject.jsx";
|
||||||
import Signup from "./pages/Signup.jsx";
|
import Signup from "./pages/Signup.jsx";
|
||||||
import Login from "./pages/Login.jsx";
|
import Login from "./pages/Login.jsx";
|
||||||
import Settings from "./pages/Settings.jsx";
|
import Profil from "./pages/Profil.jsx";
|
||||||
import Sidebar from "./pages/Admin/sidebar.jsx";
|
import Sidebar from "./pages/Admin/sidebar.jsx";
|
||||||
import User from "./pages/Admin/User.jsx";
|
import User from "./pages/Admin/User.jsx";
|
||||||
import Dashboard from "./pages/Admin/Dashboard.jsx";
|
import Dashboard from "./pages/Admin/Dashboard.jsx";
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import {
|
|||||||
UserPlus,
|
UserPlus,
|
||||||
RadioTower,
|
RadioTower,
|
||||||
Binoculars,
|
Binoculars,
|
||||||
Settings,
|
|
||||||
BadgePlus,
|
BadgePlus,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
function Gestion() {
|
function Gestion() {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Mail, Lock } from "lucide-react";
|
import { Mail, Lock, AlertCircle } from "lucide-react";
|
||||||
import { useNavigate, Link } from "react-router-dom";
|
import { useNavigate, Link } from "react-router-dom";
|
||||||
import axios from "axios"; // Assurez-vous d'avoir axios importé
|
import axios from "axios";
|
||||||
import { useAuth } from "../AuthContext";
|
import { useAuth } from "../AuthContext";
|
||||||
import { API_BASE_URL } from "../config";
|
import { API_BASE_URL } from "../config";
|
||||||
|
|
||||||
@ -10,6 +10,7 @@ function Login() {
|
|||||||
email: "",
|
email: "",
|
||||||
password: "",
|
password: "",
|
||||||
});
|
});
|
||||||
|
const [error, setError] = useState("");
|
||||||
const { login } = useAuth(); // Utilisation du hook useAuth pour accéder à la fonction login
|
const { login } = useAuth(); // Utilisation du hook useAuth pour accéder à la fonction login
|
||||||
const navigate = useNavigate(); // Initialisation de useNavigate
|
const navigate = useNavigate(); // Initialisation de useNavigate
|
||||||
|
|
||||||
@ -19,43 +20,72 @@ function Login() {
|
|||||||
...prev,
|
...prev,
|
||||||
[name]: value,
|
[name]: value,
|
||||||
}));
|
}));
|
||||||
|
// Réinitialiser l'erreur lorsque l'utilisateur commence à modifier le formulaire
|
||||||
|
if (error) setError("");
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
setError(""); // Réinitialiser les erreurs à chaque tentative
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${API_BASE_URL}/login`, {
|
const response = await axios.post(`${API_BASE_URL}/login`, formData, {
|
||||||
method: "POST",
|
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(formData),
|
|
||||||
});
|
});
|
||||||
|
const data = response.data;
|
||||||
|
|
||||||
// Récupérer les données JSON de la réponse
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
// Vérifiez que la réponse contient bien un token
|
|
||||||
if (data.token) {
|
if (data.token) {
|
||||||
// Appel de la fonction login du contexte pour stocker le token
|
|
||||||
login(data.token);
|
login(data.token);
|
||||||
|
|
||||||
// Rediriger vers la page d'accueil après la connexion
|
|
||||||
navigate("/");
|
navigate("/");
|
||||||
} else {
|
} else {
|
||||||
console.error("Token manquant dans la réponse");
|
setError("Authentification échouée : token manquant dans la réponse");
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Erreur lors de la connexion", error);
|
console.error("Erreur lors de la connexion", error);
|
||||||
|
|
||||||
|
if (error.response) {
|
||||||
|
// Le serveur a répondu avec un statut d'erreur (4xx, 5xx)
|
||||||
|
if (error.response.status === 401) {
|
||||||
|
setError("Email ou mot de passe incorrect");
|
||||||
|
} else if (error.response.status === 422) {
|
||||||
|
setError("Données de formulaire invalides");
|
||||||
|
} else if (error.response.status >= 500) {
|
||||||
|
setError("Erreur serveur. Veuillez réessayer plus tard.");
|
||||||
|
} else {
|
||||||
|
setError(
|
||||||
|
error.response.data.message ||
|
||||||
|
"Une erreur s'est produite lors de la connexion"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (error.request) {
|
||||||
|
// La requête a été faite mais pas de réponse reçue
|
||||||
|
setError(
|
||||||
|
"Impossible de joindre le serveur. Vérifiez votre connexion internet."
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Une erreur s'est produite lors de la configuration de la requête
|
||||||
|
setError("Une erreur s'est produite. Veuillez réessayer.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-50 py-12 px-4 sm:px-6 lg:px-8">
|
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-50 py-12 px-4 sm:px-6 lg:px-8">
|
||||||
<div className="md:w-96 w-full bg-white rounded-lg shadow-md p-6 mx-auto">
|
<div className="md:w-96 w-full bg-white rounded-lg shadow-md p-6 mx-auto">
|
||||||
<h2 className="text-2xl font-bold text-gray-800 mb-6 text-center">
|
<h2 className="text-2xl font-bold text-gray-800 mb-6 text-center">
|
||||||
Connexion
|
Connexion
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
{/* Message d'erreur */}
|
||||||
|
{error && (
|
||||||
|
<div className="mb-4 p-3 bg-red-50 border border-red-200 text-red-700 rounded-md flex items-start">
|
||||||
|
<AlertCircle className="h-5 w-5 mr-2 mt-0.5 flex-shrink-0" />
|
||||||
|
<span className="text-sm">{error}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<form onSubmit={handleSubmit} className="space-y-4">
|
<form onSubmit={handleSubmit} className="space-y-4">
|
||||||
{/* Email */}
|
{/* Email */}
|
||||||
<div>
|
<div>
|
||||||
@ -94,6 +124,7 @@ function Login() {
|
|||||||
className="pl-10 block w-full rounded-lg border-gray-300 border p-2.5 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
|
className="pl-10 block w-full rounded-lg border-gray-300 border p-2.5 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
|
||||||
required
|
required
|
||||||
minLength="8"
|
minLength="8"
|
||||||
|
autoComplete="current-password"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
321
Front-end/src/pages/Profil.jsx
Normal file
321
Front-end/src/pages/Profil.jsx
Normal file
@ -0,0 +1,321 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { Mail, User, Lock, Edit, Save } from 'lucide-react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { API_BASE_URL } from "../config";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
function Profil() {
|
||||||
|
const [userData, setUserData] = useState({});
|
||||||
|
const identifiant=4;
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
oldPassword: '',
|
||||||
|
newPassword: '',
|
||||||
|
confirmPassword: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const [editMode, setEditMode] = useState(false);
|
||||||
|
const [errorMessage, setErrorMessage] = useState('');
|
||||||
|
const [successMessage, setSuccessMessage] = useState('');
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
axios
|
||||||
|
.post(`${API_BASE_URL}/user`, {
|
||||||
|
id: identifiant,
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
setUserData(response.data);
|
||||||
|
console.log("Infos récupérées :", response.data);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Erreur lors de la récupération :", error);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
const { name, value } = e.target;
|
||||||
|
setFormData(prev => ({
|
||||||
|
...prev,
|
||||||
|
[name]: value
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleProfileChange = (e) => {
|
||||||
|
const { name, value } = e.target;
|
||||||
|
setUserData(prev => ({
|
||||||
|
...prev,
|
||||||
|
[name]: value
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setErrorMessage('');
|
||||||
|
setSuccessMessage('');
|
||||||
|
|
||||||
|
if (formData.newPassword !== formData.confirmPassword) {
|
||||||
|
setErrorMessage("Les nouveaux mots de passe ne correspondent pas !");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
axios
|
||||||
|
.post(`${API_BASE_URL}/changePassword`, {
|
||||||
|
id: userData.id, // Il faudrait s'assurer que userData contient l'ID de l'utilisateur
|
||||||
|
oldPassword: formData.oldPassword,
|
||||||
|
newPassword: formData.newPassword
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
console.log("Modification du mot de passe réussie :", response.data);
|
||||||
|
setSuccessMessage("Mot de passe modifié avec succès !");
|
||||||
|
setFormData({
|
||||||
|
oldPassword: '',
|
||||||
|
newPassword: '',
|
||||||
|
confirmPassword: ''
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Erreur lors de la modification du mot de passe :", error);
|
||||||
|
setErrorMessage(error.response?.data?.error || "Une erreur est survenue");
|
||||||
|
});
|
||||||
|
|
||||||
|
setSuccessMessage("Mot de passe modifié avec succès !");
|
||||||
|
setFormData({
|
||||||
|
oldPassword: '',
|
||||||
|
newPassword: '',
|
||||||
|
confirmPassword: ''
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setErrorMessage(error.message || "Une erreur est survenue");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleProfileSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setErrorMessage('');
|
||||||
|
setSuccessMessage('');
|
||||||
|
|
||||||
|
axios
|
||||||
|
.post(`${API_BASE_URL}/updateProfil`, {
|
||||||
|
id: userData.id,
|
||||||
|
name: userData.name,
|
||||||
|
surname: userData.surname,
|
||||||
|
pseudo:userData.pseudo,
|
||||||
|
email: userData.email
|
||||||
|
})
|
||||||
|
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Erreur lors de la mise à jour du profil :", error);
|
||||||
|
setErrorMessage(error.response?.data?.error || "Une erreur est survenue");
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
console.log("Mise à jour du profil réussie :", response.data);
|
||||||
|
setSuccessMessage("Profil mis à jour avec succès !");
|
||||||
|
setEditMode(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-50 py-12 px-4 sm:px-6 lg:px-8">
|
||||||
|
<div className="max-w-3xl mx-auto">
|
||||||
|
<h1 className="text-3xl font-bold text-gray-900 mb-8 text-center">Mon Profil</h1>
|
||||||
|
|
||||||
|
{errorMessage && (
|
||||||
|
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4">
|
||||||
|
{errorMessage}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{successMessage && (
|
||||||
|
<div className="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded relative mb-4">
|
||||||
|
{successMessage}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="grid md:grid-cols-2 gap-8">
|
||||||
|
{/* Informations du profil */}
|
||||||
|
<div className="bg-white rounded-lg shadow-md p-6">
|
||||||
|
<div className="flex justify-between items-center mb-4">
|
||||||
|
<h2 className="text-xl font-semibold text-gray-800">Informations Personnelles</h2>
|
||||||
|
<button
|
||||||
|
onClick={() => setEditMode(!editMode)}
|
||||||
|
className="text-indigo-600 hover:text-indigo-800"
|
||||||
|
>
|
||||||
|
{editMode ? <Save className="h-5 w-5" /> : <Edit className="h-5 w-5" />}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form onSubmit={handleProfileSubmit} className="space-y-4">
|
||||||
|
<div className="flex items-center space-x-4 mb-4">
|
||||||
|
<div className="w-20 h-20 bg-indigo-100 rounded-full flex items-center justify-center">
|
||||||
|
<User className="h-10 w-10 text-indigo-600" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="text-lg font-medium">{userData.name} {userData.surname} ({userData.pseudo})</h3>
|
||||||
|
<p className="text-gray-500">{userData.email}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bg-indigo-50 p-3 rounded-lg mb-4">
|
||||||
|
<p className="text-sm text-gray-700">Points de fidélité: <span className="font-semibold">{userData.points}</span> ({userData.role})</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{editMode ? (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">Prénom:</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="name"
|
||||||
|
value={userData.name}
|
||||||
|
onChange={handleProfileChange}
|
||||||
|
className="block w-full rounded-lg border-gray-300 border p-2.5 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">Nom:</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="surname"
|
||||||
|
value={userData.surname}
|
||||||
|
onChange={handleProfileChange}
|
||||||
|
className="block w-full rounded-lg border-gray-300 border p-2.5 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">Pseudo:</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="pseudo"
|
||||||
|
value={userData.pseudo}
|
||||||
|
onChange={handleProfileChange}
|
||||||
|
className="block w-full rounded-lg border-gray-300 border p-2.5 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">Email:</label>
|
||||||
|
<div className="relative">
|
||||||
|
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||||
|
<Mail className="h-5 w-5 text-gray-400" />
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
name="email"
|
||||||
|
value={userData.email}
|
||||||
|
disabled
|
||||||
|
className="pl-10 block w-full rounded-lg border-gray-300 border p-2.5 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="w-full flex justify-center py-2 px-4 border border-transparent rounded-lg shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
|
||||||
|
>
|
||||||
|
Sauvegarder
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div className="space-y-3">
|
||||||
|
<div>
|
||||||
|
<p className="text-sm font-medium text-gray-500">Prénom</p>
|
||||||
|
<p className="mt-1">{userData.name}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-sm font-medium text-gray-500">Nom</p>
|
||||||
|
<p className="mt-1">{userData.surname}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-sm font-medium text-gray-500">Pseudo</p>
|
||||||
|
<p className="mt-1">{userData.pseudo}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-sm font-medium text-gray-500">Email</p>
|
||||||
|
<p className="mt-1">{userData.email}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Changement de mot de passe */}
|
||||||
|
<div className="bg-white rounded-lg shadow-md p-6">
|
||||||
|
<h2 className="text-xl font-semibold text-gray-800 mb-4">Modifier le mot de passe</h2>
|
||||||
|
<form onSubmit={handleSubmit} className="space-y-4">
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
|
Mot de passe actuel:
|
||||||
|
</label>
|
||||||
|
<div className="relative">
|
||||||
|
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||||
|
<Lock className="h-5 w-5 text-gray-400" />
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
name="oldPassword"
|
||||||
|
value={formData.oldPassword}
|
||||||
|
onChange={handleChange}
|
||||||
|
className="pl-10 block w-full rounded-lg border-gray-300 border p-2.5 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
|
||||||
|
required
|
||||||
|
minLength="8"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
|
Nouveau mot de passe:
|
||||||
|
</label>
|
||||||
|
<div className="relative">
|
||||||
|
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||||
|
<Lock className="h-5 w-5 text-gray-400" />
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
name="newPassword"
|
||||||
|
value={formData.newPassword}
|
||||||
|
onChange={handleChange}
|
||||||
|
className="pl-10 block w-full rounded-lg border-gray-300 border p-2.5 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
|
||||||
|
required
|
||||||
|
minLength="8"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
|
Confirmer le nouveau mot de passe:
|
||||||
|
</label>
|
||||||
|
<div className="relative">
|
||||||
|
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||||
|
<Lock className="h-5 w-5 text-gray-400" />
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
name="confirmPassword"
|
||||||
|
value={formData.confirmPassword}
|
||||||
|
onChange={handleChange}
|
||||||
|
className="pl-10 block w-full rounded-lg border-gray-300 border p-2.5 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
|
||||||
|
required
|
||||||
|
minLength="8"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="w-full flex justify-center py-2.5 px-4 border border-transparent rounded-lg shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
|
||||||
|
>
|
||||||
|
Modifier le mot de passe
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Profil;
|
||||||
@ -1,161 +0,0 @@
|
|||||||
import React, { useState } from 'react';
|
|
||||||
import { Mail, User, Lock } from 'lucide-react';
|
|
||||||
import { useNavigate, Link} from 'react-router-dom'; // Importation du hook useNavigate
|
|
||||||
|
|
||||||
function Settings() {
|
|
||||||
const [formData, setFormData] = useState({
|
|
||||||
name: '',
|
|
||||||
surname: '',
|
|
||||||
email: '',
|
|
||||||
gender: '',
|
|
||||||
password: '',
|
|
||||||
confirmPassword: ''
|
|
||||||
});
|
|
||||||
const navigate = useNavigate(); // Initialisation de useNavigate
|
|
||||||
|
|
||||||
const handleChange = (e) => {
|
|
||||||
const { name, value } = e.target;
|
|
||||||
setFormData(prev => ({
|
|
||||||
...prev,
|
|
||||||
[name]: value
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmit = async (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
if (formData.password !== formData.confirmPassword) {
|
|
||||||
alert("Les mots de passe ne correspondent pas !");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(`${API_BASE_URL}/settings`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(formData),
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(data.error || "Erreur lors de la modification");
|
|
||||||
}
|
|
||||||
|
|
||||||
alert("Modification réussie !");
|
|
||||||
|
|
||||||
// Redirection vers la page d'accueil après une inscription réussie
|
|
||||||
navigate("/home"); // Remplace "/home" par l'URL de ta page d'accueil
|
|
||||||
} catch (error) {
|
|
||||||
alert(error.message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-50 py-12 px-4 sm:px-6 lg:px-8">
|
|
||||||
<div className="w-96 bg-white rounded-lg shadow-md p-6 mx-auto">
|
|
||||||
<h2 className="text-2xl font-bold text-gray-800 mb-6 text-center">Settings</h2>
|
|
||||||
<form onSubmit={handleSubmit} className="space-y-4">
|
|
||||||
{/* (Formulaire changement Email, Mot de passe) */}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{/* Email */}
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
||||||
Modifier votre email:
|
|
||||||
</label>
|
|
||||||
<div className="relative">
|
|
||||||
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
|
||||||
<Mail className="h-5 w-5 text-gray-400" />
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
type="email"
|
|
||||||
name="email"
|
|
||||||
value={formData.email}
|
|
||||||
onChange={handleChange}
|
|
||||||
className="pl-10 block w-full rounded-lg border-gray-300 border p-2.5 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Mot de passe */}
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
|
||||||
Ancien mot de passe:
|
|
||||||
</label>
|
|
||||||
<div className="relative">
|
|
||||||
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
|
||||||
<Lock className="h-5 w-5 text-gray-400" />
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
name="password"
|
|
||||||
value={formData.password}
|
|
||||||
onChange={handleChange}
|
|
||||||
className="pl-10 block w-full rounded-lg border-gray-300 border p-2.5 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
|
|
||||||
required
|
|
||||||
minLength="8"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* nouveau mot de passe */}
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
|
||||||
Nouveau mot de passe:
|
|
||||||
</label>
|
|
||||||
<div className="relative">
|
|
||||||
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
|
||||||
<Lock className="h-5 w-5 text-gray-400" />
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
name="confirmPassword"
|
|
||||||
value={formData.confirmPassword}
|
|
||||||
onChange={handleChange}
|
|
||||||
className="pl-10 block w-full rounded-lg border-gray-300 border p-2.5 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
|
|
||||||
required
|
|
||||||
minLength="8"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
|
||||||
Confirmer le nouveau mot de passe:
|
|
||||||
</label>
|
|
||||||
<div className="relative">
|
|
||||||
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
|
||||||
<Lock className="h-5 w-5 text-gray-400" />
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
name="confirmPassword"
|
|
||||||
value={formData.confirmPassword}
|
|
||||||
onChange={handleChange}
|
|
||||||
className="pl-10 block w-full rounded-lg border-gray-300 border p-2.5 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
|
|
||||||
required
|
|
||||||
minLength="8"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* Bouton d'inscription */}
|
|
||||||
<div className="pt-4">
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
className="w-full flex justify-center py-2.5 px-4 border border-transparent rounded-lg shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
|
|
||||||
>
|
|
||||||
Sauvegarder
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Settings;
|
|
||||||
@ -7,6 +7,7 @@ function Signup() {
|
|||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
name: '',
|
name: '',
|
||||||
surname: '',
|
surname: '',
|
||||||
|
pseudo:'',
|
||||||
email: '',
|
email: '',
|
||||||
gender: '',
|
gender: '',
|
||||||
password: '',
|
password: '',
|
||||||
@ -62,7 +63,7 @@ function Signup() {
|
|||||||
{/* Formulaire (Nom, Prénom, Sexe, Email, Mot de passe) */}
|
{/* Formulaire (Nom, Prénom, Sexe, Email, Mot de passe) */}
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
Nom:
|
Prénom:
|
||||||
</label>
|
</label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||||
@ -81,7 +82,7 @@ function Signup() {
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
Prénom:
|
Nom:
|
||||||
</label>
|
</label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||||
@ -98,6 +99,25 @@ function Signup() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
|
Pseudo:
|
||||||
|
</label>
|
||||||
|
<div className="relative">
|
||||||
|
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||||
|
<User className="h-5 w-5 text-gray-400" />
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="pseudo"
|
||||||
|
value={formData.pseudo}
|
||||||
|
onChange={handleChange}
|
||||||
|
className="pl-10 block w-full rounded-lg border-gray-300 border p-2.5 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Sexe */}
|
{/* Sexe */}
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user