Skip to content

Commit deae6ae

Browse files
committed
Add unregister functionality and delete icon for participants in activity cards
1 parent f3ad7ff commit deae6ae

File tree

3 files changed

+77
-4
lines changed

3 files changed

+77
-4
lines changed

src/app.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
"""
23
High School Management System API
34
@@ -109,3 +110,19 @@ def signup_for_activity(activity_name: str, email: str):
109110
# Add student
110111
activity["participants"].append(email)
111112
return {"message": f"Signed up {email} for {activity_name}"}
113+
114+
@app.post("/activities/{activity_name}/unregister")
115+
def unregister_from_activity(activity_name: str, email: str):
116+
"""Remove a student from an activity"""
117+
# Validate activity exists
118+
if activity_name not in activities:
119+
raise HTTPException(status_code=404, detail="Activity not found")
120+
121+
activity = activities[activity_name]
122+
123+
# Validate student is signed up
124+
if email not in activity["participants"]:
125+
raise HTTPException(status_code=400, detail="Student not registered for this activity")
126+
127+
activity["participants"].remove(email)
128+
return {"message": f"Removed {email} from {activity_name}"}

src/static/app.js

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,19 @@ document.addEventListener("DOMContentLoaded", () => {
2020

2121
const spotsLeft = details.max_participants - details.participants.length;
2222

23-
// Participants list HTML
23+
// Participants list HTML with delete icon
2424
let participantsHTML = "";
2525
if (details.participants.length > 0) {
2626
participantsHTML = `
2727
<div class="participants-section">
2828
<strong>Participants:</strong>
2929
<ul class="participants-list">
30-
${details.participants.map(p => `<li>${p}</li>`).join("")}
30+
${details.participants.map(p => `
31+
<li>
32+
<span class="participant-email">${p}</span>
33+
<span class="delete-icon" title="Remove participant" data-activity="${name}" data-email="${p}">&times;</span>
34+
</li>
35+
`).join("")}
3136
</ul>
3237
</div>
3338
`;
@@ -48,6 +53,42 @@ document.addEventListener("DOMContentLoaded", () => {
4853
${participantsHTML}
4954
`;
5055

56+
// Add event listener for delete icons after rendering
57+
setTimeout(() => {
58+
activityCard.querySelectorAll('.delete-icon').forEach(icon => {
59+
icon.addEventListener('click', async (e) => {
60+
const activityName = icon.getAttribute('data-activity');
61+
const email = icon.getAttribute('data-email');
62+
if (!activityName || !email) return;
63+
try {
64+
const response = await fetch(`/activities/${encodeURIComponent(activityName)}/unregister?email=${encodeURIComponent(email)}`, {
65+
method: 'POST',
66+
});
67+
const result = await response.json();
68+
if (response.ok) {
69+
messageDiv.textContent = result.message || 'Participant removed.';
70+
messageDiv.className = 'success';
71+
fetchActivities();
72+
} else {
73+
messageDiv.textContent = result.detail || 'Failed to remove participant.';
74+
messageDiv.className = 'error';
75+
}
76+
messageDiv.classList.remove('hidden');
77+
setTimeout(() => {
78+
messageDiv.classList.add('hidden');
79+
}, 4000);
80+
} catch (err) {
81+
messageDiv.textContent = 'Error removing participant.';
82+
messageDiv.className = 'error';
83+
messageDiv.classList.remove('hidden');
84+
setTimeout(() => {
85+
messageDiv.classList.add('hidden');
86+
}, 4000);
87+
}
88+
});
89+
});
90+
}, 0);
91+
5192
activitiesList.appendChild(activityCard);
5293

5394
// Add option to select dropdown
@@ -83,6 +124,7 @@ document.addEventListener("DOMContentLoaded", () => {
83124
messageDiv.textContent = result.message;
84125
messageDiv.className = "success";
85126
signupForm.reset();
127+
fetchActivities();
86128
} else {
87129
messageDiv.textContent = result.detail || "An error occurred";
88130
messageDiv.className = "error";

src/static/styles.css

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,24 @@ footer {
158158
}
159159

160160
.participants-list {
161-
list-style-type: disc;
162-
margin-left: 20px;
161+
list-style-type: none;
162+
margin-left: 0;
163163
margin-bottom: 0;
164164
color: #333;
165+
padding-left: 0;
166+
}
167+
168+
.delete-icon {
169+
display: inline-block;
170+
margin-left: 8px;
171+
color: #c62828;
172+
cursor: pointer;
173+
font-size: 16px;
174+
vertical-align: middle;
175+
transition: color 0.2s;
176+
}
177+
.delete-icon:hover {
178+
color: #a31515;
165179
}
166180

167181
.no-participants {

0 commit comments

Comments
 (0)