This commit is contained in:
mepiphana2023
2024-04-25 15:40:41 +02:00
parent 8ebddc6d18
commit 8b252e7038
12 changed files with 202 additions and 144 deletions

View File

@@ -4,6 +4,8 @@ import com.google.i18n.phonenumbers.PhoneNumberUtil;
import org.apache.commons.validator.routines.EmailValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.filter.RequestContextFilter;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import org.springframework.context.annotation.Bean;
@@ -41,4 +43,14 @@ public class WebConfig {
return PhoneNumberUtil.getInstance();
}
@Bean
public RequestContextListener requestContextListener() {
return new RequestContextListener();
}
@Bean
public RequestContextFilter requestContextFilter() {
return new RequestContextFilter();
}
}

View File

@@ -44,8 +44,9 @@ public class AccueilController {
}
@GetMapping({"/", "/accueil"})
public String viewAccueil(@AuthenticationPrincipal UserDetails userDetails, @RequestParam(required = false) String searchTitle, @RequestParam(required = false) Integer searchCategory, Model model, @RequestParam(value = "venteOption", required = false) String[] venteOptions, @RequestParam(value = "achatOption", required = false) String[] achatOptions) {
public String viewAccueil(HttpServletRequest request, @AuthenticationPrincipal UserDetails userDetails, @RequestParam(required = false) String searchTitle, @RequestParam(required = false) Integer searchCategory, Model model, @RequestParam(value = "venteOption", required = false) String[] venteOptions, @RequestParam(value = "achatOption", required = false) String[] achatOptions) {
model.addAttribute("categories", categorieService.findAllCategories());
model.addAttribute("requestURI", request.getRequestURI());
SearchArticleCritere critere = new SearchArticleCritere();
critere.setNoCategorie(searchCategory);
critere.setTitle(searchTitle);
@@ -59,10 +60,10 @@ public class AccueilController {
}
@PostMapping("/accueil")
public String handleSearch(@AuthenticationPrincipal UserDetails userDetails, @RequestParam("searchTitle") String searchTitle, @RequestParam(value = "searchCategory", required = false) Integer searchCategory, Model model, @RequestParam(value = "venteOption", required = false) String[] venteOptions, @RequestParam(value = "achatOption", required = false) String[] achatOptions ) {
public String handleSearch(HttpServletRequest request, @AuthenticationPrincipal UserDetails userDetails, @RequestParam("searchTitle") String searchTitle, @RequestParam(value = "searchCategory", required = false) Integer searchCategory, Model model, @RequestParam(value = "venteOption", required = false) String[] venteOptions, @RequestParam(value = "achatOption", required = false) String[] achatOptions ) {
return viewAccueil(userDetails, searchTitle, searchCategory, model, venteOptions, achatOptions);
return viewAccueil(request, userDetails, searchTitle, searchCategory, model, venteOptions, achatOptions);
}

View File

@@ -8,6 +8,7 @@ import fr.eni.enchere.bo.Article;
import fr.eni.enchere.bo.Categorie;
import fr.eni.enchere.bo.Retrait;
import fr.eni.enchere.bo.UserProfil;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -70,10 +71,11 @@ public class ArticleController {
//Création d'un article
@GetMapping("/new")
public String newArticleForm(Model model) {
public String newArticleForm(HttpServletRequest request, Model model) {
model.addAttribute("categories", categorieService.findAllCategories());
model.addAttribute("article", new Article());
model.addAttribute("retrait", new Retrait());
model.addAttribute("requestURI", request.getRequestURI());
//Récupérer l'utilisateur pour set le retrait à son adresse par defaut
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = authentication.getName();

View File

@@ -21,11 +21,17 @@ public class LanguageController {
}
@GetMapping("/change-language")
public String changeLanguage(HttpServletRequest request, HttpServletResponse response, @RequestParam("lang") String lang) {
public String changeLanguage(HttpServletRequest request, HttpServletResponse response, Locale locale) {
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
System.out.println(locale.getLanguage());
if (localeResolver != null) {
localeResolver.setLocale(request, response, Locale.forLanguageTag(lang));
if (locale.getLanguage().equals("en")) {
localeResolver.setLocale(request, response, Locale.FRENCH); // Changer la langue en français
} else {
localeResolver.setLocale(request, response, Locale.ENGLISH); // Changer la langue en anglais
}
}
return "redirect:/";
}
}

View File

@@ -1,6 +1,7 @@
home.search.title = Search for an item by name...
home.search.cat = All categories
home.search.button = Search
home.button.lang = Changer en Fran\u00E7ais
profil.title = My Profile
profil.button = Edit

View File

@@ -1,6 +1,7 @@
home.search.title = Rechercher un article par nom...
home.search.cat = Toutes les cat\u00e9gories
home.search.button = Recherche
home.button.lang = Switch to English
profil.title = Mon profile
profil.button = Modifier
@@ -30,16 +31,17 @@ login.forgotpassword = Mot de passe oubli\u00e9
login.connection = Connexion
login.makecompte = Cr\u00e9er un compte
register.title = Mon profile
register.button = Modifier
register.pseudo = Pseudo:
register.surname = Pr\u00e9nom:
register.name = Nom:
register.email = Email:
register.phone = T\u00e9l\u00e9phone:
register.street = Rue:
register.postal = Code postal:
register.city = Ville:
register.credit = Cr\u00e9dits:
register.make = cr\u00e9er
register.cancel = annuler
register.title = Inscription
register.pseudo.label = Pseudo:
register.prenom.label = Prénom:
register.nom.label = Nom:
register.email.label = Email:
register.telephone.label = Téléphone:
register.rue.label = Rue:
register.code_postal.label = Code postal:
register.ville.label = Ville:
register.password.label = Mot de passe:
register.confirm_password.label = Confirmation du mot de passe:
register.submit_button = Créer
register.cancel_button = Annuler

View File

@@ -2,4 +2,32 @@
display: flex;
align-items: center;
height: 100%;
}
}
.text-decoration-none {
text-decoration: none !important;
}
.text-dark {
color: black !important;
}
.card-article {
transition: transform 0.3s ease;
}
.card-article:hover {
transform: scale(1.05);
}
/* Positionne le bouton de langue en haut à droite */
#languageButton {
margin-right: 20px; /* Espacement du bouton par rapport à la droite */
}
/* Réduit l'espace entre le bouton de langue et les autres éléments de la barre de navigation */
.navbar-nav {
margin-right: 10px; /* Espacement entre le bouton de langue et les autres éléments de la barre de navigation */
}
.navbar-nav .nav-item.active .nav-link {
color: white; /* Couleur du texte pour le lien actif */
}

View File

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -15,7 +15,7 @@
<form th:action="@{/accueil}" method="post" class="mb-3">
<div class="row">
<!-- Colonne pour la zone de recherche et Achats/Ventes -->
<div class="col-md-6">
<div class="col-md-6" th:if="${#authorization.expression('hasRole(''MEMBRE'')')}">
<!-- Zone de recherche -->
<div class="mb-3">
<input type="text" class="form-control" th:attr="placeholder=#{home.search.title}" name="searchTitle">
@@ -27,11 +27,28 @@
</select>
</div>
<!-- Achats et Ventes -->
</div>
<div class="col-md-12" th:if="${#authentication.principal == 'anonymousUser'}">
<!-- Zone de recherche -->
<div class="mb-3">
<input type="text" class="form-control" th:attr="placeholder=#{home.search.title}" name="searchTitle">
</div>
<div class="mb-4">
<select class="form-control" name="searchCategory">
<option value="" th:text="#{home.search.cat}"></option>
<option th:each="category : ${categories}" th:value="${category.id}" th:text="${category.libelle}"></option>
</select>
</div>
<!-- Achats et Ventes -->
</div>
<!-- Colonne pour le bouton de recherche -->
<div class="col-md-6 d-flex justify-content-center align-items-center"th:if="${#authorization.expression('hasRole(''MEMBRE'')')}">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h5 class="card-title">Achats</h5>
<div class="mb-3">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="typeTransaction" id="achats" value="achats" onchange="toggleCheckbox(this.value)">
@@ -55,12 +72,11 @@
</div>
</div>
<div class="col-md-6">
<h5 class="card-title">Ventes</h5>
<!-- Boutons radio pour Ventes -->
<div class="mb-3">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="typeTransaction" id="ventes" value="ventes" onchange="toggleCheckbox(this.value)">
<label class="form-check-label" for="ventes">Ventes</label>
<label class="form-check-label" for="ventes">Mes Ventes</label>
</div>
</div>
<!-- Checkboxes pour Ventes -->
@@ -80,12 +96,19 @@
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Colonne pour le bouton de recherche -->
<div class="col-md-6 d-flex justify-content-center align-items-center">
<button type="submit" style="font-size: 2em;" class="btn btn-primary btn-lg">Recherche</button>
</div>
<div class="row">
<br>
</div>
<div class="row">
<div class="col-md-12 col-12 d-flex justify-content-center align-items-center">
<button type="submit" style="font-size: 1em;" class="btn btn-primary btn-lg w-100">Recherche</button>
</div>
</div>
</form>
@@ -94,18 +117,18 @@
</div>
</div>
<div class="row">
<div th:each="article : ${articles}" class="col-md-6 mb-4">
<a th:href="@{/article/show(id=${article.id})}">
<div class="card shadow-sm h-100">
<div th:each="article : ${articles}" class="col-md-6 mb-4" >
<a th:href="@{/article/show(id=${article.id})}" >
<div class="card shadow-sm h-100 ">
<div class="row g-0">
<div class="col-md-4 d-flex align-items-center justify-content-center p-3">
<img th:src="${'images/articles/' + article.id + '.jpg'}" alt="Image de l'article" class="img-fluid rounded">
</div>
<div class="col-md-8">
<div class="card-body d-flex flex-column">
<h5 class="card-title" th:text="${article.nom}">Nom de l'article</h5>
<p class="card-text mb-auto" th:text="${article.desc}">Description</p>
<div class="d-flex justify-content-between align-items-center">
<div class="card-body d-flex flex-column ">
<h5 class="text-dark card-title text" th:text="${article.nom}">Nom de l'article</h5>
<p class="text-dark card-text mb-auto" th:text="${article.desc}">Description</p>
<div class="text-dark d-flex justify-content-between align-items-center">
<div>
<h6>Prix de vente: <span th:text="${article.prixVente}"></span></h6>
<h6>Vendeur: <span th:text="${article.pseudoUtilisateur}"></span> </h6>

View File

@@ -1,134 +1,121 @@
<!DOCTYPE html>
<html th:replace="~{modele-page :: layout('Inscription',~{::link} , ~{::#container-main})}" xmlns:th="http://www.thymeleaf.org">
<html th:replace="~{modele-page :: layout('Inscription', ~{::link}, ~{::#container-main})}" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
</head>
<body>
<!-- Ajouter la page de nav bar -->
<div id="container-main">
<form th:action="@{/inscription/newUser}" method="post" th:object="${userProfile}">
<!--<div class="erreur-saisie" th:if="${#fields.hasErrors('*')}" >
<p th:text="#{index.erreurs}">Message d'erreur</p>
</div>-->
<!-- Champ pseudo-->
<div class="champ-saisie">
<label for="pseudo">Pseudo: </label>
<div>
<input type="text" th:field="*{pseudo}" id="pseudo" required/>
</div>
<span style="color: red;" th:if="${#fields.hasErrors('pseudo')}">
<body>
<div id="container-main">
<form th:action="@{/inscription/newUser}" method="post" th:object="${userProfile}">
<div class="champ-saisie">
<label for="pseudo" th:text="#{register.pseudo.label}">Pseudo: </label>
<div>
<input type="text" th:field="*{pseudo}" id="pseudo" required/>
</div>
<span style="color: red;" th:if="${#fields.hasErrors('pseudo')}">
<ul>
<li th:each="erreur: ${#fields.errors('pseudo')}" th:text="${erreur}"></li>
</ul>
</span>
</div>
<div class="champ-saisie">
<label for="prenom" th:text="#{register.prenom.label}">Prénom: </label>
<div>
<input type="text" th:field="*{prenom}" id="prenom" required/>
</div>
<!-- Champ prénom-->
<div class="champ-saisie">
<label for="prenom">Prénom: </label>
<div>
<input type="text" th:field="*{prenom}" id="prenom" required/>
</div>
<span style="color: red;" th:if="${#fields.hasErrors('prenom')}">
<span style="color: red;" th:if="${#fields.hasErrors('prenom')}">
<ul>
<li th:each="erreur: ${#fields.errors('prenom')}" th:text="${erreur}"></li>
</ul>
</span>
</div>
<div class="champ-saisie">
<label for="nom" th:text="#{register.nom.label}">Nom: </label>
<div>
<input type="text" th:field="*{nom}" id="nom" required/>
</div>
<!-- Champ nom-->
<div class="champ-saisie">
<label for="nom">Nom: </label>
<div>
<input type="text" th:field="*{nom}" id="nom" required/>
</div>
<span style="color: red;" th:if="${#fields.hasErrors('nom')}">
<span style="color: red;" th:if="${#fields.hasErrors('nom')}">
<ul>
<li th:each="erreur: ${#fields.errors('nom')}" th:text="${erreur}"></li>
</ul>
</span>
</div>
<div class="champ-saisie">
<label for="email" th:text="#{register.email.label}">Email: </label>
<div>
<input type="email" th:field="*{email}" id="email" required/>
</div>
<!-- Champ email-->
<div class="champ-saisie">
<label for="email">Email: </label>
<div>
<input type="email" th:field="*{email}" id="email" required/>
</div>
<span style="color: red;" th:if="${#fields.hasErrors('email')}">
<span style="color: red;" th:if="${#fields.hasErrors('email')}">
<ul>
<li th:each="erreur: ${#fields.errors('email')}" th:text="${erreur}"></li>
</ul>
</span>
</div>
<div class="champ-saisie">
<label for="telephone" th:text="#{register.telephone.label}">Téléphone: </label>
<div>
<input type="text" th:field="*{telephone}" id="telephone" />
</div>
<!-- Champ téléphone-->
<div class="champ-saisie">
<label for="telephone">Téléphone: </label>
<div>
<input type="text" th:field="*{telephone}" id="telephone" />
</div>
<span style="color: red;" th:if="${#fields.hasErrors('telephone')}">
<span style="color: red;" th:if="${#fields.hasErrors('telephone')}">
<ul>
<li th:each="erreur: ${#fields.errors('telephone')}" th:text="${erreur}"></li>
</ul>
</span>
</div>
<div class="champ-saisie">
<label for="rue" th:text="#{register.rue.label}">Rue: </label>
<div>
<input type="text" th:field="*{rue}" id="rue" required/>
</div>
<!-- Champ Rue-->
<div class="champ-saisie">
<label for="rue">Rue: </label>
<div>
<input type="text" th:field="*{rue}" id="rue" required/>
</div>
<span style="color: red;" th:if="${#fields.hasErrors('rue')}">
<span style="color: red;" th:if="${#fields.hasErrors('rue')}">
<ul>
<li th:each="erreur: ${#fields.errors('rue')}" th:text="${erreur}"></li>
</ul>
</span>
</div>
<div class="champ-saisie">
<label for="code_postal" th:text="#{register.code_postal.label}">Code postal: </label>
<div>
<input type="text" th:field="*{code_postal}" id="code_postal" required/>
</div>
<!-- Champ Code postal-->
<div class="champ-saisie">
<label for="code_postal">Code postal: </label>
<div>
<input type="text" th:field="*{code_postal}" id="code_postal" required/>
</div>
<span style="color: red;" th:if="${#fields.hasErrors('code_postal')}">
<span style="color: red;" th:if="${#fields.hasErrors('code_postal')}">
<ul>
<li th:each="erreur: ${#fields.errors('code_postal')}" th:text="${erreur}"></li>
</ul>
</span>
</div>
<div class="champ-saisie">
<label for="ville" th:text="#{register.ville.label}">Ville: </label>
<div>
<input type="text" th:field="*{ville}" id="ville" required/>
</div>
<!-- Champ Ville-->
<div class="champ-saisie">
<label for="code_postal">Ville: </label>
<div>
<input type="text" th:field="*{ville}" id="ville" required/>
</div>
<span style="color: red;" th:if="${#fields.hasErrors('ville')}">
<span style="color: red;" th:if="${#fields.hasErrors('ville')}">
<ul>
<li th:each="erreur: ${#fields.errors('ville')}" th:text="${erreur}"></li>
</ul>
</span>
</div>
<div class="champ-saisie">
<label for="password" th:text="#{register.password.label}">Mot de passe: </label>
<div>
<input type="password" th:field="*{password}" id="password" required/>
</div>
<div class="champ-saisie">
<label for="password">Mot de passe: </label>
<div>
<input type="password" th:field="*{password}" id="password" required/>
</div>
<span style="color: red;" th:if="${#fields.hasErrors('password')}">
<span style="color: red;" th:if="${#fields.hasErrors('password')}">
<ul>
<li th:each="erreur: ${#fields.errors('password')}" th:text="${erreur}"></li>
</ul>
</span>
</div>
<div class="champ-saisie">
<label for="confirmPassword" th:text="#{register.confirm_password.label}">Confirmation du mot de passe: </label>
<div>
<input type="password" name="confirmPassword" id="confirmPassword" required/>
</div>
<div class="champ-saisie">
<label for="confirmPassword">Confirmation du mot de passe: </label>
<div>
<input type="password" name="confirmPassword" id="confirmPassword" required/>
</div>
</div>
<input type="submit" value="Créer" />
</form>
<form th:action="@{/accueil}" method="post">
<button type="submit">Annuler</button>
</form>
</div>
<!-- Ajouter le footer -->
</body>
</html>
</div>
<input type="submit" th:value="#{register.submit_button}" />
</form>
<form th:action="@{/accueil}" method="post">
<button type="submit" th:text="#{register.cancel_button}">Annuler</button>
</form>
</div>
</body>
</html>

View File

@@ -6,43 +6,39 @@
<link rel="icon" th:href="@{/img/favicon.ico}" />
<link href="/css/bootstrap/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="/assets/fontawesome/css/all.css">
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<header>
<nav class="navbar navbar-expand-lg navbar navbar-dark bg-dark navbar-">
<a class="navbar-brand" href="/accueil">
<img src="/img/logo.png" width="70" height="70" alt="Logo">
<label class="text-light"><strong>ENI-Encheres</strong></label>
</a>
<div th:if="${#authentication.principal != 'anonymousUser'}" class="text-light d-flex justify-content-center align-items-center" th:text="#{'Mes crédits : '} + ${user}"></div>
<div th:if="${#authentication.principal != 'anonymousUser'}" class="text-light text-center d-flex justify-content-center align-items-center" th:text="#{'Mes crédits : '} + ${user}"></div>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse " id="navbarNav">
<ul class="navbar-nav ml-auto">
<li class="nav-item active" th:if="${#authorization.expression('hasRole(''MEMBRE'')')}">
<li class="nav-item" th:if="${#authorization.expression('hasRole(''MEMBRE'')')}" th:classappend="${requestURI == '/accueil'} ? 'active'">
<a class="nav-link" href="/accueil">Encheres <span class="sr-only" >(current)</span></a>
</li>
<li class="nav-item" th:if="${#authorization.expression('hasRole(''MEMBRE'')')}">
<a class="nav-link" href="#">Vendre un article</a>
</li>
<li class="nav-item" th:if="${#authorization.expression('hasRole(''MEMBRE'')')}">
<a class="nav-link" href="/profil">Mon profile</a>
</li>
<li class="nav-item" th:if="${#authorization.expression('hasRole(''MEMBRE'')')}">
<a class="nav-link disabled" href="/logout" tabindex="-1" aria-disabled="true" >Déconnection</a>
<li class="nav-item" th:if="${#authorization.expression('hasRole(''MEMBRE'')')}" th:classappend="${requestURI == '/article/new'} ? 'active'">
<a class="nav-link" href="/article/new">Vendre un article</a>
</li>
<li class="nav-item" th:if="${#authentication.principal == 'anonymousUser'}">
<a class="btn btn-primary" href="/login" role="button" style="background-color: #1B4463;">S'inscrire / Se connecter</a>
</li>
<li class="nav-item dropdown">
<div class="dropdown">
<a class="nav-link dropdown-toggle" href="" id="navbarDropdownMenuLink" role="button" data-toggle="dropdown" aria-expanded="false">
<i class="fa-solid fa-earth-americas"></i>
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownMenuLink" role="menu">
<a class="dropdown-item" th:href="@{/change-language(lang='en')}">English</a>
<a class="dropdown-item" th:href="@{/change-language(lang='fr')}">Français</a>
</div>
<li class="nav-item dropdown" th:if="${#authorization.expression('hasRole(''MEMBRE'')')}">
<a class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-user"></i> <!-- Icône de profil -->
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item" href="/profil">Profil</a> <!-- Bouton de profil -->
<a class="dropdown-item" href="/logout">Déconnexion</a> <!-- Bouton de déconnexion -->
<div class="dropdown-divider"></div> <!-- Diviseur -->
<a class="dropdown-item" th:href="@{/change-language}" th:text="#{home.button.lang}"></a> <!-- Option de changement de langue vers l'anglais --><!-- Option de changement de langue vers le français -->
</div>
</li>
</ul>
@@ -53,11 +49,10 @@
<div th:insert="${content}"></div>
<footer class="text-center text-lg-start bg-body-tertiary text-muted " >
<section class="" style="background-color: #2a2b30;">
<div class="container text-lg-left text-md-start mt-5 text-white">
<div class="row mt-3">
<footer class="text-center text-lg-start bg-body-tertiary text-muted mt-7 py-3">
<section class="py-4 mb-0" style="background-color: #2a2b30;">
<div class="container text-lg-left text-md-start mt-4 mb-5">
<div class="row">
<div class="col-md-3 col-lg-4 col-xl-3 mx-auto mb-4">
<h6 class="text-uppercase fw-bold mb-4">
<i class="fas fa-gem me-3"></i>ENI-Encheres
@@ -96,10 +91,11 @@
</div>
</section>
<div class="text-center p-4" style="background-color: #1c1b1b;">
<div class="text-center py-2 mt-0" style="background-color: #1c1b1b;">
© 2024 Copyright:
</div>
</footer>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="/js/bootstrap/bootstrap.min.js"></script>
<script th:src="@{/js/toggleCheckbox.js}"></script>