-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5b3c7d3
commit 2356063
Showing
9 changed files
with
139 additions
and
151 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { useQuery } from "@tanstack/react-query"; | ||
import axios from "axios"; | ||
import { AttendanceRecord } from "../util/Types"; | ||
import { getStatus } from "../util/converters"; | ||
|
||
export default function useAttendanceRecords(id: string | undefined) { | ||
return useQuery({ | ||
queryKey: ["records", id], | ||
queryFn: async (): Promise<AttendanceRecord[]> => { | ||
const response = await axios.get<AttendanceRecord[]>( | ||
`/api/record/getAttendanceRecordForMember/?id=${id}` | ||
); | ||
|
||
return response.data.map((r): AttendanceRecord => { | ||
r.event.startTime = new Date(r.event.startTime); | ||
r.event.endTime = new Date(r.event.endTime); | ||
r.event.status = getStatus(r.event); | ||
return r; | ||
}); | ||
}, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,145 +1,123 @@ | ||
import { useContext, useState } from "react"; | ||
import { getAttendanceRecordForMember } from "../client/client"; | ||
import { AttendanceRecordPercentages } from "../components/AttendanceRecord/AttendanceRecordPercent"; | ||
import { AttendanceRecordRow } from "../components/AttendanceRecord/AttendanceRecordRow"; | ||
import { AttendanceStanding } from "../components/AttendanceRecord/AttendanceStanding"; | ||
import Loading from "../components/Loading"; | ||
import { AuthContext } from "../hooks/useAuth"; | ||
import useAttendanceRecords from "../hooks/useAttendanceRecords"; | ||
import { useAuth } from "../hooks/useAuth"; | ||
import { createDateString } from "../util/Date"; | ||
import { AttendanceRecord, Event } from "../util/Types"; | ||
|
||
/** | ||
* | ||
* | ||
* @returns The page which displays the attendance for each event during the semester. | ||
*/ | ||
const AttendanceRecordPage = () => { | ||
// --- STATE ------------------------------------------------------ | ||
const [attendanceRecord, setAttendanceRecord] = useState< | ||
AttendanceRecord[] | [] | ||
>([]); | ||
const [attendanceEvents, setAttendanceEvents] = useState<Event[] | []>(); | ||
|
||
// --- CONTEXT ---------------------------------------------------- | ||
const { member } = useContext(AuthContext); | ||
const { member } = useAuth(); | ||
const { | ||
status, | ||
data: records, | ||
error, | ||
isFetching, | ||
} = useAttendanceRecords(member?.id); | ||
|
||
// --- VARIABLES -------------------------------------------------- | ||
const { month, dayOfWeek, fulldate, year } = createDateString(new Date()); | ||
let totalHours = 0; | ||
|
||
const fetchMemberRecord = async (): Promise<Event[]> => { | ||
// Get the attendance records for the selected member | ||
if (!member) return []; | ||
const attendanceRecords = await getAttendanceRecordForMember(member?.id); | ||
setAttendanceRecord(attendanceRecords); | ||
|
||
// Fetch the event data for each event | ||
const events: Event[] = []; | ||
// for (const record of attendanceRecords) { | ||
// const event = await fetchEvent(record.eventID); | ||
// events.push(event); | ||
// } | ||
let totalHours = records | ||
?.map((r) => { | ||
const timeDifInSeconds = | ||
(r.event.endTime.getTime() - r.event.startTime.getTime()) / 1000; | ||
const timeDiffInHours = Math.round(timeDifInSeconds / 3600); | ||
return timeDiffInHours; | ||
}) | ||
.reduce((a, b) => a + b, 0); | ||
|
||
return events; | ||
}; | ||
|
||
if (!attendanceEvents) { | ||
fetchMemberRecord().then((e) => { | ||
setAttendanceEvents(e); | ||
}); | ||
if (isFetching) { | ||
return <Loading />; | ||
} | ||
|
||
for (const event of attendanceEvents) { | ||
const endTime = new Date(event.endTime).getTime(); | ||
const startTime = new Date(event.startTime).getTime(); | ||
const timeDifInSeconds = (endTime - startTime) / 1000; | ||
const timeDiffInHours = Math.round(timeDifInSeconds / 3600); | ||
totalHours += timeDiffInHours; | ||
} | ||
|
||
return ( | ||
<div className="flex flex-col p-10 flex-1 h-fit"> | ||
<div className="flex flex-col md:flex-row md:justify-between w-[70vw] md:w-full"> | ||
<div className="flex flex-col justify-between"> | ||
<span className="text-2xl font-bold">ATTENDANCE HISTORY</span> | ||
<div className="text-xl text-gray-600"> | ||
<div className="hidden md:flex"> | ||
<span className="border-b pb-2 border-gray-600"> | ||
{dayOfWeek + ", " + month + " " + fulldate + ", " + year}{" "} | ||
</span> | ||
} else if (status === "error") { | ||
return <div>Error: {error.message}</div>; | ||
} else if (records) { | ||
return ( | ||
<div className="flex flex-col p-10 flex-1 h-fit"> | ||
<div className="flex flex-col md:flex-row md:justify-between w-[70vw] md:w-full"> | ||
<div className="flex flex-col justify-between"> | ||
<span className="text-2xl font-bold">ATTENDANCE HISTORY</span> | ||
<div className="text-xl text-gray-600"> | ||
<div className="hidden md:flex"> | ||
<span className="border-b pb-2 border-gray-600"> | ||
{dayOfWeek + ", " + month + " " + fulldate + ", " + year}{" "} | ||
</span> | ||
</div> | ||
<div className="flex-col md:hidden"> | ||
<span>{member?.firstName + " " + member?.lastName}</span> | ||
<div className="w-full border border-t-0 border-gray-600 my-2"></div> | ||
</div> | ||
</div> | ||
<div className="flex-col md:hidden"> | ||
<span>{member?.firstName + " " + member?.lastName}</span> | ||
<div className="w-full border border-t-0 border-gray-600 my-2"></div> | ||
<div className="hidden md:block"> | ||
<AttendanceRecordPercentages attendanceRecord={records} /> | ||
</div> | ||
</div> | ||
<div className="hidden md:block"> | ||
<AttendanceRecordPercentages attendanceRecord={attendanceRecord} /> | ||
</div> | ||
</div> | ||
|
||
<div className="flex flex-col"> | ||
<span className="hidden md:block text-2xl font-bold"> | ||
{" "} | ||
{member?.firstName + " " + member?.lastName} | ||
</span> | ||
<div className="py-2 my-3 md:my-1"> | ||
<AttendanceStanding | ||
member={member} | ||
attendanceRecord={attendanceRecord} | ||
className={"py-[0.5em] md:py-1 text-lg md:text-base"} | ||
/> | ||
</div> | ||
<div className="flex gap-x-12"> | ||
<div className="flex flex-col"> | ||
<span className="font-montserrat font-medium"> | ||
Total attendance | ||
</span> | ||
<span className="text-xl font-bold"> | ||
{attendanceRecord.length + " Meetings"} | ||
</span> | ||
<div className="flex flex-col"> | ||
<span className="hidden md:block text-2xl font-bold"> | ||
{" "} | ||
{member?.firstName + " " + member?.lastName} | ||
</span> | ||
<div className="py-2 my-3 md:my-1"> | ||
<AttendanceStanding | ||
member={member} | ||
attendanceRecord={records} | ||
className={"py-[0.5em] md:py-1 text-lg md:text-base"} | ||
/> | ||
</div> | ||
<div className="flex flex-col"> | ||
<span className="font-montserrat font-medium">Total Hours</span> | ||
<span className="text-xl font-bold">{totalHours}</span> | ||
<div className="flex gap-x-12"> | ||
<div className="flex flex-col"> | ||
<span className="font-montserrat font-medium"> | ||
Total attendance | ||
</span> | ||
<span className="text-xl font-bold"> | ||
{records.length + " Meetings"} | ||
</span> | ||
</div> | ||
<div className="flex flex-col"> | ||
<span className="font-montserrat font-medium">Total Hours</span> | ||
<span className="text-xl font-bold">{totalHours}</span> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div className="block md:hidden"> | ||
<AttendanceRecordPercentages | ||
attendanceRecord={attendanceRecord} | ||
mobile={true} | ||
/> | ||
<div className="block md:hidden"> | ||
<AttendanceRecordPercentages | ||
attendanceRecord={records} | ||
mobile={true} | ||
/> | ||
</div> | ||
</div> | ||
<div className="overflow-x-auto max-w-full"> | ||
<table className="text-left w-full mt-12 border-collapse"> | ||
<thead> | ||
<tr className="text-xl text-gray-600 border-t border-b border-gray-600"> | ||
<th className="font-normal py-2 w-3/12">Event Name</th> | ||
<th className="font-normal border-l border-gray-600 px-4 py-2 w-2/12"> | ||
Date | ||
</th> | ||
<th className="font-normal border-l border-r border-gray-600 px-4 py-2 w-4/12"> | ||
Time | ||
</th> | ||
<th className="font-normal pl-4 w-3/12">Your Status</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{records.map((r) => ( | ||
<AttendanceRecordRow attendanceRecord={r} event={r.event} /> | ||
))} | ||
</tbody> | ||
</table> | ||
</div> | ||
</div> | ||
<div className="overflow-x-auto max-w-full"> | ||
<table className="text-left w-full mt-12 border-collapse"> | ||
<thead> | ||
<tr className="text-xl text-gray-600 border-t border-b border-gray-600"> | ||
<th className="font-normal py-2 w-3/12">Event Name</th> | ||
<th className="font-normal border-l border-gray-600 px-4 py-2 w-2/12"> | ||
Date | ||
</th> | ||
<th className="font-normal border-l border-r border-gray-600 px-4 py-2 w-4/12"> | ||
Time | ||
</th> | ||
<th className="font-normal pl-4 w-3/12">Your Status</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{attendanceEvents.map((event) => ( | ||
<AttendanceRecordRow | ||
attendanceRecord={attendanceRecord} | ||
event={event} | ||
/> | ||
))} | ||
</tbody> | ||
</table> | ||
</div> | ||
</div> | ||
); | ||
); | ||
} else { | ||
return <></>; | ||
} | ||
}; | ||
|
||
export default AttendanceRecordPage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { Event, EventStatus } from "./Types"; | ||
|
||
export const getStatus = (event: Event): EventStatus => { | ||
const now = new Date(); | ||
if ( | ||
event.startTime.getTime() < now.getTime() && | ||
now.getTime() < event.endTime.getTime() | ||
) { | ||
return EventStatus.Live; | ||
} | ||
return EventStatus.Rest; | ||
}; |