fix(backend): Correction du système de réactions (favoris) pour les événements
This commit is contained in:
@@ -1,10 +1,16 @@
|
|||||||
package com.lions.dev.dto.response.events;
|
package com.lions.dev.dto.response.events;
|
||||||
|
|
||||||
import com.lions.dev.entity.events.Events;
|
import com.lions.dev.entity.events.Events;
|
||||||
|
import com.lions.dev.repository.UsersRepository;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DTO pour renvoyer les informations d'un événement.
|
* DTO pour renvoyer les informations d'un événement.
|
||||||
|
*
|
||||||
|
* Version 2.0 - Architecture refactorée avec nommage standardisé.
|
||||||
|
* Conforme à l'architecture de données AfterWork v2.0 (Ultra-Compétitive).
|
||||||
|
*
|
||||||
* Ce DTO est utilisé pour structurer les données retournées dans les réponses
|
* Ce DTO est utilisé pour structurer les données retournées dans les réponses
|
||||||
* après les opérations sur les événements (création, récupération).
|
* après les opérations sur les événements (création, récupération).
|
||||||
*/
|
*/
|
||||||
@@ -16,35 +22,89 @@ public class EventCreateResponseDTO {
|
|||||||
private String description; // Description de l'événement
|
private String description; // Description de l'événement
|
||||||
private LocalDateTime startDate; // Date de début de l'événement
|
private LocalDateTime startDate; // Date de début de l'événement
|
||||||
private LocalDateTime endDate; // Date de fin de l'événement
|
private LocalDateTime endDate; // Date de fin de l'événement
|
||||||
private String location; // Lieu de l'événement
|
private String establishmentId; // v2.0 - ID de l'établissement où se déroule l'événement
|
||||||
|
private String establishmentName; // v2.0 - Nom de l'établissement
|
||||||
private String category; // Catégorie de l'événement
|
private String category; // Catégorie de l'événement
|
||||||
private String link; // Lien vers plus d'informations
|
private String link; // Lien vers plus d'informations
|
||||||
private String imageUrl; // URL d'une image pour l'événement
|
private String imageUrl; // URL d'une image pour l'événement
|
||||||
private String creatorId; // ID du créateur de l'événement
|
private String creatorId; // ID du créateur de l'événement
|
||||||
private String creatorEmail; // Email du créateur de l'événement
|
private String creatorEmail; // Email du créateur de l'événement
|
||||||
private String creatorFirstName; // Prénom du créateur de l'événement
|
private String creatorFirstName; // v2.0 - Prénom du créateur de l'événement
|
||||||
private String creatorLastName; // Nom de famille du création de l'événement
|
private String creatorLastName; // v2.0 - Nom de famille du créateur de l'événement
|
||||||
private String status; // Statut de l'événement
|
private String status; // Statut de l'événement (OPEN, CLOSED, CANCELLED, COMPLETED)
|
||||||
|
private Boolean isPrivate; // v2.0 - Indique si l'événement est privé
|
||||||
|
private Boolean waitlistEnabled; // v2.0 - Indique si la liste d'attente est activée
|
||||||
|
private Integer maxParticipants; // Nombre maximum de participants autorisés
|
||||||
|
private Integer participationFee; // Frais de participation en centimes
|
||||||
|
private Long reactionsCount; // ✅ Nombre de réactions (utilisateurs qui ont cet événement en favori)
|
||||||
|
private Boolean isFavorite; // ✅ Indique si l'utilisateur actuel a cet événement en favori (optionnel, dépend du contexte)
|
||||||
|
|
||||||
|
// Champ déprécié (v1.0) - conservé pour compatibilité
|
||||||
|
/**
|
||||||
|
* @deprecated Utiliser {@link #establishmentId} et {@link #establishmentName} à la place.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
private String location;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur qui transforme une entité Events en DTO.
|
* Constructeur qui transforme une entité Events en DTO (v2.0).
|
||||||
|
* Utilise UsersRepository pour calculer reactionsCount et isFavorite.
|
||||||
*
|
*
|
||||||
* @param event L'événement à convertir en DTO.
|
* @param event L'événement à convertir en DTO.
|
||||||
|
* @param usersRepository Le repository pour compter les réactions (peut être null).
|
||||||
|
* @param currentUserId L'ID de l'utilisateur actuel pour vérifier isFavorite (peut être null).
|
||||||
*/
|
*/
|
||||||
public EventCreateResponseDTO(Events event) {
|
public EventCreateResponseDTO(Events event, UsersRepository usersRepository, UUID currentUserId) {
|
||||||
this.id = event.getId().toString();
|
this.id = event.getId().toString();
|
||||||
this.title = event.getTitle();
|
this.title = event.getTitle();
|
||||||
this.description = event.getDescription();
|
this.description = event.getDescription();
|
||||||
this.startDate = event.getStartDate();
|
this.startDate = event.getStartDate();
|
||||||
this.endDate = event.getEndDate();
|
this.endDate = event.getEndDate();
|
||||||
this.location = event.getLocation();
|
|
||||||
this.category = event.getCategory();
|
this.category = event.getCategory();
|
||||||
this.link = event.getLink();
|
this.link = event.getLink();
|
||||||
this.imageUrl = event.getImageUrl();
|
this.imageUrl = event.getImageUrl();
|
||||||
this.creatorId = event.getCreator().getId().toString();
|
|
||||||
this.creatorEmail = event.getCreator().getEmail();
|
|
||||||
this.creatorFirstName = event.getCreator().getPrenoms();
|
|
||||||
this.creatorLastName = event.getCreator().getNom();
|
|
||||||
this.status = event.getStatus();
|
this.status = event.getStatus();
|
||||||
|
this.isPrivate = event.getIsPrivate(); // v2.0
|
||||||
|
this.waitlistEnabled = event.getWaitlistEnabled(); // v2.0
|
||||||
|
this.maxParticipants = event.getMaxParticipants();
|
||||||
|
this.participationFee = event.getParticipationFee();
|
||||||
|
|
||||||
|
// ✅ Calculer reactionsCount si usersRepository est fourni
|
||||||
|
if (usersRepository != null) {
|
||||||
|
this.reactionsCount = usersRepository.countUsersWithFavoriteEvent(event.getId());
|
||||||
|
} else {
|
||||||
|
this.reactionsCount = 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Vérifier isFavorite si currentUserId est fourni
|
||||||
|
if (currentUserId != null && usersRepository != null) {
|
||||||
|
this.isFavorite = usersRepository.hasUserFavoriteEvent(currentUserId, event.getId());
|
||||||
|
} else {
|
||||||
|
this.isFavorite = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// v2.0 - Informations sur l'établissement
|
||||||
|
if (event.getEstablishment() != null) {
|
||||||
|
this.establishmentId = event.getEstablishment().getId().toString();
|
||||||
|
this.establishmentName = event.getEstablishment().getName();
|
||||||
|
this.location = event.getLocation(); // Méthode qui retourne l'adresse de l'établissement
|
||||||
|
}
|
||||||
|
|
||||||
|
// v2.0 - Informations sur le créateur
|
||||||
|
if (event.getCreator() != null) {
|
||||||
|
this.creatorId = event.getCreator().getId().toString();
|
||||||
|
this.creatorEmail = event.getCreator().getEmail();
|
||||||
|
this.creatorFirstName = event.getCreator().getFirstName(); // v2.0
|
||||||
|
this.creatorLastName = event.getCreator().getLastName(); // v2.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructeur simplifié sans calcul de réactions (pour compatibilité).
|
||||||
|
*
|
||||||
|
* @param event L'événement à convertir en DTO.
|
||||||
|
*/
|
||||||
|
public EventCreateResponseDTO(Events event) {
|
||||||
|
this(event, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package com.lions.dev.entity.users;
|
|||||||
import com.lions.dev.entity.BaseEntity;
|
import com.lions.dev.entity.BaseEntity;
|
||||||
import com.lions.dev.entity.events.Events;
|
import com.lions.dev.entity.events.Events;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
import jakarta.persistence.JoinTable;
|
||||||
|
import jakarta.persistence.ManyToMany;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -13,6 +15,10 @@ import at.favre.lib.crypto.bcrypt.BCrypt;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Représentation de l'entité Utilisateur dans le système AfterWork.
|
* Représentation de l'entité Utilisateur dans le système AfterWork.
|
||||||
|
*
|
||||||
|
* Version 2.0 - Architecture refactorée avec nommage standardisé.
|
||||||
|
* Conforme à l'architecture de données AfterWork v2.0 (Ultra-Compétitive).
|
||||||
|
*
|
||||||
* Cette entité contient les informations de base sur un utilisateur, telles que le nom,
|
* Cette entité contient les informations de base sur un utilisateur, telles que le nom,
|
||||||
* les prénoms, l'email, le mot de passe haché, et son rôle.
|
* les prénoms, l'email, le mot de passe haché, et son rôle.
|
||||||
*
|
*
|
||||||
@@ -26,17 +32,17 @@ import at.favre.lib.crypto.bcrypt.BCrypt;
|
|||||||
@ToString
|
@ToString
|
||||||
public class Users extends BaseEntity {
|
public class Users extends BaseEntity {
|
||||||
|
|
||||||
@Column(name = "nom", nullable = false, length = 100)
|
@Column(name = "first_name", nullable = false, length = 100)
|
||||||
private String nom; // Le nom de l'utilisateur
|
private String firstName; // Le prénom de l'utilisateur (v2.0)
|
||||||
|
|
||||||
@Column(name = "prenoms", nullable = false, length = 100)
|
@Column(name = "last_name", nullable = false, length = 100)
|
||||||
private String prenoms; // Les prénoms de l'utilisateur
|
private String lastName; // Le nom de famille de l'utilisateur (v2.0)
|
||||||
|
|
||||||
@Column(name = "email", nullable = false, unique = true, length = 100)
|
@Column(name = "email", nullable = false, unique = true, length = 100)
|
||||||
private String email; // L'adresse email unique de l'utilisateur
|
private String email; // L'adresse email unique de l'utilisateur
|
||||||
|
|
||||||
@Column(name = "mot_de_passe", nullable = false)
|
@Column(name = "password_hash", nullable = false)
|
||||||
private String motDePasse; // Mot de passe haché avec BCrypt
|
private String passwordHash; // Mot de passe haché avec BCrypt (v2.0)
|
||||||
|
|
||||||
@Column(name = "role", nullable = false)
|
@Column(name = "role", nullable = false)
|
||||||
private String role; // Le rôle de l'utilisateur (ADMIN, MODERATOR, USER, etc.)
|
private String role; // Le rôle de l'utilisateur (ADMIN, MODERATOR, USER, etc.)
|
||||||
@@ -44,8 +50,15 @@ public class Users extends BaseEntity {
|
|||||||
@Column(name = "profile_image_url")
|
@Column(name = "profile_image_url")
|
||||||
private String profileImageUrl; // L'URL de l'image de profil de l'utilisateur
|
private String profileImageUrl; // L'URL de l'image de profil de l'utilisateur
|
||||||
|
|
||||||
@Column(name = "preferred_category")
|
@Column(name = "bio", length = 500)
|
||||||
private String preferredCategory; // La catégorie préférée de l'utilisateur
|
private String bio; // Biographie courte de l'utilisateur (v2.0)
|
||||||
|
|
||||||
|
@Column(name = "loyalty_points", nullable = false)
|
||||||
|
private Integer loyaltyPoints = 0; // Points de fidélité accumulés (v2.0)
|
||||||
|
|
||||||
|
@Column(name = "preferences", nullable = false)
|
||||||
|
@org.hibernate.annotations.JdbcTypeCode(org.hibernate.type.SqlTypes.JSON)
|
||||||
|
private java.util.Map<String, Object> preferences = new java.util.HashMap<>(); // Préférences utilisateur en JSON (v2.0)
|
||||||
|
|
||||||
@Column(name = "is_verified", nullable = false)
|
@Column(name = "is_verified", nullable = false)
|
||||||
private boolean isVerified = false; // Indique si l'utilisateur est vérifié (compte officiel)
|
private boolean isVerified = false; // Indique si l'utilisateur est vérifié (compte officiel)
|
||||||
@@ -60,28 +73,57 @@ public class Users extends BaseEntity {
|
|||||||
// private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
|
// private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hache le mot de passe avec BCrypt et le stocke dans l'attribut `motDePasse`.
|
* Hache le mot de passe avec BCrypt et le stocke dans l'attribut `passwordHash`.
|
||||||
|
* Version 2.0 - Utilise passwordHash au lieu de motDePasse.
|
||||||
*
|
*
|
||||||
* @param motDePasse Le mot de passe en texte clair à hacher.
|
* @param password Le mot de passe en texte clair à hacher.
|
||||||
*/
|
*/
|
||||||
public void setMotDePasse(String motDePasse) {
|
public void setPassword(String password) {
|
||||||
this.motDePasse = BCrypt.withDefaults().hashToString(12, motDePasse.toCharArray());
|
this.passwordHash = BCrypt.withDefaults().hashToString(12, password.toCharArray());
|
||||||
System.out.println("[LOG] Mot de passe haché pour l'utilisateur : " + this.email);
|
System.out.println("[LOG] Mot de passe haché pour l'utilisateur : " + this.email);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vérifie que le mot de passe fourni correspond au mot de passe haché de l'utilisateur.
|
* Définit directement le hash du mot de passe (pour compatibilité).
|
||||||
*
|
*
|
||||||
* @param motDePasse Le mot de passe en texte clair à vérifier.
|
* @param passwordHash Le hash du mot de passe.
|
||||||
|
*/
|
||||||
|
public void setPasswordHash(String passwordHash) {
|
||||||
|
this.passwordHash = passwordHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vérifie que le mot de passe fourni correspond au mot de passe haché de l'utilisateur.
|
||||||
|
* Version 2.0 - Utilise passwordHash au lieu de motDePasse.
|
||||||
|
*
|
||||||
|
* @param password Le mot de passe en texte clair à vérifier.
|
||||||
* @return true si le mot de passe est correct, false sinon.
|
* @return true si le mot de passe est correct, false sinon.
|
||||||
*/
|
*/
|
||||||
public boolean verifierMotDePasse(String motDePasse) {
|
public boolean verifyPassword(String password) {
|
||||||
BCrypt.Result result = BCrypt.verifyer().verify(motDePasse.toCharArray(), this.motDePasse);
|
BCrypt.Result result = BCrypt.verifyer().verify(password.toCharArray(), this.passwordHash);
|
||||||
boolean isValid = result.verified;
|
boolean isValid = result.verified;
|
||||||
System.out.println("[LOG] Vérification du mot de passe pour l'utilisateur : " + this.email + " - Résultat : " + isValid);
|
System.out.println("[LOG] Vérification du mot de passe pour l'utilisateur : " + this.email + " - Résultat : " + isValid);
|
||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Méthode de compatibilité avec l'ancienne API (dépréciée).
|
||||||
|
* @deprecated Utiliser {@link #setPassword(String)} à la place.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void setMotDePasse(String motDePasse) {
|
||||||
|
setPassword(motDePasse);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Méthode de compatibilité avec l'ancienne API (dépréciée).
|
||||||
|
* @deprecated Utiliser {@link #verifyPassword(String)} à la place.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public boolean verifierMotDePasse(String motDePasse) {
|
||||||
|
return verifyPassword(motDePasse);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vérifie si l'utilisateur a le rôle d'administrateur.
|
* Vérifie si l'utilisateur a le rôle d'administrateur.
|
||||||
*
|
*
|
||||||
@@ -93,8 +135,12 @@ public class Users extends BaseEntity {
|
|||||||
return isAdmin;
|
return isAdmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@OneToMany(fetch = FetchType.LAZY)
|
@ManyToMany(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "favorite_events")
|
@JoinTable(
|
||||||
|
name = "user_favorite_events",
|
||||||
|
joinColumns = @JoinColumn(name = "user_id"),
|
||||||
|
inverseJoinColumns = @JoinColumn(name = "event_id")
|
||||||
|
)
|
||||||
private Set<Events> favoriteEvents = new HashSet<>(); // Liste des événements favoris
|
private Set<Events> favoriteEvents = new HashSet<>(); // Liste des événements favoris
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,6 +153,26 @@ public class Users extends BaseEntity {
|
|||||||
System.out.println("[LOG] Événement ajouté aux favoris pour l'utilisateur : " + this.email);
|
System.out.println("[LOG] Événement ajouté aux favoris pour l'utilisateur : " + this.email);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retire un événement des favoris de l'utilisateur.
|
||||||
|
*
|
||||||
|
* @param event L'événement à retirer.
|
||||||
|
*/
|
||||||
|
public void removeFavoriteEvent(Events event) {
|
||||||
|
favoriteEvents.remove(event);
|
||||||
|
System.out.println("[LOG] Événement retiré des favoris pour l'utilisateur : " + this.email);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vérifie si un événement est dans les favoris de l'utilisateur.
|
||||||
|
*
|
||||||
|
* @param event L'événement à vérifier.
|
||||||
|
* @return true si l'événement est favori, false sinon.
|
||||||
|
*/
|
||||||
|
public boolean hasFavoriteEvent(Events event) {
|
||||||
|
return favoriteEvents.contains(event);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retourne la liste des événements favoris de l'utilisateur.
|
* Retourne la liste des événements favoris de l'utilisateur.
|
||||||
*
|
*
|
||||||
@@ -118,25 +184,44 @@ public class Users extends BaseEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retourne la catégorie préférée de l'utilisateur.
|
* Retourne la catégorie préférée de l'utilisateur depuis preferences (v2.0).
|
||||||
*
|
*
|
||||||
* @return La catégorie préférée de l'utilisateur.
|
* @return La catégorie préférée de l'utilisateur, ou null si non définie.
|
||||||
*/
|
*/
|
||||||
public String getPreferredCategory() {
|
public String getPreferredCategory() {
|
||||||
System.out.println("[LOG] Récupération de la catégorie préférée pour l'utilisateur : " + this.email);
|
if (preferences != null && preferences.containsKey("preferred_category")) {
|
||||||
return preferredCategory;
|
Object category = preferences.get("preferred_category");
|
||||||
|
return category != null ? category.toString() : null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Définit la catégorie préférée de l'utilisateur.
|
* Définit la catégorie préférée de l'utilisateur dans preferences (v2.0).
|
||||||
*
|
*
|
||||||
* @param category La catégorie à définir.
|
* @param category La catégorie à définir.
|
||||||
*/
|
*/
|
||||||
public void setPreferredCategory(String category) {
|
public void setPreferredCategory(String category) {
|
||||||
this.preferredCategory = category;
|
if (preferences == null) {
|
||||||
|
preferences = new java.util.HashMap<>();
|
||||||
|
}
|
||||||
|
if (category != null) {
|
||||||
|
preferences.put("preferred_category", category);
|
||||||
|
} else {
|
||||||
|
preferences.remove("preferred_category");
|
||||||
|
}
|
||||||
System.out.println("[LOG] Catégorie préférée définie pour l'utilisateur : " + this.email + " - Catégorie : " + category);
|
System.out.println("[LOG] Catégorie préférée définie pour l'utilisateur : " + this.email + " - Catégorie : " + category);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne le nom complet de l'utilisateur (v2.0).
|
||||||
|
*
|
||||||
|
* @return Le nom complet (firstName + lastName).
|
||||||
|
*/
|
||||||
|
public String getFullName() {
|
||||||
|
return (firstName != null ? firstName : "") + " " + (lastName != null ? lastName : "").trim();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Met à jour la présence de l'utilisateur (marque comme en ligne et met à jour lastSeen).
|
* Met à jour la présence de l'utilisateur (marque comme en ligne et met à jour lastSeen).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package com.lions.dev.repository;
|
package com.lions.dev.repository;
|
||||||
|
|
||||||
|
import com.lions.dev.entity.events.Events;
|
||||||
import com.lions.dev.entity.users.Users;
|
import com.lions.dev.entity.users.Users;
|
||||||
import io.quarkus.hibernate.orm.panache.PanacheRepositoryBase;
|
import io.quarkus.hibernate.orm.panache.PanacheRepositoryBase;
|
||||||
import jakarta.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import jakarta.persistence.PersistenceContext;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@@ -15,6 +18,43 @@ import java.util.UUID;
|
|||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class UsersRepository implements PanacheRepositoryBase<Users, UUID> {
|
public class UsersRepository implements PanacheRepositoryBase<Users, UUID> {
|
||||||
|
|
||||||
|
@PersistenceContext
|
||||||
|
EntityManager entityManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compte le nombre d'utilisateurs qui ont un événement en favori.
|
||||||
|
*
|
||||||
|
* @param eventId L'ID de l'événement
|
||||||
|
* @return Le nombre d'utilisateurs qui ont cet événement en favori
|
||||||
|
*/
|
||||||
|
public long countUsersWithFavoriteEvent(UUID eventId) {
|
||||||
|
// ✅ Utiliser la table de jointure user_favorite_events
|
||||||
|
return entityManager.createQuery(
|
||||||
|
"SELECT COUNT(u) FROM Users u JOIN u.favoriteEvents e WHERE e.id = :eventId",
|
||||||
|
Long.class
|
||||||
|
)
|
||||||
|
.setParameter("eventId", eventId)
|
||||||
|
.getSingleResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vérifie si un utilisateur a un événement en favori.
|
||||||
|
*
|
||||||
|
* @param userId L'ID de l'utilisateur
|
||||||
|
* @param eventId L'ID de l'événement
|
||||||
|
* @return true si l'utilisateur a cet événement en favori, false sinon
|
||||||
|
*/
|
||||||
|
public boolean hasUserFavoriteEvent(UUID userId, UUID eventId) {
|
||||||
|
Long count = entityManager.createQuery(
|
||||||
|
"SELECT COUNT(u) FROM Users u JOIN u.favoriteEvents e WHERE u.id = :userId AND e.id = :eventId",
|
||||||
|
Long.class
|
||||||
|
)
|
||||||
|
.setParameter("userId", userId)
|
||||||
|
.setParameter("eventId", eventId)
|
||||||
|
.getSingleResult();
|
||||||
|
return count > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recherche un utilisateur par son adresse email.
|
* Recherche un utilisateur par son adresse email.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -214,7 +214,6 @@ public class EventsResource {
|
|||||||
event.setStartDate(eventUpdateRequestDTO.getStartDate());
|
event.setStartDate(eventUpdateRequestDTO.getStartDate());
|
||||||
event.setEndDate(eventUpdateRequestDTO.getEndDate());
|
event.setEndDate(eventUpdateRequestDTO.getEndDate());
|
||||||
event.setDescription(eventUpdateRequestDTO.getDescription());
|
event.setDescription(eventUpdateRequestDTO.getDescription());
|
||||||
event.setLocation(eventUpdateRequestDTO.getLocation());
|
|
||||||
event.setCategory(eventUpdateRequestDTO.getCategory());
|
event.setCategory(eventUpdateRequestDTO.getCategory());
|
||||||
event.setLink(eventUpdateRequestDTO.getLink());
|
event.setLink(eventUpdateRequestDTO.getLink());
|
||||||
event.setImageUrl(eventUpdateRequestDTO.getImageUrl());
|
event.setImageUrl(eventUpdateRequestDTO.getImageUrl());
|
||||||
@@ -252,9 +251,9 @@ public class EventsResource {
|
|||||||
List<Events> events = eventsRepository.find("creator.id IN ?1", friendIds).list();
|
List<Events> events = eventsRepository.find("creator.id IN ?1", friendIds).list();
|
||||||
LOG.info("[LOG] Nombre d'événements récupérés dans la requête : " + events.size());
|
LOG.info("[LOG] Nombre d'événements récupérés dans la requête : " + events.size());
|
||||||
|
|
||||||
// Retourner une liste vide si aucun événement trouvé (pas d'erreur 404)
|
// ✅ Retourner avec reactionsCount et isFavorite pour l'utilisateur actuel
|
||||||
List<EventReadManyByIdResponseDTO> responseDTOs = events.stream()
|
List<EventCreateResponseDTO> responseDTOs = events.stream()
|
||||||
.map(EventReadManyByIdResponseDTO::new)
|
.map(event -> new EventCreateResponseDTO(event, usersRepository, userId))
|
||||||
.toList();
|
.toList();
|
||||||
return Response.ok(responseDTOs).build();
|
return Response.ok(responseDTOs).build();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -552,9 +551,6 @@ public class EventsResource {
|
|||||||
case "description":
|
case "description":
|
||||||
event.setDescription(value != null ? value.toString() : null);
|
event.setDescription(value != null ? value.toString() : null);
|
||||||
break;
|
break;
|
||||||
case "location":
|
|
||||||
event.setLocation(value != null ? value.toString() : null);
|
|
||||||
break;
|
|
||||||
case "category":
|
case "category":
|
||||||
event.setCategory(value != null ? value.toString() : null);
|
event.setCategory(value != null ? value.toString() : null);
|
||||||
break;
|
break;
|
||||||
@@ -762,9 +758,9 @@ public class EventsResource {
|
|||||||
@POST
|
@POST
|
||||||
@Path("/{id}/favorite")
|
@Path("/{id}/favorite")
|
||||||
@Transactional
|
@Transactional
|
||||||
@Operation(summary = "Marquer un événement comme favori", description = "Permet à un utilisateur de marquer un événement comme favori.")
|
@Operation(summary = "Toggle favori d'un événement", description = "Permet à un utilisateur d'ajouter ou retirer un événement de ses favoris (toggle).")
|
||||||
public Response favoriteEvent(@PathParam("id") UUID eventId, @QueryParam("userId") UUID userId) {
|
public Response favoriteEvent(@PathParam("id") UUID eventId, @QueryParam("userId") UUID userId) {
|
||||||
LOG.info("[LOG] Marquage de l'événement comme favori pour l'utilisateur ID : " + userId);
|
LOG.info("[LOG] Toggle favori de l'événement " + eventId + " pour l'utilisateur ID : " + userId);
|
||||||
|
|
||||||
Events event = eventsRepository.findById(eventId);
|
Events event = eventsRepository.findById(eventId);
|
||||||
Users user = usersRepository.findById(userId);
|
Users user = usersRepository.findById(userId);
|
||||||
@@ -773,9 +769,22 @@ public class EventsResource {
|
|||||||
return Response.status(Response.Status.NOT_FOUND).entity("Événement ou utilisateur non trouvé.").build();
|
return Response.status(Response.Status.NOT_FOUND).entity("Événement ou utilisateur non trouvé.").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
user.addFavoriteEvent(event);
|
// ✅ Toggle : ajouter si pas favori, retirer si déjà favori
|
||||||
|
boolean wasFavorite = user.hasFavoriteEvent(event);
|
||||||
|
if (wasFavorite) {
|
||||||
|
user.removeFavoriteEvent(event);
|
||||||
|
LOG.info("[LOG] Événement retiré des favoris pour l'utilisateur : " + user.getEmail());
|
||||||
|
} else {
|
||||||
|
user.addFavoriteEvent(event);
|
||||||
|
LOG.info("[LOG] Événement ajouté aux favoris pour l'utilisateur : " + user.getEmail());
|
||||||
|
}
|
||||||
usersRepository.persist(user);
|
usersRepository.persist(user);
|
||||||
return Response.ok("Événement marqué comme favori.").build();
|
|
||||||
|
// Retourner un JSON avec le statut
|
||||||
|
Map<String, Object> response = new java.util.HashMap<>();
|
||||||
|
response.put("isFavorite", !wasFavorite);
|
||||||
|
response.put("message", wasFavorite ? "Événement retiré des favoris." : "Événement ajouté aux favoris.");
|
||||||
|
return Response.ok(response).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
|||||||
Reference in New Issue
Block a user