From a23fba6b6bcfe0271def0654100dde11b892085d Mon Sep 17 00:00:00 2001 From: Jessica Date: Thu, 23 Mar 2023 19:51:38 -0400 Subject: [PATCH 1/6] Added Table View --- .../Dashboard/Components/CourseTable.tsx | 118 ++++++++++++++++++ .../Dashboard/Components/Dashboard.tsx | 42 +++++-- 2 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 frontend/src/modules/Dashboard/Components/CourseTable.tsx diff --git a/frontend/src/modules/Dashboard/Components/CourseTable.tsx b/frontend/src/modules/Dashboard/Components/CourseTable.tsx new file mode 100644 index 00000000..6b71ca32 --- /dev/null +++ b/frontend/src/modules/Dashboard/Components/CourseTable.tsx @@ -0,0 +1,118 @@ +import React from 'react' +import Table from '@mui/material/Table' +import { + StyledTextBox, + StyledSmallText, + StyledClassesContainer, + StyledNoClasses, +} from 'Dashboard/Styles/Groups.style' + +import { + Box, + 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 { EDIT_ZING_PATH } from '@core/Constants' +import { defaultSortingOrder, defaultFilterOption } from './Dashboard' + +export const CourseTable = ({ courses }: CourseGridProps) => { + const history = useHistory() + + 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 + New Students + Groups + Date In Question + + + + {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, + }, + }) + }} + > + {c.names[0]} + + + {c.unmatched.length} + + {c.lastGroupNumber} Groups Formed + + + {c.latestSubmissionTime.toDateString()} + + + ))} + +
+
+
+ )} +
+ ) +} + +interface CourseGridProps { + courses: Course[] +} diff --git a/frontend/src/modules/Dashboard/Components/Dashboard.tsx b/frontend/src/modules/Dashboard/Components/Dashboard.tsx index cb3a6dcc..799dcdb2 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, Button, IconButton, SelectChangeEvent } from '@mui/material' import { DropdownSelect } from '@core/Components' import { useCourseValue } from '@context/CourseContext' import { useStudentValue } from '@context/StudentContext' @@ -15,6 +15,7 @@ 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' type SortOrder = | 'newest-requests-first' | 'oldest-requests-first' @@ -62,6 +63,12 @@ export const Dashboard = () => { const [filteredOption, setFilteredOption] = useState(() => state?.filterOption ? state.filterOption : defaultFilterOption ) + const [tableView, setTableView] = useState(false) + //helper function to change view + const handleClickTable = () => { + setTableView((current) => !current) + } + //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']) @@ -129,12 +136,10 @@ export const Dashboard = () => { b.latestSubmissionTime.valueOf() - a.latestSubmissionTime.valueOf() ) case 'oldest-requests-first': - return [...courseInfo] - .sort( - (a, b) => - a.latestSubmissionTime.valueOf() - - b.latestSubmissionTime.valueOf() - ) + return [...courseInfo].sort( + (a, b) => + a.latestSubmissionTime.valueOf() - b.latestSubmissionTime.valueOf() + ) case 'classes-a-z': return [...courseInfo].sort((a, b) => { return a.names[0].localeCompare(b.names[0], undefined, { @@ -283,6 +288,23 @@ export const Dashboard = () => { /> + + + { showSettingsLink={true} /> - + {tableView ? ( + + ) : ( + + )} ) } From b1b3583f72b3c72403f55ebdaba32fed8480a605 Mon Sep 17 00:00:00 2001 From: Jessica Date: Tue, 25 Apr 2023 22:25:20 -0400 Subject: [PATCH 2/6] Added styling to table --- .../Dashboard/Components/CourseTable.tsx | 135 ++++++++++++++---- .../Dashboard/Components/Dashboard.tsx | 80 +++++++++-- 2 files changed, 175 insertions(+), 40 deletions(-) diff --git a/frontend/src/modules/Dashboard/Components/CourseTable.tsx b/frontend/src/modules/Dashboard/Components/CourseTable.tsx index 6b71ca32..c3bdde65 100644 --- a/frontend/src/modules/Dashboard/Components/CourseTable.tsx +++ b/frontend/src/modules/Dashboard/Components/CourseTable.tsx @@ -6,9 +6,7 @@ import { StyledClassesContainer, StyledNoClasses, } from 'Dashboard/Styles/Groups.style' - import { - Box, Paper, TableBody, TableCell, @@ -19,11 +17,33 @@ import { import { Course } from '@core/Types' import { useHistory } from 'react-router-dom' import Link from '@mui/material/Link' -import { EDIT_ZING_PATH } from '@core/Constants' +import { colors, EDIT_ZING_PATH } from '@core' import { defaultSortingOrder, defaultFilterOption } 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 ( { > - + Course - New Students - Groups - Date In Question + 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, - }, - }) + - {c.names[0]} - + { + 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, + }, + }) + }} + > + {c.names[0]} + + {getColor(c.unmatched.length, c.lastGroupNumber) + .new_match === 'yes' && } + - {c.unmatched.length} - {c.lastGroupNumber} Groups Formed + + {c.unmatched.length === 1 ? ( + + ) : ( + + )} + + {c.unmatched.length}{' '} + {c.unmatched.length === 1 + ? 'New Student' + : 'New Students'} + + - {c.latestSubmissionTime.toDateString()} + + + + {c.lastGroupNumber}{' '} + {c.lastGroupNumber === 1 + ? 'Group Formed' + : 'Groups Formed'} + + + + + + {c.latestSubmissionTime.getMonth() + 1} + {'/'} + {c.latestSubmissionTime.getDay()} + {'/'} + {c.latestSubmissionTime.getFullYear()} + ))} diff --git a/frontend/src/modules/Dashboard/Components/Dashboard.tsx b/frontend/src/modules/Dashboard/Components/Dashboard.tsx index 799dcdb2..11afd327 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, Button, 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' @@ -16,6 +16,8 @@ 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' type SortOrder = | 'newest-requests-first' | 'oldest-requests-first' @@ -111,7 +113,7 @@ export const Dashboard = () => { case 'matchable': return [...courseInfo].filter( (course, _) => - (course.lastGroupNumber > 0 && course.unmatched.length > 0) || + (course.lastGroupNumber > 0 && course.unmatched.length > 1) || (course.lastGroupNumber === 0 && course.unmatched.length > 1) ) case 'can-add-to-existing-group': @@ -295,16 +297,7 @@ export const Dashboard = () => { padding: 1, margin: 1, }} - > - - + > { showSettingsLink={true} /> + + + + {filteredSortedCourses.length} + {' classes'} + + + + {' '} + + + + + {tableView ? ( ) : ( From 8ee007c69b380e5f7d3b825e859e67b582d2ae5b Mon Sep 17 00:00:00 2001 From: Jessica Date: Tue, 25 Apr 2023 22:44:45 -0400 Subject: [PATCH 3/6] Fixed date and logic of showing table vs grid --- frontend/src/modules/Dashboard/Components/CourseTable.tsx | 4 +--- frontend/src/modules/Dashboard/Components/Dashboard.tsx | 8 ++++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/frontend/src/modules/Dashboard/Components/CourseTable.tsx b/frontend/src/modules/Dashboard/Components/CourseTable.tsx index c3bdde65..43567eb2 100644 --- a/frontend/src/modules/Dashboard/Components/CourseTable.tsx +++ b/frontend/src/modules/Dashboard/Components/CourseTable.tsx @@ -74,8 +74,6 @@ export const CourseTable = ({ courses }: CourseGridProps) => { sx={{ width: '100%', justifyContent: 'center', - gap: 4, - gridTemplateColumns: 'repeat(auto-fill, 300px)', px: 10, py: 4, }} @@ -176,7 +174,7 @@ export const CourseTable = ({ courses }: CourseGridProps) => { {c.latestSubmissionTime.getMonth() + 1} {'/'} - {c.latestSubmissionTime.getDay()} + {c.latestSubmissionTime.getDate()} {'/'} {c.latestSubmissionTime.getFullYear()} diff --git a/frontend/src/modules/Dashboard/Components/Dashboard.tsx b/frontend/src/modules/Dashboard/Components/Dashboard.tsx index 11afd327..e8c8732d 100644 --- a/frontend/src/modules/Dashboard/Components/Dashboard.tsx +++ b/frontend/src/modules/Dashboard/Components/Dashboard.tsx @@ -323,7 +323,7 @@ export const Dashboard = () => { { {' '} { {tableView ? ( - - ) : ( + ) : ( + )} ) From 75798b463dc5f23d1c36ce012e862aa96bac6451 Mon Sep 17 00:00:00 2001 From: Jessica Date: Wed, 26 Apr 2023 10:01:37 -0400 Subject: [PATCH 4/6] Make coursetable one component --- frontend/src/modules/Dashboard/Components/Dashboard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/modules/Dashboard/Components/Dashboard.tsx b/frontend/src/modules/Dashboard/Components/Dashboard.tsx index e8c8732d..136ada65 100644 --- a/frontend/src/modules/Dashboard/Components/Dashboard.tsx +++ b/frontend/src/modules/Dashboard/Components/Dashboard.tsx @@ -370,7 +370,7 @@ export const Dashboard = () => { {tableView ? ( - + ) : ( )} From 0f55da3ec17af730c08c4ddb87923ec36b42b048 Mon Sep 17 00:00:00 2001 From: Jessica Date: Fri, 5 May 2023 11:33:19 -0400 Subject: [PATCH 5/6] Fixed minor changes --- frontend/src/modules/Dashboard/Components/CourseTable.tsx | 4 ++-- frontend/src/modules/Dashboard/Components/Dashboard.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/modules/Dashboard/Components/CourseTable.tsx b/frontend/src/modules/Dashboard/Components/CourseTable.tsx index 43567eb2..9675750f 100644 --- a/frontend/src/modules/Dashboard/Components/CourseTable.tsx +++ b/frontend/src/modules/Dashboard/Components/CourseTable.tsx @@ -173,9 +173,9 @@ export const CourseTable = ({ courses }: CourseGridProps) => { {c.latestSubmissionTime.getMonth() + 1} - {'/'} + {'-'} {c.latestSubmissionTime.getDate()} - {'/'} + {'-'} {c.latestSubmissionTime.getFullYear()} diff --git a/frontend/src/modules/Dashboard/Components/Dashboard.tsx b/frontend/src/modules/Dashboard/Components/Dashboard.tsx index 0c3970c7..dd9c229c 100644 --- a/frontend/src/modules/Dashboard/Components/Dashboard.tsx +++ b/frontend/src/modules/Dashboard/Components/Dashboard.tsx @@ -72,7 +72,7 @@ export const Dashboard = () => { const [tableView, setTableView] = useState(false) //helper function to change view const handleClickTable = () => { - setTableView((current) => !current) + setTableView(!state.tableView) } //Helper function to check if a given course has any groups without check-in emails From fc2ad6ffd745f4c2359ae6ad675eaf78acf1daca Mon Sep 17 00:00:00 2001 From: Jessica Date: Fri, 5 May 2023 12:05:11 -0400 Subject: [PATCH 6/6] Preserve state of view selection --- .../Dashboard/Components/CourseCard.tsx | 7 ++- .../Dashboard/Components/CourseTable.tsx | 7 ++- .../Dashboard/Components/Dashboard.tsx | 44 +++++++++++++++---- .../modules/EditZing/Components/EditZing.tsx | 1 + 4 files changed, 48 insertions(+), 11 deletions(-) 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 index 9675750f..94f5b9e3 100644 --- a/frontend/src/modules/Dashboard/Components/CourseTable.tsx +++ b/frontend/src/modules/Dashboard/Components/CourseTable.tsx @@ -18,7 +18,11 @@ 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 } from './Dashboard' +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' @@ -118,6 +122,7 @@ export const CourseTable = ({ courses }: CourseGridProps) => { filterOption: state?.filterOption ? state.filterOption : defaultFilterOption, + tableView: !defaultView, }, }) }} diff --git a/frontend/src/modules/Dashboard/Components/Dashboard.tsx b/frontend/src/modules/Dashboard/Components/Dashboard.tsx index dd9c229c..4a3e451e 100644 --- a/frontend/src/modules/Dashboard/Components/Dashboard.tsx +++ b/frontend/src/modules/Dashboard/Components/Dashboard.tsx @@ -39,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'], @@ -62,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 @@ -69,11 +70,9 @@ export const Dashboard = () => { const [filteredOption, setFilteredOption] = useState(() => state?.filterOption ? state.filterOption : defaultFilterOption ) - const [tableView, setTableView] = useState(false) - //helper function to change view - const handleClickTable = () => { - setTableView(!state.tableView) - } + 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) { @@ -169,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, }, }) } @@ -180,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, }, }) } @@ -337,7 +359,9 @@ export const Dashboard = () => { { {' '} { - {tableView ? ( + {(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={{