From f577d0c1d9763dc8218eedc562bdf0d788c35d9f Mon Sep 17 00:00:00 2001
From: "riste.stojanov" <riste.stojanov@finki.ukim.mk>
Date: Mon, 18 Nov 2024 14:18:57 +0100
Subject: [PATCH 01/13] mail config update

---
 src/main/resources/emailconfig.properties | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/src/main/resources/emailconfig.properties b/src/main/resources/emailconfig.properties
index 35566ff..7525efc 100644
--- a/src/main/resources/emailconfig.properties
+++ b/src/main/resources/emailconfig.properties
@@ -1,6 +1,3 @@
-spring.mail.host=smtp.gmail.com
-spring.mail.port=587
-spring.mail.username=${EMAIL_USERNAME:noreplay@finki.ukim.mk}
-spring.mail.password=${EMAIL_PASSWORD:empty}
-spring.mail.properties.mail.smtp.auth=true
-spring.mail.properties.mail.smtp.starttls.enable=true
\ No newline at end of file
+spring.mail.host=mailer.finki.ukim.mk
+spring.mail.port=25
+spring.mail.username=noreplay@finki.ukim.mk
\ No newline at end of file
-- 
GitLab


From d4533bc5a369a90b56d8a5567250d9f3a19767df Mon Sep 17 00:00:00 2001
From: "riste.stojanov" <riste.stojanov@finki.ukim.mk>
Date: Mon, 18 Nov 2024 14:24:14 +0100
Subject: [PATCH 02/13] mail config update

---
 src/main/resources/emailconfig.properties | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/main/resources/emailconfig.properties b/src/main/resources/emailconfig.properties
index 7525efc..2e695a2 100644
--- a/src/main/resources/emailconfig.properties
+++ b/src/main/resources/emailconfig.properties
@@ -1,3 +1,4 @@
 spring.mail.host=mailer.finki.ukim.mk
 spring.mail.port=25
-spring.mail.username=noreplay@finki.ukim.mk
\ No newline at end of file
+spring.mail.username=noreply@finki.ukim.mk
+spring.mail.password=
\ No newline at end of file
-- 
GitLab


From cca1acbd1803184038b8092e8b1ecd0b6f204152 Mon Sep 17 00:00:00 2001
From: "riste.stojanov" <riste.stojanov@finki.ukim.mk>
Date: Mon, 18 Nov 2024 14:30:38 +0100
Subject: [PATCH 03/13] mail config update

---
 .../java/mk/ukim/finki/konsultacii/config/MailConfig.java   | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/src/main/java/mk/ukim/finki/konsultacii/config/MailConfig.java b/src/main/java/mk/ukim/finki/konsultacii/config/MailConfig.java
index aadf8fa..cf40baa 100644
--- a/src/main/java/mk/ukim/finki/konsultacii/config/MailConfig.java
+++ b/src/main/java/mk/ukim/finki/konsultacii/config/MailConfig.java
@@ -16,7 +16,6 @@ import org.thymeleaf.templateresolver.ITemplateResolver;
 
 import java.nio.charset.StandardCharsets;
 import java.util.Objects;
-import java.util.Properties;
 
 
 @Configuration
@@ -34,11 +33,6 @@ public class MailConfig {
         mailSender.setPort(Integer.parseInt(Objects.requireNonNull(environment.getProperty("spring.mail.port"))));
         mailSender.setUsername(environment.getProperty("spring.mail.username"));
         mailSender.setPassword(environment.getProperty("spring.mail.password"));
-
-        Properties props = new Properties();
-        props.put("mail.smtp.auth", environment.getProperty("spring.mail.properties.mail.smtp.auth"));
-        props.put("mail.smtp.starttls.enable", environment.getProperty("spring.mail.properties.mail.smtp.starttls.enable"));
-        mailSender.setJavaMailProperties(props);
         return mailSender;
     }
 
-- 
GitLab


From 82474ef38f090083c4496d8bbd01420a8b57d79e Mon Sep 17 00:00:00 2001
From: "riste.stojanov" <riste.stojanov@finki.ukim.mk>
Date: Sat, 11 Jan 2025 16:38:10 +0100
Subject: [PATCH 04/13] mail config update

---
 .../finki/konsultacii/config/AuthConfig.java  | 25 ++++++++++---------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java b/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java
index f6da255..dc5b854 100644
--- a/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java
+++ b/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java
@@ -12,19 +12,20 @@ public class AuthConfig {
     public HttpSecurity authorize(HttpSecurity http) throws Exception {
         return http
                 .authorizeHttpRequests((requests) -> requests
-                    .requestMatchers(HttpMethod.OPTIONS).permitAll()
-                    .requestMatchers(HttpMethod.POST, "/consultations").hasAnyAuthority(
-                            AppRole.STUDENT.name(), AppRole.ADMIN.name(), AppRole.PROFESSOR.name())
-                    .requestMatchers("/auth/*", "/","","/display/*","/css/*", "/js/*", "/images/*").permitAll()
-                    .requestMatchers("/studentAttendances/**").hasRole(AppRole.STUDENT.name())
-                    .requestMatchers("/professorAttendances/**").hasAnyRole(AppRole.PROFESSOR.name(), AppRole.ADMIN.name())
-                    .requestMatchers("/adminAttendances/**").hasRole(AppRole.ADMIN.name())
-                    .requestMatchers("/manage-consultations/import").hasRole(AppRole.ADMIN.name())
-                    .requestMatchers("/manage-consultations/sample-tsv").hasRole(AppRole.ADMIN.name())
-                    .requestMatchers("/manage-consultations/{professorId}/**").access(
+                        .requestMatchers(HttpMethod.OPTIONS).permitAll()
+                        .requestMatchers("/Consultations/GetTermsByTeacherCode?teacherCode").permitAll()
+                        .requestMatchers(HttpMethod.POST, "/consultations").hasAnyAuthority(
+                                AppRole.STUDENT.name(), AppRole.ADMIN.name(), AppRole.PROFESSOR.name())
+                        .requestMatchers("/auth/*", "/", "", "/display/*", "/css/*", "/js/*", "/images/*").permitAll()
+                        .requestMatchers("/studentAttendances/**").hasRole(AppRole.STUDENT.name())
+                        .requestMatchers("/professorAttendances/**").hasAnyRole(AppRole.PROFESSOR.name(), AppRole.ADMIN.name())
+                        .requestMatchers("/adminAttendances/**").hasRole(AppRole.ADMIN.name())
+                        .requestMatchers("/manage-consultations/import").hasRole(AppRole.ADMIN.name())
+                        .requestMatchers("/manage-consultations/sample-tsv").hasRole(AppRole.ADMIN.name())
+                        .requestMatchers("/manage-consultations/{professorId}/**").access(
                                 new WebExpressionAuthorizationManager("#professorId == authentication.name or hasRole('ROLE_ADMIN')")
-                    )
-                    .anyRequest().authenticated()
+                        )
+                        .anyRequest().authenticated()
                 )
                 .logout(LogoutConfigurer::permitAll);
     }
-- 
GitLab


From 76276d2bde17145bc5583105cb90c8283c410528 Mon Sep 17 00:00:00 2001
From: "riste.stojanov" <riste.stojanov@finki.ukim.mk>
Date: Sat, 11 Jan 2025 16:40:16 +0100
Subject: [PATCH 05/13] mail config update

---
 src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java b/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java
index dc5b854..7d474ff 100644
--- a/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java
+++ b/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java
@@ -13,7 +13,7 @@ public class AuthConfig {
         return http
                 .authorizeHttpRequests((requests) -> requests
                         .requestMatchers(HttpMethod.OPTIONS).permitAll()
-                        .requestMatchers("/Consultations/GetTermsByTeacherCode?teacherCode").permitAll()
+                        .requestMatchers("/Consultations/GetTermsByTeacherCode").permitAll()
                         .requestMatchers(HttpMethod.POST, "/consultations").hasAnyAuthority(
                                 AppRole.STUDENT.name(), AppRole.ADMIN.name(), AppRole.PROFESSOR.name())
                         .requestMatchers("/auth/*", "/", "", "/display/*", "/css/*", "/js/*", "/images/*").permitAll()
-- 
GitLab


From adeed1087ece90a7ba5479849d94b636878b6894 Mon Sep 17 00:00:00 2001
From: "riste.stojanov" <riste.stojanov@finki.ukim.mk>
Date: Tue, 4 Mar 2025 11:59:35 +0100
Subject: [PATCH 06/13] changed method to post

---
 .../finki/konsultacii/web/rest/ConsultationController.java    | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/main/java/mk/ukim/finki/konsultacii/web/rest/ConsultationController.java b/src/main/java/mk/ukim/finki/konsultacii/web/rest/ConsultationController.java
index 357df66..33b18a7 100644
--- a/src/main/java/mk/ukim/finki/konsultacii/web/rest/ConsultationController.java
+++ b/src/main/java/mk/ukim/finki/konsultacii/web/rest/ConsultationController.java
@@ -2,7 +2,7 @@ package mk.ukim.finki.konsultacii.web.rest;
 
 import mk.ukim.finki.konsultacii.model.dtos.ConsultationResponseDto;
 import mk.ukim.finki.konsultacii.service.ConsultationService;
-import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -17,7 +17,7 @@ public class ConsultationController {
         this.consultationService = consultationService;
     }
 
-    @GetMapping("/Consultations/GetTermsByTeacherCode")
+    @PostMapping("/Consultations/GetTermsByTeacherCode")
     public List<ConsultationResponseDto> getTermsByTeacherCode(
             @RequestParam String teacherCode,
             @RequestParam String token) {
-- 
GitLab


From e5d2f3c5e10b34a63dfd2ebc79159cda34476abf Mon Sep 17 00:00:00 2001
From: "riste.stojanov" <riste.stojanov@finki.ukim.mk>
Date: Tue, 4 Mar 2025 12:00:44 +0100
Subject: [PATCH 07/13] changed method to combined with get and post

---
 .../finki/konsultacii/web/rest/ConsultationController.java   | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/main/java/mk/ukim/finki/konsultacii/web/rest/ConsultationController.java b/src/main/java/mk/ukim/finki/konsultacii/web/rest/ConsultationController.java
index 33b18a7..26f4da1 100644
--- a/src/main/java/mk/ukim/finki/konsultacii/web/rest/ConsultationController.java
+++ b/src/main/java/mk/ukim/finki/konsultacii/web/rest/ConsultationController.java
@@ -2,7 +2,8 @@ package mk.ukim.finki.konsultacii.web.rest;
 
 import mk.ukim.finki.konsultacii.model.dtos.ConsultationResponseDto;
 import mk.ukim.finki.konsultacii.service.ConsultationService;
-import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -17,7 +18,7 @@ public class ConsultationController {
         this.consultationService = consultationService;
     }
 
-    @PostMapping("/Consultations/GetTermsByTeacherCode")
+    @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, value = "/Consultations/GetTermsByTeacherCode")
     public List<ConsultationResponseDto> getTermsByTeacherCode(
             @RequestParam String teacherCode,
             @RequestParam String token) {
-- 
GitLab


From ae42e10e3f49b825e68e0cbab465033ae0a094bb Mon Sep 17 00:00:00 2001
From: "bojana.marojevikj" <bojana.marojevikj@finki.ukim.mk>
Date: Fri, 14 Mar 2025 10:23:17 +0100
Subject: [PATCH 08/13] ui improvements

---
 .../finki/konsultacii/config/AuthConfig.java  |  3 ++
 .../controllers/ConsultationsController.java  | 49 +++++++++++++------
 .../professorConsultations.html               |  4 +-
 .../templates/fragments/irregularPaging.html  |  4 +-
 .../templates/fragments/regularPaging.html    |  4 +-
 src/main/resources/templates/index.html       |  4 +-
 6 files changed, 46 insertions(+), 22 deletions(-)

diff --git a/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java b/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java
index f6da255..ad28122 100644
--- a/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java
+++ b/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java
@@ -17,6 +17,9 @@ public class AuthConfig {
                             AppRole.STUDENT.name(), AppRole.ADMIN.name(), AppRole.PROFESSOR.name())
                     .requestMatchers("/auth/*", "/","","/display/*","/css/*", "/js/*", "/images/*").permitAll()
                     .requestMatchers("/studentAttendances/**").hasRole(AppRole.STUDENT.name())
+                    .requestMatchers("/consultations/schedule").hasRole(AppRole.STUDENT.name())
+                    .requestMatchers("/consultations/cancel").hasRole(AppRole.STUDENT.name())
+                    .requestMatchers("/consultations/student/**").hasRole(AppRole.STUDENT.name())
                     .requestMatchers("/professorAttendances/**").hasAnyRole(AppRole.PROFESSOR.name(), AppRole.ADMIN.name())
                     .requestMatchers("/adminAttendances/**").hasRole(AppRole.ADMIN.name())
                     .requestMatchers("/manage-consultations/import").hasRole(AppRole.ADMIN.name())
diff --git a/src/main/java/mk/ukim/finki/konsultacii/web/controllers/ConsultationsController.java b/src/main/java/mk/ukim/finki/konsultacii/web/controllers/ConsultationsController.java
index f416f42..3f6b682 100644
--- a/src/main/java/mk/ukim/finki/konsultacii/web/controllers/ConsultationsController.java
+++ b/src/main/java/mk/ukim/finki/konsultacii/web/controllers/ConsultationsController.java
@@ -56,11 +56,13 @@ public class ConsultationsController {
         TreeMap<Character, List<Professor>> professors = this.professorService.findAllProfessorsSortedByFirstName(professor);
 
         String studentUsername = authentication.getName();
+        boolean isStudent = false;
 
         Page<ConsultationAttendance> attendances = Page.empty();
         if(authentication.getAuthorities().stream().anyMatch(auth -> auth.getAuthority().equals("ROLE_STUDENT"))){
             attendances = consultationAttendanceService
                     .listAttendancesPage(time, type, "", studentUsername, results, pageNum);
+            isStudent = true;
         }
         boolean isAuthenticated = !authentication.getPrincipal().equals("anonymousUser");
         String username = "";
@@ -71,15 +73,39 @@ public class ConsultationsController {
         model.addAttribute("username", username);
         model.addAttribute("page", attendances);
         model.addAttribute("professorsMap", professors);
+        model.addAttribute("isStudent", isStudent);
         return "index";
     }
 
     @GetMapping(value = "/professor/{id}")
     public String getConsultationsByProfessor(@PathVariable("id") String professorId,
                                               @RequestParam(defaultValue = "1") Integer regularPageNum,
-                                              @RequestParam(defaultValue = "3") Integer regularResults,
+                                              @RequestParam(defaultValue = "4") Integer regularResults,
                                               @RequestParam(defaultValue = "1") Integer irregularPageNum,
-                                              @RequestParam(defaultValue = "3") Integer irregularResults,
+                                              @RequestParam(defaultValue = "4") Integer irregularResults,
+                                              Model model) {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        Professor professor = this.professorService.getProfessorById(professorId);
+        model.addAttribute("professor", professor);
+        model.addAttribute("username", authentication.getName());
+
+        Page<Consultation> regularConsultationTerms = this.consultationService
+                .consultationTermsByProfessor(professorId, "WEEKLY","UPCOMING","ACTIVE", regularResults, regularPageNum);
+        Page<Consultation> irregularConsultationTerms = this.consultationService
+                .consultationTermsByProfessor(professorId, "ONE_TIME","UPCOMING", "ACTIVE", irregularResults, irregularPageNum);
+        model.addAttribute("regularPage", regularConsultationTerms);
+        model.addAttribute("irregularPage", irregularConsultationTerms);
+
+        return "consultationsDisplay/professorConsultations";
+
+    }
+
+    @GetMapping(value = "/student/professor/{id}")
+    public String getStudentConsultationsByProfessor(@PathVariable("id") String professorId,
+                                              @RequestParam(defaultValue = "1") Integer regularPageNum,
+                                              @RequestParam(defaultValue = "2") Integer regularResults,
+                                              @RequestParam(defaultValue = "1") Integer irregularPageNum,
+                                              @RequestParam(defaultValue = "2") Integer irregularResults,
                                               Model model) {
         String studentEmail = getStudentEmail();
         Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
@@ -95,11 +121,6 @@ public class ConsultationsController {
         model.addAttribute("regularPage", regularConsultationTerms);
         model.addAttribute("irregularPage", irregularConsultationTerms);
 
-        if(authentication.getAuthorities().stream().anyMatch(auth -> auth.getAuthority().equals("ROLE_PROFESSOR"))
-                || authentication.getAuthorities().stream().anyMatch(auth -> auth.getAuthority().equals("ROLE_ADMIN"))){
-            return "consultationsDisplay/professorConsultations";
-        }
-
         Map<Long, Boolean> consultationAvailability = new HashMap<>();
         Map<Long, ConsultationAttendance> consultationAttendanceMap = new HashMap<>();
         for (Consultation consultation : regularConsultationTerms) {
@@ -137,7 +158,7 @@ public class ConsultationsController {
         } catch (Exception e) {
             redirectAttributes.addFlashAttribute("error", "An error occurred while registering for the consultation.");
         }
-        return "redirect:/consultations/professor/" + professorId;
+        return "redirect:/consultations/student/professor/" + professorId;
     }
 
     @PostMapping("/cancel")
@@ -151,15 +172,15 @@ public class ConsultationsController {
             redirectAttributes.addFlashAttribute("errorMessage", "Грешка при откажувањето на консултацијата.");
         }
 
-        return "redirect:/consultations/professor/" + professorId;
+        return "redirect:/consultations/student/professor/" + professorId;
     }
 
     @PostMapping("/addComment")
     public String addComment(@RequestParam Long attendanceId,
-                                   @RequestParam("professorId") String professorId,
-                                   @RequestParam("newComment") String comment,
-                                    @RequestParam("consultationId") String consultationId,
-                                   RedirectAttributes redirectAttributes) {
+                             @RequestParam("professorId") String professorId,
+                             @RequestParam("newComment") String comment,
+                             @RequestParam("consultationId") String consultationId,
+                             RedirectAttributes redirectAttributes) {
         Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
         boolean isStudent = authentication.getAuthorities().stream().anyMatch(auth -> auth.getAuthority().equals("ROLE_STUDENT"));
         try {
@@ -177,7 +198,7 @@ public class ConsultationsController {
             return "redirect:/professorAttendances";
         }
 
-        return "redirect:/consultations/professor/" + professorId;
+        return "redirect:/consultations/student/professor/" + professorId;
     }
 
 
diff --git a/src/main/resources/templates/consultationsDisplay/professorConsultations.html b/src/main/resources/templates/consultationsDisplay/professorConsultations.html
index 31d9f15..2df7363 100644
--- a/src/main/resources/templates/consultationsDisplay/professorConsultations.html
+++ b/src/main/resources/templates/consultationsDisplay/professorConsultations.html
@@ -24,7 +24,7 @@
                         <p>Нема закажани консултации</p>
                     </div>
                     <div class="row">
-                        <div th:each="consultation : ${regularPage.getContent()}" class="col-lg-4 col-md-3 col-sm-12 mb-4">
+                        <div th:each="consultation : ${regularPage.getContent()}" class="col-lg-3 col-md-4 col-sm-12 mb-4">
                             <div class="consultation-div px-2 py-2 d-flex flex-column justify-content-between">
                                 <div>
                                     <div class="d-flex align-items-top">
@@ -66,7 +66,7 @@
                         <p>Нема закажани консултации</p>
                     </div>
                     <div class="row">
-                        <div th:each="consultation : ${irregularPage.getContent()}" class="col-lg-4 col-md-3 col-sm-12 mb-4">
+                        <div th:each="consultation : ${irregularPage.getContent()}" class="col-lg-3 col-md-4 col-sm-12 mb-4">
                             <div class="consultation-div px-2 py-2 d-flex flex-column justify-content-between">
                                 <div>
                                     <div class="d-flex align-items-top">
diff --git a/src/main/resources/templates/fragments/irregularPaging.html b/src/main/resources/templates/fragments/irregularPaging.html
index d2d6ff4..f23e8db 100644
--- a/src/main/resources/templates/fragments/irregularPaging.html
+++ b/src/main/resources/templates/fragments/irregularPaging.html
@@ -36,8 +36,8 @@
                 <label for="results" class="mb-0 me-1 small">Резултати:</label>
                 <select id="results" class="form-control form-control-sm" style="max-width: 70px;"
                         onchange="updateQueryStringParameter('irregularResults',this.value)">
-                    <option value="3" th:selected="${page.size == 3}">3</option>
-                    <option value="5" th:selected="${page.size == 5}">5</option>
+                    <option value="2" th:selected="${page.size == 2}">2</option>
+                    <option value="4" th:selected="${page.size == 4}">4</option>
                     <option value="10" th:selected="${page.size == 10}">10</option>
                     <option value="20" th:selected="${page.size == 20}">20</option>
                     <option value="50" th:selected="${page.size == 50}">50</option>
diff --git a/src/main/resources/templates/fragments/regularPaging.html b/src/main/resources/templates/fragments/regularPaging.html
index ec353c5..bfd539b 100644
--- a/src/main/resources/templates/fragments/regularPaging.html
+++ b/src/main/resources/templates/fragments/regularPaging.html
@@ -36,8 +36,8 @@
                 <label for="results" class="mb-0 me-1 small">Резултати:</label>
                 <select id="results" class="form-control form-control-sm" style="max-width: 70px;"
                         onchange="updateQueryStringParameter('regularResults',this.value)">
-                    <option value="3" th:selected="${page.size == 3}">3</option>
-                    <option value="5" th:selected="${page.size == 5}">5</option>
+                    <option value="2" th:selected="${page.size == 2}">2</option>
+                    <option value="4" th:selected="${page.size == 4}">4</option>
                     <option value="10" th:selected="${page.size == 10}">10</option>
                     <option value="20" th:selected="${page.size == 20}">20</option>
                     <option value="50" th:selected="${page.size == 50}">50</option>
diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html
index dbc78ff..21dcc1c 100644
--- a/src/main/resources/templates/index.html
+++ b/src/main/resources/templates/index.html
@@ -74,8 +74,8 @@
                      class="col-xl-3 col-sm-6 mb-3 mx-2 shadow-sm py-2 px-3 float-left card-style">
                     <h5 th:text="${professor.getName()}" class="mb-0 card-header-font"></h5>
                     <a th:id="${professor.getId()}"
-                       th:href="${isAuthenticated ? '/consultations/professor/' + professor.getId() :
-                                '/display/' + professor.getId()}"
+                       th:href="${isAuthenticated ? (isStudent ? '/consultations/student/professor/' + professor.getId() : '/consultations/professor/' + professor.getId()) :
+                            '/display/' + professor.getId()}"
                        class="text-decoration-none mt-4 consultation-link">
                         Консултации
                     </a>
-- 
GitLab


From d58846ca1c09d7e6ee2d22ae45330937b36db78e Mon Sep 17 00:00:00 2001
From: "bojana.marojevikj" <bojana.marojevikj@finki.ukim.mk>
Date: Fri, 14 Mar 2025 10:37:58 +0100
Subject: [PATCH 09/13] display irregular consultations first

---
 .../consultationsDisplay/consultations.html   | 46 ++++++++++---------
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/src/main/resources/templates/consultationsDisplay/consultations.html b/src/main/resources/templates/consultationsDisplay/consultations.html
index 89e027f..4a8a353 100644
--- a/src/main/resources/templates/consultationsDisplay/consultations.html
+++ b/src/main/resources/templates/consultationsDisplay/consultations.html
@@ -45,8 +45,8 @@
 
 
             <div id="consultations" class="row">
-                <div class="col-12">
-                    <h5 class="consultations-type-modal">Редовни консултации
+                <div th:unless="${#lists.isEmpty(irregularPage.getContent())}" class="col-12">
+                    <h5 class="consultations-type-modal">Дополнителни консултации
                         <span data-toggle="tooltip"
                               data-placement="right"
                               title="Доколку се пријавите, професорот автоматски ќе биде
@@ -54,13 +54,12 @@
                               style="cursor: pointer;">
                             <i class="fas fa-info-circle"></i></span>
                     </h5>
-
-                    <div th:if="${#lists.isEmpty(regularPage.getContent())}">
+                    <div th:if="${#lists.isEmpty(irregularPage.getContent())}" style="padding-bottom: 3rem">
                         <p>Нема закажани консултации</p>
                     </div>
 
 
-                    <div th:each="consultation : ${regularPage.getContent()}">
+                    <div th:each="consultation : ${irregularPage.getContent()}">
                         <form action="/consultations/schedule" method="post"
                               th:if="${consultationAttendanceMap[consultation.id] == null}">
                             <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
@@ -77,7 +76,7 @@
                                         <div class="d-flex align-items-top">
                                     <span><img class="consultation-logos mx-2" src="/images/consultation-logo-time.png"
                                                alt=""></span>
-                                            <p th:text="|${consultation.startTime} - ${consultation.endTime}|"
+                                            <p th:text="${consultation.startTime} + ' - ' + ${consultation.endTime}"
                                                class="time mb-0 d-inline-block ml-2"></p>
                                         </div>
                                         <div th:unless="${consultation.online==null}" class="d-flex align-items-top">
@@ -120,7 +119,8 @@
                         </form>
 
 
-                        <div th:if="${consultationAttendanceMap[consultation.id] != null}">
+
+                        <div th:if="${consultationAttendanceMap[consultation.id] != null}" style="padding-bottom: 3rem">
                             <div class="consultation-div mb-3 px-2 py-1">
                                 <div class="row">
                                     <div class="col-md-3 col-sm-12 col-12">
@@ -178,26 +178,26 @@
                                             <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
                                             <input type="hidden" name="attendanceId"
                                                    th:value="${consultationAttendanceMap[consultation.id].id}"/>
-                                            <input type="hidden" name="consultationId" value=""/>
                                             <input type="hidden" name="professorId" th:value="${professor.id}"/>
+                                            <input type="hidden" name="consultationId" value=""/>
 
                                             <textarea name="newComment" class="form-control mt-2 me-2"
                                                       placeholder="Коментар..." maxlength="1000" rows="3"
                                                       style="width: 75%;"></textarea>
 
-                                            <button type="submit" class="custom-comment-button mt-2 btn-sm">Додај коментар</button>
+                                            <button type="submit" class="custom-comment-button mt-2">Додај коментар</button>
                                         </form>
                                     </div>
                                 </div>
                             </div>
                         </div>
                     </div>
-                    <div th:unless="${#lists.isEmpty(regularPage.getContent())}" th:include="fragments/regularPaging :: pageSection(${regularPage})" class="mb-4"></div>
-                </div>
 
+                    <div th:unless="${#lists.isEmpty(irregularPage.getContent())}" th:include="fragments/irregularPaging :: pageSection(${irregularPage})" class="mb-2"></div>
+                </div>
 
-                <div class="col-12">
-                    <h5 class="consultations-type-modal">Дополнителни консултации
+                <div th:unless="${#lists.isEmpty(regularPage.getContent())}" class="col-12">
+                    <h5 class="consultations-type-modal">Редовни консултации
                         <span data-toggle="tooltip"
                               data-placement="right"
                               title="Доколку се пријавите, професорот автоматски ќе биде
@@ -205,12 +205,13 @@
                               style="cursor: pointer;">
                             <i class="fas fa-info-circle"></i></span>
                     </h5>
-                    <div th:if="${#lists.isEmpty(irregularPage.getContent())}" style="padding-bottom: 3rem">
+
+                    <div th:if="${#lists.isEmpty(regularPage.getContent())}">
                         <p>Нема закажани консултации</p>
                     </div>
 
 
-                    <div th:each="consultation : ${irregularPage.getContent()}">
+                    <div th:each="consultation : ${regularPage.getContent()}">
                         <form action="/consultations/schedule" method="post"
                               th:if="${consultationAttendanceMap[consultation.id] == null}">
                             <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
@@ -227,7 +228,7 @@
                                         <div class="d-flex align-items-top">
                                     <span><img class="consultation-logos mx-2" src="/images/consultation-logo-time.png"
                                                alt=""></span>
-                                            <p th:text="${consultation.startTime} + ' - ' + ${consultation.endTime}"
+                                            <p th:text="|${consultation.startTime} - ${consultation.endTime}|"
                                                class="time mb-0 d-inline-block ml-2"></p>
                                         </div>
                                         <div th:unless="${consultation.online==null}" class="d-flex align-items-top">
@@ -270,8 +271,7 @@
                         </form>
 
 
-
-                        <div th:if="${consultationAttendanceMap[consultation.id] != null}" style="padding-bottom: 3rem">
+                        <div th:if="${consultationAttendanceMap[consultation.id] != null}">
                             <div class="consultation-div mb-3 px-2 py-1">
                                 <div class="row">
                                     <div class="col-md-3 col-sm-12 col-12">
@@ -329,22 +329,26 @@
                                             <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
                                             <input type="hidden" name="attendanceId"
                                                    th:value="${consultationAttendanceMap[consultation.id].id}"/>
-                                            <input type="hidden" name="professorId" th:value="${professor.id}"/>
                                             <input type="hidden" name="consultationId" value=""/>
+                                            <input type="hidden" name="professorId" th:value="${professor.id}"/>
 
                                             <textarea name="newComment" class="form-control mt-2 me-2"
                                                       placeholder="Коментар..." maxlength="1000" rows="3"
                                                       style="width: 75%;"></textarea>
 
-                                            <button type="submit" class="custom-comment-button mt-2">Додај коментар</button>
+                                            <button type="submit" class="custom-comment-button mt-2 btn-sm">Додај коментар</button>
                                         </form>
                                     </div>
                                 </div>
                             </div>
                         </div>
                     </div>
+                    <div th:unless="${#lists.isEmpty(regularPage.getContent())}" th:include="fragments/regularPaging :: pageSection(${regularPage})" class="mb-4"></div>
+                </div>
 
-                    <div th:unless="${#lists.isEmpty(irregularPage.getContent())}" th:include="fragments/irregularPaging :: pageSection(${irregularPage})" class="mb-4"></div>
+                <div th:if="${#lists.isEmpty(regularPage.getContent()) and #lists.isEmpty(irregularPage.getContent())}"
+                     class="alert alert-info mt-4" role="alert">
+                    <h6 class="mb-0">Нема закажани консултации.</h6>
                 </div>
 
             </div>
-- 
GitLab


From 0da36cb64b24f889a590a2d6fde2d51e3fb9c0e9 Mon Sep 17 00:00:00 2001
From: "bojana.marojevikj" <bojana.marojevikj@finki.ukim.mk>
Date: Fri, 14 Mar 2025 10:45:23 +0100
Subject: [PATCH 10/13] remove unnecessary check

---
 .../templates/consultationsDisplay/consultations.html     | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/src/main/resources/templates/consultationsDisplay/consultations.html b/src/main/resources/templates/consultationsDisplay/consultations.html
index 4a8a353..61097fd 100644
--- a/src/main/resources/templates/consultationsDisplay/consultations.html
+++ b/src/main/resources/templates/consultationsDisplay/consultations.html
@@ -54,10 +54,6 @@
                               style="cursor: pointer;">
                             <i class="fas fa-info-circle"></i></span>
                     </h5>
-                    <div th:if="${#lists.isEmpty(irregularPage.getContent())}" style="padding-bottom: 3rem">
-                        <p>Нема закажани консултации</p>
-                    </div>
-
 
                     <div th:each="consultation : ${irregularPage.getContent()}">
                         <form action="/consultations/schedule" method="post"
@@ -206,10 +202,6 @@
                             <i class="fas fa-info-circle"></i></span>
                     </h5>
 
-                    <div th:if="${#lists.isEmpty(regularPage.getContent())}">
-                        <p>Нема закажани консултации</p>
-                    </div>
-
 
                     <div th:each="consultation : ${regularPage.getContent()}">
                         <form action="/consultations/schedule" method="post"
-- 
GitLab


From 2e8c8fb4c0881326667b1a1be99f88d419bed4f0 Mon Sep 17 00:00:00 2001
From: "bojana.marojevikj" <bojana.marojevikj@finki.ukim.mk>
Date: Fri, 14 Mar 2025 10:51:13 +0100
Subject: [PATCH 11/13] auth config sync

---
 src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java b/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java
index ad28122..75b716b 100644
--- a/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java
+++ b/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java
@@ -13,6 +13,7 @@ public class AuthConfig {
         return http
                 .authorizeHttpRequests((requests) -> requests
                     .requestMatchers(HttpMethod.OPTIONS).permitAll()
+                    .requestMatchers("/Consultations/GetTermsByTeacherCode").permitAll()
                     .requestMatchers(HttpMethod.POST, "/consultations").hasAnyAuthority(
                             AppRole.STUDENT.name(), AppRole.ADMIN.name(), AppRole.PROFESSOR.name())
                     .requestMatchers("/auth/*", "/","","/display/*","/css/*", "/js/*", "/images/*").permitAll()
-- 
GitLab


From cc77280f9a73c854d423cef35e4f0ec0163a05c5 Mon Sep 17 00:00:00 2001
From: "bojana.marojevikj" <bojana.marojevikj@finki.ukim.mk>
Date: Fri, 14 Mar 2025 10:54:36 +0100
Subject: [PATCH 12/13] auth config sync

---
 .../finki/konsultacii/config/AuthConfig.java  | 32 +++++++++----------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java b/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java
index 75b716b..169fa16 100644
--- a/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java
+++ b/src/main/java/mk/ukim/finki/konsultacii/config/AuthConfig.java
@@ -12,23 +12,23 @@ public class AuthConfig {
     public HttpSecurity authorize(HttpSecurity http) throws Exception {
         return http
                 .authorizeHttpRequests((requests) -> requests
-                    .requestMatchers(HttpMethod.OPTIONS).permitAll()
-                    .requestMatchers("/Consultations/GetTermsByTeacherCode").permitAll()
-                    .requestMatchers(HttpMethod.POST, "/consultations").hasAnyAuthority(
-                            AppRole.STUDENT.name(), AppRole.ADMIN.name(), AppRole.PROFESSOR.name())
-                    .requestMatchers("/auth/*", "/","","/display/*","/css/*", "/js/*", "/images/*").permitAll()
-                    .requestMatchers("/studentAttendances/**").hasRole(AppRole.STUDENT.name())
-                    .requestMatchers("/consultations/schedule").hasRole(AppRole.STUDENT.name())
-                    .requestMatchers("/consultations/cancel").hasRole(AppRole.STUDENT.name())
-                    .requestMatchers("/consultations/student/**").hasRole(AppRole.STUDENT.name())
-                    .requestMatchers("/professorAttendances/**").hasAnyRole(AppRole.PROFESSOR.name(), AppRole.ADMIN.name())
-                    .requestMatchers("/adminAttendances/**").hasRole(AppRole.ADMIN.name())
-                    .requestMatchers("/manage-consultations/import").hasRole(AppRole.ADMIN.name())
-                    .requestMatchers("/manage-consultations/sample-tsv").hasRole(AppRole.ADMIN.name())
-                    .requestMatchers("/manage-consultations/{professorId}/**").access(
+                        .requestMatchers(HttpMethod.OPTIONS).permitAll()
+                        .requestMatchers("/Consultations/GetTermsByTeacherCode").permitAll()
+                        .requestMatchers(HttpMethod.POST, "/consultations").hasAnyAuthority(
+                                AppRole.STUDENT.name(), AppRole.ADMIN.name(), AppRole.PROFESSOR.name())
+                        .requestMatchers("/auth/*", "/", "", "/display/*", "/css/*", "/js/*", "/images/*").permitAll()
+                        .requestMatchers("/studentAttendances/**").hasRole(AppRole.STUDENT.name())
+                        .requestMatchers("/professorAttendances/**").hasAnyRole(AppRole.PROFESSOR.name(), AppRole.ADMIN.name())
+                        .requestMatchers("/adminAttendances/**").hasRole(AppRole.ADMIN.name())
+                        .requestMatchers("/manage-consultations/import").hasRole(AppRole.ADMIN.name())
+                        .requestMatchers("/manage-consultations/sample-tsv").hasRole(AppRole.ADMIN.name())
+                        .requestMatchers("/manage-consultations/{professorId}/**").access(
                                 new WebExpressionAuthorizationManager("#professorId == authentication.name or hasRole('ROLE_ADMIN')")
-                    )
-                    .anyRequest().authenticated()
+                        )
+                        .requestMatchers("/consultations/schedule").hasRole(AppRole.STUDENT.name())
+                        .requestMatchers("/consultations/cancel").hasRole(AppRole.STUDENT.name())
+                        .requestMatchers("/consultations/student/**").hasRole(AppRole.STUDENT.name())
+                        .anyRequest().authenticated()
                 )
                 .logout(LogoutConfigurer::permitAll);
     }
-- 
GitLab


From 280a2a1a99c098df302a49d4006fed6cea69e70e Mon Sep 17 00:00:00 2001
From: "bojana.marojevikj" <bojana.marojevikj@finki.ukim.mk>
Date: Fri, 14 Mar 2025 10:58:29 +0100
Subject: [PATCH 13/13] Merge main

---
 .../mk/ukim/finki/konsultacii/config/MailConfig.java   |  6 ------
 src/main/resources/emailconfig.properties              | 10 ++++------
 2 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/src/main/java/mk/ukim/finki/konsultacii/config/MailConfig.java b/src/main/java/mk/ukim/finki/konsultacii/config/MailConfig.java
index aadf8fa..cf40baa 100644
--- a/src/main/java/mk/ukim/finki/konsultacii/config/MailConfig.java
+++ b/src/main/java/mk/ukim/finki/konsultacii/config/MailConfig.java
@@ -16,7 +16,6 @@ import org.thymeleaf.templateresolver.ITemplateResolver;
 
 import java.nio.charset.StandardCharsets;
 import java.util.Objects;
-import java.util.Properties;
 
 
 @Configuration
@@ -34,11 +33,6 @@ public class MailConfig {
         mailSender.setPort(Integer.parseInt(Objects.requireNonNull(environment.getProperty("spring.mail.port"))));
         mailSender.setUsername(environment.getProperty("spring.mail.username"));
         mailSender.setPassword(environment.getProperty("spring.mail.password"));
-
-        Properties props = new Properties();
-        props.put("mail.smtp.auth", environment.getProperty("spring.mail.properties.mail.smtp.auth"));
-        props.put("mail.smtp.starttls.enable", environment.getProperty("spring.mail.properties.mail.smtp.starttls.enable"));
-        mailSender.setJavaMailProperties(props);
         return mailSender;
     }
 
diff --git a/src/main/resources/emailconfig.properties b/src/main/resources/emailconfig.properties
index 35566ff..2e695a2 100644
--- a/src/main/resources/emailconfig.properties
+++ b/src/main/resources/emailconfig.properties
@@ -1,6 +1,4 @@
-spring.mail.host=smtp.gmail.com
-spring.mail.port=587
-spring.mail.username=${EMAIL_USERNAME:noreplay@finki.ukim.mk}
-spring.mail.password=${EMAIL_PASSWORD:empty}
-spring.mail.properties.mail.smtp.auth=true
-spring.mail.properties.mail.smtp.starttls.enable=true
\ No newline at end of file
+spring.mail.host=mailer.finki.ukim.mk
+spring.mail.port=25
+spring.mail.username=noreply@finki.ukim.mk
+spring.mail.password=
\ No newline at end of file
-- 
GitLab