diff --git a/csm_web/frontend/src/components/section/StudentSection.tsx b/csm_web/frontend/src/components/section/StudentSection.tsx index fc5d6500..89c2279c 100644 --- a/csm_web/frontend/src/components/section/StudentSection.tsx +++ b/csm_web/frontend/src/components/section/StudentSection.tsx @@ -3,7 +3,8 @@ import { Navigate, Route, Routes } from "react-router-dom"; import { useDropUserMutation, useStudentAttendances, - useStudentSubmitWordOfTheDayMutation + useStudentSubmitWordOfTheDayMutation, + useSectionStudents } from "../../utils/queries/sections"; import { Mentor, Override, Spacetime } from "../../utils/types"; import Modal from "../Modal"; @@ -47,7 +48,8 @@ export default function StudentSection({ userRole={ROLES.STUDENT} links={[ ["Section", ""], - ["Attendance", "attendance"] + ["Attendance", "attendance"], + ["Students", "students"] ]} > @@ -55,6 +57,7 @@ export default function StudentSection({ path="attendance" element={} /> + } />
{mentor.name}
- {mentor.email} + {/* {mentor.email} */} + )} + {spacetimes.map(({ override, ...spacetime }, index) => ( 1} @@ -155,6 +160,46 @@ function DropSection({ profileId }: DropSectionProps) { } } +interface ProfileSectionProps { + profileId: number; +} + +enum ProfileSectionStage { + CLOSED = "CLOSED", + OPENED = "OPENED" +} + +function ProfileSection({ profileId }: ProfileSectionProps) { + // const studentDropMutation = useDropUserMutation(profileId); + const [stage, setStage] = useState(ProfileSectionStage.CLOSED); + + // const performDrop = () => { + // studentDropMutation.mutate(undefined, { + // onSuccess: () => { + // setStage(ProfileSectionStage.CLOSED); + // } + // }); + // }; + + switch (stage) { + case ProfileSectionStage.CLOSED: + return ( + + ); + case ProfileSectionStage.OPENED: + return ( + setStage(ProfileSectionStage.CLOSED)}> +
+
Are you sure you want to drop?
+

You are not guaranteed an available spot in another section!

+
+
+ ); + } +} + interface StudentSectionAttendanceProps { associatedProfileId: number; id: number; @@ -358,3 +403,61 @@ function StudentSectionAttendance({ associatedProfileId, id }: StudentSectionAtt ); } + +interface StudentListProps { + associatedProfileId: number; + id: number; +} + +// Need permission for student to load student list, or new backend point? +function StudentList({ associatedProfileId, id }: StudentListProps) { + const { + data: studentList, + isSuccess: listLoaded, + isError: listLoadError, + refetch: refetchStudentList + } = useSectionStudents(associatedProfileId); + + return listLoaded ? ( + +
+

Submit Word of the Day

+
+
+
+
+
+
+
+ + + + + + + + + {studentList + // convert to a table row + .map(({ name, email }) => { + // const [label, cssSuffix] = ATTENDANCE_LABELS[presence]; + // const attendanceColor = scssColors[`attendance-${cssSuffix}`]; + // const attendanceFgColor = scssColors[`attendance-${cssSuffix}-fg`]; + return ( + + + + + ); + })} + +
NameProfile
{name} +
{email}
+
+
+ ) : listLoadError ? ( +

Student List could not be loaded

+ ) : ( + + ); +} diff --git a/csm_web/frontend/src/utils/queries/sections.tsx b/csm_web/frontend/src/utils/queries/sections.tsx index a4bbcf8c..75b5aaa9 100644 --- a/csm_web/frontend/src/utils/queries/sections.tsx +++ b/csm_web/frontend/src/utils/queries/sections.tsx @@ -4,7 +4,7 @@ import { useMutation, UseMutationResult, useQuery, useQueryClient, UseQueryResult } from "@tanstack/react-query"; import { fetchNormalized, fetchWithMethod, HTTP_METHODS } from "../api"; -import { Attendance, RawAttendance, Section, Spacetime, Student } from "../types"; +import { Attendance, RawAttendance, Section, Spacetime, Student, UserInfo } from "../types"; import { handleError, handlePermissionsError, handleRetry, PermissionError, ServerError } from "./helpers"; /* ===== Queries ===== */ @@ -112,6 +112,29 @@ export const useStudentAttendances = (studentId: number): UseQueryResult => { +// const queryResult = useQuery( +// ["students", studentId, "attendance"], +// async () => { +// if (isNaN(studentId)) { +// throw new PermissionError("Invalid student id"); +// } +// const response = await fetchNormalized(`/students/${studentId}/attendances`); +// if (response.ok) { +// return await response.json(); +// } else { +// handlePermissionsError(response.status); +// throw new ServerError(`Failed to fetch student ${studentId} attendances`); +// } +// }, +// { retry: handleRetry } +// ); +// +// handleError(queryResult); +// return queryResult; +// }; + interface WordOfTheDayResponse { id: number; // section occurrence id wordOfTheDay: string;