Skip to content

Commit 6d69599

Browse files
authored
Merge pull request #106 from Schlaumeier5/32-student-list-by-room
Added student list by room in gui for admin and teacher
2 parents cf4caaf + 53b5ac2 commit 6d69599

File tree

6 files changed

+161
-3
lines changed

6 files changed

+161
-3
lines changed

src/main/java/de/igslandstuhl/database/api/Student.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,11 @@ public static List<Student> getAll() {
202202
.filter(Objects::nonNull)
203203
.collect(Collectors.toList());
204204
}
205+
206+
public static List<Student> getByRoom(Room room) {
207+
return students.values().stream().filter((s) -> room.equals(s.getCurrentRoom())).toList();
208+
}
209+
205210
/**
206211
* Registers a new student with a password.
207212
* This method creates a new student in the database and returns the created Student object.

src/main/java/de/igslandstuhl/database/server/webserver/PostRequestHandler.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ public PostResponse handlePostRequest(PostRequest request) throws IOException {
138138
return handleDeleteTopics(request);
139139
case "/change-graduation-level":
140140
return handleChangeGraduationLevel(request);
141+
case "/get-students-by-room":
142+
return handleGetStudentsByRoom(request);
141143
default:
142144
return PostResponse.notFound("Unknown POST request path: " + path, request);
143145
}
@@ -1203,4 +1205,39 @@ private PostResponse handleChangeGraduationLevel(PostRequest request) throws IOE
12031205
return PostResponse.badRequest("Invalid input: " + e.getMessage(), request);
12041206
}
12051207
}
1208+
private PostResponse handleGetStudentsByRoom(PostRequest request) {
1209+
// Test if current user is admin or teacher
1210+
User user = Server.getInstance().getWebServer().getSessionManager().getSessionUser(request);
1211+
if (user == null || !(user.isAdmin() || user.isTeacher())) {
1212+
return PostResponse.unauthorized("Not logged in or invalid session", request);
1213+
}
1214+
1215+
Map<String, Object> json = request.getJson();
1216+
Room room = Room.getRoom((String) json.get("room"));
1217+
1218+
java.util.List<Student> students = Student.getByRoom(room);
1219+
StringBuilder responseBuilder = new StringBuilder("[");
1220+
for (int i = 0; i < students.size(); i++) {
1221+
Student student = students.get(i);
1222+
responseBuilder.append("{\"id\":").append(student.getId())
1223+
.append(",\"name\":\"").append(student.getFirstName()).append(" ").append(student.getLastName()).append('"')
1224+
.append(", \"actionRequired\":").append(student.isActionRequired())
1225+
.append(", \"graduationLevel\":").append(student.getGraduationLevel().getLevel())
1226+
.append(", \"room\":\"").append(student.getCurrentRoom() != null ? student.getCurrentRoom().getLabel() : "None").append("\"");
1227+
if (request.getJson().containsKey("subjectId") && request.getJson().get("subjectId") instanceof Number subjectId) {
1228+
Set<SubjectRequest> subjectRequests = student.getCurrentRequests().keySet().contains(subjectId.intValue()) ? student.getCurrentRequests().get(subjectId.intValue()) : Set.of();
1229+
responseBuilder.append(", \"experiment\":").append(subjectRequests.stream().anyMatch(r -> r == SubjectRequest.EXPERIMENT))
1230+
.append(", \"help\":").append(subjectRequests.stream().anyMatch(r -> r == SubjectRequest.HELP))
1231+
.append(", \"test\":").append(subjectRequests.stream().anyMatch(r -> r == SubjectRequest.EXAM))
1232+
.append(", \"partner\":").append(subjectRequests.stream().anyMatch(r -> r == SubjectRequest.PARTNER));
1233+
}
1234+
responseBuilder.append("}");
1235+
if (i < students.size() - 1) {
1236+
responseBuilder.append(", ");
1237+
}
1238+
}
1239+
responseBuilder.append("]");
1240+
1241+
return PostResponse.ok(responseBuilder.toString(), ContentType.JSON, request);
1242+
}
12061243
}

src/main/resources/html/admin/teacher.html

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,28 @@ <h3>Schüler in der Klasse:</h3>
7171
</thead>
7272
<tbody id="subjectStudentTableBody"></tbody>
7373
</table>
74+
</section>
75+
76+
<section id="room-info">
77+
<h2>Raumübersicht</h2>
78+
<section id="subject-selection">
79+
<label for="roomSelect">Wählen Sie einen Raum:</label>
80+
<select id="roomSelect"></select>
81+
</section>
82+
<section id="room-student-list">
83+
<h3>Schüler im Raum:</h3>
84+
<table id="roomStudentTable">
85+
<thead>
86+
<tr>
87+
<th>Name</th>
88+
<th>Braucht Unterstützung</th>
89+
<th></th>
90+
</tr>
91+
</thead>
92+
<tbody id="roomStudentTableBody"></tbody>
93+
</table>
94+
</section>
95+
</section>
7496
</section>
7597
</main>
7698
<nav>

src/main/resources/html/teacher/dashboard.html

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,26 @@ <h3>Schüler in der Klasse:</h3>
5757
<tbody id="subjectStudentTableBody"></tbody>
5858
</table>
5959
</section>
60+
<section id="room-info">
61+
<h2>Raumübersicht</h2>
62+
<section id="subject-selection">
63+
<label for="roomSelect">Wählen Sie einen Raum:</label>
64+
<select id="roomSelect"></select>
65+
</section>
66+
<section id="room-student-list">
67+
<h3>Schüler im Raum:</h3>
68+
<table id="roomStudentTable">
69+
<thead>
70+
<tr>
71+
<th>Name</th>
72+
<th>Braucht Unterstützung</th>
73+
<th></th>
74+
</tr>
75+
</thead>
76+
<tbody id="roomStudentTableBody"></tbody>
77+
</table>
78+
</section>
79+
</section>
6080
</div>
6181
</body>
6282
</html>

src/main/resources/js/admin/build_teacher.js

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ async function fetchSubjects() {
2727
});
2828
return subjects;
2929
}
30+
function populateRoomSelect(roomSelect, rooms) {
31+
roomSelect.innerHTML = ""; // clear previous options if any
32+
rooms.forEach(room => {
33+
const option = document.createElement('option');
34+
option.value = room.label;
35+
option.textContent = room.label;
36+
roomSelect.appendChild(option);
37+
});
38+
}
3039

3140
function populateClassSelect(classSelect, classes) {
3241
classSelect.innerHTML = ""; // clear previous options if any
@@ -104,6 +113,29 @@ async function populateSubjectStudentList(event) {
104113
studentTable.appendChild(row);
105114
});
106115
}
116+
async function populateRoomStudentList(event) {
117+
const room = event.target.value;
118+
119+
const students = await fetchJson("/get-students-by-room", {
120+
method: 'POST',
121+
body: JSON.stringify({ room }),
122+
headers: {
123+
'Content-Type': 'application/json'
124+
}
125+
});
126+
127+
const studentTable = document.getElementById("roomStudentTableBody");
128+
studentTable.innerHTML = ""; // clear previous rows
129+
students.forEach(student => {
130+
const row = document.createElement('tr');
131+
row.innerHTML = `
132+
<td class="student-name">${student.name}</td>
133+
<td class="student-action-required">${student.actionRequired ? "Ja" : "Nein"}</td>
134+
<td class="student-action"><button onclick="viewStudent(${student.id})">Bearbeiten</button></td>
135+
`;
136+
studentTable.appendChild(row);
137+
});
138+
}
107139
function viewStudent(studentId) {
108140
// Add studentId to session storage
109141
sessionStorage.setItem('selectedStudentId', studentId);
@@ -130,7 +162,12 @@ document.addEventListener('DOMContentLoaded', async () => {
130162
const allSubjects = await fetchJson('/subjects');
131163
populateSubjectSelect(editSubjectSelect, allSubjects);
132164

133-
const editClassSelect = document.getElementById('editClassSelect')
134-
const allClasses = await fetchJson('/classes')
135-
populateClassSelect(editClassSelect, allClasses)
165+
const editClassSelect = document.getElementById('editClassSelect');
166+
const allClasses = await fetchJson('/classes');
167+
populateClassSelect(editClassSelect, allClasses);
168+
const roomSelect = document.getElementById("roomSelect");
169+
const rooms = await fetchJson("/rooms");
170+
populateRoomSelect(roomSelect, rooms);
171+
roomSelect.addEventListener('change', populateRoomStudentList);
172+
populateRoomStudentList({target: roomSelect});
136173
});

src/main/resources/js/teacher/build_dashboard.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ function populateSubjectSelect(subjectSelect, subjects) {
2626
subjectSelect.appendChild(option);
2727
});
2828
}
29+
function populateRoomSelect(roomSelect, rooms) {
30+
roomSelect.innerHTML = ""; // clear previous options if any
31+
rooms.forEach(room => {
32+
const option = document.createElement('option');
33+
option.value = room.label;
34+
option.textContent = room.label;
35+
roomSelect.appendChild(option);
36+
});
37+
}
2938

3039
async function onClassChange(event) {
3140
const selectedClassId = event.target.value;
@@ -83,6 +92,29 @@ async function populateSubjectStudentList(event) {
8392
studentTable.appendChild(row);
8493
});
8594
}
95+
async function populateRoomStudentList(event) {
96+
const room = event.target.value;
97+
98+
const students = await fetchJson("/get-students-by-room", {
99+
method: 'POST',
100+
body: JSON.stringify({ room }),
101+
headers: {
102+
'Content-Type': 'application/json'
103+
}
104+
});
105+
106+
const studentTable = document.getElementById("roomStudentTableBody");
107+
studentTable.innerHTML = ""; // clear previous rows
108+
students.forEach(student => {
109+
const row = document.createElement('tr');
110+
row.innerHTML = `
111+
<td class="student-name">${student.name}</td>
112+
<td class="student-action-required">${student.actionRequired ? "Ja" : "Nein"}</td>
113+
<td class="student-action"><button onclick="viewStudent(${student.id})">Bearbeiten</button></td>
114+
`;
115+
studentTable.appendChild(row);
116+
});
117+
}
86118

87119
function viewStudent(studentId) {
88120
// Add studentId to session storage
@@ -105,4 +137,9 @@ document.addEventListener('DOMContentLoaded', async () => {
105137
populateSubjectSelect(subjectSelect, subjects);
106138
subjectSelect.addEventListener('change', populateSubjectStudentList);
107139
populateSubjectStudentList({ target: subjectSelect }); // Trigger initial load
140+
const roomSelect = document.getElementById("roomSelect");
141+
const rooms = await fetchJson("/rooms");
142+
populateRoomSelect(roomSelect, rooms);
143+
roomSelect.addEventListener('change', populateRoomStudentList);
144+
populateRoomStudentList({target: roomSelect});
108145
});

0 commit comments

Comments
 (0)