Index: src/main/java/it/finki/charitable/controller/DonationPostController.java
===================================================================
--- src/main/java/it/finki/charitable/controller/DonationPostController.java	(revision ee0e2972779503cbac7ff1584f4ff29c30bac548)
+++ src/main/java/it/finki/charitable/controller/DonationPostController.java	(revision 7888b17443c71c7e2c64f2beae81d2a29dc74d25)
@@ -4,5 +4,5 @@
 import it.finki.charitable.services.*;
 import it.finki.charitable.util.FileUploadUtil;
-import org.springframework.data.domain.Page;
+import org.springframework.data.domain.*;
 import org.springframework.format.annotation.DateTimeFormat;
 import org.springframework.security.core.context.SecurityContextHolder;
@@ -15,8 +15,5 @@
 import java.io.IOException;
 import java.time.LocalDate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
 import java.util.stream.Collectors;
 
@@ -126,6 +123,61 @@
                         @RequestParam int page,
                         @RequestParam String sort,
-                        @RequestParam(required = false,defaultValue = "") String order) {
-        Page<DonationPost> postList = donationPostService.findPaginated(page,6, sort, order, true);
+                        @RequestParam(required = false, defaultValue = "desc") String order,
+                        @RequestParam(required = false, defaultValue = "all") String groupBy) {
+
+        Sort s = Sort.by(sort);
+        s = order.equals("asc") ? s.ascending() : s.descending();
+        Pageable pageable = PageRequest.of(page - 1, 6, s);
+        Page<DonationPost> postList;
+        postList = donationPostService.findPaginated(page, 6, sort, order, true);
+
+        if (!groupBy.equals("all")) {
+            List<DonationPost> allPosts = donationPostService.findAllByApproved(true);
+
+            if (sort.equals("title")) {
+                if (order.equals("asc")) {
+                    allPosts.sort(Comparator.comparing(DonationPost::getTitle, (s1, s2) -> s1.compareToIgnoreCase(s2)));
+                } else {
+                    allPosts.sort(Comparator.comparing(DonationPost::getTitle, (s1, s2) -> s2.compareToIgnoreCase(s1)));
+                }
+            } else if (sort.equals("dateDue")) {
+                if (order.equals("asc")) {
+                    allPosts.sort(Comparator.comparing(DonationPost::getDateDue));
+                } else {
+                    allPosts.sort(Comparator.comparing(DonationPost::getDateDue).reversed());
+                }
+            } else if (sort.equals("fundsNeeded")) {
+                if (order.equals("asc")) {
+                    allPosts.sort(Comparator.comparing(DonationPost::getFundsNeeded));
+                } else {
+                    allPosts.sort(Comparator.comparing(DonationPost::getFundsNeeded).reversed());
+                }
+            }
+
+            if (groupBy.equals("completed")) {
+                List<DonationPost> completed = allPosts.stream().filter(post -> {
+                    double fundsCollected = post.getFundsCollected().stream().mapToDouble(FundsCollected::getFunds).sum();
+                    return fundsCollected >= post.getFundsNeeded();
+                }).collect(Collectors.toList());
+
+                int start = (int) pageable.getOffset();
+                int end = Math.min((start + pageable.getPageSize()), completed.size());
+                if (start <= end) {
+                    postList = new PageImpl<>(completed.subList(start, end), pageable, completed.size());
+                }
+            } else if (groupBy.equals("expired")) {
+                List<DonationPost> expired = allPosts.stream().filter(post -> {
+                    double fundsCollected = post.getFundsCollected().stream().mapToDouble(FundsCollected::getFunds).sum();
+                    return LocalDate.now().isAfter(post.getDateDue()) && fundsCollected < post.getFundsNeeded();
+                }).collect(Collectors.toList());
+
+                int start = (int) pageable.getOffset();
+                int end = Math.min((start + pageable.getPageSize()), expired.size());
+                if (start <= end) {
+                    postList = new PageImpl<>(expired.subList(start, end), pageable, expired.size());
+                }
+            }
+        }
+
         if (postList.getTotalElements() == 0) {
             model.addAttribute("noPosts", true);
@@ -193,5 +245,5 @@
         DonationPost donationPost = donationPostService.getById(postid);
         ReportPost reportPost = reportPostService.findByDonationPost(donationPost);
-        if(reportPost == null) {
+        if (reportPost == null) {
             reportPost = new ReportPost();
             reportPost.setDonationPost(donationPost);
Index: src/main/resources/static/js/pagination.js
===================================================================
--- src/main/resources/static/js/pagination.js	(revision ee0e2972779503cbac7ff1584f4ff29c30bac548)
+++ src/main/resources/static/js/pagination.js	(revision 7888b17443c71c7e2c64f2beae81d2a29dc74d25)
@@ -5,4 +5,5 @@
 let sort = findGetParameter("sort");
 let order = findGetParameter("order");
+let group = findGetParameter("groupBy")
 
 let sortByInput = document.getElementById("sortBy");
@@ -12,10 +13,17 @@
 orderInput.value = order;
 
+let groupByInput = document.getElementById("groupBy") === null ? document.createElement("input") : document.getElementById("groupBy");
+groupByInput.value = group;
+
 sortByInput.addEventListener("change", function () {
-    window.location.href = url + "?page=" + currentPage + "&sort=" + sortByInput.value + "&order=" + orderInput.value;
+    window.location.href = url + "?page=" + currentPage + "&sort=" + sortByInput.value + "&order=" + orderInput.value + "&groupBy=" + groupByInput.value;
 })
 
 orderInput.addEventListener("change", function() {
-    window.location.href = url + "?page=" + currentPage + "&sort=" + sortByInput.value + "&order=" + orderInput.value;
+    window.location.href = url + "?page=" + currentPage + "&sort=" + sortByInput.value + "&order=" + orderInput.value + "&groupBy=" + groupByInput.value;
+})
+
+groupByInput.addEventListener("change", function () {
+    window.location.href = url + "?page=" + 1 + "&sort=" + sortByInput.value + "&order=" + orderInput.value + "&groupBy=" + groupByInput.value;
 })
 
@@ -29,5 +37,5 @@
 
     if (page > 1) {
-        str += '<li class="page-item"><a class="page-link" href="'+url+'?page='+(page-1)+'&sort='+sort+'&order='+order+'">Previous</a></li>';
+        str += '<li class="page-item"><a class="page-link" href="'+url+'?page='+(page-1)+'&sort='+sort+'&order='+order+'&groupBy='+group+'">Previous</a></li>';
     }
 
@@ -35,5 +43,5 @@
         for (let p = 1; p <= pages; p++) {
             active = page == p ? "active" : "";
-            str += '<li class="page-item '+active+'"><a class="page-link" href="'+url+'?page='+p+'&sort='+sort+'&order='+order+'">'+ p +'</a></li>';
+            str += '<li class="page-item '+active+'"><a class="page-link" href="'+url+'?page='+p+'&sort='+sort+'&order='+order+'&groupBy='+group+'">'+ p +'</a></li>';
         }
     }
@@ -41,7 +49,7 @@
     else {
         if (page > 2) {
-            str += '<li class="page-item"><a class="page-link" href="'+url+'?page=1&sort='+sort+'&order='+order+'">1</a></li>';
+            str += '<li class="page-item"><a class="page-link" href="'+url+'?page=1&sort='+sort+'&order='+order+'&groupBy='+group+'">1</a></li>';
             if (page > 3) {
-                str += '<li class="page-item"><a class="page-link" href="'+url+'?page='+(page-2)+'&sort='+sort+'&order='+order+'">...</a></li>';
+                str += '<li class="page-item"><a class="page-link" href="'+url+'?page='+(page-2)+'&sort='+sort+'&order='+order+'&groupBy='+group+'">...</a></li>';
             }
         }
@@ -67,17 +75,17 @@
             }
             active = page == p ? "active" : "";
-            str += '<li class="page-item '+active+'"><a class="page-link" href="'+url+'?page='+p+'&sort='+sort+'&order='+order+'">'+ p +'</a></li>';
+            str += '<li class="page-item '+active+'"><a class="page-link" href="'+url+'?page='+p+'&sort='+sort+'&order='+order+'&groupBy='+group+'">'+ p +'</a></li>';
         }
 
         if (page < pages-1) {
             if (page < pages-2) {
-                str += '<li class="page-item"><a class="page-link" href="'+url+'?page='+(page+2)+'&sort='+sort+'&order='+order+'">...</a></li>';
+                str += '<li class="page-item"><a class="page-link" href="'+url+'?page='+(page+2)+'&sort='+sort+'&order='+order+'&groupBy='+group+'">...</a></li>';
             }
-            str += '<li class="page-item"><a class="page-link" href="'+url+'?page='+pages+'&sort='+sort+'&order='+order+'">'+pages+'</a></li>';
+            str += '<li class="page-item"><a class="page-link" href="'+url+'?page='+pages+'&sort='+sort+'&order='+order+'&groupBy='+group+'">'+pages+'</a></li>';
         }
     }
 
     if (page < pages) {
-        str += '<li class="page-item"><a class="page-link" href="'+url+'?page='+(page+1)+'&sort='+sort+'&order='+order+'">Next</a></li>';
+        str += '<li class="page-item"><a class="page-link" href="'+url+'?page='+(page+1)+'&sort='+sort+'&order='+order+'&groupBy='+group+'">Next</a></li>';
     }
     str += '</ul>';
Index: src/main/resources/templates/album.html
===================================================================
--- src/main/resources/templates/album.html	(revision ee0e2972779503cbac7ff1584f4ff29c30bac548)
+++ src/main/resources/templates/album.html	(revision 7888b17443c71c7e2c64f2beae81d2a29dc74d25)
@@ -35,4 +35,12 @@
                     </select>
                 </div>
+                <div class="col-md-2">
+                    <label class="form-label" for="groupBy">Group by</label>
+                    <select class="input-group-text" id="groupBy">
+                        <option value="all">All</option>
+                        <option value="completed">Completed</option>
+                        <option value="expired">Expired</option>
+                    </select>
+                </div>
             </div>
             <br>
Index: src/main/resources/templates/common/navbar.html
===================================================================
--- src/main/resources/templates/common/navbar.html	(revision ee0e2972779503cbac7ff1584f4ff29c30bac548)
+++ src/main/resources/templates/common/navbar.html	(revision 7888b17443c71c7e2c64f2beae81d2a29dc74d25)
@@ -23,5 +23,5 @@
                     </li>
                     <li class="nav-item">
-                        <a sec:authorize="isAnonymous() or hasAuthority('USER')" th:href="@{/album?page=1&sort=id}" class="nav-link px-2 text-white">Posts</a>
+                        <a sec:authorize="isAnonymous() or hasAuthority('USER')" th:href="@{/album?page=1&sort=id&order=desc&groupBy=all}" class="nav-link px-2 text-white">Posts</a>
                         <a sec:authorize="hasAuthority('MODERATOR')" th:href="@{/moderator/approval?page=1&sort=id}" class="nav-link px-2 text-white">Posts for approval</a>
                     </li>
Index: src/main/resources/templates/post.html
===================================================================
--- src/main/resources/templates/post.html	(revision ee0e2972779503cbac7ff1584f4ff29c30bac548)
+++ src/main/resources/templates/post.html	(revision 7888b17443c71c7e2c64f2beae81d2a29dc74d25)
@@ -67,14 +67,17 @@
                 Donate
             </button>
-            <a sec:authorize="isAnonymous()" type="button" class="btn btn-primary" th:href="@{/login}">
+            <button sec:authorize="isAnonymous()" type="button" class="btn btn-primary" disabled>
                 Donate
-            </a>
-            <button type="button" class="btn btn-danger" data-bs-toggle="modal"
+            </button>
+            <button sec:authorize="isAuthenticated()" type="button" class="btn btn-danger" data-bs-toggle="modal"
                     data-bs-target="#staticBackdrop1">
                 Report
             </button>
+            <button sec:authorize="isAnonymous()" type="button" class="btn btn-danger" disabled>
+                Report
+            </button>
 
             <!-- Modal -->
-            <div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
+            <div sec:authorize="isAuthenticated()" class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
                 <div class="modal-dialog modal-dialog-centered">
                     <div class="modal-content">
@@ -136,5 +139,5 @@
                 </div>
             </div>
-            <div class="modal fade" id="staticBackdrop1" data-bs-backdrop="static" data-bs-keyboard="false"
+            <div sec:authorize="isAuthenticated()" class="modal fade" id="staticBackdrop1" data-bs-backdrop="static" data-bs-keyboard="false"
                  tabindex="-1" aria-labelledby="staticBackdropLabel1" aria-hidden="true">
                 <div class="modal-dialog modal-dialog-centered">
