From 873d3855e187729507e8c9e69db08b0be8dc9e28 Mon Sep 17 00:00:00 2001 From: Diogo Santos Rodrigues <109999912+dioguit0s@users.noreply.github.com> Date: Wed, 20 May 2026 21:36:06 -0300 Subject: [PATCH 1/3] feat: add profile picture support for user --- .../com/EC6/Convive/Config/MvcConfig.java | 10 +++- .../Controller/MoradorHomeController.java | 7 +-- .../Controller/MoradorUsuarioController.java | 9 +++- .../TriagemOcorrenciasController.java | 9 +++- .../Controller/TriagemReservasController.java | 6 ++- .../Convive/Controller/UserController.java | 46 ++++++++++++++++++ .../java/com/EC6/Convive/Model/Usuario.java | 3 ++ .../Convive/Service/FileStorageService.java | 19 ++++++++ .../EC6/Convive/Service/UsuarioService.java | 10 ++++ .../fragments/morador/components.html | 16 +++++-- .../templates/moderador/gestaoMoradores.html | 47 +++++++++---------- 11 files changed, 147 insertions(+), 35 deletions(-) create mode 100644 Convive/src/main/java/com/EC6/Convive/Controller/UserController.java diff --git a/Convive/src/main/java/com/EC6/Convive/Config/MvcConfig.java b/Convive/src/main/java/com/EC6/Convive/Config/MvcConfig.java index 589d067..700f7e0 100644 --- a/Convive/src/main/java/com/EC6/Convive/Config/MvcConfig.java +++ b/Convive/src/main/java/com/EC6/Convive/Config/MvcConfig.java @@ -1,13 +1,20 @@ package com.EC6.Convive.Config; + import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import java.nio.file.Paths; +import org.springframework.beans.factory.annotation.Value; + @Configuration public class MvcConfig implements WebMvcConfigurer { + @Value("${app.upload.dir}") + private String uploadDir; + @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("public/landing"); @@ -16,6 +23,5 @@ public void addViewControllers(ViewControllerRegistry registry) { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/uploads/**") - .addResourceLocations("file:uploads/"); - } + .addResourceLocations("file:" + Paths.get(uploadDir).toAbsolutePath().toString() + "/"); } } \ No newline at end of file diff --git a/Convive/src/main/java/com/EC6/Convive/Controller/MoradorHomeController.java b/Convive/src/main/java/com/EC6/Convive/Controller/MoradorHomeController.java index 93a263d..6f18fe4 100644 --- a/Convive/src/main/java/com/EC6/Convive/Controller/MoradorHomeController.java +++ b/Convive/src/main/java/com/EC6/Convive/Controller/MoradorHomeController.java @@ -39,10 +39,9 @@ public class MoradorHomeController { @GetMapping("/home") public String dashboardMorador(@AuthenticationPrincipal CustomUserDetails userDetails, Model model) { - Usuario usuario = userDetails.getUsuario(); + Usuario usuario = usuarioService.getByEmail(userDetails.getUsername()); List comunicados = comunicadoService.findAllOrderByDate(); - List reservas = reservaService.listByUser(usuario.getId()); model.addAttribute("usuario", usuario); @@ -54,12 +53,14 @@ public String dashboardMorador(@AuthenticationPrincipal CustomUserDetails userDe @GetMapping("/reservas") public String listarReservasMorador(@AuthenticationPrincipal CustomUserDetails userDetails, Model model) { - Usuario usuario = userDetails.getUsuario(); + Usuario usuario = usuarioService.getByEmail(userDetails.getUsername()); + List reservas = reservaService.listByUser(usuario.getId()).stream() .sorted(Comparator.comparing(Reserva::getInicio, Comparator.nullsLast(Comparator.naturalOrder()))) .toList(); List areasComuns = areaComumService.listAll(); boolean temAreaAtiva = areasComuns.stream().anyMatch(a -> a.getStatusArea() == StatusArea.ATIVA); + model.addAttribute("usuario", usuario); model.addAttribute("reservas", reservas); model.addAttribute("areasComuns", areasComuns); diff --git a/Convive/src/main/java/com/EC6/Convive/Controller/MoradorUsuarioController.java b/Convive/src/main/java/com/EC6/Convive/Controller/MoradorUsuarioController.java index 6275049..334a49b 100644 --- a/Convive/src/main/java/com/EC6/Convive/Controller/MoradorUsuarioController.java +++ b/Convive/src/main/java/com/EC6/Convive/Controller/MoradorUsuarioController.java @@ -10,12 +10,15 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.mvc.support.RedirectAttributes; -import java.util.UUID; +import java.util.UUID;import com.EC6.Convive.Security.CustomUserDetails; @Controller @RequiredArgsConstructor @@ -28,11 +31,15 @@ public class MoradorUsuarioController { @GetMapping public String listarUsuarios( + @AuthenticationPrincipal CustomUserDetails userDetails, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size, @RequestParam(required = false) String search, Model model) { + Usuario usuarioLogado = usuarioService.getByEmail(userDetails.getUsername()); + model.addAttribute("usuario", usuarioLogado); + Pageable pageable = PageRequest.of(page, size); Page moradorPage = usuarioService.findPaginatedAndFiltered(search, pageable); diff --git a/Convive/src/main/java/com/EC6/Convive/Controller/TriagemOcorrenciasController.java b/Convive/src/main/java/com/EC6/Convive/Controller/TriagemOcorrenciasController.java index 6bb4847..55ee0e6 100644 --- a/Convive/src/main/java/com/EC6/Convive/Controller/TriagemOcorrenciasController.java +++ b/Convive/src/main/java/com/EC6/Convive/Controller/TriagemOcorrenciasController.java @@ -3,8 +3,12 @@ import com.EC6.Convive.Model.Ocorrencia; import com.EC6.Convive.Model.Prioridade; import com.EC6.Convive.Model.StatusOcorrencia; +import com.EC6.Convive.Model.Usuario; +import com.EC6.Convive.Security.CustomUserDetails; import com.EC6.Convive.Service.OcorrenciaService; +import com.EC6.Convive.Service.UsuarioService; import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; @@ -19,9 +23,12 @@ public class TriagemOcorrenciasController { private final OcorrenciaService ocorrenciaService; + private final UsuarioService usuarioService; @GetMapping - public String gerenciarOcorrencias(Model model) { + public String gerenciarOcorrencias(@AuthenticationPrincipal CustomUserDetails userDetails, Model model) { + Usuario usuarioLogado = usuarioService.getByEmail(userDetails.getUsername()); + model.addAttribute("usuario", usuarioLogado); List ocorrencias = ocorrenciaService.listAll(); model.addAttribute("ocorrencias", ocorrencias); return "moderador/triagemOcorrencias"; diff --git a/Convive/src/main/java/com/EC6/Convive/Controller/TriagemReservasController.java b/Convive/src/main/java/com/EC6/Convive/Controller/TriagemReservasController.java index a98b334..363928c 100644 --- a/Convive/src/main/java/com/EC6/Convive/Controller/TriagemReservasController.java +++ b/Convive/src/main/java/com/EC6/Convive/Controller/TriagemReservasController.java @@ -4,10 +4,12 @@ import com.EC6.Convive.Model.Reserva; import com.EC6.Convive.Model.StatusReserva; import com.EC6.Convive.Model.Usuario; +import com.EC6.Convive.Security.CustomUserDetails; import com.EC6.Convive.Service.ReservaService; import com.EC6.Convive.Service.UsuarioService; import lombok.RequiredArgsConstructor; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; @@ -26,7 +28,9 @@ public class TriagemReservasController { private final ApplicationEventPublisher eventPublisher; @GetMapping - public String gerenciarReservas(Model model) { + public String gerenciarReservas(@AuthenticationPrincipal CustomUserDetails userDetails, Model model) { + Usuario usuarioLogado = usuarioService.getByEmail(userDetails.getUsername()); + model.addAttribute("usuario", usuarioLogado); List reservas = reservaService.listAll(); model.addAttribute("reservas", reservas); return "moderador/triagemReservas"; diff --git a/Convive/src/main/java/com/EC6/Convive/Controller/UserController.java b/Convive/src/main/java/com/EC6/Convive/Controller/UserController.java new file mode 100644 index 0000000..0d1c05a --- /dev/null +++ b/Convive/src/main/java/com/EC6/Convive/Controller/UserController.java @@ -0,0 +1,46 @@ +package com.EC6.Convive.Controller; + + +import com.EC6.Convive.Model.Usuario; +import com.EC6.Convive.Repository.UsuarioRepository; +import com.EC6.Convive.Service.FileStorageService; +import com.EC6.Convive.Service.UsuarioService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +import java.security.Principal; + +@Controller +@RequiredArgsConstructor +@RequestMapping("/perfil") +public class UserController { + + private final FileStorageService fileStorageService; + private final UsuarioService usuarioService; + + + @PostMapping("/upload-foto") + public String uploadFotoPerfil(@RequestParam("foto") MultipartFile foto, Principal principal, RedirectAttributes redirectAttributes) { + try { + Usuario usuario = usuarioService.getByEmail(principal.getName()); + + String caminhoImagem = fileStorageService.salvarImagemPerfil(foto); + + if (caminhoImagem != null) { + usuario.setFotoPerfil(caminhoImagem); + usuarioService.update(usuario.getId(), usuario); + } + + redirectAttributes.addFlashAttribute("sucesso", "Foto de perfil atualizada com sucesso!"); + } catch (Exception e) { + redirectAttributes.addFlashAttribute("erro", "Erro ao fazer upload da foto de perfil."); + } + + return "redirect:/morador/home"; + } +} diff --git a/Convive/src/main/java/com/EC6/Convive/Model/Usuario.java b/Convive/src/main/java/com/EC6/Convive/Model/Usuario.java index c756cab..ad97a23 100644 --- a/Convive/src/main/java/com/EC6/Convive/Model/Usuario.java +++ b/Convive/src/main/java/com/EC6/Convive/Model/Usuario.java @@ -36,6 +36,9 @@ public abstract class Usuario { @Column(name = "isInadimplente") private boolean isInadimplente; + @Column(name = "fotoPerfil") + private String fotoPerfil; + public abstract String getTipoUsuario(); } diff --git a/Convive/src/main/java/com/EC6/Convive/Service/FileStorageService.java b/Convive/src/main/java/com/EC6/Convive/Service/FileStorageService.java index 174d8a3..bc3ce8d 100644 --- a/Convive/src/main/java/com/EC6/Convive/Service/FileStorageService.java +++ b/Convive/src/main/java/com/EC6/Convive/Service/FileStorageService.java @@ -49,4 +49,23 @@ public String salvarImagemComunicado(MultipartFile arquivo) throws IOException { Files.copy(arquivo.getInputStream(), caminhoDestino, StandardCopyOption.REPLACE_EXISTING); return "/uploads/comunicados/" + nomeArquivoUnico; } + + public String salvarImagemPerfil(MultipartFile arquivo) throws IOException { + if (arquivo.isEmpty()) { + return null; + } + + Path uploadPath = Paths.get(uploadDir).resolve("perfis"); + if (!Files.exists(uploadPath)) { + Files.createDirectories(uploadPath); + } + + String nomeArquivoOriginal = arquivo.getOriginalFilename(); + String nomeArquivoUnico = UUID.randomUUID().toString() + "_perfil_" + nomeArquivoOriginal; + + Path caminhoDestino = uploadPath.resolve(nomeArquivoUnico); + Files.copy(arquivo.getInputStream(), caminhoDestino, StandardCopyOption.REPLACE_EXISTING); + + return "/uploads/perfis/" + nomeArquivoUnico; + } } \ No newline at end of file diff --git a/Convive/src/main/java/com/EC6/Convive/Service/UsuarioService.java b/Convive/src/main/java/com/EC6/Convive/Service/UsuarioService.java index 3e7782e..97435db 100644 --- a/Convive/src/main/java/com/EC6/Convive/Service/UsuarioService.java +++ b/Convive/src/main/java/com/EC6/Convive/Service/UsuarioService.java @@ -51,6 +51,16 @@ public void delete(UUID id) { usuarioRepository.deleteById(id); } + public Usuario update(UUID id, Usuario moradorAtualizado) { + Usuario usuario = searchById(id); + + usuario.setNome(moradorAtualizado.getNome()); + usuario.setEmail(moradorAtualizado.getEmail()); + usuario.setFotoPerfil(moradorAtualizado.getFotoPerfil()); + + return usuarioRepository.save(usuario); + } + public Page findPaginatedAndFiltered(String search, Pageable pageable) { if (search != null && !search.trim().isEmpty()) { return usuarioRepository.findByNomeContainingIgnoreCaseOrEmailContainingIgnoreCase(search, search, pageable); diff --git a/Convive/src/main/resources/templates/fragments/morador/components.html b/Convive/src/main/resources/templates/fragments/morador/components.html index 3d1bdc0..af101a2 100644 --- a/Convive/src/main/resources/templates/fragments/morador/components.html +++ b/Convive/src/main/resources/templates/fragments/morador/components.html @@ -12,9 +12,19 @@