From c3d507dc32e9e52480e8251080eb196252c6beda Mon Sep 17 00:00:00 2001 From: andrechalella Date: Tue, 9 Sep 2025 13:59:46 +0000 Subject: [PATCH 1/2] Add extracurricular activities and signup validation to the API --- src/app.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/app.py b/src/app.py index 4ebb1d9..1285954 100644 --- a/src/app.py +++ b/src/app.py @@ -38,6 +38,45 @@ "schedule": "Mondays, Wednesdays, Fridays, 2:00 PM - 3:00 PM", "max_participants": 30, "participants": ["john@mergington.edu", "olivia@mergington.edu"] + }, + # Sports activities + "Soccer Team": { + "description": "Join the school soccer team and compete in local leagues", + "schedule": "Tuesdays and Thursdays, 4:00 PM - 5:30 PM", + "max_participants": 22, + "participants": ["lucas@mergington.edu", "mia@mergington.edu"] + }, + "Basketball Club": { + "description": "Practice basketball and participate in tournaments", + "schedule": "Wednesdays, 3:30 PM - 5:00 PM", + "max_participants": 15, + "participants": ["liam@mergington.edu", "ava@mergington.edu"] + }, + # Artistic activities + "Art Workshop": { + "description": "Explore painting, drawing, and sculpture techniques", + "schedule": "Mondays, 4:00 PM - 5:30 PM", + "max_participants": 18, + "participants": ["noah@mergington.edu", "isabella@mergington.edu"] + }, + "Drama Club": { + "description": "Act, direct, and produce school plays and performances", + "schedule": "Fridays, 3:30 PM - 5:30 PM", + "max_participants": 20, + "participants": ["amelia@mergington.edu", "benjamin@mergington.edu"] + }, + # Intellectual activities + "Math Olympiad": { + "description": "Prepare for math competitions and solve challenging problems", + "schedule": "Thursdays, 3:30 PM - 5:00 PM", + "max_participants": 16, + "participants": ["charlotte@mergington.edu", "elijah@mergington.edu"] + }, + "Debate Team": { + "description": "Develop public speaking and argumentation skills", + "schedule": "Wednesdays, 4:00 PM - 5:30 PM", + "max_participants": 14, + "participants": ["jack@mergington.edu", "harper@mergington.edu"] } } @@ -62,6 +101,10 @@ def signup_for_activity(activity_name: str, email: str): # Get the specific activity activity = activities[activity_name] + # Check if student already signed up + if email in activity["participants"]: + raise HTTPException(status_code=400, detail="Student already signed up for this activity") + # Add student activity["participants"].append(email) return {"message": f"Signed up {email} for {activity_name}"} From d119399d15a4d570c7c69446c4337ad7214695a3 Mon Sep 17 00:00:00 2001 From: andrechalella Date: Tue, 9 Sep 2025 14:17:42 +0000 Subject: [PATCH 2/2] Refactor activity card rendering and add styles for participants section --- src/static/app.js | 53 +++++++++++++++++++++++++++++++++---------- src/static/styles.css | 27 ++++++++++++++++++++++ 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/static/app.js b/src/static/app.js index dcc1e38..d0ba62a 100644 --- a/src/static/app.js +++ b/src/static/app.js @@ -15,18 +15,7 @@ document.addEventListener("DOMContentLoaded", () => { // Populate activities list Object.entries(activities).forEach(([name, details]) => { - const activityCard = document.createElement("div"); - activityCard.className = "activity-card"; - - const spotsLeft = details.max_participants - details.participants.length; - - activityCard.innerHTML = ` -

${name}

-

${details.description}

-

Schedule: ${details.schedule}

-

Availability: ${spotsLeft} spots left

- `; - + const activityCard = renderActivityCard(name, details); activitiesList.appendChild(activityCard); // Add option to select dropdown @@ -41,6 +30,46 @@ document.addEventListener("DOMContentLoaded", () => { } } + // Render activity card + function renderActivityCard(name, details) { + const card = document.createElement("div"); + card.className = "activity-card"; + + const spotsLeft = details.max_participants - details.participants.length; + + card.innerHTML = ` +

${name}

+

${details.description}

+

Schedule: ${details.schedule}

+

Availability: ${spotsLeft} spots left

+ `; + + // Participants section + const participantsSection = document.createElement("div"); + participantsSection.className = "participants-section"; + const participantsTitle = document.createElement("h4"); + participantsTitle.textContent = "Participants"; + participantsSection.appendChild(participantsTitle); + const participantsList = document.createElement("ul"); + participantsList.className = "participants-list"; + if (details.participants && details.participants.length > 0) { + details.participants.forEach((participant) => { + const li = document.createElement("li"); + li.textContent = participant; + participantsList.appendChild(li); + }); + } else { + const li = document.createElement("li"); + li.textContent = "No participants yet."; + li.className = "no-participants"; + participantsList.appendChild(li); + } + participantsSection.appendChild(participantsList); + card.appendChild(participantsSection); + + return card; + } + // Handle form submission signupForm.addEventListener("submit", async (event) => { event.preventDefault(); diff --git a/src/static/styles.css b/src/static/styles.css index a533b32..30dde86 100644 --- a/src/static/styles.css +++ b/src/static/styles.css @@ -142,3 +142,30 @@ footer { padding: 20px; color: #666; } + +.participants-section { + background: #f8f9fa; + border-radius: 8px; + margin-top: 1em; + padding: 1em; + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04); +} + +.participants-section h4 { + margin: 0 0 0.5em 0; + font-size: 1.1em; + color: #333; + letter-spacing: 0.5px; +} + +.participants-list { + list-style: disc inside; + margin: 0; + padding-left: 1em; + color: #444; +} + +.participants-list li.no-participants { + color: #aaa; + font-style: italic; +}