Avancement de la mise à jour des points pour les users

This commit is contained in:
Mathis 2025-04-11 23:20:29 +02:00
parent a5c14c769f
commit 23f15fcf75
17 changed files with 154 additions and 104 deletions

View File

@ -47,7 +47,7 @@ public class MainVerticle extends AbstractVerticle {
// Déclaration des routes
router.get("/objets").handler(queryObjects::getObjects);
router.get("/objet").handler(queryObjects::getParticularObject);
router.post("/objet").handler(queryObjects::getParticularObject);
router.post("/modifObjet").handler(setObjects::setInfoObjet);
router.get("/wind").handler(queryWeather::getWindInfos);
router.get("/meteo").handler(queryWeather::getMeteoInfos);

View File

@ -41,9 +41,16 @@ public class QueryObjects {
}
public void getParticularObject(RoutingContext context) {
String id = context.request().getParam("id");
// Integer idUser = body.getInteger("idUser");
Integer idUser = 4;
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;
}
String id = body.getString("id");
String idUser = body.getString("userId");
if (id == null) {
context.response()
.setStatusCode(400)
@ -66,10 +73,13 @@ public class QueryObjects {
.end(new JsonObject().put("error", "Objet non trouvé").encode());
return;
}
if (idUser != null) {
setUser.updateUserPoints(idUser, 1);
System.out.println(idUser);
Boolean shouldUpdatePoints = body.getBoolean("shouldUpdatePoints", false);
if (Boolean.TRUE.equals(shouldUpdatePoints) && idUser != null) {
setUser.updateUserPoints(Integer.parseInt(idUser), 1);
}
;
context.response()
.putHeader("content-type", "application/json: charset=UTF-8")
.end(getInfosObjects(rows).encode());

View File

@ -109,8 +109,7 @@ public class QueryUsers {
.end(new JsonObject().put("error", "Corps de la requête manquant").encode());
return;
}
//Integer idUser = body.getInteger("idUser");
Integer idUser = 4;
Integer idUser = body.getInteger("idUser");
databaseService.pool
.preparedQuery("SELECT * FROM users WHERE id=?;")
.execute(Tuple.of(idUser))

View File

@ -7,12 +7,15 @@ import io.vertx.sqlclient.Tuple;
public class SetObjects {
private DatabaseService databaseService;
private SetUser setUser;
public SetObjects(DatabaseService ddbs) {
this.databaseService = ddbs;
}
public void setUserHandler(SetUser setUser){
public void setUserHandler(SetUser setUser) {
this.setUser = setUser;
}
public void setInfoObjet(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
if (body == null) {
@ -22,8 +25,7 @@ public class SetObjects {
return;
}
Integer id = body.getInteger("id");
// Integer idUser = body.getInteger("idUser");
Integer idUser = 4;
Integer idUser = body.getInteger("idUser");
String description = body.getString("description");
String type = body.getString("type");
String location = body.getString("location");
@ -46,57 +48,60 @@ public class SetObjects {
.end(new JsonObject().put("error", "Objet non trouvé").encode());
return;
}
if(idUser!=null){
setUser.updateUserPoints(idUser,1);
};
Boolean shouldUpdatePoints = body.getBoolean("shouldUpdatePoints", false);
if (Boolean.TRUE.equals(shouldUpdatePoints) && idUser != null) {
setUser.updateUserPoints(idUser, 1);
}
context.response()
.putHeader("content-type", "application/json: charset=UTF-8")
.end(new JsonObject().put("success", "L'objet à bien été mis à jour").encode());
return;
});
}
public void deleteObject(RoutingContext context){
public void deleteObject(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
if(body== null){
if (body == null) {
context.response()
.setStatusCode(400)
.end(new JsonObject().put("error","Corps de la requête manquant").encode());
.setStatusCode(400)
.end(new JsonObject().put("error", "Corps de la requête manquant").encode());
return;
}
String id = body.getString("id");
databaseService.pool
.preparedQuery("DELETE FROM weather_objects WHERE id=?")
.execute(Tuple.of(Integer.parseInt(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){
.preparedQuery("DELETE FROM weather_objects WHERE id=?")
.execute(Tuple.of(Integer.parseInt(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", "Objet non trouvé").encode());
return;
}
context.response()
.putHeader("content-type","application/json: charset=UTF-8")
.end(new JsonObject().put("success", "L'objet à bien été supprimé").encode());
return;
});
}
context.response()
.putHeader("content-type", "application/json: charset=UTF-8")
.end(new JsonObject().put("success", "L'objet à bien été supprimé").encode());
return;
});
}
public void newObject(RoutingContext context){
public void newObject(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
if(body== null){
if (body == null) {
context.response()
.setStatusCode(400)
.end(new JsonObject().put("error","Corps de la requête manquant").encode());
.setStatusCode(400)
.end(new JsonObject().put("error", "Corps de la requête manquant").encode());
return;
}
// Integer idUser = body.getInteger("idUser");
Integer idUser = 4;
Integer idUser = body.getInteger("proprio_id");
String name = body.getString("nom");
String description = body.getString("description");
String type = body.getString("type");
@ -105,29 +110,31 @@ public class SetObjects {
String batterieType = body.getString("batterieType");
Integer proprio_id = body.getInteger("proprio_id");
databaseService.pool
.preparedQuery("INSERT INTO weather_objects (name,description,type,location,status,type_batterie,proprio_id) VALUES (?,?,?,?,?,?,?)")
.execute(Tuple.of(name,description,type,location,status,batterieType,proprio_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){
.preparedQuery(
"INSERT INTO weather_objects (name,description,type,location,status,type_batterie,proprio_id) VALUES (?,?,?,?,?,?,?)")
.execute(Tuple.of(name, description, type, location, status, batterieType, proprio_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", "Objet non trouvé").encode());
return;
}
if(idUser!=null){
setUser.updateUserPoints(idUser,2);
};
context.response()
.putHeader("content-type","application/json: charset=UTF-8")
.end(new JsonObject().put("success", "L'objet à bien été ajouté").encode());
return;
});
}
if (idUser != null) {
setUser.updateUserPoints(idUser, 2);
}
;
context.response()
.putHeader("content-type", "application/json: charset=UTF-8")
.end(new JsonObject().put("success", "L'objet à bien été ajouté").encode());
return;
});
}
}

View File

@ -41,8 +41,7 @@ public class SetWeatherData {
return;
}
String query = String.format("UPDATE range_data SET %s_min=?, %s_max=? WHERE station_id=?", type, type);
// Integer idUser = body.getInteger("idUser");
Integer idUser = 4;
Integer idUser = body.getInteger("idUser");
databaseService.pool
.preparedQuery(
query)

View File

@ -41,7 +41,6 @@ function App() {
{/* Routes protégées pour tous les utilisateurs connectés */}
<Route path="/sidebar" element={<ProtectedRoute element={<Sidebar />} allowedRoles={['admin', 'complexe', 'user']} />} />
<Route path="/user" element={<ProtectedRoute element={<User />} allowedRoles={['admin', 'complexe', 'user']} />} />
{/* Routes protégées pour les admins uniquement */}
<Route path="/dashboard" element={<ProtectedRoute element={<Dashboard />} allowedRoles={['admin']} />} />
<Route path="/adminobjet" element={<ProtectedRoute element={<AdminObjet />} allowedRoles={['admin']} />} />

View File

@ -4,19 +4,17 @@ import { useAuth } from "./AuthContext"; // Utilisation du contexte d'authentif
function ProtectedRoute({ element, allowedRoles }) {
const { token, user } = useAuth(); // Vérifier si un token existe, donc si l'utilisateur est authentifié
// Si l'utilisateur n'est pas authentifié, redirigez-le vers la page de login
if (!token) {
return <Navigate to="/login" />;
}
// Si l'utilisateur est authentifié mais n'a pas le bon rôle
if (allowedRoles && !allowedRoles.includes(user?.role)) {
return <Navigate to="/" />;
if(user){
if (allowedRoles && !allowedRoles.includes(user?.role)) {
return <Navigate to="/" />;
}
return element;
}
// Si l'utilisateur est authentifié et a les bons rôles, permettez l'accès à la route
return element;
}
export default ProtectedRoute;

View File

@ -1,9 +1,11 @@
import React, {useState} from "react";
import { TriangleAlert,X } from "lucide-react";
import { useAuth } from "../AuthContext";
function AlertInactive({affAlert,setAffAlert}) {
const { user } = useAuth();
return (
(affAlert&&(
(affAlert&&(user?.role!=="user")&&(
<div className="flex flex-col md:flex-row bg-slate-600 w-full md:w-1/2 lg:w-1/3 fixed top-20 right-1 sm:right-4 rounded-lg p-4 md:p-5 items-center gap-4 md:gap-6 shadow-lg opacity-90">
<button onClick={()=>setAffAlert(false)}className="absolute top-2 right-2 text-white hover:text-gray-300">
<X/>

View File

@ -4,7 +4,7 @@ import { Link } from "react-router-dom";
import { useAuth } from "../AuthContext";
function Header() {
const { token, logout } = useAuth();
const { token, user, logout } = useAuth();
const [isMenuOpen, setIsMenuOpen] = useState(false);
return (
@ -44,15 +44,6 @@ function Header() {
À propos
</Link>
</li>
<li>
<Link
to="/gestion"
onClick={() => setIsMenuOpen(false)}
className="text-gray-600 hover:text-indigo-600"
>
Gestion
</Link>
</li>
{!token ? (
<>
<li className="sm:hidden">
@ -78,10 +69,31 @@ function Header() {
</>
) : (
<>
{user?.role === "user" ? (
<li>
<Link
to="/gestionObjets"
onClick={() => setIsMenuOpen(false)}
className="text-gray-600 hover:text-indigo-600"
>
Visualisation
</Link>
</li>
) : (
<li>
<Link
to="/gestion"
onClick={() => setIsMenuOpen(false)}
className="text-gray-600 hover:text-indigo-600"
>
Gestion
</Link>
</li>
)}
<li className="sm:hidden">
<Link
to="/profil"
onClick={()=>setIsMenuOpen(false)}
onClick={() => setIsMenuOpen(false)}
className="flex items-center gap-2 text-gray-600 hover:text-indigo-600"
>
<User size={20} />
@ -91,9 +103,10 @@ function Header() {
</li>
<li className="sm:hidden">
<button
onClick={()=>{
onClick={() => {
logout();
setIsMenuOpen(false)}}
setIsMenuOpen(false);
}}
className="flex items-center gap-2 text-gray-600 hover:text-red-600"
>
<LogOut size={20} />
@ -109,7 +122,7 @@ function Header() {
<div className="hidden sm:flex gap-4 ">
<Link
to="/login"
onClick={()=>setIsMenuOpen(false)}
onClick={() => setIsMenuOpen(false)}
className="hover:text-indigo-600 flex items-center gap-2"
>
<LogIn size={20} />
@ -117,7 +130,7 @@ function Header() {
</Link>
<Link
to="/signup"
onClick={()=>setIsMenuOpen(false)}
onClick={() => setIsMenuOpen(false)}
className="flex items-center gap-2 bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700"
>
<UserPlus size={20} />
@ -128,7 +141,7 @@ function Header() {
<div className="hidden sm:flex gap-4">
<Link
to="/profil"
onClick={()=>setIsMenuOpen(false)}
onClick={() => setIsMenuOpen(false)}
className="flex items-center gap-2 text-gray-600 hover:text-indigo-600"
>
<User size={20} />

View File

@ -1,7 +1,9 @@
import React from "react";
import { Info } from "lucide-react";
import { useAuth } from "../AuthContext";
function InfoObject({ object,defafficherModif }) {
const {user} = useAuth();
return (
<div key={object.id} className="bg-white p-6 rounded-xl min-w-5xl">
<div className="flex align-items gap-6 mb-6">
@ -36,9 +38,11 @@ function InfoObject({ object,defafficherModif }) {
</p>
<p className="text-gray-600">{object.last_update}</p>
</div>
{user?.role!=="user"&&(
<div className="flex items-center gap-4 mb-1">
<a className="text-blue-500 hover:cursor-pointer" onClick={(()=>defafficherModif(true))}>Modifier ces infos</a>
</div>
)}
</div>
);
}

View File

@ -2,8 +2,10 @@ import React, { useState } from "react";
import { Info } from "lucide-react";
import axios from "axios";
import { API_BASE_URL } from "../config";
import {useAuth} from "../AuthContext";
function ModifObject({ object, defafficherModif }) {
const {user}=useAuth();
const [description, setDescription] = useState(object.description || "");
const [type, setType] = useState(object.type || "");
const [location, setLocalisation] = useState(object.location || "");
@ -15,10 +17,12 @@ function ModifObject({ object, defafficherModif }) {
axios
.post(`${API_BASE_URL}/modifObjet`, {
id: object.id,
idUser:user.id,
description,
type,
location,
status,
shouldUpdatePoints:true
})
.then((response) => {
console.log("Modification réussie :", response.data);

View File

@ -4,6 +4,7 @@ import { Bell } from "lucide-react";
import Slider from "@mui/material/Slider";
import { API_BASE_URL } from "../config";
import axios from "axios";
import { useAuth } from "../AuthContext";
const identifiant = new URLSearchParams(window.location.search).get("id");
function ParticularMeteo({
@ -16,6 +17,7 @@ function ParticularMeteo({
setGraphStates,
graphRefs,
}) {
const {user} = useAuth();
const [affRegles, setAffRegles] = useState(false);
const [rangeValue, setRangeValue] = useState([0, 0]);
const [alerteActive, setAlerteActive] = useState(false);
@ -107,6 +109,7 @@ function ParticularMeteo({
</div>
</div>
<div className="flex gap-2">
{user?.role!=="user" && (
<button
onClick={() => {
setAffRegles(!affRegles);
@ -117,7 +120,7 @@ function ParticularMeteo({
size={30}
/>
</button>
)}
<BoutonGraphique
type={type}
graphStates={graphStates}

View File

@ -11,16 +11,19 @@ import {
Binoculars,
BadgePlus,
} from "lucide-react";
import { useAuth } from "../../AuthContext";
function Gestion() {
return (
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-50">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div className="text-center mb-12">
<h2 className="text-4xl font-bold text-gray-900 mb-4">
Bienvenue dans le module <b>Gestion</b>.
</h2>
<p className="text-xl text-gray-600 max-w-3xl mx-auto">
Ce module vous permet de gérer les capteur et stations connectés de France de manière simple et efficace.
Ce module vous permet de gérer les capteurs et stations connectés de France de manière simple et efficace.
</p>
</div>
@ -42,6 +45,7 @@ function Gestion() {
Explorer les objets <ArrowRight size={16} className="ml-2" />
</a>
</div>
<div className="bg-white p-6 rounded-xl shadow-sm hover:shadow-md transition-shadow">
<div className="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-4">
<BadgePlus className="text-indigo-600" size={24} />

View File

@ -3,8 +3,9 @@ import { Search, ArrowRight, RadioTower,Plus } from "lucide-react";
import { useEffect, useState } from "react";
import axios from "axios";
import { API_BASE_URL } from "../../config";
import { useAuth } from "../../AuthContext";
function ObjectManagement() {
const {user} = useAuth();
const [searchQuery, setSearchQuery] = useState("");
const [activeFilter, setActiveFilter] = useState("");
const [objects, setObjects] = useState([]);
@ -34,7 +35,7 @@ function ObjectManagement() {
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div className="text-center mb-12">
<h2 className="text-4xl font-bold text-gray-900 mb-4">
Gestion des <b>Objets</b> connectés.
{(user?.role!=="user")?("Gestion"):("Visualisation")} des <b>Objets</b> connectés.
</h2>
</div>
<div className="max-w-3xl mx-auto mb-12">

View File

@ -12,7 +12,9 @@ import WindInfo from "../../components/WindInfo";
import MeteoInfos from "../../components/MeteoInfos";
import MeteoGraph from "../../components/MeteoGraph";
import BatterieInfo from "../../components/BatterieInfo";
import { useAuth } from "../../AuthContext";
function Objet() {
const {user} =useAuth();
const identifiant = new URLSearchParams(window.location.search).get("id");
const [object, setObject] = useState({});
const [graphStates, setGraphStates] = useState({
@ -28,12 +30,20 @@ function Objet() {
humidity: useRef(null),
wind: useRef(null),
};
useEffect(() => {
axios.get(`${API_BASE_URL}/objet?id=${identifiant}`).then((response) => {
setObject(response.data[0]);
});
}, [identifiant]);
axios
.post(`${API_BASE_URL}/objet`, {
id: identifiant,
userId:user.id,
shouldUpdatePoints:true,
})
.then((response) => {
setObject(response.data[0]);
})
.catch((error) => {
console.error("Erreur lors de la récupération :", error);
});
}, [user]);
return object && object.id ? (
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-50">
<div className=" max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">

View File

@ -11,8 +11,8 @@ function Login() {
password: "",
});
const [error, setError] = useState("");
const { login } = useAuth(); // Utilisation du hook useAuth pour accéder à la fonction login
const navigate = useNavigate(); // Initialisation de useNavigate
const { login } = useAuth();
const navigate = useNavigate();
const handleChange = (e) => {
const { name, value } = e.target;
@ -20,13 +20,12 @@ function Login() {
...prev,
[name]: value,
}));
// Réinitialiser l'erreur lorsque l'utilisateur commence à modifier le formulaire
if (error) setError("");
};
const handleSubmit = async (e) => {
e.preventDefault();
setError(""); // Réinitialiser les erreurs à chaque tentative
setError("");
try {
const response = await axios.post(`${API_BASE_URL}/login`, formData, {
@ -46,7 +45,6 @@ function Login() {
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) {
@ -60,12 +58,10 @@ function Login() {
);
}
} 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.");
}
}

View File

@ -7,6 +7,7 @@ import axios from "axios";
function Profil() {
const [userData, setUserData] = useState({});
const { user } = useAuth();
useEffect(() => {
if (user) {