Un peu de tout

This commit is contained in:
mepiphana2023
2024-04-30 13:14:37 +02:00
parent 474dec272c
commit 882d9bede0
20 changed files with 187 additions and 80 deletions

View File

@@ -6,14 +6,16 @@ public class Enchere {
private int id; private int id;
private int noUtilisateur; private int noUtilisateur;
private String pseudoUtilisateur;
private int noArticle; private int noArticle;
private Date dateEnchere; private Date dateEnchere;
private float montantEnchere; private float montantEnchere;
public Enchere(){} public Enchere(){}
public Enchere(int noUtilisateur, int noArticle, Date dateEnchere, float montantEnchere) { public Enchere(int noUtilisateur, int noArticle, String pseudoUtilisateur, Date dateEnchere, float montantEnchere ) {
setNoUtilisateur(noUtilisateur); setNoUtilisateur(noUtilisateur);
setPseudoUtilisateur(pseudoUtilisateur);
setNoArticle(noArticle); setNoArticle(noArticle);
setDateEnchere(dateEnchere); setDateEnchere(dateEnchere);
setMontantEnchere(montantEnchere); setMontantEnchere(montantEnchere);
@@ -58,4 +60,12 @@ public class Enchere {
public void setNoUtilisateur(int noUtilisateur) { public void setNoUtilisateur(int noUtilisateur) {
this.noUtilisateur = noUtilisateur; this.noUtilisateur = noUtilisateur;
} }
public String getPseudoUtilisateur() {
return pseudoUtilisateur;
}
public void setPseudoUtilisateur(String pseudoUtilisateur) {
this.pseudoUtilisateur = pseudoUtilisateur;
}
} }

View File

@@ -45,8 +45,12 @@ public class AccueilController {
this.userService = userService; this.userService = userService;
} }
@GetMapping({"/", "/accueil"}) @GetMapping({"/", "/enchere"})
public String viewAccueil(HttpServletRequest request, @AuthenticationPrincipal UserDetails userDetails, @RequestParam(required = false) String searchTitle, @RequestParam(required = false) Integer searchCategory, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "6") int size, 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,
@RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "6") int size, Model model,
@RequestParam(value = "venteOption", required = false) String[] venteOptions,
@RequestParam(value = "achatOption", required = false) String[] achatOptions) {
model.addAttribute("categories", categorieService.findAllCategories()); model.addAttribute("categories", categorieService.findAllCategories());
model.addAttribute("requestURI", request.getRequestURI()); model.addAttribute("requestURI", request.getRequestURI());
SearchArticleCritere critere = new SearchArticleCritere(); SearchArticleCritere critere = new SearchArticleCritere();
@@ -58,16 +62,25 @@ public class AccueilController {
critere.setVenteOptions(venteOptions); critere.setVenteOptions(venteOptions);
critere.setAchatOptions(achatOptions); critere.setAchatOptions(achatOptions);
// Si la page est 1 ou plus, décrémentez la valeur de la page de 1
if (page > 0) {
page -= 1;
}
// Pagination // Pagination
Page<Article> articlePage = articleService.searchArticlePageable(critere, PageRequest.of(page, size)); Page<Article> articlePage = articleService.searchArticlePageable(critere, PageRequest.of(page, size));
model.addAttribute("articles", articlePage.getContent()); model.addAttribute("articles", articlePage.getContent());
model.addAttribute("currentPage", page);
// Ajoutez 1 à la valeur de la page actuelle pour l'affichage dans la vue
int currentPage = page + 1;
model.addAttribute("currentPage", currentPage);
model.addAttribute("totalPages", articlePage.getTotalPages()); model.addAttribute("totalPages", articlePage.getTotalPages());
return "accueil"; return "accueil";
} }
@PostMapping("/accueil") @PostMapping("/enchere")
public String handleSearch(HttpServletRequest request, @AuthenticationPrincipal UserDetails userDetails, @RequestParam(required = false) String searchTitle, @RequestParam(required = false) Integer searchCategory, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "6") int size, 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(required = false) String searchTitle, @RequestParam(required = false) Integer searchCategory, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "6") int size, Model model, @RequestParam(value = "venteOption", required = false) String[] venteOptions, @RequestParam(value = "achatOption", required = false) String[] achatOptions) {

View File

@@ -21,11 +21,9 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList; import java.util.*;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
@Controller() @Controller()
@RequestMapping("/article") @RequestMapping("/article")
@@ -50,7 +48,7 @@ public class ArticleController {
@GetMapping @GetMapping
public String viewArticle(Model model) { public String viewArticle(Model model) {
return "redirect:/accueil"; return "redirect:/enchere";
} }
//Affichage d'un article //Affichage d'un article
@@ -65,14 +63,20 @@ public class ArticleController {
Retrait retrait = retraitService.retraitByNumarticle(article.getId()); Retrait retrait = retraitService.retraitByNumarticle(article.getId());
article.setPseudoUtilisateur(user.getPseudo()); article.setPseudoUtilisateur(user.getPseudo());
List<Enchere> lastEnchere = this.enchereService.enchereByArticle(article.getId()); List<Enchere> lastEnchere = this.enchereService.enchereByArticle(article.getId());
Optional<Float> maxMontantEnchere = lastEnchere.stream() Optional<Float> maxMontantEnchere = lastEnchere.stream()
.map(Enchere::getMontantEnchere) // Récupère seulement les montants d'enchère .map(Enchere::getMontantEnchere)
.max(Float::compareTo); .max(Float::compareTo);
UserProfil currentUser = userService.utilisateurByName(authentication.getName()); UserProfil currentUser = userService.utilisateurByName(authentication.getName());
boolean isArticleCurrentUser = false; boolean isArticleCurrentUser = false;
if (currentUser.getId() == user.getId()) { if (currentUser.getId() == user.getId()) {
isArticleCurrentUser = true; isArticleCurrentUser = true;
} }
lastEnchere = lastEnchere.stream()
.sorted(Comparator.comparing(Enchere::getMontantEnchere).reversed())
.collect(Collectors.toList());
model.addAttribute("encheres", lastEnchere);
model.addAttribute("isArticleCurrentUser", isArticleCurrentUser); model.addAttribute("isArticleCurrentUser", isArticleCurrentUser);
model.addAttribute("article", article); model.addAttribute("article", article);
model.addAttribute("username", user); model.addAttribute("username", user);
@@ -89,7 +93,7 @@ public class ArticleController {
} }
return "article"; return "article";
} else { } else {
return "redirect:/accueil"; return "redirect:/enchere";
} }
} }
@@ -229,7 +233,7 @@ public class ArticleController {
//Validation du formulaire //Validation du formulaire
retrait.setNumArticle(articleService.saveArticle(article)); retrait.setNumArticle(articleService.saveArticle(article));
retraitService.setRetrait(retrait); retraitService.setRetrait(retrait);
return "redirect:/accueil"; return "redirect:/enchere";
} }
//Update d'un article //Update d'un article

View File

@@ -27,7 +27,7 @@ public class BankController {
public String homeCredit(Model model) { public String homeCredit(Model model) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!authentication.getName().equals("anonymousUser")){ if (!authentication.getName().equals("anonymousUser")){
return "redirect:/accueil"; return "redirect:/enchere";
} }
String username = authentication.getName(); String username = authentication.getName();
UserProfil userProfile = userService.utilisateurByName(username); UserProfil userProfile = userService.utilisateurByName(username);

View File

@@ -38,7 +38,7 @@ public class ForgotPasswordController {
// Vérifier si l'utilisateur est déjà authentifié // Vérifier si l'utilisateur est déjà authentifié
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!authentication.getName().equals("anonymousUser")){ if (!authentication.getName().equals("anonymousUser")){
return "redirect:/accueil"; return "redirect:/enchere";
} }
if (link != null) { if (link != null) {
ForgotPassword forgotPassword = forgotPasswordService.getForgotPassword(link); ForgotPassword forgotPassword = forgotPasswordService.getForgotPassword(link);
@@ -79,7 +79,7 @@ public class ForgotPasswordController {
// Vérifier si l'utilisateur est déjà authentifié // Vérifier si l'utilisateur est déjà authentifié
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!authentication.getName().equals("anonymousUser")){ if (!authentication.getName().equals("anonymousUser")){
return "redirect:/accueil"; return "redirect:/enchere";
} }
ForgotPassword forgotPassword = forgotPasswordService.getForgotPassword(link); ForgotPassword forgotPassword = forgotPasswordService.getForgotPassword(link);
if (forgotPassword != null) { if (forgotPassword != null) {
@@ -135,7 +135,7 @@ public class ForgotPasswordController {
// Vérifier si l'utilisateur est déjà authentifié // Vérifier si l'utilisateur est déjà authentifié
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!authentication.getName().equals("anonymousUser")){ if (!authentication.getName().equals("anonymousUser")){
return "redirect:/accueil"; return "redirect:/enchere";
} }
ForgotPassword forgotPassword = forgotPasswordService.getForgotPassword(link); ForgotPassword forgotPassword = forgotPasswordService.getForgotPassword(link);
if (forgotPassword != null) { if (forgotPassword != null) {

View File

@@ -52,7 +52,7 @@ public class InscriptionController {
// Vérifier si l'utilisateur est déjà authentifié // Vérifier si l'utilisateur est déjà authentifié
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!authentication.getName().equals("anonymousUser")){ if (!authentication.getName().equals("anonymousUser")){
return "redirect:/accueil"; return "redirect:/enchere";
} }
model.addAttribute("userProfile", new UserProfil()); model.addAttribute("userProfile", new UserProfil());
return "inscription"; return "inscription";

View File

@@ -24,10 +24,9 @@ public class LoginController {
@GetMapping("/login") @GetMapping("/login")
public String login(Model modele) { public String login(Model modele) {
// Vérifier si l'utilisateur est déjà authentifié
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!authentication.getName().equals("anonymousUser")){ if (!authentication.getName().equals("anonymousUser")){
return "redirect:/accueil"; return "redirect:/enchere";
} }
return "security/login"; return "security/login";
} }
@@ -36,7 +35,7 @@ public class LoginController {
public String login(@RequestParam("username") String username, @RequestParam("password") String password) { public String login(@RequestParam("username") String username, @RequestParam("password") String password) {
UserProfil user = userService.utilisateurByName(username); UserProfil user = userService.utilisateurByName(username);
if (user != null && user.getPassword().equals(password)) { if (user != null && user.getPassword().equals(password)) {
return "redirect:/accueil"; return "redirect:/enchere";
} else { } else {
return "redirect:/security/login?error"; return "redirect:/security/login?error";
} }

View File

@@ -6,10 +6,7 @@ import org.springframework.ui.Model;
import fr.eni.enchere.bll.UserService; import fr.eni.enchere.bll.UserService;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult; import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
@@ -87,7 +84,7 @@ public class ProfilController {
//Supprimer le compte //Supprimer le compte
userService.deleteUtilisateur(userProfile.getId()); userService.deleteUtilisateur(userProfile.getId());
//ATTENTION AJOUTER LA DECONNEXION //ATTENTION AJOUTER LA DECONNEXION
return "redirect:/accueil"; return "redirect:/enchere";
} }
@PostMapping("/updateUser") @PostMapping("/updateUser")
@@ -127,4 +124,15 @@ public class ProfilController {
return "accueil"; return "accueil";
} }
} }
@GetMapping("/showProfil")
public String showOtherProfil(@RequestParam("userPseudo") String userPseudo, Model model) {
model.addAttribute("userProfil", userService.utilisateurByName(userPseudo));
return "showProfil";
}
} }

View File

@@ -1,6 +1,10 @@
package fr.eni.enchere.dal; package fr.eni.enchere.dal;
import fr.eni.enchere.bll.EnchereService;
import fr.eni.enchere.bll.UserService;
import fr.eni.enchere.bo.Enchere; import fr.eni.enchere.bo.Enchere;
import fr.eni.enchere.bo.UserProfil;
import org.apache.catalina.User;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.GeneratedKeyHolder;
@@ -14,9 +18,11 @@ import java.util.List;
public class EnchereRepositoryImpl implements EnchereRepository { public class EnchereRepositoryImpl implements EnchereRepository {
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private UserService userService;
public EnchereRepositoryImpl(JdbcTemplate jdbcTemplate) { public EnchereRepositoryImpl(JdbcTemplate jdbcTemplate, UserService userService) {
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.userService = userService;
} }
public class EnchereRowMapper implements RowMapper<Enchere> { public class EnchereRowMapper implements RowMapper<Enchere> {
@@ -27,6 +33,8 @@ public class EnchereRepositoryImpl implements EnchereRepository {
enchere.setNoArticle(rs.getInt("no_article")); enchere.setNoArticle(rs.getInt("no_article"));
enchere.setMontantEnchere(rs.getInt("montant_enchere")); enchere.setMontantEnchere(rs.getInt("montant_enchere"));
enchere.setDateEnchere(rs.getDate("date_enchere")); enchere.setDateEnchere(rs.getDate("date_enchere"));
UserProfil user = userService.utilisateurById(rs.getInt("no_utilisateur"));
enchere.setPseudoUtilisateur(user.getPseudo());
return enchere; return enchere;
} }
} }

View File

@@ -19,17 +19,17 @@ public class WebSecurityConfig{
@Bean @Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((requests) -> requests http.authorizeHttpRequests((requests) -> requests
.requestMatchers("/","/accueil", "/login", "/forgotPassword/**", "/inscription/**", "/searchArticle", "/article/show", "/change-language").permitAll() .requestMatchers("/","/enchere", "/login", "/forgotPassword/**", "/inscription/**", "/searchArticle", "/article/show", "/change-language").permitAll()
.requestMatchers("/css/**", "/images/**", "/assets/**", "/img/**", "/js/**", "/assets/**", "/i18n/**").permitAll() .requestMatchers("/css/**", "/images/**", "/assets/**", "/img/**", "/js/**", "/assets/**", "/i18n/**").permitAll()
.requestMatchers("/profil/**", "/article/new/**", "/article/update", "/article/delete").authenticated() .requestMatchers("/profil/**", "/article/new/**", "/article/update", "/article/delete").authenticated()
.requestMatchers("/admin").hasRole("ADMIN") .requestMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()) .anyRequest().authenticated())
.formLogin((form) -> form .formLogin((form) -> form
.loginPage("/login") .loginPage("/login")
.defaultSuccessUrl("/", true)) .defaultSuccessUrl("/enchere", true))
.logout((logout) -> logout .logout((logout) -> logout
.clearAuthentication(true).invalidateHttpSession(true) .clearAuthentication(true).invalidateHttpSession(true)
.deleteCookies("JSESSIONID").logoutSuccessUrl("/login?logout") .deleteCookies("JSESSIONID").logoutSuccessUrl("/enchere")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll()); .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll());
return http.build(); return http.build();

View File

@@ -109,12 +109,12 @@ article.add.form.button.cancel = Annuler
article.details.title = Article - NOMARTICLE article.details.title = Article - NOMARTICLE
article.details.heading = Article article.details.heading = Article
article.details.label.description = Description article.details.label.description = Description :
article.details.label.seller = Vendeur article.details.label.seller = Vendeur:
article.details.label.category = Cat\u00E9gorie article.details.label.category = Cat\u00E9gorie :
article.details.label.sale_price = Prix de vente article.details.label.sale_price = Prix de vente :
article.details.label.end_date = Date fin ench\u00E8re article.details.label.end_date = Date fin ench\u00E8re :
article.details.label.pickup = Retrait article.details.label.pickup = Retrait :
article.details.label.amount = Montant article.details.label.amount = Montant
article.details.button.bid = Ench\u00E9rir article.details.button.bid = Ench\u00E9rir
article.details.address.unknown = Adresse inconnue article.details.address.unknown = Adresse inconnue

View File

@@ -1,16 +1,21 @@
/* Classe utilitaire Flexbox */
.v-center { .v-center {
display: flex; display: flex;
align-items: center; align-items: center;
height: 100%; height: 100%;
} }
/* Classe utilitaire pour supprimer la décoration du texte */
.text-decoration-none { .text-decoration-none {
text-decoration: none !important; text-decoration: none !important;
} }
/* Classe utilitaire pour la couleur du texte */
.text-dark { .text-dark {
color: black !important; color: black !important;
} }
/* Styles de la carte d'article */
.card-article { .card-article {
transition: transform 0.3s ease; transition: transform 0.3s ease;
} }
@@ -19,18 +24,39 @@
transform: scale(1.05); transform: scale(1.05);
} }
/* Styles du bouton de langue */
#languageButton { #languageButton {
margin-right: 20px; /* Espacement du bouton par rapport à la droite */ margin-right: 20px; /* Espacement du bouton par rapport à la droite */
} }
/* Styles de la barre de navigation */
.navbar-nav { .navbar-nav {
margin-right: 10px; margin-right: 10px;
} }
.navbar-nav .nav-item.active .nav-link { .navbar-nav .nav-item.active .nav-link {
color: white; color: white;
} }
/* Styles du conteneur principal */
#container-main { #container-main {
padding-bottom: 40px; padding-bottom: 40px;
} }
/* Styles du bouton principal */
.btn-primary {
background-color: #0E314C;
border-color: #0E314C;
}
.btn-primary:hover {
background-color: #1B4463 !important;
color: #EDCE86 !important;
}
.btn-primary:after {
color: #1B4463 !important;
border-color: #EDCE86 !important;
background: #EDCE86 !important;
outline-color: #EDCE86 !important;
}

View File

@@ -12,7 +12,7 @@
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<!-- Formulaire de recherche avec sélection de catégorie --> <!-- Formulaire de recherche avec sélection de catégorie -->
<form th:action="@{/accueil}" method="post" class="mb-3"> <form th:action="@{/enchere}" method="post" class="mb-3">
<div class="row"> <div class="row">
<!-- Colonne pour la zone de recherche et Achats/Ventes --> <!-- Colonne pour la zone de recherche et Achats/Ventes -->
<div class="col-md-6" th:if="${#authentication.principal != 'anonymousUser'}"> <div class="col-md-6" th:if="${#authentication.principal != 'anonymousUser'}">
@@ -128,10 +128,23 @@
<div class="card-body d-flex flex-column "> <div class="card-body d-flex flex-column ">
<h5 class="text-dark card-title text" th:text="${article.nom}"></h5> <h5 class="text-dark card-title text" th:text="${article.nom}"></h5>
<p class="text-dark card-text mb-auto" th:text="${article.desc}"></p> <p class="text-dark card-text mb-auto" th:text="${article.desc}"></p>
<div class="text-dark d-flex justify-content-between align-items-center"> <div class="mt-2 d-flex flex-row align-items-center justify-content-between">
<div> <strong><label class="col-form-label mr-2" th:text="#{article.details.label.sale_price}"></label></strong>
<h6 th:text="#{home.article.sellprice}"> <span th:text="${article.prixVente}"></span></h6> <div class="col-form-label">
<h6 th:text="#{home.article.seller}"> <span th:text="${article.pseudoUtilisateur}"></span> </h6> <span class="text-dark" th:if="${article.prixInitial < article.prixVente}">
<i class="fas fa-coins"></i> <!-- Assurez-vous de remplacer "fa-coins" par la classe de votre icône -->
<span th:text="${article.prixVente}"></span>
</span>
<span class="text-dark" th:if="${article.prixVente < article.prixInitial}">
<i class="fas fa-coins"></i> <!-- Assurez-vous de remplacer "fa-coins" par la classe de votre icône -->
<span th:text="${article.prixInitial}"></span>
</span>
</div>
</div>
<div class="mt-2 d-flex flex-row align-items-center justify-content-between">
<strong><label class="col-form-label mr-2" th:text="#{article.details.label.seller}"></label></strong>
<div class="col-form-label">
<span class="text-dark" th:text="${article.pseudoUtilisateur}"></span>
</div> </div>
</div> </div>
<br> <br>
@@ -150,30 +163,29 @@
<ul class="pagination justify-content-center"> <ul class="pagination justify-content-center">
<!-- Bouton pour la première page --> <!-- Bouton pour la première page -->
<li class="page-item"> <li class="page-item">
<a class="page-link" th:href="@{/(page=0)}"> <a class="page-link" th:href="@{/(page=1)}">
<span aria-hidden="true">&laquo;</span> <span aria-hidden="true">&laquo;</span>
<span th:text="#{home.button.first}"></span> <span th:text="#{home.button.first}"></span>
</a> </a>
</li> </li>
<!-- Bouton pour la page précédente --> <!-- Bouton pour la page précédente -->
<li th:if="${currentPage > 0}" class="page-item"> <li th:if="${currentPage > 1}" class="page-item">
<a class="page-link" th:href="@{/(page=${currentPage - 1})}"> <a class="page-link" th:href="@{/(page=${currentPage - 1})}">
<span aria-hidden="true">&lsaquo;</span> <span aria-hidden="true">&lsaquo;</span>
<span th:text="#{home.button.previous}"></span> <span th:text="#{home.button.previous}"></span>
</a> </a>
</li> </li>
<!-- Boucle pour afficher les numéros de page --> <!-- Afficher les deux dernières pages, la page en cours et les deux suivantes -->
<!-- Vous pouvez ajuster la plage de pages affichées comme vous le souhaitez --> <th:block th:each="page,iter : ${#numbers.sequence((currentPage - 2 > 0 ? currentPage - 2 : 1), (currentPage + 2 < totalPages ? currentPage + 2 : totalPages))}">
<th:block th:each="page,iter : ${#numbers.sequence(0, totalPages - 1)}"> <li class="page-item" th:classappend="${currentPage == page ? 'active' : ''}">
<li class="page-item" th:if="${iter.index >= (currentPage - 2) && iter.index <= (currentPage + 2)}"> <a class="page-link" th:href="@{/(page=${page})}" th:text="${page}"></a>
<a class="page-link" th:href="@{/(page=${page})}" th:text="${page} + 1"></a>
</li> </li>
</th:block> </th:block>
<!-- Bouton pour la page suivante --> <!-- Bouton pour la page suivante -->
<li th:if="${currentPage < totalPages - 1}" class="page-item"> <li th:if="${currentPage < totalPages}" class="page-item">
<a class="page-link" th:href="@{/(page=${currentPage + 1})}"> <a class="page-link" th:href="@{/(page=${currentPage + 1})}">
<span aria-hidden="true">&rsaquo;</span> <span aria-hidden="true">&rsaquo;</span>
<span th:text="#{home.button.next}"></span> <span th:text="#{home.button.next}"></span>
@@ -182,7 +194,7 @@
<!-- Bouton pour la dernière page --> <!-- Bouton pour la dernière page -->
<li class="page-item"> <li class="page-item">
<a class="page-link" th:href="@{/(page=${totalPages - 1})}"> <a class="page-link" th:href="@{/(page=${totalPages})}">
<span aria-hidden="true">&raquo;</span> <span aria-hidden="true">&raquo;</span>
<span th:text="#{home.button.end}"></span> <span th:text="#{home.button.end}"></span>
</a> </a>

View File

@@ -2,7 +2,6 @@
<html th:replace="~{modele-page :: layout('__${#messages.msg('admin.panel.title')}__',~{::link} , ~{::#container-main})}" xmlns:th="http://www.thymeleaf.org"> <html th:replace="~{modele-page :: layout('__${#messages.msg('admin.panel.title')}__',~{::link} , ~{::#container-main})}" xmlns:th="http://www.thymeleaf.org">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="style.css"> <!-- Ajoutez le lien vers votre fichier CSS si nécessaire -->
</head> </head>
<body> <body>
<div id="container-main" class="container mt-4"> <div id="container-main" class="container mt-4">

View File

@@ -4,45 +4,45 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
</head> </head>
<body> <body>
<div class="container-fluid" id="container-main" > <div class="container-fluid" id="container-main">
<div class="row mt-3 justify-content-center"> <!-- Ajoutez la classe justify-content-center pour centrer le contenu --> <div class="row mt-3 justify-content-center">
<div class="col-md-6"> <div class="col-12 col-md-8 col-lg-6"> <!-- Utilisation de classes Bootstrap pour rendre la colonne responsive -->
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
<h4 th:text="#{article.details.heading}"></h4> <h4 th:text="#{article.details.heading}"></h4>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="row"> <div class="row">
<div class="col-md-3"> <div class="col-12 col-md-4">
<img th:src="@{'/images/articles/' + ${article.id} + '.jpg'}" alt="image-vente" class="img-thumbnail" style="width: 250px; height: auto;"> <img th:src="@{'/images/articles/' + ${article.id} + '.jpg'}" alt="image-vente" class="img-thumbnail" style="width: 100%; height: auto;">
</div> </div>
<div class="col-md-9 d-flex flex-column"> <div class="col-12 col-md-8">
<div class="mt-2 d-flex flex-column align-items-center"> <div class="mt-2 d-flex flex-column align-items-center">
<h1 th:text="${article.nom}"></h1> <h1 th:text="${article.nom}"></h1>
</div> </div>
<div class="mt-2 d-flex flex-row align-items-end justify-content-between"> <div class="mt-2 d-flex flex-row align-items-center justify-content-between">
<strong><label class="col-form-label" th:text="#{article.details.label.description}"></label></strong> <strong><label class="col-form-label" th:text="#{article.details.label.description}"></label></strong>
<span th:text="${article.desc}"></span> <span class="d-inline-block text-wrap text-sm text-justify" style="max-width: 60%;" th:text="${article.desc}"></span>
</div> </div>
<div class="mt-2 d-flex flex-row align-items-end justify-content-between"> <div class="mt-2 d-flex flex-row align-items-center justify-content-between">
<strong><label class="col-form-label" th:text="#{article.details.label.seller}"></label></strong> <strong><label class="col-form-label" th:text="#{article.details.label.seller}"></label></strong>
<span th:text="${username.pseudo}"></span> <a th:href="@{/profil/showProfil(userPseudo=${username.pseudo})}" class="text-decoration-none">
<span th:text="${username.pseudo}"></span>
</a>
</div> </div>
<div class="mt-2 d-flex flex-row align-items-end justify-content-between"> <div class="mt-2 d-flex flex-row align-items-center justify-content-between">
<strong><label class="col-form-label" th:text="#{article.details.label.category}"></label></strong> <strong><label class="col-form-label" th:text="#{article.details.label.category}"></label></strong>
<span th:text="${cate}"></span> <span th:text="${cate}"></span>
</div> </div>
<div class="mt-2 d-flex flex-row align-items-end justify-content-between"> <div class="mt-2 d-flex flex-row align-items-center justify-content-between">
<strong><label class="col-form-label" th:text="#{article.details.label.sale_price}"></label></strong> <strong><label class="col-form-label" th:text="#{article.details.label.sale_price}"></label></strong>
<span th:text="${article.prixInitial}"></span> <span th:text="${article.prixInitial}"></span>
</div> </div>
<div class="mt-2 d-flex flex-row align-items-end justify-content-between"> <div class="mt-2 d-flex flex-row align-items-center justify-content-between">
<strong><label class="col-form-label" th:text="#{article.details.label.end_date}"></label></strong> <strong><label class="col-form-label" th:text="#{article.details.label.end_date}"></label></strong>
<span th:text="${article.dateFinEnch}"></span> <span th:text="${article.dateFinEnch}"></span>
</div> </div>
<!-- Rajouter une condition sur retrait pour l'afficher uniquement quand --> <div class="mt-2 d-flex flex-row align-items-center justify-content-between">
<!-- la vente est gagné ET à l'utilisateur qui a remporté la vente-->
<div class="mt-2 d-flex flex-row align-items-end justify-content-between">
<strong><label class="col-form-label" th:text="#{article.details.label.pickup}"></label></strong> <strong><label class="col-form-label" th:text="#{article.details.label.pickup}"></label></strong>
<span th:text="${retrait} ? ${retrait.rue} + ' ' + ${retrait.code_postale} + ' ' + ${retrait.ville} : #{article.details.address.unknown}"></span> <span th:text="${retrait} ? ${retrait.rue} + ' ' + ${retrait.code_postale} + ' ' + ${retrait.ville} : #{article.details.address.unknown}"></span>
</div> </div>
@@ -60,6 +60,30 @@
<button th:if="${isArticleCurrentUser}" type="button" class="btn btn-success"> Modifier</button> <button th:if="${isArticleCurrentUser}" type="button" class="btn btn-success"> Modifier</button>
</div> </div>
</div> </div>
<hr>
<div class="mt-2">
<h5>Enchérisseurs</h5>
<table class="table table-striped">
<thead>
<tr>
<th>Pseudo</th>
<th>Montant Enchère</th> <!-- Nouvelle colonne pour afficher le montant de l'enchère -->
</tr>
</thead>
<tbody>
<tr th:each="enchere : ${encheres}">
<td>
<a th:href="@{/profil/showProfil(userPseudo=${enchere.pseudoUtilisateur})}" class="text-decoration-none">
<span th:text="${enchere.pseudoUtilisateur}"></span>
</a>
</td>
<td>
<span th:text="${enchere.montantEnchere}"></span>
</td>
</tr>
</tbody>
</table>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -74,7 +74,7 @@
<p style="color: red;" th:text="${param.erreur}"></p> <p style="color: red;" th:text="${param.erreur}"></p>
</div> </div>
</form> </form>
<form th:action="@{/accueil}" method="post" class="mt-3"> <form th:action="@{/enchere}" method="post" class="mt-3">
<button type="submit" class="btn btn-secondary" th:text="#{article.add.form.button.cancel}">Annuler</button> <button type="submit" class="btn btn-secondary" th:text="#{article.add.form.button.cancel}">Annuler</button>
</form> </form>
<script> <script>

View File

@@ -107,7 +107,7 @@
</div> </div>
<input type="hidden" th:field="*{id}" id="userId" th:value="${userProfile.id}"> <input type="hidden" th:field="*{id}" id="userId" th:value="${userProfile.id}">
<div class="d-flex justify-content-end align-items-center"> <div class="d-flex justify-content-end align-items-center">
<a class="btn btn-secondary" href="/accueil" th:text="#{edit.profil.button.cancel}"></a> <a class="btn btn-secondary" href="/enchere" th:text="#{edit.profil.button.cancel}"></a>
<button type="submit" class="btn btn-primary border-right ml-2" th:text="#{edit.profil.button.edit}"></button> <button type="submit" class="btn btn-primary border-right ml-2" th:text="#{edit.profil.button.edit}"></button>
</div> </div>
</div> </div>

View File

@@ -100,7 +100,7 @@
<button type="submit" class="btn btn-primary w-100">S'inscrire</button> <button type="submit" class="btn btn-primary w-100">S'inscrire</button>
</form> </form>
<form th:action="@{/accueil}" method="post"> <form th:action="@{/enchere}" method="post">
<button type="submit" class="btn btn-secondary w-100 mt-3">Annuler</button> <button type="submit" class="btn btn-secondary w-100 mt-3">Annuler</button>
</form> </form>
</div> </div>

View File

@@ -20,18 +20,22 @@
<body> <body>
<header> <header>
<nav class="navbar navbar-expand-lg navbar navbar-dark bg-dark navbar-"> <nav class="navbar navbar-expand-lg navbar navbar-dark bg-dark navbar-">
<a class="navbar-brand" href="/accueil"> <a class="navbar-brand" href="/enchere">
<img href="/accueil" src="/img/logo.png" width="70" height="70" alt="Logo"> <img href="/enchere" src="/img/logo.png" width="70" height="70" alt="Logo">
<label href="/accueil" class="text-light"><strong>ENI-Encheres</strong></label> <label href="/enchere" class="text-light"><strong>ENI-Encheres</strong></label>
</a> </a>
<div th:if="${#authentication.principal != 'anonymousUser'}" class="text-light text-center d-flex justify-content-center align-items-center" th:text="#{home.credit} + ${user.getCredit()}"></div> <div th:if="${#authentication.principal != 'anonymousUser'}" class="text-light text-center d-flex justify-content-center align-items-center"><!-- Assurez-vous de remplacer "fa-credit-card" par la classe de votre icône -->
<span th:text="#{home.credit} + ${user.getCredit()} + ' '"></span>
<i class="fas fa-coins"></i>
</div>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <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> <span class="navbar-toggler-icon"></span>
</button> </button>
<div class="collapse navbar-collapse " id="navbarNav"> <div class="collapse navbar-collapse " id="navbarNav">
<ul class="navbar-nav ml-auto"> <ul class="navbar-nav ml-auto">
<li class="nav-item" th:if="${#authentication.principal != 'anonymousUser'}" th:classappend="${requestURI == '/accueil'} ? 'active'"> <li class="nav-item" th:if="${#authentication.principal != 'anonymousUser'}" th:classappend="${requestURI == '/enchere'} ? 'active'">
<a class="nav-link" href="/accueil" th:text="#{home.nav.enchere}"> <span class="sr-only" >(current)</span></a> <a class="nav-link" href="/enchere" th:text="#{home.nav.enchere}"> <span class="sr-only" >(current)</span></a>
</li> </li>
<li class="nav-item" th:if="${#authentication.principal != 'anonymousUser'}" th:classappend="${requestURI == '/article/new'} ? 'active'"> <li class="nav-item" th:if="${#authentication.principal != 'anonymousUser'}" th:classappend="${requestURI == '/article/new'} ? 'active'">
<a class="nav-link" href="/article/new" th:text="#{home.nav.vend}"></a> <a class="nav-link" href="/article/new" th:text="#{home.nav.vend}"></a>
@@ -80,7 +84,7 @@
Menu Menu
</h6> </h6>
<p> <p>
<a href="/accueil" class="text-reset" th:text="#{home.nav.enchere}"></a> <a href="/enchere" class="text-reset" th:text="#{home.nav.enchere}"></a>
</p> </p>
<p> <p>
<a href="/article/new" class="text-reset" th:text="#{home.nav.vend}"></a> <a href="/article/new" class="text-reset" th:text="#{home.nav.vend}"></a>

View File

@@ -74,7 +74,7 @@
<p style="color: red;" th:text="${param.erreur}"></p> <p style="color: red;" th:text="${param.erreur}"></p>
</div> </div>
</form> </form>
<form th:action="@{/accueil}" method="post" class="mt-3"> <form th:action="@{/enchere}" method="post" class="mt-3">
<button type="submit" class="btn btn-secondary" th:text="#{article.add.form.button.cancel}">Annuler</button> <button type="submit" class="btn btn-secondary" th:text="#{article.add.form.button.cancel}">Annuler</button>
</form> </form>
<script> <script>