diff --git a/frontend/src/modules/Dashboard/Components/CourseCard.tsx b/frontend/src/modules/Dashboard/Components/CourseCard.tsx index 044e6b00..20a0bbb5 100644 --- a/frontend/src/modules/Dashboard/Components/CourseCard.tsx +++ b/frontend/src/modules/Dashboard/Components/CourseCard.tsx @@ -6,7 +6,11 @@ import { ReactComponent as GroupsIcon } from '@assets/img/groupsicon.svg' import { ReactComponent as PlusIcon } from '@assets/img/plusicon.svg' import { ReactComponent as WarningIcon } from '@assets/img/warning.svg' import { useHistory } from 'react-router' -import { defaultSortingOrder, defaultFilterOption } from './Dashboard' +import { + defaultSortingOrder, + defaultFilterOption, + defaultView, +} from './Dashboard' import BookmarkBorderIcon from '@mui/icons-material/BookmarkBorder' import BookmarkIcon from '@mui/icons-material/Bookmark' import axios from 'axios' @@ -31,6 +35,7 @@ export const CourseCard = ({ filterOption: state?.filterOption ? state.filterOption : defaultFilterOption, + tableView: defaultView, }, }) } diff --git a/frontend/src/modules/Dashboard/Components/CourseTable.tsx b/frontend/src/modules/Dashboard/Components/CourseTable.tsx new file mode 100644 index 00000000..94f5b9e3 --- /dev/null +++ b/frontend/src/modules/Dashboard/Components/CourseTable.tsx @@ -0,0 +1,200 @@ +import React from 'react' +import Table from '@mui/material/Table' +import { + StyledTextBox, + StyledSmallText, + StyledClassesContainer, + StyledNoClasses, +} from 'Dashboard/Styles/Groups.style' +import { + Paper, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, +} from '@mui/material' +import { Course } from '@core/Types' +import { useHistory } from 'react-router-dom' +import Link from '@mui/material/Link' +import { colors, EDIT_ZING_PATH } from '@core' +import { + defaultSortingOrder, + defaultFilterOption, + defaultView, +} from './Dashboard' +import { Box, Typography } from '@mui/material' +import { ReactComponent as NewlyMatchableIcon } from '@assets/img/newlymatchable.svg' +import { ReactComponent as GroupsIcon } from '@assets/img/groupsicon.svg' +import { ReactComponent as PlusIcon } from '@assets/img/plusicon.svg' +import { ReactComponent as WarningIcon } from '@assets/img/warning.svg' + +export const CourseTable = ({ courses }: CourseGridProps) => { + const history = useHistory() + // returns color of background, button, and if newly matchable + function getColor(students: number, groups: number) { + //all students are matched + if (students === 0 && groups > 0) { + return { color: colors.white, new_match: 'no' } + } + //students are ready to be matched + else if (students > 0 && groups > 0) { + return { color: colors.lightgreen, new_match: 'no' } + } + //NEWLY MATCHABLE + else if (students > 1 && groups === 0) { + return { color: colors.lightgreen, new_match: 'yes' } + } + //only 1 student & 0 groups formed + else return { color: colors.yellow, new_match: 'no' } + } + + return ( + + {courses.length === 0 ? ( + <> + +

No Courses to Show

+
+ + Once students request study partners, they'll automatically be + placed into courses on this page! + + + {[...Array(8)].map((_, i) => ( + + ))} + + + ) : ( + + + + + + Course + Students + Groups + Recent Date + + + + {courses.map((c) => ( + + + + { + const state = history.location.state as any + history.push({ + pathname: `${EDIT_ZING_PATH}/${c.courseId}`, + state: { + sortedOrder: state?.sortedOrder + ? state.sortedOrder + : defaultSortingOrder, + filterOption: state?.filterOption + ? state.filterOption + : defaultFilterOption, + tableView: !defaultView, + }, + }) + }} + > + {c.names[0]} + + {getColor(c.unmatched.length, c.lastGroupNumber) + .new_match === 'yes' && } + + + + + {c.unmatched.length === 1 ? ( + + ) : ( + + )} + + {c.unmatched.length}{' '} + {c.unmatched.length === 1 + ? 'New Student' + : 'New Students'} + + + + + + + + {c.lastGroupNumber}{' '} + {c.lastGroupNumber === 1 + ? 'Group Formed' + : 'Groups Formed'} + + + + + + {c.latestSubmissionTime.getMonth() + 1} + {'-'} + {c.latestSubmissionTime.getDate()} + {'-'} + {c.latestSubmissionTime.getFullYear()} + + + + ))} + +
+
+
+ )} +
+ ) +} + +interface CourseGridProps { + courses: Course[] +} diff --git a/frontend/src/modules/Dashboard/Components/Dashboard.tsx b/frontend/src/modules/Dashboard/Components/Dashboard.tsx index 94365731..4a3e451e 100644 --- a/frontend/src/modules/Dashboard/Components/Dashboard.tsx +++ b/frontend/src/modules/Dashboard/Components/Dashboard.tsx @@ -7,7 +7,7 @@ import { StyledHeaderMenu, } from 'Dashboard/Styles/Dashboard.style' import { CourseGrid } from 'Dashboard/Components/CourseGrid' -import { Box, IconButton, SelectChangeEvent } from '@mui/material' +import { Box, IconButton, SelectChangeEvent, Typography } from '@mui/material' import { DropdownSelect } from '@core/Components' import { useCourseValue } from '@context/CourseContext' import { useStudentValue } from '@context/StudentContext' @@ -15,6 +15,9 @@ import { Course } from '@core/Types' import { useHistory } from 'react-router-dom' import { AccountMenu } from 'Dashboard/Components/AccountMenu' import ClearIcon from '@mui/icons-material/Clear' +import { CourseTable } from './CourseTable' +import ViewWeekOutlinedIcon from '@mui/icons-material/ViewWeekOutlined' +import ViewHeadlineIcon from '@mui/icons-material/ViewHeadline' import axios from 'axios' import { API_ROOT, COURSE_API } from '@core/Constants' @@ -36,7 +39,7 @@ type FilterOption = export const defaultSortingOrder = 'newest-requests-first' export const defaultFilterOption = 'no-filter' - +export const defaultView = false const filterOptionDisplay = [ ['no-filter', 'All Classes'], ['unmatchable', 'Unmatchable'], @@ -59,6 +62,7 @@ export const Dashboard = () => { const state = history.location.state as { sortedOrder: SortOrder filterOption: FilterOption + tableView: boolean } const [sortedOrder, setSortedOrder] = useState(() => state?.sortedOrder ? state.sortedOrder : defaultSortingOrder @@ -66,6 +70,10 @@ export const Dashboard = () => { const [filteredOption, setFilteredOption] = useState(() => state?.filterOption ? state.filterOption : defaultFilterOption ) + const [tableView, setTableView] = useState(() => + state?.tableView === undefined || state?.tableView ? true : defaultView + ) + //Helper function to check if a given course has any groups without check-in emails function hasUnsentCheckIns(c: Course) { return c.groups.some((group) => !group.templateTimestamps['check-in']) @@ -160,6 +168,7 @@ export const Dashboard = () => { state: { sortedOrder: event.target.value as SortOrder, filterOption: state?.filterOption ? state.filterOption : 'no-filter', + tableView: state?.tableView ? state.tableView : defaultView, }, }) } @@ -171,6 +180,28 @@ export const Dashboard = () => { ? state.sortedOrder : 'newest-requests-first', filterOption: event.target.value as FilterOption, + tableView: state?.tableView ? state.tableView : defaultView, + }, + }) + } + + //helper function to change view + const handleClickTable = () => { + setTableView( + state?.tableView === undefined || state?.tableView ? false : !defaultView + ) + history.replace({ + state: { + sortedOrder: state?.sortedOrder + ? state.sortedOrder + : defaultSortingOrder, + filterOption: state?.filterOption + ? state.filterOption + : defaultFilterOption, + tableView: + state?.tableView === undefined || state?.tableView + ? false + : !defaultView, }, }) } @@ -311,7 +342,78 @@ export const Dashboard = () => { /> - + + + + {filteredSortedCourses.length} + {' classes'} + + + + {' '} + + + + + + {(state?.tableView ? state.tableView : defaultView) ? ( + + ) : ( + + )} ) } diff --git a/frontend/src/modules/EditZing/Components/EditZing.tsx b/frontend/src/modules/EditZing/Components/EditZing.tsx index e6d30ba4..b64cadd8 100644 --- a/frontend/src/modules/EditZing/Components/EditZing.tsx +++ b/frontend/src/modules/EditZing/Components/EditZing.tsx @@ -199,6 +199,7 @@ export const EditZing = () => { filterOption: state?.filterOption ? state.filterOption : 'no-filter', + tableView: state?.tableView ? state.tableView : false, }, }} sx={{