From 8f65b6078cda98721598843322c89d3e109d559d Mon Sep 17 00:00:00 2001 From: Rohaansandhu Date: Sat, 7 Mar 2026 19:31:32 -0800 Subject: [PATCH 1/2] Move attendance creation to getSession, adjust Date Selection --- backend/src/controllers/attendance.ts | 33 ++++++++++++++++++ backend/src/controllers/session.ts | 36 ++++---------------- frontend/src/app/(pages)/attendance/page.tsx | 18 ++++++---- 3 files changed, 50 insertions(+), 37 deletions(-) diff --git a/backend/src/controllers/attendance.ts b/backend/src/controllers/attendance.ts index 6069c3e..29df9d5 100644 --- a/backend/src/controllers/attendance.ts +++ b/backend/src/controllers/attendance.ts @@ -2,6 +2,8 @@ import { validationResult } from "express-validator"; import { Types } from "mongoose"; import { AttendanceModel } from "../models/attendance"; +import { Section } from "../models/sections"; +import { SessionModel } from "../models/session"; import type { RequestHandler } from "express"; @@ -54,6 +56,37 @@ export const updateAttendanceById: RequestHandler = async (req, res, next) => { } }; +const getStudentsInSection = async (sectionId: Types.ObjectId): Promise => { + const section = await Section.findById(sectionId).select("enrolledStudents"); + + // Can't be null because of validation checks prior to calling this function + return section!.enrolledStudents; +}; + +export const ensureAttendanceForSession = async (sessionId: string) => { + const existing = await AttendanceModel.find({ session: sessionId }); + if (existing.length > 0) return existing; + + const session = await SessionModel.findById(sessionId); + if (!session) throw new Error("Session not found"); + + const sessionDate = new Date(session.sessionDate); + const today = new Date(); + sessionDate.setHours(0, 0, 0, 0); + today.setHours(0, 0, 0, 0); + // Don't create attendance for future sessions + if (sessionDate > today) return []; + + const students = await getStudentsInSection(session.section); + await Promise.all( + students.map(async (studentId) => + AttendanceModel.create({ session: session._id, student: studentId, status: "PRESENT" }), + ), + ); + + return AttendanceModel.find({ session: sessionId }); +}; + export const getAttendanceBySessionId: RequestHandler = async (req, res, next) => { try { const errors = validationResult(req); diff --git a/backend/src/controllers/session.ts b/backend/src/controllers/session.ts index 9182da1..6065cf8 100644 --- a/backend/src/controllers/session.ts +++ b/backend/src/controllers/session.ts @@ -1,18 +1,11 @@ import { validationResult } from "express-validator"; import { AttendanceModel } from "../models/attendance"; -import { Section } from "../models/sections"; import { SessionModel } from "../models/session"; -import type { RequestHandler } from "express"; -import type { Types } from "mongoose"; - -const getStudentsInSection = async (sectionId: string): Promise => { - const section = await Section.findById(sectionId).select("enrolledStudents"); +import { ensureAttendanceForSession } from "./attendance"; - // Can't be null because of validation checks prior to calling this function - return section!.enrolledStudents; -}; +import type { RequestHandler } from "express"; type CreateSessionBody = { section: string; @@ -30,22 +23,6 @@ export const createSession: RequestHandler = async (req, res, next) => { sessionDate, }); - // create Attendance records for all students enrolled in Section - - // Get all student Ids in the section (enrolledStudents list) - const students = await getStudentsInSection(section); - - // Create attendance records for all students in session - await Promise.all( - students.map(async (studentId) => - AttendanceModel.create({ - session: session._id, - student: studentId, - status: "PRESENT", - }), - ), - ); - return res.status(201).json(session); } catch (error) { next(error); @@ -87,14 +64,13 @@ export const getSession: RequestHandler = async (req, res, next) => { return res.status(404).json({ error: "Session not found" }); } - // Check what we are searching for in the Attendance collection - const query = { session: id }; - // Run the query - const attendanceRecords = await AttendanceModel.find(query).populate("student"); + // This creates records if missing, checks the date, returns them + const attendanceRecords = await ensureAttendanceForSession(id); + const populated = await AttendanceModel.populate(attendanceRecords, { path: "student" }); const response = { ...session.toObject(), - attendees: attendanceRecords, + attendees: populated, }; res.status(200).json(response); diff --git a/frontend/src/app/(pages)/attendance/page.tsx b/frontend/src/app/(pages)/attendance/page.tsx index adaadab..9700f31 100644 --- a/frontend/src/app/(pages)/attendance/page.tsx +++ b/frontend/src/app/(pages)/attendance/page.tsx @@ -62,13 +62,12 @@ export default function Attendance() { void load(); }, [activeSectionId]); - // Derive available dates from the loaded sessions for this section + // Derive available dates using local time const availableDates = sessionList.map((s) => { const d = new Date(s.sessionDate); - // Use UTC values to avoid timezone shift - const year = d.getUTCFullYear(); - const month = String(d.getUTCMonth() + 1).padStart(2, "0"); - const day = String(d.getUTCDate()).padStart(2, "0"); + const year = d.getFullYear(); + const month = String(d.getMonth() + 1).padStart(2, "0"); + const day = String(d.getDate()).padStart(2, "0"); return `${year}-${month}-${day}`; }); @@ -88,8 +87,13 @@ export default function Attendance() { if (!activeSectionId || !activeDate) return; const match = sessionList.find((s) => { - const sDate = new Date(s.sessionDate).toISOString().split("T")[0]; - return sDate === activeDate; + const d = new Date(s.sessionDate); + const year = d.getFullYear(); + const month = String(d.getMonth() + 1).padStart(2, "0"); + const day = String(d.getDate()).padStart(2, "0"); + const localSessionDate = `${year}-${month}-${day}`; + + return localSessionDate === activeDate; }); if (match) { From a374fcd2f0bdcf15890390492323d11b4ad8d758 Mon Sep 17 00:00:00 2001 From: Rohaansandhu Date: Sat, 7 Mar 2026 19:41:34 -0800 Subject: [PATCH 2/2] Fix frontend lint --- frontend/src/app/(pages)/attendance/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/(pages)/attendance/page.tsx b/frontend/src/app/(pages)/attendance/page.tsx index 9700f31..14a8488 100644 --- a/frontend/src/app/(pages)/attendance/page.tsx +++ b/frontend/src/app/(pages)/attendance/page.tsx @@ -92,7 +92,7 @@ export default function Attendance() { const month = String(d.getMonth() + 1).padStart(2, "0"); const day = String(d.getDate()).padStart(2, "0"); const localSessionDate = `${year}-${month}-${day}`; - + return localSessionDate === activeDate; });