Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Table View #163

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion frontend/src/modules/Dashboard/Components/CourseCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -31,6 +35,7 @@ export const CourseCard = ({
filterOption: state?.filterOption
? state.filterOption
: defaultFilterOption,
tableView: defaultView,
},
})
}
Expand Down
200 changes: 200 additions & 0 deletions frontend/src/modules/Dashboard/Components/CourseTable.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Box
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
overflow: 'auto',
}}
>
{courses.length === 0 ? (
<>
<StyledTextBox>
<h2>No Courses to Show</h2>
</StyledTextBox>
<StyledSmallText>
Once students request study partners, they'll automatically be
placed into courses on this page!
</StyledSmallText>
<StyledClassesContainer>
{[...Array(8)].map((_, i) => (
<StyledNoClasses key={i} />
))}
</StyledClassesContainer>
</>
) : (
<Box
sx={{
width: '100%',
justifyContent: 'center',
px: 10,
py: 4,
}}
>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead sx={{ background: '#EDEDEE' }}>
<TableRow>
<TableCell>Course </TableCell>
<TableCell align="left">Students</TableCell>
<TableCell align="left">Groups</TableCell>
<TableCell align="left">Recent Date</TableCell>
</TableRow>
</TableHead>
<TableBody>
{courses.map((c) => (
<TableRow key={c.courseId}>
<TableCell>
<Box
sx={{
display: 'flex',
alignItems: 'center',
gap: 2,
}}
>
<Link
sx={{
color: 'black',
fontWeight: 'bold',
textDecorationColor: 'black',
}}
component="button"
variant="body1"
onClick={() => {
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]}
</Link>
{getColor(c.unmatched.length, c.lastGroupNumber)
.new_match === 'yes' && <NewlyMatchableIcon />}
</Box>
</TableCell>
<TableCell align="right">
<Box
sx={{
display: 'flex',
alignItems: 'center',
gap: 2,
background: getColor(
c.unmatched.length,
c.lastGroupNumber
).color,
}}
>
{c.unmatched.length === 1 ? (
<WarningIcon />
) : (
<PlusIcon />
)}
<Typography>
{c.unmatched.length}{' '}
{c.unmatched.length === 1
? 'New Student'
: 'New Students'}
</Typography>
</Box>
</TableCell>
<TableCell align="right">
<Box
sx={{
display: 'flex',
alignItems: 'center',
gap: 2,
}}
>
<GroupsIcon />
<Typography>
{c.lastGroupNumber}{' '}
{c.lastGroupNumber === 1
? 'Group Formed'
: 'Groups Formed'}
</Typography>
</Box>
</TableCell>
<TableCell>
<Typography>
{c.latestSubmissionTime.getMonth() + 1}
{'-'}
{c.latestSubmissionTime.getDate()}
{'-'}
{c.latestSubmissionTime.getFullYear()}
</Typography>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Box>
)}
</Box>
)
}

interface CourseGridProps {
courses: Course[]
}
108 changes: 105 additions & 3 deletions frontend/src/modules/Dashboard/Components/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ 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'
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'
Expand All @@ -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'],
Expand All @@ -59,13 +62,18 @@ export const Dashboard = () => {
const state = history.location.state as {
sortedOrder: SortOrder
filterOption: FilterOption
tableView: boolean
}
const [sortedOrder, setSortedOrder] = useState<SortOrder>(() =>
state?.sortedOrder ? state.sortedOrder : defaultSortingOrder
)
const [filteredOption, setFilteredOption] = useState<FilterOption>(() =>
state?.filterOption ? state.filterOption : defaultFilterOption
)
const [tableView, setTableView] = useState(() =>
state?.tableView === undefined || state?.tableView ? true : defaultView
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change this line to state?.tableView === undefined ? defaultView : state?.tableView

)

//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'])
Expand Down Expand Up @@ -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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change this line to tableView: state?.tableView !== undefined ? state.tableView : defaultView,

},
})
}
Expand All @@ -171,6 +180,28 @@ export const Dashboard = () => {
? state.sortedOrder
: 'newest-requests-first',
filterOption: event.target.value as FilterOption,
tableView: state?.tableView ? state.tableView : defaultView,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tableView: state?.tableView !== undefined ? state.tableView : defaultView,

},
})
}

//helper function to change view
const handleClickTable = () => {
setTableView(
state?.tableView === undefined || state?.tableView ? false : !defaultView
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change this line to !tableView

)
history.replace({
state: {
sortedOrder: state?.sortedOrder
? state.sortedOrder
: defaultSortingOrder,
filterOption: state?.filterOption
? state.filterOption
: defaultFilterOption,
tableView:
state?.tableView === undefined || state?.tableView
? false
: !defaultView,
Comment on lines +202 to +204
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!tableView (these are just toggles)

},
})
}
Expand Down Expand Up @@ -311,7 +342,78 @@ export const Dashboard = () => {
/>
</Box>
</StyledHeaderMenu>
<CourseGrid courses={filteredSortedCourses} />

<Box
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'right',
flexDirection: 'row',
gap: 1,
paddingRight: '80px',
}}
>
<Typography sx={{ paddingRight: '5px' }}>
{filteredSortedCourses.length}
{' classes'}
</Typography>
<IconButton
onClick={handleClickTable}
disabled={
state?.tableView || state?.tableView === undefined ? false : true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change this to state?.tableView !== undefined ? !state.tableView : !tableView

}
color="default"
sx={{
'&.Mui-disabled': {
background: '#939393',
color: 'white',
},
boxSizing: 'border-box',
display: 'flex',
flexDirection: 'row',
padding: '8px',
gap: '10px',
width: '40px',
height: '40px',
background: '#F3F3F3',
border: '1px solid #939393',
borderRadius: '6px',
}}
>
<ViewWeekOutlinedIcon />
</IconButton>{' '}
<IconButton
onClick={handleClickTable}
disabled={
state?.tableView || state?.tableView === undefined ? true : false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to state?.tableView !== undefined ? state.tableView : tableView

}
color="default"
sx={{
'&.Mui-disabled': {
background: '#939393',
color: 'white',
},
boxSizing: 'border-box',
display: 'flex',
flexDirection: 'row',
padding: '8px',
gap: '10px',
width: '40px',
height: '40px',
background: '#F3F3F3',
border: '1px solid #939393',
borderRadius: '6px',
}}
>
<ViewHeadlineIcon />
</IconButton>
</Box>

{(state?.tableView ? state.tableView : defaultView) ? (
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

state?.tableView !== undefined ? state.tableView : tableView

<CourseTable courses={filteredSortedCourses} />
) : (
<CourseGrid courses={filteredSortedCourses} />
)}
</StyledContainer>
)
}
1 change: 1 addition & 0 deletions frontend/src/modules/EditZing/Components/EditZing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ export const EditZing = () => {
filterOption: state?.filterOption
? state.filterOption
: 'no-filter',
tableView: state?.tableView ? state.tableView : false,
},
}}
sx={{
Expand Down