diff --git a/src/components/Calendar.tsx b/src/components/Calendar.tsx
index 39d0fdf..695f98b 100644
--- a/src/components/Calendar.tsx
+++ b/src/components/Calendar.tsx
@@ -7,9 +7,14 @@ import "react-day-picker/style.css";
interface CalendarProps {
selectedDate: Date | undefined;
setSelectedDate: (date: Date | undefined) => void;
+ previousDisabled: boolean;
}
-export function Calendar({ selectedDate, setSelectedDate }: CalendarProps) {
+export function Calendar({
+ selectedDate,
+ setSelectedDate,
+ previousDisabled,
+}: CalendarProps) {
const customDays = ["s", "m", "t", "w", "t", "f", "s"];
return (
@@ -25,12 +30,16 @@ export function Calendar({ selectedDate, setSelectedDate }: CalendarProps) {
}}
showOutsideDays
disabled={(date) => {
- const tomorrow = new Date();
- tomorrow.setDate(tomorrow.getDate() + 1);
- tomorrow.setHours(0, 0, 0, 0);
+ if (previousDisabled) {
+ const tomorrow = new Date();
+ tomorrow.setDate(tomorrow.getDate() + 1);
+ tomorrow.setHours(0, 0, 0, 0);
- const cutoff = new Date(tomorrow.getTime() - 24 * 60 * 60 * 1000);
- return date < cutoff;
+ const cutoff = new Date(tomorrow.getTime() - 24 * 60 * 60 * 1000);
+ return date < cutoff;
+ } else {
+ return false;
+ }
}}
formatters={{
formatWeekdayName: (weekday) => customDays[weekday.getDay()],
diff --git a/src/components/GroupSignUpModal.tsx b/src/components/GroupSignUpModal.tsx
index 519f805..c9892f2 100644
--- a/src/components/GroupSignUpModal.tsx
+++ b/src/components/GroupSignUpModal.tsx
@@ -167,6 +167,7 @@ const GroupSignUpModal = ({ onClose }: { onClose: () => void }) => {
setShowCalendar(false);
}
}}
+ previousDisabled
/>
)}
diff --git a/src/components/SideNavBar.tsx b/src/components/SideNavBar.tsx
index 61d278c..d077f17 100644
--- a/src/components/SideNavBar.tsx
+++ b/src/components/SideNavBar.tsx
@@ -102,23 +102,31 @@ const SideNavBar = ({ user }: SideNavBarProps) => {
diff --git a/src/components/TimeTable.tsx b/src/components/TimeTable.tsx
new file mode 100644
index 0000000..264c871
--- /dev/null
+++ b/src/components/TimeTable.tsx
@@ -0,0 +1,221 @@
+import {
+ Box,
+ Button,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableHead,
+ TableRow,
+ Typography,
+} from "@mui/material";
+import { VolunteerSession } from "@prisma/client";
+import React from "react";
+
+interface TimeTableProps {
+ volunteerSessions: VolunteerSession[];
+}
+
+export default function TimeTable({ volunteerSessions }: TimeTableProps) {
+ const [page, setPage] = React.useState(0);
+
+ const sortedSessions = [...volunteerSessions].sort((a, b) => {
+ const dateA = new Date(a.dateWorked).getTime();
+ const dateB = new Date(b.dateWorked).getTime();
+
+ if (dateA !== dateB) {
+ return dateB - dateA; // descending by dateWorked
+ }
+
+ const checkInA = new Date(a.checkInTime).getTime();
+ const checkInB = new Date(b.checkInTime).getTime();
+
+ return checkInB - checkInA; // ascending by checkInTime if same date
+ });
+
+ const paginatedRows = sortedSessions.slice(page * 5, page * 5 + 5);
+
+ return (
+
+
+
+
+
+ Date
+
+
+
+ Total Hours Worked
+
+
+ Volunteer Session(s)
+
+
+
+
+ {paginatedRows.map((row) => {
+ const date = new Date(row.dateWorked).toLocaleDateString("en-US", {
+ month: "2-digit",
+ day: "2-digit",
+ year: "2-digit",
+ });
+
+ const hoursWorked = row.durationHours?.toFixed(1) ?? "N/A";
+
+ const sessionRange =
+ row.checkInTime && row.checkOutTime
+ ? `${new Date(row.checkInTime).toLocaleTimeString("en-US", {
+ hour: "numeric",
+ minute: "2-digit",
+ })} - ${new Date(row.checkOutTime).toLocaleTimeString(
+ "en-US",
+ {
+ hour: "numeric",
+ minute: "2-digit",
+ }
+ )}`
+ : "In Progress";
+
+ return (
+
+
+ {date}
+
+
+ {hoursWorked} hours
+
+
+ {sessionRange}
+
+
+ );
+ })}
+
+
+
+
+ Page {page + 1} of {Math.ceil((volunteerSessions?.length || 0) / 5)}
+
+
+
+
+
+
+
+
+ );
+}