Ajout du backend sur les users
This commit is contained in:
parent
68917bbcb0
commit
b10408f443
@ -54,6 +54,8 @@ public class MainVerticle extends AbstractVerticle {
|
||||
router.post("/deleteObject").handler(setObjects::deleteObject);
|
||||
router.get("/users").handler(queryUsers::getUsers);
|
||||
router.post("/setUserPoints").handler(setUser::setUserPoints);
|
||||
router.post("/deleteUser").handler(setUser::deleteUser);
|
||||
|
||||
// Routes d'authentification
|
||||
router.post("/signup").handler(authHandler::handleSignup);
|
||||
router.post("/login").handler(authHandler::handleLogin);
|
||||
|
||||
@ -25,7 +25,7 @@ public class SetUser {
|
||||
databaseService.pool
|
||||
.preparedQuery(
|
||||
"UPDATE users SET points=? WHERE id=?")
|
||||
.execute(Tuple.of(points,id))
|
||||
.execute(Tuple.of(points, id))
|
||||
.onFailure(e -> {
|
||||
System.err.println("Erreur de récupération de la BDD :" + e.getMessage());
|
||||
context.response()
|
||||
@ -41,8 +41,41 @@ public class SetUser {
|
||||
}
|
||||
context.response()
|
||||
.putHeader("content-type", "application/json: charset=UTF-8")
|
||||
.end(new JsonObject().put("success", "Les points de l'utilisateur ont bien été mis à jour").encode());
|
||||
.end(new JsonObject().put("success", "Les points de l'utilisateur ont bien été mis à jour")
|
||||
.encode());
|
||||
return;
|
||||
});
|
||||
}
|
||||
public void deleteUser(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");
|
||||
databaseService.pool
|
||||
.preparedQuery("DELETE 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;
|
||||
}
|
||||
context.response()
|
||||
.putHeader("content-type","application/json: charset=UTF-8")
|
||||
.end(new JsonObject().put("success", "L'utilisateur à bien été supprimé").encode());
|
||||
return;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,51 +1,8 @@
|
||||
import React, { useState,useEffect } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Sidebar from "./sidebar.jsx";
|
||||
import { API_BASE_URL } from "../../config.js";
|
||||
import axios from "axios";
|
||||
|
||||
|
||||
const dashboardStyles = {
|
||||
mainContent: {
|
||||
flexGrow: 1,
|
||||
padding: "20px",
|
||||
},
|
||||
summaryContainer: {
|
||||
display: "flex",
|
||||
gap: "20px",
|
||||
marginBottom: "20px",
|
||||
},
|
||||
summaryCard: {
|
||||
background: "#f4f4f4",
|
||||
padding: "20px",
|
||||
flex: 1,
|
||||
borderRadius: "5px",
|
||||
textAlign: "center",
|
||||
},
|
||||
table: {
|
||||
width: "100%",
|
||||
borderCollapse: "collapse",
|
||||
},
|
||||
tableHeader: {
|
||||
padding: "10px",
|
||||
border: "1px solid #ccc",
|
||||
backgroundColor: "#f4f4f4",
|
||||
},
|
||||
tableCell: {
|
||||
padding: "10px",
|
||||
border: "1px solid #ccc",
|
||||
textAlign: "left",
|
||||
},
|
||||
viewMoreButton: {
|
||||
marginTop: "10px",
|
||||
padding: "10px 15px",
|
||||
backgroundColor: "#007bff",
|
||||
color: "#fff",
|
||||
border: "none",
|
||||
borderRadius: "5px",
|
||||
cursor: "pointer",
|
||||
},
|
||||
};
|
||||
|
||||
function Dashboard() {
|
||||
const [users, setUsers] = useState([]);
|
||||
const [logs, setLogs] = useState([
|
||||
@ -62,64 +19,67 @@ function Dashboard() {
|
||||
timestamp: new Date().toLocaleString(),
|
||||
},
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
axios.get(`${API_BASE_URL}/users`).then((response) => {
|
||||
setUsers(response.data);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div style={{ display: "flex", minHeight: "100vh" }}>
|
||||
<div className="flex h-screen">
|
||||
<Sidebar />
|
||||
<main style={dashboardStyles.mainContent}>
|
||||
<h1>Dashboard</h1>
|
||||
<div style={dashboardStyles.summaryContainer}>
|
||||
<div style={dashboardStyles.summaryCard}>
|
||||
<h2>Total Users</h2>
|
||||
<p>{users.length}</p>
|
||||
<main className="flex-grow p-5">
|
||||
<h1 className="text-2xl font-bold mb-6">Dashboard</h1>
|
||||
|
||||
<div className="flex gap-5 mb-6">
|
||||
<div className="bg-gray-100 p-6 flex-1 rounded-lg text-center">
|
||||
<h2 className="text-xl font-semibold">Total Users</h2>
|
||||
<p className="text-2xl mt-2">{users.length}</p>
|
||||
</div>
|
||||
<div style={dashboardStyles.summaryCard}>
|
||||
<h2>Dernier Log</h2>
|
||||
<div className="bg-gray-100 p-6 flex-1 rounded-lg text-center">
|
||||
<h2 className="text-xl font-semibold">Dernier Log</h2>
|
||||
{logs.length > 0 ? (
|
||||
<p>
|
||||
{logs[logs.length - 1].username} -{" "}
|
||||
{logs[logs.length - 1].action}
|
||||
<p className="mt-2">
|
||||
{logs[logs.length - 1].username} - {logs[logs.length - 1].action}
|
||||
</p>
|
||||
) : (
|
||||
<p>Aucun log</p>
|
||||
<p className="mt-2">Aucun log</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section>
|
||||
<h2>Aperçu des Utilisateurs</h2>
|
||||
<table style={dashboardStyles.table}>
|
||||
<h2 className="text-xl font-semibold mb-4">Aperçu des Utilisateurs</h2>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="min-w-full border border-gray-300">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={dashboardStyles.tableHeader}>Username</th>
|
||||
<th style={dashboardStyles.tableHeader}>Email</th>
|
||||
<th style={dashboardStyles.tableHeader}>Niveau d'accès</th>
|
||||
<tr className="bg-gray-100">
|
||||
<th className="p-3 border text-left">Username</th>
|
||||
<th className="p-3 border text-left">Email</th>
|
||||
<th className="p-3 border text-left">Niveau d'accès</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{users.slice(0, 5).map((user) => (
|
||||
<tr key={user.id}>
|
||||
<td style={dashboardStyles.tableCell}>{user.name}</td>
|
||||
<td style={dashboardStyles.tableCell}>{user.email}</td>
|
||||
<td style={dashboardStyles.tableCell}>{user.role}</td>
|
||||
<tr key={user.id} className="hover:bg-gray-50">
|
||||
<td className="p-3 border text-left">{user.name}</td>
|
||||
<td className="p-3 border text-left">{user.email}</td>
|
||||
<td className="p-3 border text-left">{user.role}</td>
|
||||
</tr>
|
||||
))}
|
||||
{users.length === 0 && (
|
||||
<tr>
|
||||
<td colSpan="3" style={dashboardStyles.tableCell}>
|
||||
<td colSpan="3" className="p-3 border text-center">
|
||||
Aucun utilisateur disponible
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
{/* Bouton pour accéder à la page complète */}
|
||||
</div>
|
||||
<button
|
||||
style={dashboardStyles.viewMoreButton}
|
||||
className="mt-4 px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
|
||||
onClick={() => (window.location.href = "/user")}
|
||||
>
|
||||
Voir plus
|
||||
|
||||
@ -1,51 +1,10 @@
|
||||
import React, { useState,useEffect} from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Sidebar from "./sidebar.jsx";
|
||||
import { API_BASE_URL } from "../../config.js";
|
||||
import axios from "axios";
|
||||
|
||||
const styles = {
|
||||
mainContent: {
|
||||
flexGrow: 1,
|
||||
padding: "20px",
|
||||
},
|
||||
header: {
|
||||
marginBottom: "20px",
|
||||
},
|
||||
userManagement: {
|
||||
marginTop: "20px",
|
||||
},
|
||||
userForm: {
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr 1fr auto",
|
||||
gap: "10px",
|
||||
marginBottom: "20px",
|
||||
},
|
||||
input: {
|
||||
padding: "10px",
|
||||
border: "1px solid #ccc",
|
||||
borderRadius: "5px",
|
||||
},
|
||||
button: {
|
||||
padding: "10px",
|
||||
backgroundColor: "#28a745",
|
||||
color: "white",
|
||||
border: "none",
|
||||
borderRadius: "5px",
|
||||
cursor: "pointer",
|
||||
},
|
||||
userTable: {
|
||||
width: "100%",
|
||||
borderCollapse: "collapse",
|
||||
},
|
||||
thTd: {
|
||||
padding: "10px",
|
||||
border: "1px solid #ccc",
|
||||
textAlign: "left",
|
||||
},
|
||||
th: {
|
||||
backgroundColor: "#f4f4f4",
|
||||
},
|
||||
};
|
||||
const thTd = "p-2 border border-gray-300 text-left";
|
||||
const th = `${thTd} bg-gray-100`;
|
||||
|
||||
function User() {
|
||||
const [users, setUsers] = useState([]);
|
||||
@ -64,7 +23,7 @@ function User() {
|
||||
points: 0,
|
||||
};
|
||||
setUsers([...users, newUser]);
|
||||
logAction(name, "User added");
|
||||
logAction(name, "Utilisateur ajouté");
|
||||
setname("");
|
||||
setEmail("");
|
||||
};
|
||||
@ -76,7 +35,22 @@ function User() {
|
||||
const handleDeleteUser = (userId) => {
|
||||
const user = users.find((u) => u.id === userId);
|
||||
if (user) {
|
||||
logAction(user.name, "User deleted");
|
||||
axios
|
||||
.post(`${API_BASE_URL}/deleteUser`, {
|
||||
id: userId,
|
||||
})
|
||||
.then((response) => {
|
||||
alert("L'utilisateur à bien été supprimé !");
|
||||
console.log("L'utilisateur à été supprimé :", response.data);
|
||||
window.location.reload();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(
|
||||
"Erreur lors de la suppression de l'utilisateur :",
|
||||
error
|
||||
);
|
||||
});
|
||||
logAction(user.name, "Utilisateur supprimé");
|
||||
}
|
||||
setUsers(users.filter((u) => u.id !== userId));
|
||||
};
|
||||
@ -84,13 +58,33 @@ function User() {
|
||||
const handleChangeAccessLevel = (userId, newLevel) => {
|
||||
setUsers(
|
||||
users.map((user) => {
|
||||
if (user.id === userId) {
|
||||
if (user.id === userId && newLevel!=user.role) {
|
||||
const oldLevel = user.role;
|
||||
user.role = newLevel;
|
||||
/*ToDO*/
|
||||
if (user.role === "user") {
|
||||
user.points = 0;
|
||||
} else if (user.role === "complexe") {
|
||||
user.points = 60;
|
||||
} else if (user.role === "admin") {
|
||||
user.points = 100;
|
||||
}
|
||||
axios
|
||||
.post(`${API_BASE_URL}/setUserPoints`, {
|
||||
id: user.id,
|
||||
points: user.points,
|
||||
})
|
||||
.then((response) => {
|
||||
alert("Le changement de niveau a bien été enregistré !");
|
||||
console.log("Changement de niveau réussit :", response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
alert("Il y a eu une erreur dans le changement de niveau !");
|
||||
console.error("Erreur lors du changement de niveau :", error);
|
||||
});
|
||||
logAction(
|
||||
user.name,
|
||||
`Access level changed from ${oldLevel} to ${newLevel}`
|
||||
`Niveau d'accés changé de ${oldLevel} à ${newLevel}`
|
||||
);
|
||||
}
|
||||
return user;
|
||||
@ -103,19 +97,18 @@ function User() {
|
||||
setUsers(
|
||||
users.map((user) => {
|
||||
if (user.id === userId) {
|
||||
user.points += pointsToAdd;
|
||||
user.points = pointsToAdd;
|
||||
axios
|
||||
.post(`${API_BASE_URL}/setUserPoints`, {
|
||||
id:user.id,
|
||||
points:user.points,
|
||||
id: user.id,
|
||||
points: user.points,
|
||||
})
|
||||
.then((response) => {
|
||||
setMessRequete("Les points ont bien été enregistré !");
|
||||
setEnregistre(true);
|
||||
alert("Les points ont bien été enregistré !");
|
||||
console.log("Ajout des points réussit :", response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
setMessRequete("Il y a eu une erreur dans l'ajout des points!");
|
||||
alert("Il y a eu une erreur dans l'ajout des points!");
|
||||
console.error("Erreur lors de l'ajout des points :", error);
|
||||
});
|
||||
logAction(user.name, `Points ajustés par ${pointsToAdd}`);
|
||||
@ -134,16 +127,21 @@ function User() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ display: "flex", minHeight: "100vh" }}>
|
||||
<div className="flex min-h-screen">
|
||||
<Sidebar />
|
||||
<main style={styles.mainContent}>
|
||||
<section style={styles.userManagement}>
|
||||
<h1>User Management</h1>
|
||||
<main className="flex-grow p-5">
|
||||
<section className="mt-5">
|
||||
<h1 className="text-2xl font-bold text-gray-900 mb-5">
|
||||
User Management
|
||||
</h1>
|
||||
<p>Manage users from this panel.</p>
|
||||
{/* Formulaire d'ajout d'utilisateur */}
|
||||
<form style={styles.userForm} onSubmit={handleAddUser}>
|
||||
<form
|
||||
className="gap-3 mb-5 grid grid-cols-[1fr_1fr_auto]"
|
||||
onSubmit={handleAddUser}
|
||||
>
|
||||
<input
|
||||
style={styles.input}
|
||||
className="p-3 border rounded-md"
|
||||
type="text"
|
||||
id="name"
|
||||
placeholder="name"
|
||||
@ -152,7 +150,7 @@ function User() {
|
||||
required
|
||||
/>
|
||||
<input
|
||||
style={styles.input}
|
||||
className="p-3 border rounded-md"
|
||||
type="email"
|
||||
id="email"
|
||||
placeholder="Email"
|
||||
@ -160,49 +158,50 @@ function User() {
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
required
|
||||
/>
|
||||
<button style={styles.button} type="submit">
|
||||
Add User
|
||||
<button
|
||||
className="p-3 bg-green-600 text-white border-none rounded-md "
|
||||
type="submit"
|
||||
>
|
||||
Ajouter utilisateur
|
||||
</button>
|
||||
</form>
|
||||
{/* Tableau des utilisateurs */}
|
||||
<table style={styles.userTable}>
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Nom</th>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Email</th>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Niveau d'accès</th>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Points</th>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Actions</th>
|
||||
<th className={`${th}`}>Nom</th>
|
||||
<th className={`${th}`}>Email</th>
|
||||
<th className={`${th}`}>Niveau d'accès</th>
|
||||
<th className={`${th}`}>Points</th>
|
||||
<th className={`${th}`}>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{users.map((user) => (
|
||||
<tr key={user.id}>
|
||||
<td style={styles.thTd}>{user.name}</td>
|
||||
<td style={styles.thTd}>{user.email}</td>
|
||||
<td style={styles.thTd}>
|
||||
<td className={`${thTd}`}>{user.name}</td>
|
||||
<td className={`${thTd}`}>{user.email}</td>
|
||||
<td className={`${thTd}`}>
|
||||
{/* Menu déroulant pour changer le niveau d'accès */}
|
||||
<select
|
||||
value={user.role}
|
||||
onChange={(e) =>
|
||||
handleChangeAccessLevel(user.id, e.target.value)
|
||||
}
|
||||
style={{ padding: "5px", borderRadius: "5px" }}
|
||||
className="p-2 rounded-md"
|
||||
>
|
||||
<option value="admin">Admin</option>
|
||||
<option value="user">User</option>
|
||||
<option value="complexe">Complexe</option>
|
||||
</select>
|
||||
</td>
|
||||
<td style={styles.thTd}>
|
||||
<span>{user.points}</span>
|
||||
<td className={`${thTd}`}>
|
||||
{/* Input et bouton pour ajuster les points */}
|
||||
<input
|
||||
className="border ml-4 w-16"
|
||||
type="number"
|
||||
min="0"
|
||||
style={{ width: "60px", marginLeft: "10px" }}
|
||||
placeholder="Adjust"
|
||||
value={pointsInput[user.id] || ""}
|
||||
value={pointsInput[user.id] || user.points}
|
||||
onChange={(e) =>
|
||||
setPointsInput({
|
||||
...pointsInput,
|
||||
@ -211,27 +210,19 @@ function User() {
|
||||
}
|
||||
/>
|
||||
<button
|
||||
style={{
|
||||
...styles.button,
|
||||
padding: "5px 10px",
|
||||
marginLeft: "5px",
|
||||
}}
|
||||
className="p-2 bg-green-600 text-white border-none rounded-md"
|
||||
onClick={() => handleAdjustPoints(user.id)}
|
||||
>
|
||||
Adjust
|
||||
Changer
|
||||
</button>
|
||||
</td>
|
||||
<td style={styles.thTd}>
|
||||
<td className={`${thTd}`}>
|
||||
{/* Bouton de suppression */}
|
||||
<button
|
||||
style={{
|
||||
...styles.button,
|
||||
backgroundColor: "#dc3545",
|
||||
padding: "5px 10px",
|
||||
}}
|
||||
className="p-2 bg-red-600 text-white border-none rounded-md"
|
||||
onClick={() => handleDeleteUser(user.id)}
|
||||
>
|
||||
Delete
|
||||
Supprimer
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
@ -240,22 +231,24 @@ function User() {
|
||||
</table>
|
||||
</section>
|
||||
{/* Tableau des logs */}
|
||||
<section className="user-logs" style={{ marginTop: "40px" }}>
|
||||
<h2>Historique des connexions et journal des logs </h2>
|
||||
<table style={styles.userTable}>
|
||||
<section className="user-logs mt-10">
|
||||
<h2 className="text-2xl font-bold text-gray-900 mb-5">
|
||||
Historique des connexions et journal des logs{" "}
|
||||
</h2>
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Nom</th>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Action</th>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Timestamp</th>
|
||||
<th className={`${th}`}>Nom</th>
|
||||
<th className={`${th}`}>Action</th>
|
||||
<th className={`${th}`}>Timestamp</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{logs.map((log) => (
|
||||
<tr key={log.id}>
|
||||
<td style={styles.thTd}>{log.name}</td>
|
||||
<td style={styles.thTd}>{log.action}</td>
|
||||
<td style={styles.thTd}>{log.timestamp}</td>
|
||||
<td className={`${thTd}`}>{log.name}</td>
|
||||
<td className={`${thTd}`}>{log.action}</td>
|
||||
<td className={`${thTd}`}>{log.timestamp}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user