diff --git a/src/main/java/com/projet/projetIndu/ProjetInduApplication.java b/src/main/java/com/projet/projetIndu/ProjetInduApplication.java index ab5f191cad9d2f52ef1d5f5ffaf37ede7850ba16..a7037d536d98754e6f63519370decb47c03f3cd5 100644 --- a/src/main/java/com/projet/projetIndu/ProjetInduApplication.java +++ b/src/main/java/com/projet/projetIndu/ProjetInduApplication.java @@ -1,27 +1,21 @@ package com.projet.projetIndu; -import com.projet.projetIndu.entities.Role; -import com.projet.projetIndu.entities.User; -import com.projet.projetIndu.services.UserService; -import jakarta.annotation.PostConstruct; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ProjetInduApplication { - @Autowired - private UserService userService; +// @Autowired +// private UserService userService; +// +// @PostConstruct +// public void init() { +// User aichatou = userService.registerUser("aichatou", "test", Role.ADMIN); +// System.out.println(aichatou); +// } - @PostConstruct - public void init() { - User aichatou = userService.registerUser("aichatou", "test", Role.ADMIN); - System.out.println(aichatou); - } - - public static void main(String[] args) { - SpringApplication.run(ProjetInduApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(ProjetInduApplication.class, args); + } } diff --git a/src/main/java/com/projet/projetIndu/bootstrap/DatabaseSeeder.java b/src/main/java/com/projet/projetIndu/bootstrap/DatabaseSeeder.java index 122c87f153c787b5527c8e5869a0cb6603a98adf..8397063f37f9ad2bc82ded246e04a5e2abcf9c30 100644 --- a/src/main/java/com/projet/projetIndu/bootstrap/DatabaseSeeder.java +++ b/src/main/java/com/projet/projetIndu/bootstrap/DatabaseSeeder.java @@ -1,19 +1,16 @@ package com.projet.projetIndu.bootstrap; import com.projet.projetIndu.entities.*; +import com.projet.projetIndu.repositories.*; +import org.springframework.boot.CommandLineRunner; import org.springframework.core.io.ClassPathResource; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; -import org.springframework.boot.CommandLineRunner; -import com.projet.projetIndu.repositories.DoctorRepository; -import com.projet.projetIndu.repositories.MedicalFilesRepository; -import com.projet.projetIndu.repositories.PatientRepository; -import com.projet.projetIndu.repositories.MedicalDocumentRepository; -import com.projet.projetIndu.repositories.AppointmentRepository; -import java.time.LocalDateTime; import java.io.IOException; -import java.nio.file.Files; +import java.io.InputStream; import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.List; @Component @@ -21,75 +18,83 @@ public class DatabaseSeeder implements CommandLineRunner { private final DoctorRepository doctorRepository; private final PatientRepository patientRepository; - private final MedicalFilesRepository medicalFilesRepository; + private final MedicalFileRepository medicalFileRepository; private final MedicalDocumentRepository medicalDocumentRepository; - private final AppointmentRepository appointmentRepository; // Ajout du repository des rendez-vous + private final AppointmentRepository appointmentRepository; + private final PasswordEncoder passwordEncoder; public DatabaseSeeder(DoctorRepository doctorRepository, PatientRepository patientRepository, - MedicalFilesRepository medicalFilesRepository, + MedicalFileRepository medicalFileRepository, MedicalDocumentRepository medicalDocumentRepository, - AppointmentRepository appointmentRepository) { // Injection du repository + AppointmentRepository appointmentRepository, + PasswordEncoder passwordEncoder) { this.doctorRepository = doctorRepository; this.patientRepository = patientRepository; - this.medicalFilesRepository = medicalFilesRepository; + this.medicalFileRepository = medicalFileRepository; this.medicalDocumentRepository = medicalDocumentRepository; this.appointmentRepository = appointmentRepository; + this.passwordEncoder = passwordEncoder; } @Override public void run(String... args) { - if (medicalFilesRepository.count() == 0) { - Doctor doctor1 = new Doctor("Jean", "Dupont", "Généraliste", "jean.dupont@example.com"); - Doctor doctor2 = new Doctor("Sophie", "Martin", "Cardiologue", "sophie.martin@example.com"); - + if (medicalFileRepository.count() == 0) { + Doctor doctor1 = new Doctor("Jean", "Dupont", "0444444444", "jean.dupont@example.com", "Generaliste", passwordEncoder.encode("password123")); + Doctor doctor2 = new Doctor("Sophie", "Martin", "0455555555", "sophie.martin@example.com", "Cardiologue", passwordEncoder.encode("password123")); doctorRepository.saveAll(List.of(doctor1, doctor2)); - //Patient patient1 = new Patient("Paul", "Durand", LocalDate.of(1990, 5, 15), "0678901234", "paul.durand@example.com", "5 Rue des Lilas", "Pollen", "Paracétamol"); - //Patient patient2 = new Patient("Alice", "Lemoine", LocalDate.of(1985, 10, 20), "0687654321", "alice.lemoine@example.com", "8 Rue du Lac", "Arachide", "Ibuprofène"); - Patient patient1 = new Patient("Paul", "Durand", LocalDate.parse("1990-05-15"), "0678901234", "paul.durand@example.com", "5 Rue des Lilas", "Pollen", "Paracétamol"); - Patient patient2 = new Patient("Alice", "Lemoine", LocalDate.parse("1990-05-15"), "0687654321", "alice.lemoine@example.com", "8 Rue du Lac", "Arachide", "Ibuprofène"); - + Patient patient1 = new Patient("Paul", "Durand", LocalDate.parse("1990-05-15"), "0678901234", "paul.durand@example.com", "5 Rue des Lilas", passwordEncoder.encode("test123")); + Patient patient2 = new Patient("Alice", "Lemoine", LocalDate.parse("1990-05-15"), "0687654321", "alice.lemoine@example.com", "8 Rue du Lac", passwordEncoder.encode("test123")); patientRepository.saveAll(List.of(patient1, patient2)); - MedicalFiles file1 = new MedicalFiles(patient1, doctor1, "Antécédents : Opération de l’appendicite."); - MedicalFiles file2 = new MedicalFiles(patient2, doctor2, "Antécédents : Hypertension traitée."); - - medicalFilesRepository.saveAll(List.of(file1, file2)); + MedicalFile file1 = new MedicalFile(patient1, "Arachide", "Ibuprofene"); + MedicalFile file2 = new MedicalFile(patient2, "Pollen", "Bisoprolol"); + medicalFileRepository.saveAll(List.of(file1, file2)); addDefaultDocument(file1, "documents/exemple1.pdf", "Rapport Médical.pdf"); addDefaultDocument(file2, "documents/exemple2.pdf", "Résultat Analyse.pdf"); + medicalFileRepository.saveAll(List.of(file1, file2)); + + HealthHistorical history1 = new HealthHistorical("Asthme", "Consultation pour suivi annuel", LocalDate.parse("2023-10-10"), file1); + HealthHistorical history2 = new HealthHistorical("Hypertension", "Consultation pour traitement du cœur", LocalDate.parse("2023-09-15"), file2); + file1.getHealthHistoricalList().add(history1); + file2.getHealthHistoricalList().add(history2); + + patient1.setMedicalFile(file1); + patient2.setMedicalFile(file2); + patientRepository.saveAll(List.of(patient1, patient2)); Appointment appointment1 = new Appointment(patient1, doctor1, LocalDateTime.now().plusDays(2), AppointmentStatus.CONFIRMED, "Consultation de suivi"); Appointment appointment2 = new Appointment(patient2, doctor2, LocalDateTime.now().plusDays(7), AppointmentStatus.PENDING, "Bilan annuel"); - appointmentRepository.saveAll(List.of(appointment1, appointment2)); - System.out.println("Données insérées : "); + System.out.println("Données insérées :"); System.out.println("Médecins : " + doctorRepository.count()); System.out.println("Patients : " + patientRepository.count()); - System.out.println("Dossiers médicaux : " + medicalFilesRepository.count()); + System.out.println("Dossiers médicaux : " + medicalFileRepository.count()); System.out.println("Documents médicaux : " + medicalDocumentRepository.count()); System.out.println("Rendez-vous : " + appointmentRepository.count()); } } - - private void addDefaultDocument(MedicalFiles medicalFile, String filePath, String fileName) { + private void addDefaultDocument(MedicalFile medicalFile, String filePath, String fileName) { try { ClassPathResource resource = new ClassPathResource(filePath); - byte[] fileData = Files.readAllBytes(resource.getFile().toPath()); + try (InputStream inputStream = resource.getInputStream()) { + byte[] fileData = inputStream.readAllBytes(); - MedicalDocument document = new MedicalDocument(); - document.setFileName(fileName); - document.setFileData(fileData); - document.setMedicalFile(medicalFile); + MedicalDocument document = new MedicalDocument(); + document.setFileName(fileName); + document.setFileData(fileData); + document.setMedicalFile(medicalFile); - medicalDocumentRepository.save(document); + medicalFile.getDocumentList().add(document); + medicalDocumentRepository.save(document); + } } catch (IOException e) { System.err.println("Erreur lors du chargement du fichier " + filePath); e.printStackTrace(); } } - } diff --git a/src/main/java/com/projet/projetIndu/config/SecurityConfig.java b/src/main/java/com/projet/projetIndu/config/SecurityConfig.java deleted file mode 100644 index 481194185edcd6b552908a3bacf76340bfa93350..0000000000000000000000000000000000000000 --- a/src/main/java/com/projet/projetIndu/config/SecurityConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.projet.projetIndu.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.web.SecurityFilterChain; - -@Configuration -public class SecurityConfig { - - @Bean - public BCryptPasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } - @Bean - public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - http - .csrf(csrf -> csrf.disable()) // Désactiver CSRF pour les tests (à activer en prod) - .authorizeHttpRequests(auth -> auth - .requestMatchers("/", "/register", "/login", "/css/**", "/js/**").permitAll() // Pages publiques - .requestMatchers("/dashboard/patient").hasAuthority("PATIENT") // Tableau de bord patient - .requestMatchers("/dashboard/doctor").hasAuthority("DOCTOR") // Tableau de bord médecin - .requestMatchers("/medical-files/**").authenticated() // Tout utilisateur connecté peut voir ses dossiers médicaux - .anyRequest().authenticated() - ) - .formLogin(form -> form - .loginPage("/login") - .defaultSuccessUrl("/dashboard", true) // Redirection après connexion - .permitAll() - ) - .logout(logout -> logout - .logoutUrl("/logout") - .logoutSuccessUrl("/login?logout") - .permitAll() - ); - - return http.build(); - } -} diff --git a/src/main/java/com/projet/projetIndu/controllers/AuthController.java b/src/main/java/com/projet/projetIndu/controllers/AuthController.java index 4c7a21ede1e20ac28f4e462d3387899dc06fabe4..8a20b5ddb10029e855fbddd0adc5dab3dd0dbf34 100644 --- a/src/main/java/com/projet/projetIndu/controllers/AuthController.java +++ b/src/main/java/com/projet/projetIndu/controllers/AuthController.java @@ -1,11 +1,15 @@ package com.projet.projetIndu.controllers; +import com.projet.projetIndu.dto.UserRegistrationDTO; import com.projet.projetIndu.entities.Role; -import com.projet.projetIndu.entities.User; import com.projet.projetIndu.services.UserService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import java.time.LocalDate; @Controller public class AuthController { @@ -24,24 +28,52 @@ public class AuthController { // Traite l'inscription @PostMapping("/register") public String registerUser( - @RequestParam String username, + @RequestParam String firstName, + @RequestParam String lastName, + @RequestParam String email, @RequestParam String password, - @RequestParam Role role, + @RequestParam String role, + @RequestParam(required = false) String dateOfBirth, // Facultatif + @RequestParam(required = false) String address, // Facultatif + @RequestParam(required = false) String speciality, // Facultatif Model model) { - if (userService.getUserByUsername(username).isPresent()) { + if (userService.getUserByUsername(email).isPresent()) { model.addAttribute("error", "L'utilisateur existe déjà !"); return "register"; } - // Enregistrer l'utilisateur - User newUser = userService.registerUser(username, password, role); + Role userRole; + try { + userRole = Role.valueOf(role.toUpperCase()); + } catch (IllegalArgumentException e) { + model.addAttribute("error", "Rôle invalide !"); + return "register"; + } + + UserRegistrationDTO dto = new UserRegistrationDTO(); + dto.setFirstName(firstName); + dto.setLastName(lastName); + dto.setEmail(email); + dto.setPassword(password); + dto.setRole(userRole); - // Redirection selon le rôle - if (newUser.getRole() == Role.DOCTOR) { - return "redirect:/doctor-dashboard"; - } else { - return "redirect:/patient-dashboard"; + if (userRole == Role.PATIENT) { + dto.setDateOfBirth(dateOfBirth != null ? LocalDate.parse(dateOfBirth) : null); + dto.setAddress(address); + } else if (userRole == Role.DOCTOR) { + dto.setSpeciality(speciality); } + + // Enregistrer l'utilisateur + try { + userService.registerUser(dto); + } catch (IllegalArgumentException e) { + model.addAttribute("error", e.getMessage()); + return "register"; + } + + return "redirect:/login?registered=true"; + } } diff --git a/src/main/java/com/projet/projetIndu/controllers/DashboardController.java b/src/main/java/com/projet/projetIndu/controllers/DashboardController.java deleted file mode 100644 index 37d97daba37cfae63df30ef1e3a9cd4a2cb066f8..0000000000000000000000000000000000000000 --- a/src/main/java/com/projet/projetIndu/controllers/DashboardController.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.projet.projetIndu.controllers; - -import org.springframework.security.core.Authentication; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; - -@Controller -@RequestMapping("/dashboard") -public class DashboardController { - - @GetMapping - public String redirectDashboard(Authentication authentication) { - System.out.println("Roles de l'utilisateur: " + authentication.getAuthorities()); - - if (authentication.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ROLE_DOCTOR"))) { - return "redirect:/dashboard/doctor"; - } else if (authentication.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ROLE_PATIENT"))) { - return "redirect:/dashboard/patient"; - } - return "redirect:/login"; - } - - - @GetMapping("/patient") - public String patientDashboard() { - System.out.println("Redirection vers le dashboard patient..."); - return "patient-dashboard"; - } - - @GetMapping("/doctor") - public String doctorDashboard() { - return "doctor-dashboard"; // Vue pour le médecin - } -} - diff --git a/src/main/java/com/projet/projetIndu/controllers/DoctorController.java b/src/main/java/com/projet/projetIndu/controllers/DoctorController.java index 4ee9077d5ba17200b6a1dc71fcc6aa3688c3311b..b93ce58fdaeabc2b74b49cb387205a8fb4c48186 100644 --- a/src/main/java/com/projet/projetIndu/controllers/DoctorController.java +++ b/src/main/java/com/projet/projetIndu/controllers/DoctorController.java @@ -4,13 +4,11 @@ import com.projet.projetIndu.entities.Doctor; import com.projet.projetIndu.services.DoctorService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.*; import java.util.List; +@RequestMapping("/doctors") @Controller public class DoctorController { private final DoctorService doctorService; @@ -20,35 +18,34 @@ public class DoctorController { this.doctorService = doctorService; } - @GetMapping("/doctors") + @GetMapping public String doctors(Model model) { List<Doctor> doctors = doctorService.getAllDoctors(); model.addAttribute("doctors", doctors); return "doctors"; } - // Formulaire pour ajouter un médecin - @GetMapping("/create-doctor") + @GetMapping("/create") public String showCreateForm(Model model) { model.addAttribute("doctor", new Doctor()); return "create-doctor"; } - // POST pour enregistrer un médecin - @PostMapping("/doctors") + + @PostMapping public String createDoctor(@ModelAttribute Doctor doctor) { doctorService.saveDoctor(doctor); return "redirect:/doctors"; } - @GetMapping("doctors/search") + @GetMapping("/search") public String searchDoctor(@RequestParam("firstName") String firstName, @RequestParam("lastName") String lastName, Model model) { List<Doctor> doctors = doctorService.getDoctorByName(firstName, lastName); model.addAttribute("doctors", doctors); return "doctors"; } - @GetMapping("/doctors/dashboard") + @GetMapping("/dashboard") public String showDoctorDashboard(Model model) { return "doctor-dashboard"; } diff --git a/src/main/java/com/projet/projetIndu/controllers/HomeController.java b/src/main/java/com/projet/projetIndu/controllers/HomeController.java index 40639b32f2e92f1fce92003a912b2193afc2d8f0..b07e68ec2ed2a35513feefc5ead749b5e8c17816 100644 --- a/src/main/java/com/projet/projetIndu/controllers/HomeController.java +++ b/src/main/java/com/projet/projetIndu/controllers/HomeController.java @@ -1,13 +1,28 @@ package com.projet.projetIndu.controllers; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; +import java.util.Collection; + @Controller public class HomeController { @GetMapping("/") - public String home() { + public String home(Model model) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication != null && authentication.isAuthenticated() && !authentication.getPrincipal().equals("anonymousUser")) { + model.addAttribute("username", authentication.getName()); + + Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities(); + boolean isDoctor = authorities.stream().anyMatch(auth -> auth.getAuthority().equals("DOCTOR")); + model.addAttribute("isDoctor", isDoctor); + } + return "home"; } } diff --git a/src/main/java/com/projet/projetIndu/controllers/LoginController.java b/src/main/java/com/projet/projetIndu/controllers/LoginController.java index c444a66db08224e96c5a657fd0c7d94a377664f0..c543594981c451c97858355611e2ed9a7628d76e 100644 --- a/src/main/java/com/projet/projetIndu/controllers/LoginController.java +++ b/src/main/java/com/projet/projetIndu/controllers/LoginController.java @@ -7,7 +7,7 @@ import org.springframework.web.bind.annotation.GetMapping; public class LoginController { @GetMapping("/login") - public String login() { + public String loginPage() { return "login"; } } diff --git a/src/main/java/com/projet/projetIndu/controllers/MedicalFilesController.java b/src/main/java/com/projet/projetIndu/controllers/MedicalFileController.java similarity index 58% rename from src/main/java/com/projet/projetIndu/controllers/MedicalFilesController.java rename to src/main/java/com/projet/projetIndu/controllers/MedicalFileController.java index 1b9c62bd947bcaff4ee5827779413a23f27d26e1..c8bad472512959f849e0f3182606ea209c531357 100644 --- a/src/main/java/com/projet/projetIndu/controllers/MedicalFilesController.java +++ b/src/main/java/com/projet/projetIndu/controllers/MedicalFileController.java @@ -1,9 +1,9 @@ package com.projet.projetIndu.controllers; import com.projet.projetIndu.entities.MedicalDocument; -import com.projet.projetIndu.entities.MedicalFiles; +import com.projet.projetIndu.entities.MedicalFile; import com.projet.projetIndu.repositories.MedicalDocumentRepository; -import com.projet.projetIndu.services.MedicalFilesService; +import com.projet.projetIndu.services.MedicalFileService; import org.springframework.http.*; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -12,33 +12,36 @@ import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import java.io.IOException; +import java.time.LocalDate; import java.util.List; import java.util.Optional; @Controller @RequestMapping("/medical-files") -public class MedicalFilesController { +public class MedicalFileController { - private final MedicalFilesService medicalFilesService; + private final MedicalFileService medicalFileService; private final MedicalDocumentRepository medicalDocumentRepository; - public MedicalFilesController(MedicalFilesService medicalFilesService, MedicalDocumentRepository medicalDocumentRepository) { - this.medicalFilesService = medicalFilesService; + public MedicalFileController(MedicalFileService medicalFileService, MedicalDocumentRepository medicalDocumentRepository) { + this.medicalFileService = medicalFileService; this.medicalDocumentRepository = medicalDocumentRepository; } // Afficher tous les dossiers médicaux @GetMapping public String listMedicalFiles(Model model) { - List<MedicalFiles> medicalFiles = medicalFilesService.getAllMedicalFiles(); + List<MedicalFile> medicalFiles = medicalFileService.getAllMedicalFiles(); + System.out.println("Dossiers médicaux récupérés : " + medicalFiles.size()); model.addAttribute("medicalFiles", medicalFiles); return "medical-files"; } + // Afficher un dossier médical spécifique @GetMapping("/{id}") public String viewMedicalFile(@PathVariable Long id, Model model) { - return medicalFilesService.getMedicalFileById(id) + return medicalFileService.getMedicalFileById(id) .map(medicalFile -> { model.addAttribute("medicalFile", medicalFile); return "view-medical-file"; @@ -48,51 +51,56 @@ public class MedicalFilesController { // Créer un dossier médical @PostMapping("/create") - public String createMedicalFile(@ModelAttribute MedicalFiles medicalFiles) { - medicalFilesService.saveMedicalFiles(medicalFiles); + public String createMedicalFile(@ModelAttribute MedicalFile medicalFile) { + medicalFileService.saveMedicalFiles(medicalFile); return "redirect:/medical-files"; } // Mettre à jour l'historique médical @PostMapping("/{id}/history") - public String updateMedicalFileHistory(@PathVariable Long id, @RequestParam String history) { - medicalFilesService.updateMedicalFileHistory(id, history); + public String updateMedicalFileHistory(@PathVariable Long id, + @RequestParam String antecedent, + @RequestParam String notes, + @RequestParam LocalDate consultationDate) { + medicalFileService.updateMedicalFileHistory(id, antecedent, notes, consultationDate); return "redirect:/medical-files/" + id; } + // Ajouter un document à un dossier médical @PostMapping("/{id}/documents") - public String uploadMedicalFileDocument(@PathVariable Long id, @RequestParam("document") MultipartFile document) { + public String uploadMedicalFileDocument(@PathVariable Long id, @RequestParam("document") MultipartFile document, RedirectAttributes redirectAttributes) { try { - medicalFilesService.uploadMedicalFileDocument(id, document); + medicalFileService.uploadMedicalFileDocument(id, document); } catch (IOException e) { e.printStackTrace(); - return "error"; + redirectAttributes.addFlashAttribute("errorMessage", "Erreur lors de l'upload du document."); + return "redirect:/medical-files/" + id; } return "redirect:/medical-files/" + id; } + // Télécharger un document médical @GetMapping("/{id}/documents/{docId}") @ResponseBody public ResponseEntity<byte[]> getMedicalFileDocument(@PathVariable Long id, @PathVariable Long docId) { - Optional<MedicalDocument> document = medicalDocumentRepository.findById(docId); - - if (document.isPresent()) { - byte[] documentData = document.get().getFileData(); + try { + MedicalDocument document = medicalFileService.getMedicalFileDocument(id, docId); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); headers.setContentDisposition(ContentDisposition.attachment() - .filename(document.get().getFileName()) + .filename(document.getFileName()) .build()); - return new ResponseEntity<>(documentData, headers, HttpStatus.OK); + return new ResponseEntity<>(document.getFileData(), headers, HttpStatus.OK); + } catch (RuntimeException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null); } - - return new ResponseEntity<>(HttpStatus.NOT_FOUND); } + // Supprimer un document médical @DeleteMapping("/{id}/documents/{docId}") public String deleteDocument(@PathVariable Long id, @PathVariable Long docId, RedirectAttributes redirectAttributes) { @@ -108,10 +116,17 @@ public class MedicalFilesController { return "redirect:/medical-files/" + id; } + // Supprimer un dossier médical @DeleteMapping("/{id}") - public String deleteMedicalFile(@PathVariable Long id) { - medicalFilesService.deleteMedicalFileById(id); + public String deleteMedicalFile(@PathVariable Long id, RedirectAttributes redirectAttributes) { + try { + medicalFileService.deleteMedicalFileById(id); + redirectAttributes.addFlashAttribute("successMessage", "Dossier médical supprimé avec succès."); + } catch (Exception e) { + redirectAttributes.addFlashAttribute("errorMessage", "Erreur lors de la suppression du dossier médical."); + } return "redirect:/medical-files"; } + } diff --git a/src/main/java/com/projet/projetIndu/controllers/PatientController.java b/src/main/java/com/projet/projetIndu/controllers/PatientController.java new file mode 100644 index 0000000000000000000000000000000000000000..ceb65ab10c362058f1f1be272927899782dafd17 --- /dev/null +++ b/src/main/java/com/projet/projetIndu/controllers/PatientController.java @@ -0,0 +1,10 @@ +package com.projet.projetIndu.controllers; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@RequestMapping("/patients") // doit concorder avec la route dans le SecurityConfig +@Controller +public class PatientController { + +} diff --git a/src/main/java/com/projet/projetIndu/dto/RegisterRequest.java b/src/main/java/com/projet/projetIndu/dto/RegisterRequest.java deleted file mode 100644 index e5a363d2512e5f60bae6d2e60b42a0029c904adc..0000000000000000000000000000000000000000 --- a/src/main/java/com/projet/projetIndu/dto/RegisterRequest.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.projet.projetIndu.dto; - -import com.projet.projetIndu.entities.Role; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class RegisterRequest { - private String username; - private String password; - private Role role; -} diff --git a/src/main/java/com/projet/projetIndu/dto/UserRegistrationDTO.java b/src/main/java/com/projet/projetIndu/dto/UserRegistrationDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..78114498b32bbff49c69a8fb16c0db52747dabb2 --- /dev/null +++ b/src/main/java/com/projet/projetIndu/dto/UserRegistrationDTO.java @@ -0,0 +1,21 @@ +package com.projet.projetIndu.dto; + +import com.projet.projetIndu.entities.Role; +import lombok.Getter; +import lombok.Setter; +import java.time.LocalDate; + +@Getter +@Setter +public class UserRegistrationDTO { + private String firstName; + private String lastName; + private String phoneNumber; + private String email; //utilisé comme username + private String password; + private Role role; + private String speciality; // Uniquement pour les doctors + private LocalDate dateOfBirth; // Uniquement pour les patients + private String address; // Uniquement pour les patients +} + diff --git a/src/main/java/com/projet/projetIndu/entities/Admin.java b/src/main/java/com/projet/projetIndu/entities/Admin.java new file mode 100644 index 0000000000000000000000000000000000000000..b1afc5dbeb0b6a8a36f481f9de9aca6d29a88a66 --- /dev/null +++ b/src/main/java/com/projet/projetIndu/entities/Admin.java @@ -0,0 +1,14 @@ +package com.projet.projetIndu.entities; + +import jakarta.persistence.Column; +import jakarta.persistence.DiscriminatorValue; +import jakarta.persistence.Entity; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@DiscriminatorValue("ADMIN") +public class Admin extends User { +} diff --git a/src/main/java/com/projet/projetIndu/entities/Appointment.java b/src/main/java/com/projet/projetIndu/entities/Appointment.java index 0b8fead5e0b789ec4592dc6e769fb56d38b793e5..5af4c61c08ceb90a19d5f148a61ac29223fcb57c 100644 --- a/src/main/java/com/projet/projetIndu/entities/Appointment.java +++ b/src/main/java/com/projet/projetIndu/entities/Appointment.java @@ -1,6 +1,7 @@ package com.projet.projetIndu.entities; import jakarta.persistence.*; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -13,6 +14,7 @@ import java.time.LocalDateTime; @Getter @Setter @NoArgsConstructor +@AllArgsConstructor public class Appointment { @Id @@ -21,11 +23,15 @@ public class Appointment { @ManyToOne @JoinColumn(name = "patient_id", nullable = false) - private Patient patient; //clé étrangère vers Patient + private Patient patient; @ManyToOne @JoinColumn(name = "doctor_id", nullable = false) - private Doctor doctor; //clé étrangère vers Doctor + private Doctor doctor; + + @OneToOne + @JoinColumn(name = "invoice_id", nullable = true) + private Invoice invoice; @DateTimeFormat(pattern = "dd/MM/yyyy HH:mm") @Column(nullable = false, updatable = false) @@ -51,5 +57,4 @@ public class Appointment { } - } diff --git a/src/main/java/com/projet/projetIndu/entities/Doctor.java b/src/main/java/com/projet/projetIndu/entities/Doctor.java index 7da0a7541443949a80acece2a6bf52e9ca397679..cc524e6a6a2b320b75e1d7d8c1c75d3ca20a98a1 100644 --- a/src/main/java/com/projet/projetIndu/entities/Doctor.java +++ b/src/main/java/com/projet/projetIndu/entities/Doctor.java @@ -1,47 +1,32 @@ package com.projet.projetIndu.entities; -import jakarta.persistence.*; +import jakarta.persistence.CascadeType; +import jakarta.persistence.DiscriminatorValue; +import jakarta.persistence.Entity; +import jakarta.persistence.OneToMany; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; @Entity -@Table(name = "doctors") @Getter @Setter +@DiscriminatorValue("DOCTOR") @NoArgsConstructor -public class Doctor { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(nullable = false) - private String firstName; - - @Column(nullable = false) - private String lastName; - +public class Doctor extends User { private String speciality; - @Column(unique = true, nullable = false) - private String email; + @OneToMany(mappedBy = "doctor", cascade = CascadeType.ALL, orphanRemoval = true) + private List<Appointment> appointmentList = new ArrayList<>(); - private String phone; - private String address; - - @Column(nullable = false, updatable = false) - private LocalDateTime createdAt = LocalDateTime.now(); - - - /// Pour le codage en dur (à retirer ensuite) - public Doctor(String firstName, String lastName, String speciality, String email) { - this.firstName = firstName; - this.lastName = lastName; + public Doctor(String firstName, String lastName, String phoneNumber, String email, String speciality, String password) { + super(firstName, lastName, phoneNumber, email, password); + this.role = Role.DOCTOR; this.speciality = speciality; - this.email = email; } + } diff --git a/src/main/java/com/projet/projetIndu/entities/HealthHistorical.java b/src/main/java/com/projet/projetIndu/entities/HealthHistorical.java new file mode 100644 index 0000000000000000000000000000000000000000..e6ed7270292eec91461cddc0120554b43df9e912 --- /dev/null +++ b/src/main/java/com/projet/projetIndu/entities/HealthHistorical.java @@ -0,0 +1,34 @@ +package com.projet.projetIndu.entities; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Entity +@Data +@NoArgsConstructor +@AllArgsConstructor +public class HealthHistorical { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String antecedent; + private String notes; + private LocalDate consultationDate; + + @ManyToOne + @JoinColumn(name = "medical_file_id", nullable = false) + private MedicalFile medicalFile; + + public HealthHistorical(String antecedent, String notes, LocalDate consultationDate, MedicalFile medicalFile) { + this.antecedent = antecedent; + this.notes = notes; + this.consultationDate = consultationDate; + this.medicalFile = medicalFile; + } + +} \ No newline at end of file diff --git a/src/main/java/com/projet/projetIndu/entities/HistoriqueMedical.java b/src/main/java/com/projet/projetIndu/entities/HistoriqueMedical.java deleted file mode 100644 index dd369e544c5d260d6319d70c2fe4f88e00bd55de..0000000000000000000000000000000000000000 --- a/src/main/java/com/projet/projetIndu/entities/HistoriqueMedical.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.projet.projetIndu.entities; - -import jakarta.persistence.*; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.time.LocalDate; - -@Entity -@Data -@NoArgsConstructor -@AllArgsConstructor -class HistoriqueMedical { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - private String antecedents; - private String notes; - private LocalDate dateConsultation; - - @ManyToOne - @JoinColumn(name = "patient_id") - private Patient patient; -} \ No newline at end of file diff --git a/src/main/java/com/projet/projetIndu/entities/Invoice.java b/src/main/java/com/projet/projetIndu/entities/Invoice.java index 855839ac965847dc8f35dd95ab1120655a3f78c6..af8b413d70da5d96259159d0ac97364fb9c76e2d 100644 --- a/src/main/java/com/projet/projetIndu/entities/Invoice.java +++ b/src/main/java/com/projet/projetIndu/entities/Invoice.java @@ -18,14 +18,6 @@ public class Invoice { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne - @JoinColumn(name = "patient_id", nullable = false) - private Patient patient; //clé étrangère vers Patient - - @ManyToOne - @JoinColumn(name = "doctor_id", nullable = false) - private Doctor doctor; //clé étrangère vers Doctor - @Column(nullable = false) private double amount; diff --git a/src/main/java/com/projet/projetIndu/entities/MedicalDocument.java b/src/main/java/com/projet/projetIndu/entities/MedicalDocument.java index 919b9b705942ca9b467e3416690c9101d2e1653e..fab8f1650b5d1e210af010aab967644ba6c9ed1d 100644 --- a/src/main/java/com/projet/projetIndu/entities/MedicalDocument.java +++ b/src/main/java/com/projet/projetIndu/entities/MedicalDocument.java @@ -21,6 +21,7 @@ public class MedicalDocument { private byte[] fileData; @ManyToOne - @JoinColumn(name = "medical_file_id") - private MedicalFiles medicalFile; + @JoinColumn(name = "medical_file_id", nullable = true) + private MedicalFile medicalFile; + } diff --git a/src/main/java/com/projet/projetIndu/entities/MedicalFiles.java b/src/main/java/com/projet/projetIndu/entities/MedicalFile.java similarity index 51% rename from src/main/java/com/projet/projetIndu/entities/MedicalFiles.java rename to src/main/java/com/projet/projetIndu/entities/MedicalFile.java index 00a1415b5134b7b8d592b6263da0c57b69c8e436..d83a62f11d3ba9aa8e5924d75352553dbdcf3431 100644 --- a/src/main/java/com/projet/projetIndu/entities/MedicalFiles.java +++ b/src/main/java/com/projet/projetIndu/entities/MedicalFile.java @@ -1,6 +1,7 @@ package com.projet.projetIndu.entities; import jakarta.persistence.*; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -14,33 +15,35 @@ import java.util.List; @Getter @Setter @NoArgsConstructor -public class MedicalFiles { +@AllArgsConstructor +public class MedicalFile { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne - @JoinColumn(name = "patient_id", nullable = false) - private Patient patient; //clé étrangère vers Patient + private String allergy; + private String treatment; - @ManyToOne - @JoinColumn(name = "doctor_id", nullable = false) - private Doctor doctor; //clé étrangère vers Doctor + @OneToMany(mappedBy = "medicalFile", cascade = CascadeType.ALL, orphanRemoval = true) + private List<HealthHistorical> healthHistoricalList = new ArrayList<>(); - @Column(nullable = false, columnDefinition = "TEXT") - private String history; + @OneToOne + @JoinColumn(name = "patient_id", nullable = false) + private Patient patient; @OneToMany(mappedBy = "medicalFile", cascade = CascadeType.ALL, orphanRemoval = true) - private List<MedicalDocument> documents = new ArrayList<>(); + private List<MedicalDocument> documentList = new ArrayList<>(); @Column(nullable = false, updatable = false) private LocalDateTime createdAt = LocalDateTime.now(); - public MedicalFiles(Patient patient, Doctor doctor, String history) { + public MedicalFile(Patient patient, String allergy, String treatment) { this.patient = patient; - this.doctor = doctor; - this.history = history; + this.allergy = allergy; + this.treatment = treatment; + this.healthHistoricalList = new ArrayList<>(); + this.documentList = new ArrayList<>(); } } diff --git a/src/main/java/com/projet/projetIndu/entities/MedicalRecord.java b/src/main/java/com/projet/projetIndu/entities/MedicalRecord.java deleted file mode 100644 index 9605f4d890bd29dae4b3cb187d8a3b18094326ba..0000000000000000000000000000000000000000 --- a/src/main/java/com/projet/projetIndu/entities/MedicalRecord.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.projet.projetIndu.entities; - -import jakarta.persistence.*; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.time.LocalDateTime; - -@Entity -@Table(name = "medical_records") -@Getter -@Setter -@NoArgsConstructor -class MedicalRecord { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne - @JoinColumn(name = "patient_id", nullable = false) - private Patient patient; - - private String recordType; - private String description; - private LocalDateTime recordDate = LocalDateTime.now(); -} diff --git a/src/main/java/com/projet/projetIndu/entities/Notification.java b/src/main/java/com/projet/projetIndu/entities/Notification.java index 9abd44b341bfb03490198c1d1b38e36dd43e1a95..46f222f6dae1d13bc3b0876f8b9bd489ff01a963 100644 --- a/src/main/java/com/projet/projetIndu/entities/Notification.java +++ b/src/main/java/com/projet/projetIndu/entities/Notification.java @@ -18,10 +18,6 @@ public class Notification { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne - @JoinColumn(name = "user_id", nullable = false) - private User user; //clé étrangère vers User - @Column(columnDefinition = "TEXT") private String content; @@ -35,4 +31,9 @@ public class Notification { @Column(nullable = false, updatable = false) private LocalDateTime createdAt = LocalDateTime.now(); + + @ManyToOne + @JoinColumn(name = "user_id", nullable = false) + private User user; + } diff --git a/src/main/java/com/projet/projetIndu/entities/Patient.java b/src/main/java/com/projet/projetIndu/entities/Patient.java index 45679c12ea7c54c5a9ae20ca9ed7ee696dec7672..047a23746e42ecaea0ffeeaabf901472d0fe22f5 100644 --- a/src/main/java/com/projet/projetIndu/entities/Patient.java +++ b/src/main/java/com/projet/projetIndu/entities/Patient.java @@ -6,56 +6,29 @@ import lombok.NoArgsConstructor; import lombok.Setter; import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.Date; +import java.util.ArrayList; import java.util.List; @Entity -@Table(name = "patients") @Getter @Setter +@DiscriminatorValue("PATIENT") @NoArgsConstructor -public class Patient { +public class Patient extends User { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(nullable = false) - private String firstName; - - @Column(nullable = false) - private String lastName; - - @Column(nullable = false) private LocalDate dateOfBirth; - - private String phoneNumber; - - @Column(unique = true, nullable = false) - private String email; - - private String address; - private String allergy; - private String treatment; - - @Column(nullable = false, updatable = false) - private LocalDateTime createdAt = LocalDateTime.now(); - @OneToMany(mappedBy = "patient", cascade = CascadeType.ALL) - private List<MedicalRecord> medicalRecords; + private List<Appointment> appointmentList = new ArrayList<>(); - public Patient(/*Long id,*/ String firstName, String lastName, LocalDate dateOfBirth, String phoneNumber, String email, String address, String allergy, String treatment) { - /*this.id = id;*/ - this.firstName = firstName; - this.lastName = lastName; + @OneToOne(mappedBy = "patient", cascade = CascadeType.ALL) + private MedicalFile medicalFile; + + public Patient(String firstName, String lastName, LocalDate dateOfBirth, String phoneNumber, String email, String address, String password) { + super(firstName, lastName, phoneNumber, email, address, password); + this.role = Role.PATIENT; this.dateOfBirth = dateOfBirth; - this.phoneNumber = phoneNumber; - this.email = email; - this.address = address; - this.allergy = allergy; - this.treatment = treatment; } + } diff --git a/src/main/java/com/projet/projetIndu/entities/Statistic.java b/src/main/java/com/projet/projetIndu/entities/Statistic.java deleted file mode 100644 index a19420a174885f9b546d93be25c6839d76ab792e..0000000000000000000000000000000000000000 --- a/src/main/java/com/projet/projetIndu/entities/Statistic.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.projet.projetIndu.entities; - -import jakarta.persistence.*; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.time.LocalDateTime; -import java.util.Date; - -@Entity -@Table(name = "statistics") -@Getter -@Setter -@NoArgsConstructor -public class Statistic { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne - @JoinColumn(name = "doctor_id", nullable = false) - private Doctor doctor; //clé étrangère vers Doctor - - @Column(nullable = false) - private Date date; - - private int consultations_count; - private int patients_count; - private double total_revenues; - - @Column(nullable = false, updatable = false) - private LocalDateTime createdAt = LocalDateTime.now(); -} diff --git a/src/main/java/com/projet/projetIndu/entities/User.java b/src/main/java/com/projet/projetIndu/entities/User.java index 4446bd8bc5f637483beb328e88b1a133becd9ecf..709f0de420efba52e07ace80394d1d2735e68240 100644 --- a/src/main/java/com/projet/projetIndu/entities/User.java +++ b/src/main/java/com/projet/projetIndu/entities/User.java @@ -6,42 +6,61 @@ import lombok.NoArgsConstructor; import lombok.Setter; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; @Entity @Table(name = "users") @Getter @Setter @NoArgsConstructor -public class User { +@Inheritance(strategy = InheritanceType.SINGLE_TABLE) +@DiscriminatorColumn(name = "role", discriminatorType = DiscriminatorType.STRING) +public abstract class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(nullable = false, unique = true) - private String username; + @Column(nullable = false) + private String firstName; + @Column(nullable = false) + private String lastName; + private String phoneNumber; + @Column(unique = true, nullable = false) + private String email; // Utilisé comme identifiant + private String address; + @Column(nullable = false) private String password; @Enumerated(EnumType.STRING) - @Column(nullable = false) - private Role role; - - @ManyToOne - @JoinColumn(name = "medecin_id") - private Doctor doctor; + @Column(nullable = false, updatable = false, insertable = false) + protected Role role; - @ManyToOne - @JoinColumn(name = "patient_id") - private Patient patient; + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) + private List<Notification> notificationList = new ArrayList<>(); @Column(nullable = false, updatable = false) private LocalDateTime createdAt = LocalDateTime.now(); - public User(String username, String password, Role role) { - this.username = username; + protected User(String firstName, String lastName, String phoneNumber, String email, String address, String password) { + this.firstName = firstName; + this.lastName = lastName; + this.phoneNumber = phoneNumber; + this.email = email; + this.address = address; this.password = password; - this.role = role; } + + protected User(String firstName, String lastName, String phoneNumber, String email, String password) { + this.firstName = firstName; + this.lastName = lastName; + this.phoneNumber = phoneNumber; + this.email = email; + this.password = password; + } + + } diff --git a/src/main/java/com/projet/projetIndu/repositories/AdminRepository.java b/src/main/java/com/projet/projetIndu/repositories/AdminRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..c170bd69e3740a27b629b74605b27196721d0bde --- /dev/null +++ b/src/main/java/com/projet/projetIndu/repositories/AdminRepository.java @@ -0,0 +1,7 @@ +package com.projet.projetIndu.repositories; + +import com.projet.projetIndu.entities.Admin; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface AdminRepository extends JpaRepository<Admin, Long> { +} diff --git a/src/main/java/com/projet/projetIndu/repositories/MedicalFileRepository.java b/src/main/java/com/projet/projetIndu/repositories/MedicalFileRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..54f79ccf4eacc1bcce09978871aa887cb2df20e1 --- /dev/null +++ b/src/main/java/com/projet/projetIndu/repositories/MedicalFileRepository.java @@ -0,0 +1,8 @@ +package com.projet.projetIndu.repositories; + +import com.projet.projetIndu.entities.MedicalFile; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MedicalFileRepository extends JpaRepository<MedicalFile, Long> { + +} diff --git a/src/main/java/com/projet/projetIndu/repositories/MedicalFilesRepository.java b/src/main/java/com/projet/projetIndu/repositories/MedicalFilesRepository.java deleted file mode 100644 index 6d6d04f962c65f7d6ba1e5ec7ef3c737f2635db3..0000000000000000000000000000000000000000 --- a/src/main/java/com/projet/projetIndu/repositories/MedicalFilesRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.projet.projetIndu.repositories; - -import com.projet.projetIndu.entities.MedicalFiles; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface MedicalFilesRepository extends JpaRepository<MedicalFiles, Long> { - -} diff --git a/src/main/java/com/projet/projetIndu/repositories/StatisticRepository.java b/src/main/java/com/projet/projetIndu/repositories/StatisticRepository.java deleted file mode 100644 index 23e51eb7da8a15dde3a1aad2f37267e8397c7585..0000000000000000000000000000000000000000 --- a/src/main/java/com/projet/projetIndu/repositories/StatisticRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.projet.projetIndu.repositories; - -import com.projet.projetIndu.entities.Statistic; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface StatisticRepository extends JpaRepository<Statistic, Long> { -} diff --git a/src/main/java/com/projet/projetIndu/repositories/UserRepository.java b/src/main/java/com/projet/projetIndu/repositories/UserRepository.java index 4469777bd63b5c7e998b99ff6b15ac938dc0d2d6..b0a4cd35c13138dcee7cf27f74a24e857a5a0b35 100644 --- a/src/main/java/com/projet/projetIndu/repositories/UserRepository.java +++ b/src/main/java/com/projet/projetIndu/repositories/UserRepository.java @@ -7,9 +7,6 @@ import java.util.Optional; public interface UserRepository extends JpaRepository<User,Long> { - //trouver l'utilisateur avec son username - Optional<User> findByUsername(String username); - - //vérifie si le username existe déjà - boolean existsByUsername(String username); + Optional<User> findByEmail(String email); + boolean existsByEmail(String email); } diff --git a/src/main/java/com/projet/projetIndu/security/CustomUserDetailsService.java b/src/main/java/com/projet/projetIndu/security/CustomUserDetailsService.java new file mode 100644 index 0000000000000000000000000000000000000000..6fee490eec3ec50beb60f56d277ec407af9170ad --- /dev/null +++ b/src/main/java/com/projet/projetIndu/security/CustomUserDetailsService.java @@ -0,0 +1,45 @@ +package com.projet.projetIndu.security; + +import com.projet.projetIndu.entities.User; +import com.projet.projetIndu.repositories.UserRepository; +import jakarta.transaction.Transactional; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class CustomUserDetailsService implements UserDetailsService { + + private final UserRepository userRepository; + + public CustomUserDetailsService(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @Override + @Transactional + public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { + System.out.println("Tentative de connexion avec l'email : " + email); + Optional<User> optionalUser = userRepository.findByEmail(email); + + if (optionalUser.isEmpty()) { + System.out.println("Utilisateur non trouvé !"); + throw new UsernameNotFoundException("Utilisateur non trouvé avec l'email : " + email); + } + + User user = optionalUser.get(); + System.out.println("Utilisateur trouvé : " + user.getEmail() + " | Rôle : " + user.getRole()); + + return org.springframework.security.core.userdetails.User.builder() + .username(user.getEmail()) + .password(user.getPassword()) + .authorities(String.valueOf(user.getRole())) + .build(); + } + + +} + diff --git a/src/main/java/com/projet/projetIndu/security/SecurityConfig.java b/src/main/java/com/projet/projetIndu/security/SecurityConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..da719e5a33f845f3eb6f4d628f3835459ad7e32b --- /dev/null +++ b/src/main/java/com/projet/projetIndu/security/SecurityConfig.java @@ -0,0 +1,91 @@ +package com.projet.projetIndu.security; + +import com.projet.projetIndu.repositories.UserRepository; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.core.GrantedAuthorityDefaults; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +@Configuration +public class SecurityConfig { + + @Bean + public BCryptPasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .authorizeHttpRequests(auth -> auth + .requestMatchers("/", "/register", "/login", "/css/**", "/js/**").permitAll() // Pages publiques + .requestMatchers("/admin/**").hasAuthority("ADMIN") + .requestMatchers("/doctors/**").hasAuthority("DOCTOR") + .requestMatchers("/patients/**").hasAuthority("PATIENT") + .anyRequest().authenticated() + ) + .formLogin(form -> form + .loginPage("/login") + .usernameParameter("email") + .passwordParameter("password") + .defaultSuccessUrl("/", false) + .successHandler((request, response, authentication) -> { + if (response.isCommitted()) return; + + String role = authentication.getAuthorities().iterator().next().getAuthority(); + + switch (role) { + case "ADMIN" -> response.sendRedirect("/admin/dashboard"); + case "DOCTOR" -> response.sendRedirect("/doctors/dashboard"); + case "PATIENT" -> response.sendRedirect("/patients/dashboard"); + default -> response.sendRedirect("/"); + } + }) + + .failureHandler((request, response, exception) -> { + response.sendRedirect("/login?error=true"); + }) + .permitAll() + ) + + .sessionManagement(session -> session + .maximumSessions(1) + .expiredUrl("/login?expired=true") + ) + + .logout(logout -> logout + .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) + .logoutSuccessUrl("/login?logout") + .permitAll() + ); + + return http.build(); + } + + @Bean + public UserDetailsService userDetailsService(UserRepository userRepository) { + return new CustomUserDetailsService(userRepository); + } + + + @Bean + public AuthenticationManager authenticationManager(UserDetailsService userDetailsService, BCryptPasswordEncoder passwordEncoder) { + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setUserDetailsService(userDetailsService); + provider.setPasswordEncoder(passwordEncoder); + return new ProviderManager(provider); + } + + @Bean + public GrantedAuthorityDefaults grantedAuthorityDefaults() { + return new GrantedAuthorityDefaults(""); + } + +} diff --git a/src/main/java/com/projet/projetIndu/services/MedicalFileService.java b/src/main/java/com/projet/projetIndu/services/MedicalFileService.java new file mode 100644 index 0000000000000000000000000000000000000000..a789deaff4fa4f8a70c78fdfc36338bc59b089e6 --- /dev/null +++ b/src/main/java/com/projet/projetIndu/services/MedicalFileService.java @@ -0,0 +1,118 @@ +package com.projet.projetIndu.services; + +import com.projet.projetIndu.entities.HealthHistorical; +import com.projet.projetIndu.entities.MedicalDocument; +import com.projet.projetIndu.entities.MedicalFile; +import com.projet.projetIndu.repositories.MedicalFileRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + +@Service +public class MedicalFileService { + private final MedicalFileRepository medicalFileRepository; + //private final List<MedicalFile> medicalFilesList = new ArrayList<>(); + + @Autowired + public MedicalFileService(MedicalFileRepository medicalFileRepository) { + this.medicalFileRepository = medicalFileRepository; + } + + public List<MedicalFile> getAllMedicalFiles() { + return medicalFileRepository.findAll(); + } + + public Optional<MedicalFile> getMedicalFileById(Long id) { + return medicalFileRepository.findById(id); + } + + public MedicalFile saveMedicalFiles(MedicalFile medicalFile) { + return medicalFileRepository.save(medicalFile); + } + + public void deleteMedicalFileById(Long id) { + medicalFileRepository.deleteById(id); + } + + public void updateMedicalFileHistory(Long id, String antecedent, String notes, LocalDate consultationDate) { + Optional<MedicalFile> optionalMedicalFile = medicalFileRepository.findById(id); + if (optionalMedicalFile.isPresent()) { + MedicalFile medicalFile = optionalMedicalFile.get(); + + HealthHistorical healthHistorical = new HealthHistorical(); + healthHistorical.setAntecedent(antecedent); + healthHistorical.setNotes(notes); + healthHistorical.setConsultationDate(consultationDate); + + healthHistorical.setMedicalFile(medicalFile); + + medicalFile.getHealthHistoricalList().add(healthHistorical); + + medicalFileRepository.save(medicalFile); + } else { + throw new RuntimeException("Dossier médical introuvable."); + } + } + + + public void uploadMedicalFileDocument(Long medicalFileId, MultipartFile file) throws IOException { + MedicalFile medicalFile = medicalFileRepository.findById(medicalFileId) + .orElseThrow(() -> new RuntimeException("Dossier médical introuvable")); + + if (file.getSize() > 10 * 1024 * 1024) { + throw new RuntimeException("Le fichier est trop volumineux."); + } + + MedicalDocument document = new MedicalDocument(); + document.setFileName(file.getOriginalFilename()); + document.setFileType(file.getContentType()); + document.setFileData(file.getBytes()); + document.setMedicalFile(medicalFile); + + medicalFile.getDocumentList().add(document); + medicalFileRepository.save(medicalFile); + } + + + public void deleteHealthHistorical(Long medicalFileId, Long healthHistoricalId) { + Optional<MedicalFile> optionalMedicalFile = medicalFileRepository.findById(medicalFileId); + if (optionalMedicalFile.isPresent()) { + MedicalFile medicalFile = optionalMedicalFile.get(); + + HealthHistorical healthHistorical = medicalFile.getHealthHistoricalList().stream() + .filter(h -> h.getId().equals(healthHistoricalId)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Antécédent médical introuvable.")); + + medicalFile.getHealthHistoricalList().remove(healthHistorical); + + medicalFileRepository.save(medicalFile); + } else { + throw new RuntimeException("Dossier médical introuvable."); + } + } + + public MedicalDocument getMedicalFileDocument(Long medicalFileId, Long documentId) { + Optional<MedicalFile> medicalFileOpt = medicalFileRepository.findById(medicalFileId); + if (medicalFileOpt.isEmpty()) { + throw new RuntimeException("Dossier médical introuvable."); + } + + MedicalFile medicalFile = medicalFileOpt.get(); + return medicalFile.getDocumentList().stream() + .filter(doc -> doc.getId().equals(documentId)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Document introuvable.")); + } + + +} + + + + diff --git a/src/main/java/com/projet/projetIndu/services/MedicalFilesService.java b/src/main/java/com/projet/projetIndu/services/MedicalFilesService.java deleted file mode 100644 index b81b8f6e51a45b64ac00a28bfaacd537ec496b10..0000000000000000000000000000000000000000 --- a/src/main/java/com/projet/projetIndu/services/MedicalFilesService.java +++ /dev/null @@ -1,160 +0,0 @@ -package com.projet.projetIndu.services; - -import com.projet.projetIndu.entities.Doctor; -import com.projet.projetIndu.entities.MedicalDocument; -import com.projet.projetIndu.entities.MedicalFiles; -import com.projet.projetIndu.entities.Patient; -import com.projet.projetIndu.repositories.MedicalFilesRepository; -import jakarta.annotation.PostConstruct; -import jakarta.persistence.EntityNotFoundException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -@Service -public class MedicalFilesService { - private final MedicalFilesRepository medicalFilesRepository; - //private final List<MedicalFiles> medicalFilesList = new ArrayList<>(); - - @Autowired - public MedicalFilesService(MedicalFilesRepository medicalFilesRepository) { - this.medicalFilesRepository = medicalFilesRepository; - } - - public List<MedicalFiles> getAllMedicalFiles() { - return medicalFilesRepository.findAll(); - } - - public Optional<MedicalFiles> getMedicalFileById(Long id) { - return medicalFilesRepository.findById(id); - } - - public MedicalFiles saveMedicalFiles(MedicalFiles medicalFiles) { - return medicalFilesRepository.save(medicalFiles); - } - - public void deleteMedicalFileById(Long id) { - medicalFilesRepository.deleteById(id); - } - - public void updateMedicalFileHistory(Long id, String history) { - Optional<MedicalFiles> optionalMedicalFile = medicalFilesRepository.findById(id); - if (optionalMedicalFile.isPresent()) { - MedicalFiles medicalFile = optionalMedicalFile.get(); - medicalFile.setHistory(history); // Mise à jour de l'historique - medicalFilesRepository.save(medicalFile); - } - } - - public void uploadMedicalFileDocument(Long medicalFileId, MultipartFile file) throws IOException { - MedicalFiles medicalFile = medicalFilesRepository.findById(medicalFileId) - .orElseThrow(() -> new RuntimeException("Dossier médical introuvable")); - - MedicalDocument document = new MedicalDocument(); - document.setFileName(file.getOriginalFilename()); - document.setFileType(file.getContentType()); - document.setFileData(file.getBytes()); - document.setMedicalFile(medicalFile); - - medicalFile.getDocuments().add(document); - medicalFilesRepository.save(medicalFile); - } - - - -} - - - - - - - - - -/// / Pour le dur -// -// @PostConstruct -// public void init() { // Charger les données une seule fois -// Patient patient1 = new Patient(1L, "Pierre", "Martinez", "10/05/1980", "0654789652", "jean.dupont@email.com", "1 rue de Paris", "Pollen", "Aspirine"); -// Doctor doctor1 = new Doctor(1L, "Jean", "Dupont", "Cardiologue", "jean.dupont@example.com"); -// -// medicalFilesList.add(new MedicalFiles(1L, patient1, doctor1, "Aucun antécédent majeur.")); -// } -// -// public List<MedicalFiles> getAllMedicalFiles() { -// return medicalFilesList; -// } - -// public Optional<MedicalFiles> getMedicalFileById(Long id) { -// return medicalFilesList.stream().filter(mf -> mf.getId().equals(id)).findFirst(); -// } - -// public void updateMedicalFile(Long id, String history) { -// medicalFilesList.stream() -// .filter(mf -> mf.getId().equals(id)) -// .findFirst() -// .ifPresent(mf -> mf.setHistory(history)); // Mise à jour de l'historique -// } - - /// Pour le codage en dur (à retirer ensuite avec la BDD) -// public List<MedicalFiles> getAllMedicalFiles() { -// // Récupérer les patients et médecins en dur -// Patient patient1 = new Patient(1L, "Pierre", "Martinez", "10/05/1980", "0654789652", "jean.dupont@email.com", "1 rue de Paris", "Pollen", "Aspirine"); -// Patient patient2 = new Patient(2L, "Marine", "Boz", "19/10/2001", "066666666", "marine.boz@email.com", "10 rue de Marseille", "Péniciline", "Bisoce"); -// Patient patient3 = new Patient(3L, "Laurie", "Marie", "23/11/1994", "0778456985", "marie.durand@email.com", "2 avenue des Lilas", "Arachides", "Paracétamol"); -// -// Doctor doctor1 = new Doctor(1L, "Jean", "Dupont", "Cardiologue", "jean.dupont@example.com"); -// Doctor doctor2 = new Doctor(2L, "Marie", "Curie", "Radiologue", "marie.curie@example.com"); -// Doctor doctor3 = new Doctor(3L, "Paul", "Durand", "Généraliste", "paul.durand@example.com"); -// -// return Arrays.asList( -// new MedicalFiles(1L, patient1, doctor1, "Aucun antécédent majeur."), -// new MedicalFiles(2L, patient2, doctor2, "Allergie à la pénicilline."), -// new MedicalFiles(3L, patient3, doctor3, "Diabète de type 2.") -// ); -// } - -// /// En dur -// public void updateMedicalFileDocument(Long id, byte[] document) { -// medicalFilesList.stream() -// .filter(mf -> mf.getId().equals(id)) -// .findFirst() -// .ifPresent(mf -> mf.setDocuments(document)); // Mise à jour du document -// } -// // DUR -// public void saveMedicalFile(MedicalFiles medicalFile) { -// medicalFilesRepository.save(medicalFile); // Persiste en base -// } - -// ///En dur -// public Optional<MedicalFiles> getMedicalFileById(Long id) { -// List<MedicalFiles> medicalFilesList = getAllMedicalFiles(); // Récupère les données en dur -// return medicalFilesList.stream() -// .filter(medicalFile -> medicalFile.getId().equals(id)) -// .findFirst(); -// } -// -// //En dur (remplace saveMedicalFiles pour l'instant) -// public void updateMedicalFile(Long id, String history, String documents) { -// List<MedicalFiles> medicalFilesList = getAllMedicalFiles(); -// -// for (MedicalFiles file : medicalFilesList) { -// if (file.getId().equals(id)) { -// file.setHistory(history); -// file.setDocuments(documents.getBytes()); -// break; -// } -// } -// } -// } - - - - diff --git a/src/main/java/com/projet/projetIndu/services/PatientService.java b/src/main/java/com/projet/projetIndu/services/PatientService.java index e0f4dfcbaca6a233a00465a92ae56823851a548c..48d0fe6548c13005fad2ae22fbc8a85695ad3478 100644 --- a/src/main/java/com/projet/projetIndu/services/PatientService.java +++ b/src/main/java/com/projet/projetIndu/services/PatientService.java @@ -1,12 +1,10 @@ package com.projet.projetIndu.services; -import com.projet.projetIndu.entities.Doctor; import com.projet.projetIndu.entities.Patient; import com.projet.projetIndu.repositories.PatientRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.Arrays; import java.util.List; import java.util.Optional; @@ -40,13 +38,3 @@ public class PatientService { patientRepository.deleteById(id); } } - -// /// En dur -// public List<Patient> getAllPatient() { -// return Arrays.asList( -// new Patient(1L, "Pierre", "Martinez", "10/05/1980", "0654789652", "jean.dupont@email.com", "1 rue de Paris", "Pollen", "Aspirine"), -// new Patient(2L, "Marine", "Boz", "19/10/2001", "066666666", "marine.boz@email.com", "10 rue de Marseille", "Péniciline", "Bisoce"), -// new Patient(3L, "Laurie", "Marie", "23/11/1994", "0778456985", "marie.durand@email.com", "2 avenue des Lilas", "Arachides", "Paracétamol") -// ); - - diff --git a/src/main/java/com/projet/projetIndu/services/StatisticService.java b/src/main/java/com/projet/projetIndu/services/StatisticService.java deleted file mode 100644 index 3f6b19ad33d3ebfe96e0e28e0253b5f6694f85b1..0000000000000000000000000000000000000000 --- a/src/main/java/com/projet/projetIndu/services/StatisticService.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.projet.projetIndu.services; - -import com.projet.projetIndu.entities.Statistic; -import com.projet.projetIndu.repositories.StatisticRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Optional; - -@Service -public class StatisticService { - private final StatisticRepository statisticRepository; - - @Autowired - public StatisticService(StatisticRepository statisticRepository) { - this.statisticRepository = statisticRepository; - } - - public List<Statistic> getAllStatistics() { - return statisticRepository.findAll(); - } - - public Optional<Statistic> getStatisticById(Long id) { - return statisticRepository.findById(id); - } - - public Statistic saveStatistic(Statistic statistic) { - return statisticRepository.save(statistic); - } - - public void deleteStatisticById(Long id) { - statisticRepository.deleteById(id); - } - -} diff --git a/src/main/java/com/projet/projetIndu/services/UserService.java b/src/main/java/com/projet/projetIndu/services/UserService.java index f088d0c30c0033341e8a83990b2706dfdcd3cdd0..ba62a2d3a93967a42ad289ac9ffd1c6572841ab7 100644 --- a/src/main/java/com/projet/projetIndu/services/UserService.java +++ b/src/main/java/com/projet/projetIndu/services/UserService.java @@ -1,6 +1,9 @@ package com.projet.projetIndu.services; -import com.projet.projetIndu.entities.Role; +import com.projet.projetIndu.dto.UserRegistrationDTO; +import com.projet.projetIndu.entities.Admin; +import com.projet.projetIndu.entities.Doctor; +import com.projet.projetIndu.entities.Patient; import com.projet.projetIndu.entities.User; import com.projet.projetIndu.repositories.UserRepository; import org.springframework.beans.factory.annotation.Autowired; @@ -12,11 +15,10 @@ import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @Service -public class UserService implements UserDetailsService{ +public class UserService implements UserDetailsService { private final UserRepository userRepository; private final BCryptPasswordEncoder passwordEncoder; @@ -30,13 +32,11 @@ public class UserService implements UserDetailsService{ return userRepository.findAll(); } - public Optional<User> getUserByUsername(String username) { - - return userRepository.findByUsername(username); + public Optional<User> getUserByUsername(String email) { + return userRepository.findByEmail(email); } public Optional<User> getUserById(Long id) { - return userRepository.findById(id); } @@ -48,25 +48,63 @@ public class UserService implements UserDetailsService{ userRepository.deleteById(id); } - public User registerUser(String username, String password, Role role) { - if (userRepository.findByUsername(username).isPresent()) { - throw new RuntimeException("L'utilisateur existe déjà !"); + public User registerUser(UserRegistrationDTO userDTO) { + if (userRepository.existsByEmail(userDTO.getEmail())) { + throw new IllegalArgumentException("Email already taken"); + } + + String encodedPassword = passwordEncoder.encode(userDTO.getPassword()); + User user; + + switch (userDTO.getRole()) { + case DOCTOR -> { + if (userDTO.getSpeciality() == null || userDTO.getSpeciality().isEmpty()) { + throw new IllegalArgumentException("Speciality is required for doctors"); + } + Doctor doctor = new Doctor(); + doctor.setSpeciality(userDTO.getSpeciality()); + user = doctor; + } + case PATIENT -> { + if (userDTO.getDateOfBirth() == null) { + throw new IllegalArgumentException("Date of birth is required for patients"); + } + if (userDTO.getAddress() == null || userDTO.getAddress().isBlank()) { + throw new IllegalArgumentException("Address is required for patients"); + } + Patient patient = new Patient(); + patient.setDateOfBirth(userDTO.getDateOfBirth()); + patient.setAddress(userDTO.getAddress()); + user = patient; + } + case ADMIN -> { + user = new Admin(); + } + default -> throw new IllegalArgumentException("Invalid role"); } - String encodedPassword = passwordEncoder.encode(password); - User user = new User(username, encodedPassword, role); + user.setFirstName(userDTO.getFirstName()); + user.setLastName(userDTO.getLastName()); + user.setPhoneNumber(userDTO.getPhoneNumber()); + user.setEmail(userDTO.getEmail()); + user.setPassword(encodedPassword); + user.setRole(userDTO.getRole()); + return userRepository.save(user); } @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - User user = userRepository.findByUsername(username) + public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { + User user = userRepository.findByEmail(email) .orElseThrow(() -> new UsernameNotFoundException("User not found")); + return org.springframework.security.core.userdetails.User - .withUsername(user.getUsername()) + .withUsername(user.getEmail()) .password(user.getPassword()) - .roles(user.getRole().name()) + .authorities(user.getClass().getSimpleName()) .build(); } + } + diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a00ae7713644ef7868e67dccdfa351a5126e275a..95add08cd8509282a08ebcaa89f95ea670b00fed 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,20 +1,15 @@ spring.application.name=projetIndu -spring.datasource.url=jdbc:mysql://localhost:3307/projet +spring.datasource.url=jdbc:mysql://localhost:3306/projet spring.datasource.username=root -spring.datasource.password=mypassword +spring.datasource.password=jessie spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect -spring.jpa.hibernate.ddl-auto=create +spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.show-sql=true -spring.jpa.properties.hibernate.format_sql=true spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html spring.thymeleaf.cache=false spring.servlet.multipart.max-file-size=100MB spring.servlet.multipart.max-request-size=100MB spring.mvc.hiddenmethod.filter.enabled=true - spring.banner.location=banner.txt -logging.level.org.springframework.security=DEBUG - - diff --git a/src/main/resources/sqls/create-tables.sql b/src/main/resources/sqls/create-tables.sql new file mode 100644 index 0000000000000000000000000000000000000000..7325dd15b416384fd1584fce0630b9c7a180815d --- /dev/null +++ b/src/main/resources/sqls/create-tables.sql @@ -0,0 +1,68 @@ +CREATE TABLE users ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + first_name VARCHAR(255) NOT NULL, + last_name VARCHAR(255) NOT NULL, + phone_number VARCHAR(255), + email VARCHAR(255) UNIQUE NOT NULL, + address VARCHAR(255), + password VARCHAR(255) NOT NULL, + role VARCHAR(50) NOT NULL, + created_at DATETIME NOT NULL +) ENGINE=InnoDB; + +CREATE TABLE notifications ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + content TEXT, + type VARCHAR(50) NOT NULL, + status VARCHAR(50) NOT NULL, + created_at DATETIME NOT NULL +) ENGINE=InnoDB; + +CREATE TABLE invoices ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + amount DOUBLE NOT NULL, + issue_date DATETIME NOT NULL, + status VARCHAR(50) NOT NULL, + created_at DATETIME NOT NULL +) ENGINE=InnoDB; + +CREATE TABLE appointments ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + patient_id BIGINT NOT NULL, + doctor_id BIGINT NOT NULL, + invoice_id BIGINT, + date_time DATETIME NOT NULL, + status VARCHAR(50) NOT NULL, + reason TEXT NOT NULL, + created_at DATETIME NOT NULL, + FOREIGN KEY (patient_id) REFERENCES users(id), + FOREIGN KEY (doctor_id) REFERENCES users(id), + FOREIGN KEY (invoice_id) REFERENCES invoices(id) +) ENGINE=InnoDB; + +CREATE TABLE medical_files ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + allergy VARCHAR(255), + treatment VARCHAR(255), + patient_id BIGINT UNIQUE, + created_at DATETIME NOT NULL, + FOREIGN KEY (patient_id) REFERENCES users(id) +) ENGINE=InnoDB; + +CREATE TABLE health_historical ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + antecedent VARCHAR(255), + notes VARCHAR(255), + consultation_date DATE, + medical_file_id BIGINT NOT NULL, + FOREIGN KEY (medical_file_id) REFERENCES medical_files(id) +) ENGINE=InnoDB; + +CREATE TABLE medical_documents ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + file_name VARCHAR(255), + file_type VARCHAR(255), + file_data LONGBLOB, + medical_file_id BIGINT NOT NULL, + FOREIGN KEY (medical_file_id) REFERENCES medical_files(id) +) ENGINE=InnoDB; \ No newline at end of file diff --git a/src/main/resources/sqls/insert-values.sql b/src/main/resources/sqls/insert-values.sql new file mode 100644 index 0000000000000000000000000000000000000000..a327f5e680a3e602bb0433df309422da0168d51f --- /dev/null +++ b/src/main/resources/sqls/insert-values.sql @@ -0,0 +1,26 @@ +-- Insertion des utilisateurs (médecins et patients) +INSERT INTO users (first_name, last_name, phone_number, email, address, password, role, created_at) VALUES + ('Jean', 'Dupont', '0444444444', 'jean.dupont@example.com', NULL, '$2a$10$x3BWC9e/K6cSNdoc3fsmOemY0NyAU5VTDFxkgkUsqKF1Jgvpu3Zwi', 'DOCTOR', NOW()), + ('Sophie', 'Martin', '0455555555', 'sophie.martin@example.com', NULL, '$2a$10$x3BWC9e/K6cSNdoc3fsmOemY0NyAU5VTDFxkgkUsqKF1Jgvpu3Zwi', 'DOCTOR', NOW()), + ('Paul', 'Durand', '0678901234', 'paul.durand@example.com', '5 Rue des Lilas', '$2a$10$tVWsBUEczExWqyvK5vfsnOQpaWHA4rmuXB73xuzApNELhIpZqhl0W', 'PATIENT', NOW()), + ('Alice', 'Lemoine', '0687654321', 'alice.lemoine@example.com', '8 Rue du Lac', '$2a$10$tVWsBUEczExWqyvK5vfsnOQpaWHA4rmuXB73xuzApNELhIpZqhl0W', 'PATIENT', NOW()); + +-- Récupérer les IDs des utilisateurs insérés (médecins et patients) +SET @doctor1Id = (SELECT id FROM users WHERE email = 'jean.dupont@example.com'); +SET @doctor2Id = (SELECT id FROM users WHERE email = 'sophie.martin@example.com'); +SET @patient1Id = (SELECT id FROM users WHERE email = 'paul.durand@example.com'); +SET @patient2Id = (SELECT id FROM users WHERE email = 'alice.lemoine@example.com'); + +-- Insertion des dossiers médicaux +INSERT INTO medical_files (patient_id, allergy, treatment, created_at) VALUES + (@patient1Id, 'Arachide', 'Ibuprofene', NOW()), + (@patient2Id, 'Pollen', 'Bisoprolol', NOW()); + +-- Récupérer les IDs des dossiers médicaux insérés +SET @file1Id = (SELECT id FROM medical_files WHERE patient_id = @patient1Id); +SET @file2Id = (SELECT id FROM medical_files WHERE patient_id = @patient2Id); + +-- Insertion des rendez-vous +INSERT INTO appointments (patient_id, doctor_id, invoice_id, date_time, status, reason, created_at) VALUES + (@patient1Id, @doctor1Id, NULL, DATE_ADD(NOW(), INTERVAL 2 DAY), 'CONFIRMED', 'Consultation de suivi', NOW()), + (@patient2Id, @doctor2Id, NULL, DATE_ADD(NOW(), INTERVAL 7 DAY), 'PENDING', 'Bilan annuel', NOW()); \ No newline at end of file diff --git a/src/main/resources/templates/doctor-dashboard.html b/src/main/resources/templates/doctor-dashboard.html index b5115573e560ce0816588d9c867a22c2767d8f4d..b6c86c374b55ebf8b4dd70991f7615955d143da1 100644 --- a/src/main/resources/templates/doctor-dashboard.html +++ b/src/main/resources/templates/doctor-dashboard.html @@ -22,7 +22,8 @@ <main class="mt-12"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <h2 class="text-3xl font-bold text-gray-800 text-center">Bienvenue sur votre tableau de bord</h2> - <p class="mt-4 text-lg text-gray-600 text-center">Consultez vos dossiers médicaux et gérez vos patients efficacement.</p> + <p class="mt-4 text-lg text-gray-600 text-center">Consultez vos dossiers médicaux et gérez vos patients + efficacement.</p> <div class="mt-8 grid grid-cols-1 md:grid-cols-2 gap-6"> <a href="#" class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition"> @@ -35,15 +36,15 @@ <p class="mt-2 text-gray-600">Accéder aux dossiers médicaux de vos patients.</p> </a> - <a href="/appointments" class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition"> - <h3 class="text-xl font-semibold text-gray-800">Rendez-vous</h3> - <p class="mt-2 text-gray-600">Gérer votre planning et vos rendez-vous.</p> + <a href="/appointments" + class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition md:col-span-2 flex items-center justify-center text-center"> + <div class="space-y-2"> + <h3 class="text-xl font-semibold text-gray-800">Rendez-vous</h3> + <p class="text-gray-600">Gérer votre planning et vos rendez-vous.</p> + </div> </a> - <a href="#" class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition"> - <h3 class="text-xl font-semibold text-gray-800">Statistiques</h3> - <p class="mt-2 text-gray-600">Voir vos consultations et performances.</p> - </a> + </div> </div> </main> diff --git a/src/main/resources/templates/doctors.html b/src/main/resources/templates/doctors.html index d183b39b779c250a92c34a67b23c996df942ef36..505192df7d3d132170ff82e67fd68d5a2667777b 100644 --- a/src/main/resources/templates/doctors.html +++ b/src/main/resources/templates/doctors.html @@ -1,24 +1,43 @@ <!DOCTYPE html> -<html lang="en"> +<html lang="fr"> <head> <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Liste des Médecins</title> + + <link rel="stylesheet" + href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"> </head> -<body> - <h1>Liste des médecins</h1> - <table> +<body class="bg-light"> + +<div class="container mt-5"> + <h1 class="text-center mb-4">Liste des Médecins</h1> + + <table class="table table-striped table-hover shadow-sm"> + <thead class="table-dark"> <tr> <th>Nom</th> - <th>Prenom</th> + <th>Prénom</th> <th>Spécialité</th> <th>Email</th> </tr> + </thead> + <tbody> <tr th:each="doctor : ${doctors}"> <td th:text="${doctor.lastName}"></td> <td th:text="${doctor.firstName}"></td> <td th:text="${doctor.speciality}"></td> <td th:text="${doctor.email}"></td> </tr> + </tbody> </table> + + <div class="text-center mt-4"> + <a href="/" class="btn btn-primary">Retour à l'accueil</a> + </div> +</div> + +<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script> + </body> -</html> \ No newline at end of file +</html> diff --git a/src/main/resources/templates/home.html b/src/main/resources/templates/home.html index 214562e5f629471781f6c655b108850cdc30efbd..932d441c7661c2f520bebf1323b14a9c8d13b351 100644 --- a/src/main/resources/templates/home.html +++ b/src/main/resources/templates/home.html @@ -14,9 +14,21 @@ <div class="flex justify-between items-center py-6"> <h1 class="text-2xl font-semibold text-gray-900">Gestion Dossiers Médicaux</h1> <div class="space-x-4"> - <a href="/doctors/dashboard" class="px-6 py-2 bg-green-500 text-white rounded-md hover:bg-green-600">Professionnel de santé</a> - <a href="/login" class="text-blue-500 hover:text-blue-700">Connexion</a> - <a href="/register" class="text-blue-500 hover:text-blue-700">Inscription</a> + <th:block th:if="${isDoctor}"> + <a href="/doctors/dashboard" + class="px-6 py-2 bg-green-500 text-white rounded-md hover:bg-green-600">Professionnel de + santé</a> + </th:block> + <th:block th:if="${username}"> + <span class="text-gray-900 font-semibold">Bienvenue, <b th:text="${username}"></b> !</span> + <a href="/logout" class="ml-4 text-red-500 hover:text-red-700">Déconnexion</a> + </th:block> + + <th:block th:unless="${username}"> + <a th:href="@{/login}" class="text-blue-500 hover:text-blue-700">Connexion</a> + <a th:href="@{/register}" class="text-blue-500 hover:text-blue-700">Inscription</a> + </th:block> + </div> </div> </div> @@ -26,16 +38,21 @@ <main class="mt-12"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="text-center"> - <h2 class="text-4xl font-bold text-gray-800">Bienvenue sur notre application de gestion de dossiers médicaux</h2> - <p class="mt-4 text-lg text-gray-600">Accédez facilement à vos dossiers médicaux et organisez vos rendez-vous en toute sécurité.</p> + <h2 class="text-4xl font-bold text-gray-800">Bienvenue sur notre application de gestion de dossiers + médicaux</h2> + <p class="mt-4 text-lg text-gray-600">Accédez facilement à vos dossiers médicaux et organisez vos + rendez-vous en toute sécurité.</p> </div> <!-- Search Section --> <div class="mt-8 text-center"> <form action="/doctors/search" method="get" class="max-w-md mx-auto flex items-center space-x-4"> - <input type="text" name="firstName" class="w-full px-4 py-2 border rounded-md" placeholder="Prénom du médecin"> - <input type="text" name="lastName" class="w-full px-4 py-2 border rounded-md" placeholder="Nom du médecin" required> - <button type="submit" class="px-6 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600">Rechercher</button> + <input type="text" name="firstName" class="w-full px-4 py-2 border rounded-md" + placeholder="Prénom du médecin"> + <input type="text" name="lastName" class="w-full px-4 py-2 border rounded-md" + placeholder="Nom du médecin" required> + <button type="submit" class="px-6 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600">Rechercher + </button> </form> </div> </div> diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html index 1d23b702053046e0d67a417eec6afd51d1d22c8d..772aea643864d7ecbd9505583f4aab07cffd9f6b 100644 --- a/src/main/resources/templates/login.html +++ b/src/main/resources/templates/login.html @@ -1,48 +1,34 @@ <!DOCTYPE html> -<html lang="fr"> +<html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Connexion - Gestion Dossiers Médicaux</title> - <script src="https://cdn.tailwindcss.com"></script> + <title>Connexion</title> + <link rel="stylesheet" th:href="@{/css/styles.css}"> + <link rel="stylesheet" + href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"> </head> -<body class="bg-gray-100 font-sans leading-normal tracking-normal"> - -<!-- Header --> -<header class="bg-white shadow-md"> - <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> - <div class="flex justify-between items-center py-6"> - <h1 class="text-2xl font-semibold text-gray-900">Gestion Dossiers Médicaux</h1> - <a href="/" class="text-blue-500 hover:text-blue-700">Accueil</a> +<body class="bg-light"> +<div class="container d-flex justify-content-center align-items-center vh-100"> + <div class="card shadow p-4" style="width: 350px; border-radius: 10px;"> + <h3 class="text-center mb-3">Connexion</h3> + <form th:action="@{/login}" method="post"> + <div class="mb-3"> + <label for="email" class="form-label">Nom d'utilisateur</label> + <input type="text" class="form-control" id="email" name="email" required> + </div> + <div class="mb-3"> + <label for="password" class="form-label">Mot de passe</label> + <input type="password" class="form-control" id="password" name="password" required> + </div> + <button type="submit" class="btn btn-primary w-100">Se connecter</button> + </form> + <div class="text-center mt-3"> + <a href="#" class="text-decoration-none">Mot de passe oublié ?</a> </div> - </div> -</header> - -<!-- Formulaire de Connexion --> -<main class="mt-12 max-w-md mx-auto bg-white p-6 rounded-lg shadow-md"> - <h2 class="text-3xl font-bold text-center text-gray-800">Connexion</h2> - <form action="/login" method="post" class="mt-6"> - <div class="mb-4"> - <label for="username" class="block text-gray-700">Nom d'utilisateur</label> - <input type="text" id="username" name="username" class="w-full px-4 py-2 border rounded-md" required> - </div> - <div class="mb-4"> - <label for="password" class="block text-gray-700">Mot de passe</label> - <input type="password" id="password" name="password" class="w-full px-4 py-2 border rounded-md" required> + <div class="text-center mt-3"> + <a th:href="@{/register}" class="btn btn-outline-secondary w-100">Créer un compte</a> </div> - <button type="submit" class="w-full px-6 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600">Se connecter</button> - </form> - <p class="mt-4 text-sm text-gray-600 text-center"> - Pas encore de compte ? <a href="/register" class="text-blue-500 hover:text-blue-700">Inscrivez-vous</a> - </p> -</main> - -<!-- Footer --> -<footer class="bg-white shadow-md mt-16"> - <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 text-center"> - <p class="text-sm text-gray-600">© 2025 Gestion Dossiers Médicaux. Tous droits réservés.</p> </div> -</footer> - +</div> </body> </html> diff --git a/src/main/resources/templates/medical-files.html b/src/main/resources/templates/medical-files.html index 9643afef3f8b38c020c27aed66b5b5039c64485e..368bb306f39366661a7d3f74a626405f86e4e31e 100644 --- a/src/main/resources/templates/medical-files.html +++ b/src/main/resources/templates/medical-files.html @@ -17,17 +17,27 @@ <tr> <th>ID</th> <th>Patient</th> - <th>Médecin</th> <th>Historique</th> <th>Action</th> </tr> </thead> <tbody> + <!-- Afficher chaque dossier médical --> <tr th:each="file : ${medicalFiles}"> <td th:text="${file.id}"></td> <td th:text="${file.patient.firstName} + ' ' + ${file.patient.lastName}"></td> - <td th:text="${file.doctor.firstName} + ' ' + ${file.doctor.lastName}"></td> - <td th:text="${file.history}"></td> + + <!-- Afficher l'historique médical --> + <td> + <ul> + <li th:each="history : ${file.healthHistoricalList}"> + <p th:text="'Antécédent: ' + ${history.antecedent}"></p> + <p th:text="'Notes: ' + ${history.notes}"></p> + <p th:text="'Date Consultation: ' + ${history.consultationDate}"></p> + </li> + </ul> + </td> + <td> <a th:href="@{/medical-files/{id}(id=${file.id})}" class="btn btn-info">Consulter</a> </td> diff --git a/src/main/resources/templates/register.html b/src/main/resources/templates/register.html index 1baea54731ccdf47805db5c59c802e076ddea0dc..df68dc55dc35dfb0a8efb016397f11a902c4402f 100644 --- a/src/main/resources/templates/register.html +++ b/src/main/resources/templates/register.html @@ -1,34 +1,76 @@ <!DOCTYPE html> -<html lang="fr"> +<html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Inscription</title> - <script src="https://cdn.tailwindcss.com"></script> + <link rel="stylesheet" th:href="@{/css/styles.css}"> + <link rel="stylesheet" + href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"> + <script> + function toggleFields() { + var role = document.getElementById("role").value; + document.getElementById("doctorFields").style.display = (role === "DOCTOR") ? "block" : "none"; + document.getElementById("patientFields").style.display = (role === "PATIENT") ? "block" : "none"; + } + </script> </head> -<body class="bg-gray-100 font-sans leading-normal tracking-normal"> +<body class="bg-light"> +<div class="container d-flex justify-content-center align-items-center vh-100"> + <div class="card shadow p-4" style="width: 350px; border-radius: 10px;"> + <h3 class="text-center mb-3">Inscription</h3> + <form th:action="@{/register}" method="post"> + <div class="mb-3"> + <label for="firstName" class="form-label">Prénom</label> + <input type="text" class="form-control" id="firstName" name="firstName" required> + </div> + <div class="mb-3"> + <label for="lastName" class="form-label">Nom</label> + <input type="text" class="form-control" id="lastName" name="lastName" required> + </div> + <div class="mb-3"> + <label for="email" class="form-label">Email</label> + <input type="email" class="form-control" id="email" name="email" required> + </div> + <div class="mb-3"> + <label for="password" class="form-label">Mot de passe</label> + <input type="password" class="form-control" id="password" name="password" required> + </div> + <div class="mb-3"> + <label for="role" class="form-label">Rôle</label> + <select class="form-control" id="role" name="role" required onchange="toggleFields()"> + <option value="PATIENT">Patient</option> + <option value="DOCTOR">Médecin</option> + <option value="ADMIN">Administrateur</option> + </select> + </div> -<div class="max-w-md mx-auto mt-10 bg-white p-6 rounded-lg shadow-md"> - <h2 class="text-2xl font-semibold text-center text-gray-800">Inscription</h2> + <!-- Champs spécifiques pour Médecin --> + <div id="doctorFields" style="display: none;"> + <div class="mb-3"> + <label for="speciality" class="form-label">Spécialité</label> + <input type="text" class="form-control" id="speciality" name="speciality"> + </div> + </div> - <form action="/register" method="post" class="mt-4"> - <label class="block text-gray-700">Nom d'utilisateur :</label> - <input type="text" name="username" required class="w-full p-2 border rounded-lg mt-1"> + <!-- Champs spécifiques pour Patient --> + <div id="patientFields"> + <div class="mb-3"> + <label for="dateOfBirth" class="form-label">Date de naissance</label> + <input type="date" class="form-control" id="dateOfBirth" name="dateOfBirth"> + </div> + <div class="mb-3"> + <label for="address" class="form-label">Adresse</label> + <input type="text" class="form-control" id="address" name="address"> + </div> + </div> - <label class="block text-gray-700 mt-4">Mot de passe :</label> - <input type="password" name="password" required class="w-full p-2 border rounded-lg mt-1"> - <label class="block text-gray-700 mt-4">Rôle :</label> - <select name="role" required class="w-full p-2 border rounded-lg mt-1"> - <option value="MEDECIN">Médecin</option> - <option value="PATIENT">Patient</option> - </select> - - <button type="submit" class="w-full mt-6 bg-blue-500 text-white py-2 rounded-lg hover:bg-blue-700"> - S'inscrire - </button> - </form> + <button type="submit" class="btn btn-success w-100">S'inscrire</button> + </form> + <div class="text-center mt-3"> + <a th:href="@{/login}" class="btn btn-outline-secondary w-100">J'ai déjà un compte</a> + </div> + </div> </div> - </body> </html> diff --git a/src/main/resources/templates/view-medical-file.html b/src/main/resources/templates/view-medical-file.html index a2cb064c8e874ff04d6cc4fa3ea06591e4707630..b336c379e7103434453881bc8923845dba625522 100644 --- a/src/main/resources/templates/view-medical-file.html +++ b/src/main/resources/templates/view-medical-file.html @@ -16,27 +16,24 @@ <span th:text="${medicalFile.patient != null ? medicalFile.patient.firstName : 'Inconnu'}"></span> <span th:text="${medicalFile.patient != null ? medicalFile.patient.lastName : ''}"></span> </h5> - <h6 class="card-subtitle mb-2 text-muted">Médecin : - <span th:text="${medicalFile.doctor != null ? medicalFile.doctor.firstName : 'Inconnu'}"></span> - <span th:text="${medicalFile.doctor != null ? medicalFile.doctor.lastName : ''}"></span> - </h6> - <p class="card-text"><strong>Historique médical :</strong> - <span th:text="${medicalFile.history != null ? medicalFile.history : 'Non disponible'}"></span> - </p> </div> - <!-- Formulaire de mise à jour de l'historique --> - <form method="post" th:action="@{/medical-files/{id}/history(id=${medicalFile.id})}"> - <div class="mb-3"> - <label class="form-label">Historique médical :</label> - <textarea class="form-control" name="history" th:text="${medicalFile.history}"></textarea> - </div> - <button type="submit" class="btn btn-success">Mettre à jour l'historique</button> - </form> + <!-- Historique médical --> + <div class="mt-3"> + <h5>Historique médical :</h5> + <ul class="list-group"> + <li th:each="history : ${medicalFile.healthHistoricalList}" class="list-group-item"> + <strong>Antécédent:</strong> <span th:text="${history.antecedent}"></span><br> + <strong>Notes:</strong> <span th:text="${history.notes}"></span><br> + <strong>Date de consultation:</strong> <span th:text="${history.consultationDate}"></span> + </li> + </ul> + </div> <!-- Formulaire de téléchargement du document --> - <form method="post" th:action="@{/medical-files/{id}/documents(id=${medicalFile.id})}" enctype="multipart/form-data"> - <label for="file">Importer un document :</label> + <form method="post" th:action="@{/medical-files/{id}/documents(id=${medicalFile.id})}" enctype="multipart/form-data" + class="mt-3"> + <label for="file" class="form-label">Importer un document :</label> <input type="file" name="document" id="file" class="form-control mb-2"/> <button type="submit" class="btn btn-primary">Uploader le document</button> </form> @@ -45,17 +42,19 @@ <div class="mt-3"> <h5>Documents disponibles :</h5> <ul class="list-group"> - <li th:each="doc : ${medicalFile.documents}" class="list-group-item d-flex justify-content-between align-items-center"> + <li th:each="doc : ${medicalFile.documentList}" + class="list-group-item d-flex justify-content-between align-items-center"> <span th:text="${doc.fileName}"></span> <div> - <a th:href="@{/medical-files/{id}/documents/{docId}(id=${medicalFile.id}, docId=${doc.id})}" class="btn btn-sm btn-warning"> + <a th:href="@{/medical-files/{id}/documents/{docId}(id=${medicalFile.id}, docId=${doc.id})}" + class="btn btn-sm btn-warning"> Télécharger </a> <form th:action="@{/medical-files/{id}/documents/{docId}(id=${medicalFile.id}, docId=${doc.id})}" - method="post" - class="d-inline"> + method="post" class="d-inline"> <input type="hidden" name="_method" value="delete"/> - <button type="submit" class="btn btn-sm btn-danger" onclick="return confirm('Voulez-vous vraiment supprimer ce document ?');"> + <button type="submit" class="btn btn-sm btn-danger" + onclick="return confirm('Voulez-vous vraiment supprimer ce document ?');"> Supprimer </button> </form> @@ -69,4 +68,4 @@ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script> </body> -</html> +</html> \ No newline at end of file