diff --git a/CHANGELOG.md b/CHANGELOG.md
index e8ac522566f30ca64014c06b24d13ec23ced19df..7fb9866774c4ad54277420027c9bc9b267227693 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,13 +9,24 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
-## [Unreleased]
+## [2.2.1]
 
 ### Added
+- Requests in slotted labs can now be distributed to assistants in advanced. [@hpage](https://gitlab.ewi.tudelft.nl/hpage)
 
 ### Changed
+- Teachers can only see assistant feedback for courses that they manage. [@hpage](https://gitlab.ewi.tudelft.nl/hpage)
+- Slotted requests no longer show up 15 minutes in advance on the requests page. [@rwbackx](https://gitlab.ewi.tudelft.nl/rwbackx)
 
 ### Fixed
+- Teachers can no longer see feedback of other teachers. [@hpage](https://gitlab.ewi.tudelft.nl/hpage)
+- Screens should no longer sleep when presenting (not supported on Firefox). [@rwbackx](https://gitlab.ewi.tudelft.nl/rwbackx)
+- Lab filter for shared labs now shows the correct course codes in front of assignments. [@hpage](https://gitlab.ewi.tudelft.nl/hpage)
+- Chips are no longer cut off on smaller devices. [@hpage](https://gitlab.ewi.tudelft.nl/hpage)
+- Presentation text was invisible on dark mode. [@rwbackx](https://gitlab.ewi.tudelft.nl/rwbackx)
+- Forwarded requests did not always show up or showed up for the wrong people in the requests table. [@rwbackx](https://gitlab.ewi.tudelft.nl/rwbackx)
+- All requests would be added to the request table regardless of language preference. [@rwbackx](https://gitlab.ewi.tudelft.nl/rwbackx)
+- Slotted lab page did not display requests. [@rwbackx](https://gitlab.ewi.tudelft.nl/rwbackx)
 
 ## [2.2.0]
 
@@ -41,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
  - Revoked requests could be finished (approved, rejected, etc.) by teachers. [@rwbackx](https://gitlab.ewi.tudelft.nl/rwbackx)
  - Room maps did not work. [@rwbackx](https://gitlab.ewi.tudelft.nl/rwbackx)
+ - Archive button appears again. [@mmadara](https://gitlab.ewi.tudelft.nl/mmadara)
 ### Deprecated
 
 ### Removed
diff --git a/build.gradle.kts b/build.gradle.kts
index 39121623db56c46ebe974df974a7b013cf82a726..8f4a7ac52d3c191bfbfacb7c123ab6529dcb80bd 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -6,7 +6,7 @@ import org.springframework.boot.gradle.tasks.run.BootRun
 import java.nio.file.Files
 
 group = "nl.tudelft.ewi.queue"
-version = "2.2.0"
+version = "2.2.1"
 
 val javaVersion = JavaVersion.VERSION_17
 
@@ -395,6 +395,8 @@ dependencies {
     implementation("org.webjars:momentjs:2.24.0")
     implementation("org.webjars:fullcalendar:5.9.0")
 	implementation("org.webjars:codemirror:5.62.2")
+    implementation("org.webjars.npm:simplemde:1.11.2")
+
 
     // Library for converting markdown to html
     implementation("org.commonmark:commonmark:0.18.1")
diff --git a/src/main/java/nl/tudelft/queue/controller/HomeController.java b/src/main/java/nl/tudelft/queue/controller/HomeController.java
index fb319f7ee74d58d2afc192ac2aac265e8b686004..fcc0416b048e9a7c1edf51439a822e6d86e28536 100644
--- a/src/main/java/nl/tudelft/queue/controller/HomeController.java
+++ b/src/main/java/nl/tudelft/queue/controller/HomeController.java
@@ -30,8 +30,10 @@ import nl.tudelft.labracore.api.PersonControllerApi;
 import nl.tudelft.labracore.api.SessionControllerApi;
 import nl.tudelft.labracore.api.dto.*;
 import nl.tudelft.labracore.lib.security.user.AuthenticatedPerson;
+import nl.tudelft.labracore.lib.security.user.DefaultRole;
 import nl.tudelft.labracore.lib.security.user.Person;
 import nl.tudelft.librador.dto.view.View;
+import nl.tudelft.queue.PageUtil;
 import nl.tudelft.queue.cache.EditionCacheManager;
 import nl.tudelft.queue.cache.EditionCollectionCacheManager;
 import nl.tudelft.queue.cache.PersonCacheManager;
@@ -50,6 +52,7 @@ import nl.tudelft.queue.service.PermissionService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
+import org.springframework.security.access.AccessDeniedException;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
@@ -252,13 +255,14 @@ public class HomeController {
 	@PreAuthorize("@permissionService.canViewOwnFeedback()")
 	public String ownFeedback(@AuthenticatedPerson Person person,
 			Model model, Pageable pageable) {
-		fillInFeedbackModel(person.getId(), person, model, pageable);
+		fillInFeedbackModel(person.getId(), person, model, pageable, false);
 
 		return "home/feedback";
 	}
 
 	/**
-	 * Maps the feedback url to a page. The Feedback page displays feedback for a user with the given ID.
+	 * Maps the feedback url to a page. The Feedback page displays feedback for a user with the given ID. This
+	 * endpoint is also used by TAM.
 	 *
 	 * @param  person   The person that is currently authenticated.
 	 * @param  id       The id of the person for which feedback will be shown.
@@ -270,7 +274,17 @@ public class HomeController {
 	@PreAuthorize("@permissionService.canViewFeedback(#id)")
 	public String feedback(@AuthenticatedPerson Person person, @PathVariable("id") Long id,
 			Model model, Pageable pageable) {
-		fillInFeedbackModel(id, person, model, pageable);
+		fillInFeedbackModel(id, person, model, pageable, false);
+
+		return "home/feedback";
+	}
+
+	@GetMapping("/feedback/{id}/manager")
+	@PreAuthorize("@permissionService.canViewFeedback(#id)")
+	public String feedbackManager(@AuthenticatedPerson Person person, @PathVariable("id") Long id,
+			Model model, Pageable pageable) {
+
+		fillInFeedbackModel(id, person, model, pageable, true);
 
 		return "home/feedback";
 	}
@@ -278,17 +292,32 @@ public class HomeController {
 	/**
 	 * Fills in the model for a page where feedback is shown to the user.
 	 *
-	 * @param assistantId The id of the user to find assistant for (this could be the current user).
-	 * @param person      The person that is currently authenticated.
-	 * @param model       The model that is to be filled.
-	 * @param pageable    The pageable containing information on how much feedback needs to be shown.
+	 *
+	 * @param  assistantId             The id of the user to find assistant for (this could be the current
+	 *                                 user).
+	 * @param  person                  The person that is currently authenticated.
+	 * @param  model                   The model that is to be filled.
+	 * @param  pageable                The pageable containing information on how much feedback needs to be
+	 *                                 shown.
+	 * @param  restrictToCourseManager Used to restrict feedback to the courses a manager teaches.
+	 * @throws AccessDeniedException   In the case that a teacher purposefully adds a teacher as a TA to view
+	 *                                 their feedback.
 	 */
-	private void fillInFeedbackModel(Long assistantId, Person person, Model model, Pageable pageable) {
+	private void fillInFeedbackModel(Long assistantId, Person person, Model model, Pageable pageable,
+			Boolean restrictToCourseManager) {
 		var assistant = pCache.getRequired(assistantId);
 
+		if (assistant.getDefaultRole() == PersonSummaryDTO.DefaultRoleEnum.TEACHER
+				&& person.getDefaultRole() != DefaultRole.ADMIN) {
+			throw new AccessDeniedException(
+					"Teachers are not permitted to view the feedback of other teachers.");
+		}
+
 		Page<Feedback> feedback = assistantId.equals(person.getId())
 				? fr.findByAssistantAnonymised(assistantId, pageable)
-				: fr.findByAssistant(assistantId, pageable);
+				: restrictToCourseManager
+						? fs.filterFeedbackForManagerCourses(fr.findByAssistant(assistantId), pageable)
+						: PageUtil.toPage(pageable, fr.findByAssistant(assistantId));
 
 		model.addAttribute("assistant", assistant);
 		model.addAttribute("feedback",
diff --git a/src/main/java/nl/tudelft/queue/controller/LabController.java b/src/main/java/nl/tudelft/queue/controller/LabController.java
index 6d06f33f6e6d67b0d5c5fb0d9e45b1193d88ac23..fbd719e277bab525fa37607998a0e8d6e2fe4b1d 100644
--- a/src/main/java/nl/tudelft/queue/controller/LabController.java
+++ b/src/main/java/nl/tudelft/queue/controller/LabController.java
@@ -54,6 +54,7 @@ import nl.tudelft.queue.dto.patch.labs.CapacitySessionPatchDTO;
 import nl.tudelft.queue.dto.patch.labs.ExamLabPatchDTO;
 import nl.tudelft.queue.dto.patch.labs.RegularLabPatchDTO;
 import nl.tudelft.queue.dto.patch.labs.SlottedLabPatchDTO;
+import nl.tudelft.queue.dto.util.DistributeRequestsDTO;
 import nl.tudelft.queue.dto.util.RequestTableFilterDTO;
 import nl.tudelft.queue.dto.view.RequestViewDTO;
 import nl.tudelft.queue.model.QueueSession;
@@ -144,6 +145,9 @@ public class LabController {
 	@Autowired
 	private RoleDTOService roleService;
 
+	@Autowired
+	private RequestService requestService;
+
 	@Autowired
 	private StudentGroupControllerApi sgApi;
 
@@ -251,6 +255,26 @@ public class LabController {
 		return "redirect:/lab/" + lab.getId();
 	}
 
+	/**
+	 *
+	 * @param  lab    The lab that we will distribute requests for
+	 * @param  person The distributor of the requests
+	 * @param  dto    The DTO containing the assignments and assistants to distribute
+	 * @return        A redirect to the lab overview page.
+	 */
+	@Transactional
+	@PostMapping("/lab/{lab}/distribute")
+	@PreAuthorize("@permissionService.canManageSession(#lab)")
+	public String distributeRequests(@PathEntity Lab lab, @AuthenticatedPerson Person person,
+			DistributeRequestsDTO dto) {
+
+		dto.getEditionSelections()
+				.forEach(edition -> requestService.distributeRequests(edition.getSelectedAssignments(),
+						edition.getSelectedAssistants(), person, lab));
+
+		return "redirect:/lab/" + lab.getId();
+	}
+
 	/**
 	 * Gets the student enqueue view. This page displays the form that needs to be filled out by the student
 	 * to successfully enrol into the given session.
@@ -765,6 +789,9 @@ public class LabController {
 						return isStaffInAll || roleService.rolesForPersonInEdition(edition, person).stream()
 								.noneMatch(roleService::isStaff);
 					}).toList();
+			Map<Long, CourseSummaryDTO> editionsToCourses = session.getEditions().stream()
+					.collect(Collectors.toMap(EditionSummaryDTO::getId,
+							edition -> eCache.getRequired(edition.getId()).getCourse()));
 			Map<Long, String> assignments = allowedAssignments.stream()
 					.collect(Collectors.toMap(AssignmentDetailsDTO::getId, a -> {
 						var edition = mCache.getRequired(a.getModule().getId()).getEdition();
@@ -773,6 +800,7 @@ public class LabController {
 								: eCache.getRequired(edition.getId()).getCourse().getName() + " - "
 										+ a.getName();
 					}));
+
 			Map<Long, Long> notEnqueueAble = allowedAssignments.stream().filter(a -> {
 				var edition = mCache.getRequired(a.getModule().getId()).getEdition();
 				return roleService.rolesForPersonInEdition(edition, person).isEmpty();
@@ -781,6 +809,11 @@ public class LabController {
 				return edition.getId();
 			}));
 
+			if (qSession instanceof AbstractSlottedLab<?>) {
+				model.addAttribute("distributeRequestsDto",
+						new DistributeRequestsDTO(editionsToCourses.size()));
+			}
+
 			Set<Long> alreadyInGroup = sgCache.getByPerson(person.getId()).stream()
 					.map(g -> g.getModule().getId()).collect(Collectors.toSet());
 			Set<Long> hasEmptyGroups = qSession.getModules().stream()
@@ -793,6 +826,7 @@ public class LabController {
 					allowedAssignments.stream().filter(a -> hasEmptyGroups.contains(a.getModule().getId()))
 							.map(AssignmentDetailsDTO::getId).collect(Collectors.toSet()));
 			model.addAttribute("assignments", assignments);
+			model.addAttribute("editionsToCourses", editionsToCourses);
 			model.addAttribute("notEnqueueAble", notEnqueueAble);
 			model.addAttribute("types", lab.getAllowedRequests().stream()
 					.collect(Collectors.groupingBy(AllowedRequest::getAssignment,
diff --git a/src/main/java/nl/tudelft/queue/controller/RequestController.java b/src/main/java/nl/tudelft/queue/controller/RequestController.java
index 39b90182c257f5c0cb4e85df47b74742939fc688..834d47e4f5a53f4e3e577b63f74c3ab0ae6731fd 100644
--- a/src/main/java/nl/tudelft/queue/controller/RequestController.java
+++ b/src/main/java/nl/tudelft/queue/controller/RequestController.java
@@ -20,6 +20,7 @@ package nl.tudelft.queue.controller;
 import static nl.tudelft.labracore.api.dto.RolePersonDetailsDTO.TypeEnum.*;
 
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Predicate;
@@ -43,6 +44,7 @@ import nl.tudelft.queue.model.LabRequest;
 import nl.tudelft.queue.model.QueueSession;
 import nl.tudelft.queue.model.Request;
 import nl.tudelft.queue.model.SelectionRequest;
+import nl.tudelft.queue.model.enums.RequestStatus;
 import nl.tudelft.queue.model.labs.Lab;
 import nl.tudelft.queue.repository.LabRequestRepository;
 import nl.tudelft.queue.repository.ProfileRepository;
@@ -148,7 +150,13 @@ public class RequestController {
 		model.addAttribute("showName", false);
 		model.addAttribute("showOnlyRelevant", true);
 		setRequestTableAttributes(model, pageable, assistant,
-				"/requests", r -> r.getEventInfo().getStatus().isPending(), false, true);
+				"/requests",
+				r -> r.getEventInfo().getStatus() == RequestStatus.PENDING ||
+						(r.getEventInfo().getStatus() == RequestStatus.FORWARDED &&
+								!Objects.equals(r.getEventInfo().getForwardedBy(), assistant.getId()) &&
+								(r.getEventInfo().getForwardedTo() == null ||
+										r.getEventInfo().getForwardedTo().equals(assistant.getId()))),
+				false, true);
 		return "request/list";
 	}
 
@@ -186,7 +194,7 @@ public class RequestController {
 				.collect(Collectors.toList());
 
 		List<LabRequest> filteredRequests = rs
-				.filterRequestsSharedEditionCheck(lrr.findAllByFilter(labs, filter, language))
+				.filterRequestsSharedEditionCheck(lrr.findAllByFilterUpcoming(labs, filter, language))
 				.stream().filter(requestFilter)
 				.toList();
 
diff --git a/src/main/java/nl/tudelft/queue/dto/util/DistributeRequestsDTO.java b/src/main/java/nl/tudelft/queue/dto/util/DistributeRequestsDTO.java
new file mode 100644
index 0000000000000000000000000000000000000000..faacb859ed0e653effd8c73608fb59060e6511ae
--- /dev/null
+++ b/src/main/java/nl/tudelft/queue/dto/util/DistributeRequestsDTO.java
@@ -0,0 +1,58 @@
+/*
+ * Queue - A Queueing system that can be used to handle labs in higher education
+ * Copyright (C) 2016-2021  Delft University of Technology
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+package nl.tudelft.queue.dto.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = false)
+public class DistributeRequestsDTO {
+
+	@Builder.Default
+	private List<EditionRequestDistributionDTO> editionSelections = new ArrayList<>();
+
+	public DistributeRequestsDTO(int numEditions) {
+		this.editionSelections = new ArrayList<>();
+		for (int i = 0; i < numEditions; i++) {
+			this.editionSelections.add(new EditionRequestDistributionDTO());
+		}
+	}
+
+	@Data
+	@NoArgsConstructor
+	@AllArgsConstructor
+	@EqualsAndHashCode(callSuper = false)
+	public static class EditionRequestDistributionDTO {
+
+		private List<Long> selectedAssignments = new ArrayList<>();
+
+		private List<Long> selectedAssistants = new ArrayList<>();
+
+	}
+
+}
diff --git a/src/main/java/nl/tudelft/queue/realtime/messages/RequestCreatedMessage.java b/src/main/java/nl/tudelft/queue/realtime/messages/RequestCreatedMessage.java
index db7b74d5a5d3ec86aab1a31e623d6b4d7d60404e..64cdaacb976329638e469af885357ce85df5b45d 100644
--- a/src/main/java/nl/tudelft/queue/realtime/messages/RequestCreatedMessage.java
+++ b/src/main/java/nl/tudelft/queue/realtime/messages/RequestCreatedMessage.java
@@ -51,6 +51,8 @@ public class RequestCreatedMessage extends View<LabRequest> implements Message {
 	private Long buildingId;
 	private String buildingName;
 
+	private String language;
+
 	private OnlineMode onlineMode;
 
 	private String onlineModeDisplayName;
diff --git a/src/main/java/nl/tudelft/queue/realtime/messages/RequestForwardedToAnyMessage.java b/src/main/java/nl/tudelft/queue/realtime/messages/RequestForwardedToAnyMessage.java
index 76bae7e626f74e3ae1c8cba35397edc861942e71..ba3d728913f6067ffb64f1b69d567be591919113 100644
--- a/src/main/java/nl/tudelft/queue/realtime/messages/RequestForwardedToAnyMessage.java
+++ b/src/main/java/nl/tudelft/queue/realtime/messages/RequestForwardedToAnyMessage.java
@@ -23,6 +23,7 @@ import lombok.*;
 import nl.tudelft.queue.dto.view.requests.LabRequestViewDTO;
 import nl.tudelft.queue.model.enums.OnlineMode;
 import nl.tudelft.queue.model.enums.RequestStatus;
+import nl.tudelft.queue.model.enums.RequestType;
 import nl.tudelft.queue.model.events.RequestForwardedToAnyEvent;
 
 @Data
@@ -53,6 +54,7 @@ public class RequestForwardedToAnyMessage extends RequestStatusUpdateMessage<Req
 	private String moduleName;
 
 	private Long labId;
+	private RequestType requestType;
 	private String requestTypeDisplayName;
 
 	@Override
@@ -94,6 +96,7 @@ public class RequestForwardedToAnyMessage extends RequestStatusUpdateMessage<Req
 
 		labId = view.getQSession().getId();
 
+		requestType = view.getRequestType();
 		requestTypeDisplayName = view.getRequestType().displayName();
 	}
 }
diff --git a/src/main/java/nl/tudelft/queue/realtime/messages/RequestForwardedToPersonMessage.java b/src/main/java/nl/tudelft/queue/realtime/messages/RequestForwardedToPersonMessage.java
index 7e9ea201f4548c92246bf0e917c93c5a892ad7bf..7948f282c558aeedf61b9643419a94c9a8b81e13 100644
--- a/src/main/java/nl/tudelft/queue/realtime/messages/RequestForwardedToPersonMessage.java
+++ b/src/main/java/nl/tudelft/queue/realtime/messages/RequestForwardedToPersonMessage.java
@@ -21,6 +21,7 @@ import lombok.*;
 import nl.tudelft.queue.dto.view.requests.LabRequestViewDTO;
 import nl.tudelft.queue.model.enums.OnlineMode;
 import nl.tudelft.queue.model.enums.RequestStatus;
+import nl.tudelft.queue.model.enums.RequestType;
 import nl.tudelft.queue.model.events.RequestForwardedToPersonEvent;
 
 @Data
@@ -38,15 +39,20 @@ public class RequestForwardedToPersonMessage
 
 	private String organizationName;
 
+	private Long roomId;
 	private String roomName;
+	private Long buildingId;
 	private String buildingName;
 
 	private OnlineMode onlineMode;
 	private String onlineModeDisplayName;
 
+	private Long assignmentId;
 	private String assignmentName;
+	private Long moduleId;
 	private String moduleName;
 
+	private RequestType requestType;
 	private String requestTypeDisplayName;
 
 	@Override
@@ -72,16 +78,21 @@ public class RequestForwardedToPersonMessage
 		requestedBy = view.requesterEntityName();
 
 		if (view.getRoom() != null) {
+			roomId = view.getRoom().getId();
 			roomName = view.getRoom().getName();
+			buildingId = view.getRoom().getBuilding().getId();
 			buildingName = view.getRoom().getBuilding().getName();
 		} else if (view.getOnlineMode() != null) {
 			onlineMode = view.getOnlineMode();
 			onlineModeDisplayName = view.getOnlineMode().getDisplayName();
 		}
 
+		assignmentId = view.getAssignment().getId();
 		assignmentName = view.getAssignment().getName();
+		moduleId = view.getAssignment().getModule().getId();
 		moduleName = view.getAssignment().getModule().getName();
 
+		requestType = view.getRequestType();
 		requestTypeDisplayName = view.getRequestType().displayName();
 	}
 }
diff --git a/src/main/java/nl/tudelft/queue/repository/FeedbackRepository.java b/src/main/java/nl/tudelft/queue/repository/FeedbackRepository.java
index 9fb6e629554baa23120710c0a791c163f38677ed..39ba61b6af96914bade7353cc54450477b5866ef 100644
--- a/src/main/java/nl/tudelft/queue/repository/FeedbackRepository.java
+++ b/src/main/java/nl/tudelft/queue/repository/FeedbackRepository.java
@@ -71,12 +71,11 @@ public interface FeedbackRepository
 
 	/**
 	 * @param  assistantId The assistant to find Feedback for.
-	 * @param  pageable    The pageable object to page feedback with.
 	 * @return             The page of feedback for the given Assistant.
 	 */
-	default Page<Feedback> findByAssistant(Long assistantId, Pageable pageable) {
+	default List<Feedback> findByAssistant(Long assistantId) {
 		return findAll(qf.id.assistantId.eq(assistantId)
-				.and(qf.feedback.isNotNull()).and(qf.feedback.isNotEmpty()), pageable);
+				.and(qf.feedback.isNotNull()).and(qf.feedback.isNotEmpty()));
 	}
 
 	/**
diff --git a/src/main/java/nl/tudelft/queue/repository/LabRequestRepository.java b/src/main/java/nl/tudelft/queue/repository/LabRequestRepository.java
index 556fdd0ff147ded47452390c61a0e822ce1385ba..075e27ebdc33a38e4da0cffc2280e4f306b911c7 100644
--- a/src/main/java/nl/tudelft/queue/repository/LabRequestRepository.java
+++ b/src/main/java/nl/tudelft/queue/repository/LabRequestRepository.java
@@ -355,24 +355,43 @@ public interface LabRequestRepository
 	/**
 	 * Finds all requests that pass the given filter. This filter is a DTO transferred from the page
 	 * requesting to see these requests. The filter contains all labs, rooms, assignments, etc. that need to
-	 * be displayed. If a field in the filter is left as an empty set, the filter ignores it.
+	 * be displayed. If a field in the filter is left as an empty set, the filter ignores it. Additionally,
+	 * returns only past and upcoming requests.
 	 *
 	 * @param  labs     The labs that the should also be kept in the filter.
 	 * @param  filter   The filter to apply to the boolean expression.
 	 * @param  language The assistant's language choice
 	 * @return          The filtered list of requests.
 	 */
-	default List<LabRequest> findAllByFilter(List<Lab> labs, RequestTableFilterDTO filter,
+	default List<LabRequest> findAllByFilterUpcoming(List<Lab> labs, RequestTableFilterDTO filter,
 			Language language) {
 		return findAll(qlr.in(select(qlr).from(qlr)
 				.leftJoin(qlr.timeSlot, QTimeSlot.timeSlot).on(qlr.timeSlot.id.eq(QTimeSlot.timeSlot.id))
 				.where(createFilterBooleanExpression(filter, qlr.session.in(labs).and(
 						qlr.session.type.eq(QueueSessionType.REGULAR)
 								.or(qlr.session.type.in(QueueSessionType.SLOTTED, QueueSessionType.EXAM)
-										.and(qlr.timeSlot.slot.opensAt.before(now().plusMinutes(10))))))
+										.and(qlr.timeSlot.slot.opensAt.before(now())))))
 												.and(matchesLanguagePreference(language)))));
 	}
 
+	/**
+	 * Finds all requests that pass the given filter. This filter is a DTO transferred from the page
+	 * requesting to see these requests. The filter contains all labs, rooms, assignments, etc. that need to
+	 * be displayed. If a field in the filter is left as an empty set, the filter ignores it.
+	 *
+	 * @param  labs     The labs that the should also be kept in the filter.
+	 * @param  filter   The filter to apply to the boolean expression.
+	 * @param  language The assistant's language choice
+	 * @return          The filtered list of requests.
+	 */
+	default List<LabRequest> findAllByFilter(List<Lab> labs, RequestTableFilterDTO filter,
+			Language language) {
+		return findAll(qlr.in(select(qlr).from(qlr)
+				.leftJoin(qlr.timeSlot, QTimeSlot.timeSlot).on(qlr.timeSlot.id.eq(QTimeSlot.timeSlot.id))
+				.where(createFilterBooleanExpression(filter, qlr.session.in(labs))
+						.and(matchesLanguagePreference(language)))));
+	}
+
 	/**
 	 * Creates the boolean expression that will filter requests through a filter DTO. This filter is a DTO
 	 * transferred from the page requesting to see these requests. The filter contains all labs, rooms,
diff --git a/src/main/java/nl/tudelft/queue/service/FeedbackService.java b/src/main/java/nl/tudelft/queue/service/FeedbackService.java
index 8dc69ea92dac183abdd159866fd29b64e447c7dd..3c325d8262af4cabb74dcddeb2797b0f0528aa42 100644
--- a/src/main/java/nl/tudelft/queue/service/FeedbackService.java
+++ b/src/main/java/nl/tudelft/queue/service/FeedbackService.java
@@ -21,12 +21,17 @@ import static java.time.LocalDateTime.now;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 import javax.transaction.Transactional;
 import javax.validation.ValidationException;
 
 import nl.tudelft.labracore.api.dto.PersonSummaryDTO;
+import nl.tudelft.labracore.api.dto.SessionDetailsDTO;
+import nl.tudelft.queue.PageUtil;
 import nl.tudelft.queue.cache.PersonCacheManager;
+import nl.tudelft.queue.cache.SessionCacheManager;
 import nl.tudelft.queue.dto.patch.FeedbackPatchDTO;
 import nl.tudelft.queue.model.Feedback;
 import nl.tudelft.queue.model.LabRequest;
@@ -34,6 +39,9 @@ import nl.tudelft.queue.repository.FeedbackRepository;
 import nl.tudelft.queue.repository.LabRequestRepository;
 
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 
 @Service
@@ -48,6 +56,16 @@ public class FeedbackService {
 	@Autowired
 	private LabRequestRepository rr;
 
+	@Autowired
+	private PermissionService ps;
+
+	@Autowired
+	@Lazy
+	private LabService ls;
+
+	@Autowired
+	private SessionCacheManager sessionCacheManager;
+
 	/**
 	 * Finds all assistant that are involved in the given request. This list of people is generated for
 	 * students to be able to give feedback on the one TA they want to give feedback on. This list is ordered
@@ -109,4 +127,32 @@ public class FeedbackService {
 				});
 	}
 
+	/**
+	 * Filters feedback for a manager, such that they can only see feedback for TAs in courses that they
+	 * managed.
+	 *
+	 * @param  feedback The list of feedback to be filtered.
+	 * @param  pageable The pageable used for paging.
+	 * @return          A Page of feedback that the manager can see.
+	 */
+	public Page<Feedback> filterFeedbackForManagerCourses(List<Feedback> feedback, Pageable pageable) {
+		List<Long> sessionIds = feedback.stream()
+				.map(fb -> fb.getRequest().getSession().getSession())
+				.distinct()
+				.toList();
+
+		Map<Long, Boolean> canManage = sessionCacheManager
+				.getAndHandleAll(sessionIds, ls.deleteSessionsByIds()).stream()
+				.collect(Collectors.toMap(
+						SessionDetailsDTO::getId,
+						session -> ps
+								.canManageInAnyEdition(new ArrayList<>(session.getEditions()))));
+
+		List<Feedback> filteredFeedback = feedback.stream()
+				.filter(fb -> canManage.getOrDefault(fb.getRequest().getSession().getSession(), false))
+				.toList();
+
+		return PageUtil.toPage(pageable, filteredFeedback);
+
+	}
 }
diff --git a/src/main/java/nl/tudelft/queue/service/LabService.java b/src/main/java/nl/tudelft/queue/service/LabService.java
index 3c65d220698a23cb0b33a39b9471f2d0f5abab2f..d825b05f211f8062b9936f2822c0884c2e2a95ac 100644
--- a/src/main/java/nl/tudelft/queue/service/LabService.java
+++ b/src/main/java/nl/tudelft/queue/service/LabService.java
@@ -18,6 +18,7 @@
 package nl.tudelft.queue.service;
 
 import static java.time.LocalDateTime.now;
+import static nl.tudelft.labracore.api.dto.RolePersonDetailsDTO.TypeEnum.*;
 import static nl.tudelft.queue.misc.QueueSessionStatus.*;
 
 import java.io.IOException;
diff --git a/src/main/java/nl/tudelft/queue/service/ModuleDTOService.java b/src/main/java/nl/tudelft/queue/service/ModuleDTOService.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd3c80e3b8c2d22ff863b50cc781ad46cea4199a
--- /dev/null
+++ b/src/main/java/nl/tudelft/queue/service/ModuleDTOService.java
@@ -0,0 +1,43 @@
+/*
+ * Queue - A Queueing system that can be used to handle labs in higher education
+ * Copyright (C) 2016-2021  Delft University of Technology
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+package nl.tudelft.queue.service;
+
+import java.util.List;
+
+import nl.tudelft.labracore.api.dto.AssignmentSummaryDTO;
+import nl.tudelft.labracore.api.dto.ModuleDetailsDTO;
+
+import org.springframework.stereotype.Service;
+
+@Service
+public class ModuleDTOService {
+
+	/**
+	 * Gets assignments with respect to a certain edition within several modules.
+	 *
+	 * @param  dto       The list of modules to consider.
+	 * @param  editionId The edition to consider.
+	 * @return           The assignments that belong to that edition within the modules.
+	 */
+	public List<AssignmentSummaryDTO> getAssignmentsInEdition(List<ModuleDetailsDTO> dto, Long editionId) {
+		return dto.stream().filter(module -> module.getEdition().getId().equals(editionId))
+				.flatMap(module -> module.getAssignments().stream())
+				.collect(java.util.stream.Collectors.toList());
+	}
+
+}
diff --git a/src/main/java/nl/tudelft/queue/service/PermissionService.java b/src/main/java/nl/tudelft/queue/service/PermissionService.java
index 7fb6c4d32890ea5fa4349dd977af09e9100ed50f..0f8c0bc86b29db55c026e10acd3f02c19385074a 100644
--- a/src/main/java/nl/tudelft/queue/service/PermissionService.java
+++ b/src/main/java/nl/tudelft/queue/service/PermissionService.java
@@ -759,7 +759,7 @@ public class PermissionService {
 	 *                   course and the request is not yet assigned to anybody.
 	 */
 	public boolean canPickRequest(Long requestId) {
-		return withRequest(requestId,
+		return isAdmin() || withRequest(requestId,
 				request -> withEdition(request.toViewDTO().getEdition().getId(),
 						edition -> withRole(edition.getId(),
 								(person, role) -> MANAGER_ROLES.contains(role)))
diff --git a/src/main/java/nl/tudelft/queue/service/RequestService.java b/src/main/java/nl/tudelft/queue/service/RequestService.java
index 013a04f2ce2615a3110a8ba49306e96611e89452..cb81608c0b707952a94c7944d4fec921252075d1 100644
--- a/src/main/java/nl/tudelft/queue/service/RequestService.java
+++ b/src/main/java/nl/tudelft/queue/service/RequestService.java
@@ -39,6 +39,7 @@ import nl.tudelft.queue.model.LabRequest;
 import nl.tudelft.queue.model.Request;
 import nl.tudelft.queue.model.SelectionRequest;
 import nl.tudelft.queue.model.enums.OnlineMode;
+import nl.tudelft.queue.model.enums.RequestStatus;
 import nl.tudelft.queue.model.enums.SelectionProcedure;
 import nl.tudelft.queue.model.events.*;
 import nl.tudelft.queue.model.labs.AbstractSlottedLab;
@@ -143,11 +144,6 @@ public class RequestService {
 			if (!currentlyEnqueuing.add(personId))
 				return;
 			if (request instanceof LabRequest labRequest) {
-				/*
-				 * TODO in the future, delegate to another service layer component,
-				 *  and let it generate a link for the respective online mode.
-				 * This is for the far future, when more online modes need to be supported.
-				 */
 
 				if (labRequest.getTimeSlot() != null && !labRequest.getTimeSlot().canTakeSlot()) {
 					throw new AccessDeniedException("Time slot is not available");
@@ -589,4 +585,34 @@ public class RequestService {
 				.flatMap(id -> sgApi.getStudentGroupsById(List.of(id)).collectList().map(l -> l.get(0)))
 				.block();
 	}
+
+	/**
+	 * Distributes requests by abusing the forwarding mechanism. Assigns requests in a round-robin fashion.
+	 *
+	 * @param selectedAssignments Assignments that should be distributed
+	 * @param selectedAssistants  Assistants that should receieve the distributed requests
+	 * @param distributor         Person who is responsible for distributing the requests
+	 * @param lab                 The lab session that the requests belong to.
+	 */
+	@Transactional
+	public void distributeRequests(List<Long> selectedAssignments, List<Long> selectedAssistants,
+			Person distributor, Lab lab) {
+		var assistants = pCache
+				.getAndIgnoreMissing(selectedAssistants);
+
+		if (assistants.isEmpty())
+			return;
+
+		var requests = lab.getRequests().stream()
+				.filter(rq -> selectedAssignments.contains(rq.getAssignment())
+						&& rq.getEventInfo().getStatus() == RequestStatus.PENDING)
+				.sorted(Comparator.comparing(Request::getCreatedAt))
+				.toList();
+
+		// round robin request assignment
+		for (int i = 0; i < requests.size(); i++) {
+			forwardRequestToPerson(requests.get(i), distributor, assistants.get(i % assistants.size()),
+					"Distributed by " + distributor.getDisplayName());
+		}
+	}
 }
diff --git a/src/main/java/nl/tudelft/queue/service/RequestTableService.java b/src/main/java/nl/tudelft/queue/service/RequestTableService.java
index 58ebdf0be90f91c9e848caa741e39e8cad52cc5d..7a3476c4ebec1d15a90989a986a56d11025e5fc4 100644
--- a/src/main/java/nl/tudelft/queue/service/RequestTableService.java
+++ b/src/main/java/nl/tudelft/queue/service/RequestTableService.java
@@ -22,7 +22,6 @@ import static nl.tudelft.labracore.api.dto.RolePersonDetailsDTO.TypeEnum.*;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.stream.Collectors;
-import java.util.stream.IntStream;
 import java.util.stream.Stream;
 
 import javax.servlet.http.HttpSession;
@@ -34,6 +33,7 @@ import nl.tudelft.labracore.api.SessionControllerApi;
 import nl.tudelft.labracore.api.dto.*;
 import nl.tudelft.labracore.lib.security.user.Person;
 import nl.tudelft.librador.dto.view.View;
+import nl.tudelft.queue.PageUtil;
 import nl.tudelft.queue.cache.*;
 import nl.tudelft.queue.dto.util.RequestTableFilterDTO;
 import nl.tudelft.queue.dto.view.QueueSessionSummaryDTO;
@@ -97,6 +97,9 @@ public class RequestTableService {
 	@Autowired
 	private SessionCacheManager sCache;
 
+	@Autowired
+	private ModuleCacheManager mCache;
+
 	@Autowired
 	private StudentGroupCacheManager sgCache;
 
@@ -273,10 +276,7 @@ public class RequestTableService {
 							.filter(r -> r.getEventInfo().getStatus() != RequestStatus.FORWARDED))
 					.toList();
 		}
-		final int start = (int) pageable.getOffset();
-		final int end = (int) (Math.min((start + pageable.getPageSize()), requestList.size()));
-		return new PageImpl<>(convertRequestsToView(sortedRequestList.subList(start, end)), pageable,
-				requestList.size());
+		return PageUtil.toPage(pageable, convertRequestsToView(sortedRequestList));
 	}
 
 	/**
@@ -375,18 +375,11 @@ public class RequestTableService {
 		if (assignments.isEmpty())
 			return Collections.emptyMap();
 
-		List<Long> assignmentIds = assignments.stream().map(AssignmentDetailsDTO::getId).toList();
-
-		var assignmentModules = Objects
-				.requireNonNull(aApi.getAssignmentsWithModules(assignmentIds).collectList().block());
-
-		List<String> courseCodes = eCache
-				.getAndIgnoreMissing(assignmentModules.stream()
-						.map(assignment -> assignment.getModule().getEdition().getId()))
-				.stream().map(edition -> edition.getCourse().getCode()).toList();
-
-		return IntStream.range(0, assignments.size()).boxed()
-				.collect(Collectors.toMap(assignmentIds::get, courseCodes::get));
+		return assignments.stream().collect(Collectors.toMap(
+				AssignmentDetailsDTO::getId,
+				assignment -> eCache
+						.getRequired(mCache.getRequired(assignment.getModule().getId()).getEdition().getId())
+						.getCourse().getCode()));
 
 	}
 
diff --git a/src/main/java/nl/tudelft/queue/service/RoleDTOService.java b/src/main/java/nl/tudelft/queue/service/RoleDTOService.java
index 5778a49563a7e1f775761f9a1431a2a4d71ab7e0..2824d217919b4f6182aaf6ea7130673e856959fb 100644
--- a/src/main/java/nl/tudelft/queue/service/RoleDTOService.java
+++ b/src/main/java/nl/tudelft/queue/service/RoleDTOService.java
@@ -27,7 +27,9 @@ import java.util.stream.Collectors;
 import nl.tudelft.labracore.api.RoleControllerApi;
 import nl.tudelft.labracore.api.dto.*;
 import nl.tudelft.labracore.lib.security.user.Person;
+import nl.tudelft.queue.cache.EditionCacheManager;
 import nl.tudelft.queue.cache.EditionRolesCacheManager;
+import nl.tudelft.queue.cache.SessionCacheManager;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -40,6 +42,12 @@ public class RoleDTOService {
 	@Autowired
 	private RoleControllerApi rApi;
 
+	@Autowired
+	private EditionCacheManager eCache;
+
+	@Autowired
+	private SessionCacheManager sessionCacheManager;
+
 	public List<String> names(List<PersonSummaryDTO> people) {
 		return people.stream().map(PersonSummaryDTO::getDisplayName).collect(Collectors.toList());
 	}
@@ -77,6 +85,10 @@ public class RoleDTOService {
 		return roles(erCache.getRequired(eDto.getId()).getRoles(), types);
 	}
 
+	public List<PersonSummaryDTO> roles(EditionSummaryDTO eDto, Set<RolePersonDetailsDTO.TypeEnum> types) {
+		return roles(eCache.getRequired(eDto.getId()), types);
+	}
+
 	/**
 	 * Gets the display name of the role type.
 	 *
@@ -131,6 +143,10 @@ public class RoleDTOService {
 		return roles(eDto, Set.of(TA));
 	}
 
+	public List<PersonSummaryDTO> staff(EditionSummaryDTO eDto) {
+		return roles(eDto, Set.of(TA, HEAD_TA, TEACHER, TEACHER_RO));
+	}
+
 	public List<PersonSummaryDTO> headTAs(EditionDetailsDTO eDto) {
 		return roles(eDto, Set.of(HEAD_TA));
 	}
diff --git a/src/main/resources/scss/presentation.scss b/src/main/resources/scss/presentation.scss
index 263b08d2bc7f277e7937d4ddd58c825499280530..7b3fd72f97e4c95fb1b016e43602dda44235f281 100644
--- a/src/main/resources/scss/presentation.scss
+++ b/src/main/resources/scss/presentation.scss
@@ -8,6 +8,7 @@
     }
 
     background-color: white;
+    color: black;
     display: flex;
     flex-direction: column;
     height: 100cqh;
diff --git a/src/main/resources/static/js/request_table.js b/src/main/resources/static/js/request_table.js
index 53844fe13cd17d93f184906705d675f66aa50d29..ec92da53f233f41f7f4a9d40d799caecfdd23f6d 100644
--- a/src/main/resources/static/js/request_table.js
+++ b/src/main/resources/static/js/request_table.js
@@ -77,6 +77,24 @@ const inFilter = (() => {
     };
 }).apply();
 
+/**
+ * Checks if the event matches the user's language preference.
+ *
+ * @param event The event to check
+ */
+function matchesLanguage(event) {
+    switch (event.language) {
+        case "ANY":
+            return true;
+        case "DUTCH_ONLY":
+            return userLanguage === "ANY" || userLanguage === "DUTCH_ONLY";
+        case "ENGLISH_ONLY":
+            return userLanguage === "ANY" || userLanguage === "ENGLISH_ONLY";
+        default:
+            return false;
+    }
+}
+
 /**
  * Handles the creation of a websocket connection by subscribing to the relevant topics.
  * @param client The STOMP Client object to connect with.
@@ -88,7 +106,7 @@ function handleSocketCreation(client) {
         if (page && page > 0) return;
 
         const event = JSON.parse(msg.body);
-        if (event.type === "request-created" && inFilter(event)) {
+        if (event.type === "request-created" && inFilter(event) && matchesLanguage(event)) {
             appendToRequestTable(event);
             increaseGetNextCounter(event["labId"]);
         } else if (event.type !== "request-created") {
diff --git a/src/main/resources/templates/admin/view/running.html b/src/main/resources/templates/admin/view/running.html
index 142bfc9a529e3745833b9e986fae18737ecc5e8c..9c157335de342e16028c97900abf0a32f07f0e60 100644
--- a/src/main/resources/templates/admin/view/running.html
+++ b/src/main/resources/templates/admin/view/running.html
@@ -36,22 +36,26 @@
                 <div th:if="${#lists.isEmpty(runningLabs)}">No sessions running</div>
 
                 <ul class="list divided" role="list">
-                    <li th:each="lab : ${runningLabs}" class="pbl-3">
+                    <li th:each="lab : ${runningLabs}" class="pbl-3 flex align-start align-center">
                         <a
                             class="link"
                             th:href="@{/lab/{id}(id=${lab.id})}"
                             th:text="|${lab.name} ${#temporals.format(lab.slot.opensAt, 'dd MMMM yyyy HH:mm')} - ${#temporals.format(lab.slot.closesAt, 'dd MMMM yyyy HH:mm')} ${lab.slotOccupationString}|"></a>
 
-                        <span class="chip" th:if="${lab.slot.open()}">Active</span>
-                        <span class="chip" th:if="${lab.slot.closed()}">Completed</span>
+                        <div class="flex wrap gap-2 p-1">
+                            <span class="chip" th:if="${lab.slot.open()}">Active</span>
+                            <span class="chip" th:if="${lab.slot.closed()}">Completed</span>
 
-                        <span class="chip" th:if="${lab.type == T(nl.tudelft.queue.model.enums.QueueSessionType).EXAM}">Exam</span>
-                        <span class="chip" th:if="${lab.type == T(nl.tudelft.queue.model.enums.QueueSessionType).SLOTTED}">Slotted</span>
-                        <span class="chip" th:if="${lab.type == T(nl.tudelft.queue.model.enums.QueueSessionType).CAPACITY}">Limited Capacity</span>
+                            <span class="chip" th:if="${lab.type == T(nl.tudelft.queue.model.enums.QueueSessionType).EXAM}">Exam</span>
+                            <span class="chip" th:if="${lab.type == T(nl.tudelft.queue.model.enums.QueueSessionType).SLOTTED}">Slotted</span>
+                            <span class="chip" th:if="${lab.type == T(nl.tudelft.queue.model.enums.QueueSessionType).CAPACITY}">
+                                Limited Capacity
+                            </span>
 
-                        <span class="chip" data-type="warning" th:if="${!lab.slot.closed() && lab.status.isOpenToEnqueueing()}">
-                            Open for enqueueing
-                        </span>
+                            <span class="chip" data-type="warning" th:if="${!lab.slot.closed() && lab.status.isOpenToEnqueueing()}">
+                                Open for enqueueing
+                            </span>
+                        </div>
                     </li>
                 </ul>
             </div>
diff --git a/src/main/resources/templates/edition/view/archive.html b/src/main/resources/templates/edition/view/archive.html
index 98548c6d0dbb93460dfb496fb4aba80d81dde7ff..d614d8de3e4f972c3bc93f44bb9b331d8b3c8eb2 100644
--- a/src/main/resources/templates/edition/view/archive.html
+++ b/src/main/resources/templates/edition/view/archive.html
@@ -10,9 +10,9 @@
     <body>
         <section layout:fragment="subcontent" th:with="currentDateTime=${T(java.time.LocalDateTime).now()}">
             <div class="page-sub-header">
-                <h3>Archive</h3>
+                <h3 class="font-500 mb-5">Archive edition</h3>
             </div>
-            <p th:if="${currentDateTime < edition.endDate}">
+            <p th:if="${currentDateTime < edition.endDate}" class="mb-5">
                 The edition has
                 <strong>not yet finished</strong>
                 . It will finish on
@@ -23,20 +23,18 @@
                 <strong th:text="|${edition.course.name} (${edition.name})|"></strong>
                 ?
             </p>
-            <p th:if="${currentDateTime >= edition.endDate}">
+            <p th:if="${currentDateTime >= edition.endDate}" class="mb-5">
                 The edition has finished. Are you sure you want to archive
                 <strong th:text="|${edition.course.name} (${edition.name})|"></strong>
                 ?
             </p>
 
-            <form action="#" th:action="@{/edition/{id}/archive(id=${edition.id})}" class="form-horizontal" method="post">
-                <div class="text-center">
-                    <button type="submit" class="btn btn-danger">Archive</button>
-                    <small>
-                        or
-                        <a th:href="@{/edition/{id}(id=${edition.id})}">go back</a>
-                    </small>
-                </div>
+            <form th:action="@{/edition/{id}/archive(id=${edition.id})}" method="post">
+                <button type="submit" class="button" data-type="error">Archive</button>
+                <small>
+                    or
+                    <a class="link" th:href="@{/edition/{id}(id=${edition.id})}">go back</a>
+                </small>
             </form>
         </section>
     </body>
diff --git a/src/main/resources/templates/edition/view/info.html b/src/main/resources/templates/edition/view/info.html
index 2c9773cf489b8e73082ef94a86286176e66f540f..2a6e8a82e35bbb3bba96b401e17982b1c2392252 100644
--- a/src/main/resources/templates/edition/view/info.html
+++ b/src/main/resources/templates/edition/view/info.html
@@ -88,6 +88,7 @@
                 <h3 class="font-500 mb-3">Options</h3>
 
                 <div class="flex wrap gap-3">
+                    <a th:href="@{/edition/{id}/archive(id=${edition.id})}" class="button" data-style="outlined" data-type="error">Archive edition</a>
                     <form class="d-inline" th:action="@{/edition/{editionId}/visibility(editionId=${edition.id})}" method="post">
                         <button class="button" data-style="outlined">
                             <span th:if="${edition.hidden}">Unhide in Queue</span>
diff --git a/src/main/resources/templates/edition/view/labs.html b/src/main/resources/templates/edition/view/labs.html
index a97c352404a530784a44e5d003a235736862bda5..309f8475fe96d7719bfd850b616aa687482676f0 100644
--- a/src/main/resources/templates/edition/view/labs.html
+++ b/src/main/resources/templates/edition/view/labs.html
@@ -82,14 +82,14 @@
                 <ul class="surface divided list" role="list">
                     <th:block th:each="lab : ${labs}">
                         <li class="flex space-between pbl-3">
-                            <div class="flex gap-3">
+                            <div class="flex gap-3 align-center">
                                 <a
                                     href="#"
                                     th:href="@{/lab/{id}(id=${lab.id})}"
                                     class="link"
                                     th:text="|${lab.name} ${#temporals.format(lab.slot.opensAt, 'dd MMMM yyyy HH:mm')} - ${#temporals.format(lab.slot.closesAt, 'dd MMMM yyyy HH:mm')} ${lab.slotOccupationString}|"></a>
 
-                                <div>
+                                <div class="flex wrap gap-2 p-1 align-center">
                                     <span class="chip" th:if="${lab.slot.open()}">Active</span>
                                     <span class="chip" th:if="${lab.slot.closed()}">Completed</span>
 
diff --git a/src/main/resources/templates/edition/view/participants.html b/src/main/resources/templates/edition/view/participants.html
index 8d15040c082c07d8973987ed27b5cbd13ed2261e..7835f7e0cdef6e3cc8eb2575dc03f1ddf39f6b8b 100644
--- a/src/main/resources/templates/edition/view/participants.html
+++ b/src/main/resources/templates/edition/view/participants.html
@@ -73,7 +73,7 @@
                     <ul class="surface__content divided list" role="list" th:unless="${#lists.isEmpty(headTAs)}">
                         <li class="pbl-3 flex space-between" th:each="person : ${headTAs}">
                             <th:block th:if="${@permissionService.canViewFeedback(person.id)}">
-                                <a class="link" th:href="@{/feedback/{id}(id=${person.id})}" th:text="${person.displayName}"></a>
+                                <a class="link" th:href="@{/feedback/{id}/manager(id=${person.id})}" th:text="${person.displayName}"></a>
                             </th:block>
                             <span th:unless="${@permissionService.canViewFeedback(person.id)}" th:text="${person.displayName}"></span>
                             <div class="flex gap-3">
@@ -95,7 +95,7 @@
                     <ul class="surface__content divided list" role="list" th:unless="${#lists.isEmpty(assistants)}">
                         <li class="pbl-3 flex space-between" th:each="person : ${assistants}">
                             <th:block th:if="${@permissionService.canViewFeedback(person.id)}">
-                                <a class="link" th:href="@{/feedback/{id}(id=${person.id})}" th:text="${person.displayName}"></a>
+                                <a class="link" th:href="@{/feedback/{id}/manager(id=${person.id})}" th:text="${person.displayName}"></a>
                             </th:block>
                             <span th:unless="${@permissionService.canViewFeedback(person.id)}" th:text="${person.displayName}"></span>
                             <div class="flex gap-3">
diff --git a/src/main/resources/templates/home/dashboard.html b/src/main/resources/templates/home/dashboard.html
index 514f57a554c13abeda51d0662b1e2391c8094c1b..14d9170b754051e28ee723e7c483cab3d741c358 100644
--- a/src/main/resources/templates/home/dashboard.html
+++ b/src/main/resources/templates/home/dashboard.html
@@ -175,7 +175,7 @@
                                                 class="link"
                                                 th:href="@{/lab/{id}(id=${lab.id})}"
                                                 th:text="|${lab.name} ${#temporals.format(lab.slot.opensAt, 'dd MMMM yyyy HH:mm')} - ${#temporals.format(lab.slot.closesAt, 'dd MMMM yyyy HH:mm')} ${lab.slotOccupationString}|"></a>
-                                            <div>
+                                            <div class="flex wrap gap-2 p-1">
                                                 <span th:if="${lab.isShared}" class="chip">Shared lab</span>
                                                 <span class="chip" th:if="${lab.slot.open()}">Active</span>
                                                 <span class="chip" th:if="${lab.slot.closed()}">Completed</span>
diff --git a/src/main/resources/templates/home/language.html b/src/main/resources/templates/home/language.html
index 2849ad84c997ca568ad323d64e7b2367193625ca..9670d5e3e4394a2002bca943e021f61cd0092e1e 100644
--- a/src/main/resources/templates/home/language.html
+++ b/src/main/resources/templates/home/language.html
@@ -20,6 +20,11 @@
             </div>
         </form>
 
+        <script th:inline="javascript">
+            //<![CDATA[
+            const userLanguage = /*[[${#profile.language.name()}]]*/ "ENGLISH_ONLY";
+            //]]>
+        </script>
         <script>
             document.addEventListener("DOMContentLoaded", function () {
                 const form = document.getElementById("profile-update-form");
diff --git a/src/main/resources/templates/lab/create.html b/src/main/resources/templates/lab/create.html
index 454d970d0cec50d456e1ecf5acf265b9ce880f08..ab985c3ae7db5a45243475fdf70bd8c088e04e9e 100644
--- a/src/main/resources/templates/lab/create.html
+++ b/src/main/resources/templates/lab/create.html
@@ -24,8 +24,8 @@
 
         <script src="/webjars/momentjs/min/moment.min.js"></script>
 
-        <link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css" />
-        <script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script>
+        <link rel="stylesheet" href="/webjars/simplemde/dist/simplemde.min.css" />
+        <script src="/webjars/simplemde/dist/simplemde.min.js"></script>
     </head>
 
     <!--@thymesVar id="ec" type="nl.tudelft.labracore.api.dto.EditionCollectionDetailsDTO"-->
diff --git a/src/main/resources/templates/lab/edit.html b/src/main/resources/templates/lab/edit.html
index 15d4ef7b73c4f2d40a71ed46c585684be76a6c9f..953dce4dc37e7a5a26057b0cc9747e1a0d70d4e0 100644
--- a/src/main/resources/templates/lab/edit.html
+++ b/src/main/resources/templates/lab/edit.html
@@ -22,8 +22,8 @@
     <head>
         <script src="/webjars/momentjs/min/moment.min.js"></script>
 
-        <link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css" />
-        <script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script>
+        <link rel="stylesheet" href="/webjars/simplemde/dist/simplemde.min.css" />
+        <script src="/webjars/simplemde/dist/simplemde.min.js"></script>
     </head>
 
     <!--@thymesVar id="ec" type="nl.tudelft.labracore.api.dto.EditionCollectionDetailsDTO"-->
diff --git a/src/main/resources/templates/lab/presentation/edit.html b/src/main/resources/templates/lab/presentation/edit.html
index cb70b3040ef1969908b6dc0ba482bc4f579f7145..249eea3d9757dcda9088224c8bf27f9970c402bb 100644
--- a/src/main/resources/templates/lab/presentation/edit.html
+++ b/src/main/resources/templates/lab/presentation/edit.html
@@ -22,8 +22,8 @@
     <head>
         <link rel="stylesheet" href="/css/presentation.css" />
 
-        <link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css" />
-        <script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script>
+        <link rel="stylesheet" href="/webjars/simplemde/dist/simplemde.min.css" />
+        <script src="/webjars/simplemde/dist/simplemde.min.js"></script>
     </head>
 
     <body>
diff --git a/src/main/resources/templates/lab/presentation/view.html b/src/main/resources/templates/lab/presentation/view.html
index 73ca4b2f5d941c5fa498633f67dff0fe7e004828..ce82d25041a5ba090d925fda20952b704feb0b28 100644
--- a/src/main/resources/templates/lab/presentation/view.html
+++ b/src/main/resources/templates/lab/presentation/view.html
@@ -22,6 +22,11 @@
     <head>
         <link rel="stylesheet" href="/css/presentation.css" />
         <script src="/webjars/momentjs/min/moment.min.js"></script>
+        <script>
+            document.addEventListener("DOMContentLoaded", async function () {
+                await navigator.wakeLock.request("screen");
+            });
+        </script>
     </head>
 
     <body>
diff --git a/src/main/resources/templates/lab/view/components/slots-info.html b/src/main/resources/templates/lab/view/components/slots-info.html
index bcdda9b8e98a5f8f0f0e938c10631cfb03d50b45..89dadfbd130fb055984a8635ff31cabf642e631d 100644
--- a/src/main/resources/templates/lab/view/components/slots-info.html
+++ b/src/main/resources/templates/lab/view/components/slots-info.html
@@ -22,6 +22,8 @@
 
     <!--@thymesVar id="qSession" type="nl.tudelft.queue.dto.view.labs.AbstractSlottedLabViewDTO"-->
 
+    <!--@thymesVar id="distributeRequestsDto" type="nl.tudelft.queue.dto.util.DistributeRequestsDTO"-->
+
     <body>
         <div th:fragment="slots-info">
             <div th:if="${@permissionService.canManageSession(qSession.data)}" class="tabs mb-5" role="tablist">
@@ -33,6 +35,10 @@
                     <i class="fa fa-chair"></i>
                     Edit time slot Capacity
                 </button>
+                <button type="button" role="tab" aria-controls="ts-distribution-tab" aria-selected="false">
+                    <i class="fa fa-users-cog"></i>
+                    Distribute Requests
+                </button>
             </div>
 
             <div id="basic-tab">
@@ -168,6 +174,81 @@
                     </form>
                 </div>
             </th:block>
+
+            <th:block th:if="${@permissionService.canManageSession(qSession.data)}">
+                <div id="ts-distribution-tab" hidden>
+                    <div class="flex vertical gap-5">
+                        <h2 class="font-600 fw-400">Distribute Requests</h2>
+                        <div class="banner" data-type="info">
+                            <span class="fa-solid fa-info-circle"></span>
+                            <p>
+                                Distribute pending requests relating to specific assignments in a round-robin fashion among selected assistants. The
+                                distribution will be done in the order of the assistants selected.
+                            </p>
+                        </div>
+
+                        <form
+                            th:object="${distributeRequestsDto}"
+                            th:action="@{/lab/{id}/distribute(id=${qSession.id})}"
+                            th:method="POST"
+                            class="flex vertical gap-5">
+                            <div id="distribute-edition-cards" class="flex vertical space-between">
+                                <th:block th:each="edition, editionItemStat : ${qSession.session.editions}">
+                                    <div
+                                        class="surface p-0"
+                                        th:id="'distribute-card-' + ${edition.id}"
+                                        th:if="${@permissionService.canManageEdition(edition.id)}">
+                                        <h3 class="surface__header" th:text="${editionsToCourses.get(edition.id).name}"></h3>
+
+                                        <div class="surface__content">
+                                            <div class="grid col-2 align-center" style="--col-1: minmax(0, 10rem)">
+                                                <label th:for="'assignment-distribute-select-' + ${edition.id}">Select Assignments</label>
+                                                <div>
+                                                    <select
+                                                        data-select
+                                                        multiple
+                                                        class="textfield"
+                                                        data-style="variant"
+                                                        th:id="'assignment-distribute-select-' + ${edition.id}"
+                                                        data-title="Select assignment(s) to distribute"
+                                                        th:field="*{editionSelections[__${editionItemStat.index}__].selectedAssignments}">
+                                                        <th:block
+                                                            th:each="assignment : ${@moduleDTOService.getAssignmentsInEdition(modules, edition.id)}">
+                                                            <option th:value="${assignment.id}" th:text="|${assignment.name}|"></option>
+                                                        </th:block>
+                                                    </select>
+                                                </div>
+
+                                                <label th:for="'assistant-distribute-select-' + ${edition.id}">Select Assistants</label>
+                                                <div>
+                                                    <select
+                                                        data-select
+                                                        multiple
+                                                        class="textfield"
+                                                        data-style="variant"
+                                                        th:id="'assistant-distribute-select-' + ${edition.id}"
+                                                        data-title="Select assistant(s) to distribute among"
+                                                        th:field="*{editionSelections[__${editionItemStat.index}__].selectedAssistants}">
+                                                        <th:block th:each="person : ${@roleDTOService.staff(edition)}">
+                                                            <option th:value="${person.id}" th:text="${person.displayName}"></option>
+                                                        </th:block>
+                                                    </select>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </th:block>
+                            </div>
+
+                            <div>
+                                <button type="submit" data-type="primary" data-style="filled" class="button">Distribute Requests</button>
+                            </div>
+                        </form>
+                    </div>
+                </div>
+            </th:block>
+
+            <script type="text/javascript" src="/js/form_submission_enhancer.js"></script>
         </div>
     </body>
 </html>
diff --git a/src/main/resources/templates/request/list/filters.html b/src/main/resources/templates/request/list/filters.html
index 828ed2a43c96f57bdddcfd10b7e57a4b4dde53a8..fea3caee1797687fb9b0afe24294a66284dc403d 100644
--- a/src/main/resources/templates/request/list/filters.html
+++ b/src/main/resources/templates/request/list/filters.html
@@ -61,7 +61,7 @@
                                 <option
                                     th:value="${assignment.id}"
                                     th:selected="${filter.assignments.contains(assignment.id)}"
-                                    th:text="|${assignmentsWithCourseCodes.getOrDefault(assignment.id,'CSEXXXX')} - ${assignment.name}|"></option>
+                                    th:text="|${assignmentsWithCourseCodes.getOrDefault(assignment.id,'Unknown Course')} - ${assignment.name}|"></option>
                             </th:block>
                         </select>
 
diff --git a/src/test/java/nl/tudelft/queue/controller/HomeControllerTest.java b/src/test/java/nl/tudelft/queue/controller/HomeControllerTest.java
index f5c9643d8e462f93adcc6fc9d309293c906499f3..0b27b4569df4e68325213ed1a135bd270a1e57e8 100644
--- a/src/test/java/nl/tudelft/queue/controller/HomeControllerTest.java
+++ b/src/test/java/nl/tudelft/queue/controller/HomeControllerTest.java
@@ -17,6 +17,7 @@
  */
 package nl.tudelft.queue.controller;
 
+import static org.hamcrest.Matchers.*;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.*;
@@ -48,8 +49,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
 import org.springframework.security.test.context.support.WithUserDetails;
 import org.springframework.test.web.servlet.MockMvc;
 
@@ -83,6 +84,10 @@ class HomeControllerTest {
 	private PersonSummaryDTO student50;
 	private PersonSummaryDTO student100;
 
+	private PersonSummaryDTO teacher1;
+
+	private PersonSummaryDTO teacher2;
+
 	private final ModelMapper mapper = new ModelMapper();
 
 	@BeforeEach
@@ -94,6 +99,10 @@ class HomeControllerTest {
 		student50 = db.getStudents()[50];
 		student100 = db.getStudents()[100];
 
+		teacher1 = db.getTeachers()[1];
+
+		teacher2 = db.getTeachers()[2];
+
 		// This mock has been untrustworthy in the past, so we should reset it every test.
 		reset(feedbackRepository);
 	}
@@ -189,7 +198,7 @@ class HomeControllerTest {
 				.andExpect(status().isForbidden());
 
 		verify(permissionService).canViewFeedback(student100.getId());
-		verify(feedbackRepository, never()).findByAssistant(anyLong(), any(Pageable.class));
+		verify(feedbackRepository, never()).findByAssistant(anyLong());
 	}
 
 	@Test
@@ -201,10 +210,52 @@ class HomeControllerTest {
 				.andExpect(model().attributeExists("feedback"))
 				.andExpect(view().name("home/feedback"));
 
-		verify(feedbackRepository, atLeastOnce()).findByAssistant(eq(student100.getId()), any());
+		verify(feedbackRepository, atLeastOnce()).findByAssistant(eq(student100.getId()));
+		verify(permissionService).canViewFeedback(student100.getId());
+	}
+
+	@Test
+	@WithUserDetails("teacher1")
+	void managerViewWorks() throws Exception {
+
+		mvc.perform(get("/feedback/{id}/manager", student100.getId()))
+				.andExpect(status().isOk())
+				.andExpect(model().attribute("assistant", matchPersonId(student100.getId())))
+				.andExpect(model().attributeExists("feedback"))
+				.andExpect(view().name("home/feedback"))
+				.andExpect(model().attribute("feedback", instanceOf(Page.class)))
+				.andExpect(model().attribute("feedback", hasProperty("totalElements", equalTo(0L))));
+
+		verify(feedbackRepository, atLeastOnce()).findByAssistant(eq(student100.getId()));
 		verify(permissionService).canViewFeedback(student100.getId());
 	}
 
+	@Test
+	@WithUserDetails("admin")
+	void adminCanViewTeacherFeedbackSuccessfully() throws Exception {
+		mvc.perform(get("/feedback/{id}/manager", teacher1.getId()))
+				.andExpect(status().isOk())
+				.andExpect(model().attribute("assistant", matchPersonId(teacher1.getId())))
+				.andExpect(model().attributeExists("feedback"))
+				.andExpect(view().name("home/feedback"));
+
+		mvc.perform(get("/feedback/{id}/manager", teacher2.getId()))
+				.andExpect(status().isOk())
+				.andExpect(model().attribute("assistant", matchPersonId(teacher2.getId())))
+				.andExpect(model().attributeExists("feedback"))
+				.andExpect(view().name("home/feedback"));
+
+	}
+
+	@Test
+	@WithUserDetails("teacher1")
+	void teachersCannotViewFeedbackOfOtherTeachers() throws Exception {
+		mvc.perform(get("/feedback/{id}/manager", teacher2.getId()))
+				.andExpect(status().isForbidden())
+				.andExpect(view().name("error/403"));
+
+	}
+
 	@Test
 	void specificFeedbackNeedsAuthentication() throws Exception {
 		mvc.perform(get("/feedback/1"))
diff --git a/src/test/java/nl/tudelft/queue/controller/LabControllerTest.java b/src/test/java/nl/tudelft/queue/controller/LabControllerTest.java
index 7dac8658472846052ecf43095616fcd81cf520de..c743cc76e9351dd5be02292435973d7f030ae510 100644
--- a/src/test/java/nl/tudelft/queue/controller/LabControllerTest.java
+++ b/src/test/java/nl/tudelft/queue/controller/LabControllerTest.java
@@ -42,6 +42,7 @@ import nl.tudelft.queue.dto.create.requests.SelectionRequestCreateDTO;
 import nl.tudelft.queue.dto.patch.labs.ExamLabPatchDTO;
 import nl.tudelft.queue.dto.patch.labs.RegularLabPatchDTO;
 import nl.tudelft.queue.dto.patch.labs.SlottedLabPatchDTO;
+import nl.tudelft.queue.dto.util.DistributeRequestsDTO;
 import nl.tudelft.queue.model.LabRequest;
 import nl.tudelft.queue.model.QueueSession;
 import nl.tudelft.queue.model.SelectionRequest;
@@ -69,6 +70,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.http.MediaType;
 import org.springframework.security.test.context.support.WithUserDetails;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
@@ -78,6 +80,8 @@ import reactor.core.publisher.Mono;
 import test.TestDatabaseLoader;
 import test.test.TestQueueApplication;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+
 @Transactional
 @AutoConfigureMockMvc
 @SpringBootTest(classes = TestQueueApplication.class)
@@ -712,6 +716,39 @@ class LabControllerTest {
 
 	}
 
+	@Test
+	@WithUserDetails("admin")
+	void distributingRequestsWithoutFaultWorks() throws Exception {
+		DistributeRequestsDTO dto = new DistributeRequestsDTO(2);
+		dto.getEditionSelections().get(0).getSelectedAssignments().addAll(List.of(1L, 2L));
+		dto.getEditionSelections().get(0).getSelectedAssistants().addAll(List.of(1L, 2L, 10L));
+		mvc.perform(post("/lab/" + slottedLab1.getId() + "/distribute")
+				.with(csrf())
+				.content(new ObjectMapper().writeValueAsString(dto))
+				.contentType(MediaType.APPLICATION_JSON))
+				.andExpect(status().is3xxRedirection())
+				.andExpect(redirectedUrl("/lab/" + slottedLab1.getId()));
+
+	}
+
+	@Test
+	@WithUserDetails("admin")
+	void distributingRequestsWithoutDtoDoesNotCrash() throws Exception {
+		mvc.perform(post("/lab/" + slottedLab1.getId() + "/distribute")
+				.with(csrf()))
+				.andExpect(status().is3xxRedirection());
+
+		verify(rs, never()).distributeRequests(any(), any(), any(), any());
+	}
+
+	@Test
+	@WithUserDetails("student50")
+	void sendingDistributionRequestWorksWhenAuthorised() throws Exception {
+		mvc.perform(post("/lab/" + regLab1.getId() + "/distribute")
+				.with(csrf()))
+				.andExpect(view().name("error/403"));
+	}
+
 	@Test
 	@WithUserDetails("student150")
 	void redirectToEnrollPageWhenNotEnrolled() throws Exception {
@@ -769,6 +806,7 @@ class LabControllerTest {
 				get("/lab/1/enqueue"),
 				post("/lab/1/enqueue"),
 				post("/lab/1/revoke"),
+				post("/lab/1/distribute"),
 
 				get("/edition/1/lab/create"),
 				get("/shared-edition/1/lab/create"),
diff --git a/src/test/java/nl/tudelft/queue/service/RequestServiceTest.java b/src/test/java/nl/tudelft/queue/service/RequestServiceTest.java
index fca416d1bd649af5131d7a00e2ee50ad39725a96..badbb7a3731e019b2d793aa9d68b623f9c7bc969 100644
--- a/src/test/java/nl/tudelft/queue/service/RequestServiceTest.java
+++ b/src/test/java/nl/tudelft/queue/service/RequestServiceTest.java
@@ -20,6 +20,7 @@ package nl.tudelft.queue.service;
 import static nl.tudelft.queue.model.enums.RequestStatus.*;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.AdditionalMatchers.or;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
@@ -33,7 +34,8 @@ import nl.tudelft.labracore.api.AssignmentControllerApi;
 import nl.tudelft.labracore.api.RoleControllerApi;
 import nl.tudelft.labracore.api.StudentGroupControllerApi;
 import nl.tudelft.labracore.api.dto.*;
-import nl.tudelft.queue.cache.SessionCacheManager;
+import nl.tudelft.labracore.lib.security.user.Person;
+import nl.tudelft.queue.cache.PersonCacheManager;
 import nl.tudelft.queue.dto.create.requests.SelectionRequestCreateDTO;
 import nl.tudelft.queue.model.LabRequest;
 import nl.tudelft.queue.model.QSelectionRequest;
@@ -44,6 +46,7 @@ import nl.tudelft.queue.model.enums.RequestStatus;
 import nl.tudelft.queue.model.enums.SelectionProcedure;
 import nl.tudelft.queue.model.labs.CapacitySession;
 import nl.tudelft.queue.model.labs.RegularLab;
+import nl.tudelft.queue.model.labs.SlottedLab;
 import nl.tudelft.queue.repository.CapacitySessionRepository;
 import nl.tudelft.queue.repository.SelectionRequestRepository;
 
@@ -64,7 +67,6 @@ import test.test.TestQueueApplication;
 
 @Transactional
 @SpringBootTest(classes = TestQueueApplication.class)
-@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
 public class RequestServiceTest {
 	private final RoomDetailsDTO room1 = new RoomDetailsDTO()
 			.id(8932L)
@@ -98,6 +100,8 @@ public class RequestServiceTest {
 
 	private RegularLab oopNowRegularLab1;
 
+	private SlottedLab oopNowSlottedLab1;
+
 	private RoleDetailsDTO[] oopNowTAs;
 
 	private LabRequest[] rlOopNowSharedLabRequests;
@@ -113,12 +117,9 @@ public class RequestServiceTest {
 	@Autowired
 	private SelectionRequestRepository srr;
 
-	@Autowired
+	@SpyBean
 	private RequestService rs;
 
-	@Autowired
-	private SessionCacheManager sCache;
-
 	@Autowired
 	private SessionApiMocker sApiMocker;
 
@@ -146,6 +147,9 @@ public class RequestServiceTest {
 	@Autowired
 	private StudentGroupControllerApi sgApi;
 
+	@SpyBean
+	private PersonCacheManager pCache;
+
 	@Autowired
 	private RoleControllerApi rlApi;
 
@@ -163,6 +167,8 @@ public class RequestServiceTest {
 
 		oopNowRegularLab1 = db.getOopNowRegularLab1();
 
+		oopNowSlottedLab1 = db.getOopNowSlottedLab1();
+
 		oopNowTAs = db.getOopNowTAs();
 
 		rlOopNowSharedLabRequests = db.getRlOopNowSharedLabRequests();
@@ -348,6 +354,67 @@ public class RequestServiceTest {
 
 	}
 
+	@Test
+	void distributingEmptyRequestsNothingHappens() {
+		rs.distributeRequests(List.of(), List.of(),
+				Person.builder().id(1L).displayName("Test Person").build(), oopNowSlottedLab1);
+
+		rs.distributeRequests(List.of(), List.of(1L, 2L),
+				Person.builder().id(1L).displayName("Test Person").build(), oopNowSlottedLab1);
+
+		verify(rs, never()).forwardRequestToPerson(any(), any(), any(), any());
+
+	}
+
+	@Test
+	@DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
+	void onlyPendingRequestsWithCorrectAssignmentsGetDistributed() {
+		pApiMocker.save(new PersonSummaryDTO().id(1L));
+		pApiMocker.save(new PersonSummaryDTO().id(2L));
+
+		doNothing().when(rs).forwardRequestToPerson(any(), any(), any(), any());
+
+		oopNowSlottedLab1.getRequests().addAll(List.of(LabRequest.builder().assignment(1L).build(),
+				LabRequest.builder().assignment(1L).build(), LabRequest.builder().assignment(2L).build(),
+				LabRequest.builder().assignment(3L).build(), LabRequest.builder().assignment(3L).build()));
+		oopNowSlottedLab1.getRequests().get(1).getEventInfo().setStatus(APPROVED);
+		oopNowSlottedLab1.getRequests().get(2).getEventInfo().setStatus(PROCESSING);
+
+		rs.distributeRequests(List.of(1L), List.of(1L, 2L), Person.builder().build(), oopNowSlottedLab1);
+
+		verify(rs, times(1)).forwardRequestToPerson(eq(oopNowSlottedLab1.getRequests().get(0)), any(), any(),
+				any());
+
+	}
+
+	@Test
+	@DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
+	void distributingRequestsWithMissingPeopleBehavesAsExpected() {
+		pApiMocker.save(new PersonSummaryDTO().id(1L));
+
+		doNothing().when(rs).forwardRequestToPerson(any(), any(), any(), any());
+
+		oopNowSlottedLab1.getRequests().addAll(List.of(LabRequest.builder().assignment(9801L).build(),
+				LabRequest.builder().assignment(9801L).build(),
+				LabRequest.builder().assignment(9802L).build(),
+				LabRequest.builder().assignment(9803L).build(),
+				LabRequest.builder().assignment(9803L).build()));
+		oopNowSlottedLab1.getRequests().get(1).getEventInfo().setStatus(APPROVED);
+		oopNowSlottedLab1.getRequests().get(2).getEventInfo().setStatus(PENDING);
+
+		rs.distributeRequests(List.of(9801L), List.of(2L), Person.builder().build(), oopNowSlottedLab1);
+
+		verify(rs, never()).forwardRequestToPerson(
+				or(eq(oopNowSlottedLab1.getRequests().get(0)), eq(oopNowSlottedLab1.getRequests().get(1))),
+				any(), any(), any());
+
+		rs.distributeRequests(List.of(9801L, 9802L), List.of(1L, 2L), Person.builder().build(),
+				oopNowSlottedLab1);
+
+		verify(rs, times(2)).forwardRequestToPerson(any(), any(), any(), any());
+
+	}
+
 	@Test
 	@WithUserDetails("student200")
 	void oopTaGetsOopRequestsOnlyInSharedSession() {