Improve assignment cards for professor and student
This commit is contained in:
parent
ce0720ecdb
commit
f7570c5847
7 changed files with 352 additions and 45 deletions
|
@ -9,19 +9,18 @@ import {
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
import { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter';
|
import { capitalizeFirstLetter } from '../../../utils/capitalizeFirstLetter';
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
import { AssignmentTurnedIn, PendingActions } from '@mui/icons-material';
|
||||||
|
|
||||||
function AssignmentCard({
|
function AssignmentCard({
|
||||||
title,
|
title,
|
||||||
classrooms,
|
classrooms,
|
||||||
dueDate,
|
dueDate,
|
||||||
scores,
|
|
||||||
deliveredByStudents,
|
deliveredByStudents,
|
||||||
reviewed,
|
reviewed,
|
||||||
total,
|
total,
|
||||||
isAssignmentToReview,
|
|
||||||
layoutType,
|
layoutType,
|
||||||
onClick,
|
onClick,
|
||||||
}) {
|
}) {
|
||||||
|
@ -64,29 +63,33 @@ function AssignmentCard({
|
||||||
>
|
>
|
||||||
{classrooms.map(c => c.name).join(', ')}
|
{classrooms.map(c => c.name).join(', ')}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Divider sx={dividerMiddle} />
|
|
||||||
|
|
||||||
<Typography sx={typographyDueDate} variant="p" component="div">
|
<Typography sx={typographyDueDate} variant="p" component="div">
|
||||||
<strong>Data de entrega: </strong>{' '}
|
Data de entrega:{' '}
|
||||||
{capitalizeFirstLetter(
|
{capitalizeFirstLetter(dayjs(dueDate).format('dddd, DD/MM'))}
|
||||||
dayjs(dueDate).format('dddd, DD/MM | HH:mm[h]')
|
|
||||||
)}
|
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<Divider sx={dividerMiddle} />
|
||||||
{deliveredByStudents >= 0 && total && (
|
{deliveredByStudents >= 0 && total && (
|
||||||
<Typography variant="p" component="div">
|
<Typography
|
||||||
<strong>Entregues: </strong>{' '}
|
variant="p"
|
||||||
{`${deliveredByStudents} de ${total}`}
|
component="div"
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginTop: '10px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<AssignmentTurnedIn sx={{ marginRight: '5px' }} />
|
||||||
|
{`${reviewed}`} corrigidas.
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
{reviewed >= 0 && total && (
|
{reviewed >= 0 && total && (
|
||||||
<Typography variant="p" component="div">
|
<Typography
|
||||||
<strong>Corrigidas: </strong> {`${reviewed} de ${total}`}
|
variant="p"
|
||||||
</Typography>
|
component="div"
|
||||||
)}
|
sx={{ display: 'flex', alignItems: 'center' }}
|
||||||
{!isAssignmentToReview && (
|
>
|
||||||
<Typography variant="p" component="div">
|
<PendingActions sx={{ marginRight: '5px' }} />{' '}
|
||||||
<strong>Valor: </strong>
|
{`${total - reviewed}`} pendentes.
|
||||||
{scores.map(s => s.value).join(', ')} pts
|
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
@ -121,28 +124,34 @@ function AssignmentCard({
|
||||||
>
|
>
|
||||||
{classrooms.map(c => c.name).join(', ')}
|
{classrooms.map(c => c.name).join(', ')}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Divider sx={dividerMiddle} />
|
|
||||||
<Typography sx={typographyDueDate} variant="p" component="div">
|
<Typography sx={typographyDueDate} variant="p" component="div">
|
||||||
<strong>Data de entrega: </strong>
|
Data de entrega:{' '}
|
||||||
{capitalizeFirstLetter(
|
{capitalizeFirstLetter(dayjs(dueDate).format('dddd, DD/MM'))}
|
||||||
dayjs(dueDate).format('dddd, DD/MM | HH:mm[h]')
|
|
||||||
)}
|
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<Divider sx={dividerMiddle} />
|
||||||
{deliveredByStudents >= 0 && total && (
|
{deliveredByStudents >= 0 && total && (
|
||||||
<Typography variant="p" component="div">
|
<Typography
|
||||||
<strong>Entregues: </strong>{' '}
|
variant="p"
|
||||||
{`${deliveredByStudents} de ${total}`}
|
component="div"
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginTop: '10px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<AssignmentTurnedIn sx={{ marginRight: '5px' }} />
|
||||||
|
{`${reviewed}`} corrigidas.
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
{reviewed >= 0 && total && (
|
{reviewed >= 0 && total && (
|
||||||
<Typography variant="p" component="div">
|
<Typography
|
||||||
<strong>Corrigidas: </strong> {`${reviewed} de ${total}`}
|
variant="p"
|
||||||
</Typography>
|
component="div"
|
||||||
)}
|
sx={{ display: 'flex', alignItems: 'center' }}
|
||||||
{!isAssignmentToReview && (
|
>
|
||||||
<Typography variant="p" component="div">
|
<PendingActions sx={{ marginRight: '5px' }} />{' '}
|
||||||
<strong>Valor: </strong>
|
{`${total - reviewed}`} pendentes.
|
||||||
{scores.map(s => s.value).join(', ')} pts
|
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
143
src/components/professor/AssignmentCard/styles.js
Normal file
143
src/components/professor/AssignmentCard/styles.js
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
// ========== Desktop ==========
|
||||||
|
const desktopCardContainer = classrooms => ({
|
||||||
|
position: 'relative',
|
||||||
|
width: '35em',
|
||||||
|
borderLeft: `5px solid ${classrooms[0].color}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const desktopClassroomLinesIndicator = classroom => ({
|
||||||
|
position: 'absolute',
|
||||||
|
height: '100%',
|
||||||
|
borderLeft: `5px solid ${classroom.color}`,
|
||||||
|
left: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const desktopCardActionArea = {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'start',
|
||||||
|
};
|
||||||
|
|
||||||
|
const desktopCardContent = {
|
||||||
|
width: '100%',
|
||||||
|
};
|
||||||
|
|
||||||
|
const desktopTypographyTitle = {
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
display: '-webkit-box',
|
||||||
|
WebkitLineClamp: 2,
|
||||||
|
WebkitBoxOrient: 'vertical',
|
||||||
|
fontSize: '17px',
|
||||||
|
};
|
||||||
|
|
||||||
|
const desktopStackClassroomNames = {
|
||||||
|
width: '100%',
|
||||||
|
};
|
||||||
|
|
||||||
|
const desktopTypographyClassroomNames = {
|
||||||
|
fontStyle: 'italic',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
};
|
||||||
|
|
||||||
|
const desktopDividerMiddle = {
|
||||||
|
marginTop: '10px',
|
||||||
|
};
|
||||||
|
|
||||||
|
const desktopTypographyDueDate = {
|
||||||
|
marginTop: '5px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
fontStyle: 'italic',
|
||||||
|
};
|
||||||
|
|
||||||
|
const desktop = {
|
||||||
|
cardContainer: desktopCardContainer,
|
||||||
|
classroomLinesIndicator: desktopClassroomLinesIndicator,
|
||||||
|
cardActionArea: desktopCardActionArea,
|
||||||
|
cardContent: desktopCardContent,
|
||||||
|
typographyTitle: desktopTypographyTitle,
|
||||||
|
stackClassroomNames: desktopStackClassroomNames,
|
||||||
|
typographyClassroomNames: desktopTypographyClassroomNames,
|
||||||
|
dividerMiddle: desktopDividerMiddle,
|
||||||
|
typographyDueDate: desktopTypographyDueDate,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ========== Mobile ==========
|
||||||
|
const mobileCardContainer = classrooms => ({
|
||||||
|
width: '100%',
|
||||||
|
borderTop: `5px solid ${classrooms[0].color}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const mobileClassroomLinesIndicator = classroom => ({
|
||||||
|
position: 'absolute',
|
||||||
|
width: '100%',
|
||||||
|
borderTop: `5px solid ${classroom.color}`,
|
||||||
|
top: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const mobileCardActionArea = {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
};
|
||||||
|
|
||||||
|
const mobileCardContent = {
|
||||||
|
width: '100%',
|
||||||
|
};
|
||||||
|
|
||||||
|
const mobileTypographyTitle = {
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
display: '-webkit-box',
|
||||||
|
WebkitLineClamp: 2,
|
||||||
|
WebkitBoxOrient: 'vertical',
|
||||||
|
fontSize: '17px',
|
||||||
|
};
|
||||||
|
|
||||||
|
const mobileStackClassroomNames = {
|
||||||
|
width: '100%',
|
||||||
|
};
|
||||||
|
|
||||||
|
const mobileTypographyClassroomNames = {
|
||||||
|
fontWeight: 'bold',
|
||||||
|
};
|
||||||
|
|
||||||
|
const mobileDividerMiddle = {
|
||||||
|
marginTop: '10px',
|
||||||
|
};
|
||||||
|
|
||||||
|
const mobileTypographyDueDate = {
|
||||||
|
marginTop: '5px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
fontStyle: 'italic',
|
||||||
|
};
|
||||||
|
|
||||||
|
const mobile = {
|
||||||
|
cardContainer: mobileCardContainer,
|
||||||
|
classroomLinesIndicator: mobileClassroomLinesIndicator,
|
||||||
|
cardActionArea: mobileCardActionArea,
|
||||||
|
cardContent: mobileCardContent,
|
||||||
|
typographyTitle: mobileTypographyTitle,
|
||||||
|
stackClassroomNames: mobileStackClassroomNames,
|
||||||
|
typographyClassroomNames: mobileTypographyClassroomNames,
|
||||||
|
dividerMiddle: mobileDividerMiddle,
|
||||||
|
typographyDueDate: mobileTypographyDueDate,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ========== Unset ==========
|
||||||
|
const unset = {
|
||||||
|
cardContainer: null,
|
||||||
|
classroomLinesIndicator: null,
|
||||||
|
cardActionArea: null,
|
||||||
|
cardContent: null,
|
||||||
|
typographyTitle: null,
|
||||||
|
stackClassroomNames: null,
|
||||||
|
typographyClassroomNames: null,
|
||||||
|
dividerMiddle: null,
|
||||||
|
typographyDueDate: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = { desktop, mobile, unset };
|
||||||
|
export default styles;
|
151
src/components/student/AssignmentCard/index.js
Normal file
151
src/components/student/AssignmentCard/index.js
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
import {
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
Typography,
|
||||||
|
CardActionArea,
|
||||||
|
Stack,
|
||||||
|
Tooltip,
|
||||||
|
Divider,
|
||||||
|
} from '@mui/material';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
import { capitalizeFirstLetter } from '../../../utils/capitalizeFirstLetter';
|
||||||
|
|
||||||
|
import styles from './styles';
|
||||||
|
import { Assessment, Today } from '@mui/icons-material';
|
||||||
|
|
||||||
|
function AssignmentCard({
|
||||||
|
title,
|
||||||
|
classrooms,
|
||||||
|
dueDate,
|
||||||
|
scores,
|
||||||
|
layoutType,
|
||||||
|
onClick,
|
||||||
|
}) {
|
||||||
|
const {
|
||||||
|
cardContainer,
|
||||||
|
classroomLinesIndicator,
|
||||||
|
cardActionArea,
|
||||||
|
cardContent,
|
||||||
|
typographyTitle,
|
||||||
|
stackClassroomNames,
|
||||||
|
typographyClassroomNames,
|
||||||
|
dividerMiddle,
|
||||||
|
typographyDueDate,
|
||||||
|
} = styles[layoutType];
|
||||||
|
|
||||||
|
if (layoutType === 'desktop') {
|
||||||
|
return (
|
||||||
|
<Card sx={cardContainer(classrooms)}>
|
||||||
|
{classrooms.length > 1 &&
|
||||||
|
classrooms
|
||||||
|
.filter((_, i) => i > 0)
|
||||||
|
.map(c => <div key={c.id} style={classroomLinesIndicator(c)} />)}
|
||||||
|
<CardActionArea onClick={() => onClick()} sx={cardActionArea}>
|
||||||
|
<CardContent sx={cardContent}>
|
||||||
|
<Tooltip title={title}>
|
||||||
|
<Typography
|
||||||
|
sx={typographyTitle}
|
||||||
|
gutterBottom
|
||||||
|
variant="h6"
|
||||||
|
component="div"
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</Typography>
|
||||||
|
</Tooltip>
|
||||||
|
<Stack sx={stackClassroomNames}>
|
||||||
|
<Typography
|
||||||
|
sx={typographyClassroomNames}
|
||||||
|
variant="p"
|
||||||
|
component="div"
|
||||||
|
>
|
||||||
|
{classrooms.map(c => c.name).join(', ')}
|
||||||
|
</Typography>
|
||||||
|
<Divider sx={dividerMiddle} />
|
||||||
|
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
...typographyDueDate,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
}}
|
||||||
|
variant="p"
|
||||||
|
component="div"
|
||||||
|
>
|
||||||
|
<Today sx={{ marginRight: '5px' }} />
|
||||||
|
{capitalizeFirstLetter(
|
||||||
|
dayjs(dueDate).format('dddd, DD/MM, HH:mm[h]')
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
|
<Typography
|
||||||
|
variant="p"
|
||||||
|
component="div"
|
||||||
|
sx={{ display: 'flex', alignItems: 'center' }}
|
||||||
|
>
|
||||||
|
<Assessment sx={{ marginRight: '5px' }} />
|
||||||
|
{scores.map(s => s.value).join(', ')} pontos
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
</CardContent>
|
||||||
|
</CardActionArea>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
} else if (layoutType === 'mobile') {
|
||||||
|
return (
|
||||||
|
<Card sx={cardContainer(classrooms)}>
|
||||||
|
<CardActionArea onClick={() => onClick()} sx={cardActionArea}>
|
||||||
|
{classrooms.length > 1 &&
|
||||||
|
classrooms
|
||||||
|
.filter((_, i) => i > 0)
|
||||||
|
.map(c => <div key={c.id} style={classroomLinesIndicator(c)} />)}
|
||||||
|
<CardContent sx={cardContent}>
|
||||||
|
<Tooltip title={title}>
|
||||||
|
<Typography
|
||||||
|
sx={typographyTitle}
|
||||||
|
gutterBottom
|
||||||
|
variant="h6"
|
||||||
|
component="div"
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</Typography>
|
||||||
|
</Tooltip>
|
||||||
|
<Stack sx={stackClassroomNames}>
|
||||||
|
<Typography
|
||||||
|
sx={typographyClassroomNames}
|
||||||
|
variant="p"
|
||||||
|
component="div"
|
||||||
|
>
|
||||||
|
{classrooms.map(c => c.name).join(', ')}
|
||||||
|
</Typography>
|
||||||
|
<Divider sx={dividerMiddle} />
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
...typographyDueDate,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
}}
|
||||||
|
variant="p"
|
||||||
|
component="div"
|
||||||
|
>
|
||||||
|
<Today sx={{ marginRight: '5px' }} />
|
||||||
|
{capitalizeFirstLetter(
|
||||||
|
dayjs(dueDate).format('dddd, DD/MM, HH:mm[h]')
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
|
<Typography
|
||||||
|
variant="p"
|
||||||
|
component="div"
|
||||||
|
sx={{ display: 'flex', alignItems: 'center' }}
|
||||||
|
>
|
||||||
|
<Assessment sx={{ marginRight: '5px' }} />
|
||||||
|
{scores.map(s => s.value).join(', ')} pontos
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
</CardContent>
|
||||||
|
</CardActionArea>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AssignmentCard;
|
|
@ -109,7 +109,11 @@ function AssignmentsTab({ assignmentsTabData, layoutType }) {
|
||||||
return (
|
return (
|
||||||
<Container sx={externalContainer} disableGutters>
|
<Container sx={externalContainer} disableGutters>
|
||||||
<Fab
|
<Fab
|
||||||
sx={{ width: 'fit-content', marginRight: '5%' }}
|
sx={{
|
||||||
|
width: 'fit-content',
|
||||||
|
marginRight: '5%',
|
||||||
|
borderRadius: '4px',
|
||||||
|
}}
|
||||||
color="primary"
|
color="primary"
|
||||||
aria-label="add"
|
aria-label="add"
|
||||||
variant="extended"
|
variant="extended"
|
||||||
|
@ -287,7 +291,7 @@ function AssignmentsTab({ assignmentsTabData, layoutType }) {
|
||||||
return (
|
return (
|
||||||
<Container sx={externalContainer} disableGutters>
|
<Container sx={externalContainer} disableGutters>
|
||||||
<Fab
|
<Fab
|
||||||
sx={{ width: '100%' }}
|
sx={{ width: '100%', borderRadius: '4px' }}
|
||||||
color="primary"
|
color="primary"
|
||||||
aria-label="add"
|
aria-label="add"
|
||||||
variant="extended"
|
variant="extended"
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import { Grid, Skeleton, Stack } from '@mui/material';
|
import { Grid, Skeleton, Stack } from '@mui/material';
|
||||||
import { Container } from '@mui/system';
|
import { Container } from '@mui/system';
|
||||||
import AssignmentCard from '../../../components/AssignmentCard';
|
|
||||||
|
import AssignmentCard from '../../../components/professor/AssignmentCard';
|
||||||
import ClassCard from '../../../components/ClassCard';
|
import ClassCard from '../../../components/ClassCard';
|
||||||
|
|
||||||
import { createArrayFrom1ToN } from '../../../utils/createArrayFrom1ToN';
|
import { createArrayFrom1ToN } from '../../../utils/createArrayFrom1ToN';
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
function View({
|
function View({
|
||||||
|
@ -81,11 +84,9 @@ function View({
|
||||||
title={assignment.title}
|
title={assignment.title}
|
||||||
classrooms={assignment.classrooms}
|
classrooms={assignment.classrooms}
|
||||||
dueDate={assignment.dueDate}
|
dueDate={assignment.dueDate}
|
||||||
scores={assignment.scores}
|
|
||||||
layoutType={layoutType}
|
layoutType={layoutType}
|
||||||
deliveredByStudents={assignment.deliveredByStudents}
|
deliveredByStudents={assignment.deliveredByStudents}
|
||||||
reviewed={assignment.reviewed}
|
reviewed={assignment.reviewed}
|
||||||
isAssignmentToReview={assignment.status !== null}
|
|
||||||
total={assignment.total}
|
total={assignment.total}
|
||||||
onClick={() => onClickAssignmentCard(assignment.id)}
|
onClick={() => onClickAssignmentCard(assignment.id)}
|
||||||
/>
|
/>
|
||||||
|
@ -170,11 +171,9 @@ function View({
|
||||||
title={assignment.title}
|
title={assignment.title}
|
||||||
classrooms={assignment.classrooms}
|
classrooms={assignment.classrooms}
|
||||||
dueDate={assignment.dueDate}
|
dueDate={assignment.dueDate}
|
||||||
scores={assignment.scores}
|
|
||||||
layoutType={layoutType}
|
layoutType={layoutType}
|
||||||
deliveredByStudents={assignment.deliveredByStudents}
|
deliveredByStudents={assignment.deliveredByStudents}
|
||||||
reviewed={assignment.reviewed}
|
reviewed={assignment.reviewed}
|
||||||
isAssignmentToReview={assignment.status !== null}
|
|
||||||
total={assignment.total}
|
total={assignment.total}
|
||||||
onClick={() => onClickAssignmentCard(assignment.id)}
|
onClick={() => onClickAssignmentCard(assignment.id)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { Container, Grid, Skeleton, Stack } from '@mui/material';
|
import { Container, Grid, Skeleton, Stack } from '@mui/material';
|
||||||
|
|
||||||
import ClassCard from '../../../components/ClassCard';
|
import ClassCard from '../../../components/ClassCard';
|
||||||
import AssignmentCard from '../../../components/AssignmentCard';
|
import AssignmentCard from '../../../components/student/AssignmentCard';
|
||||||
|
|
||||||
|
import { createArrayFrom1ToN } from '../../../utils/createArrayFrom1ToN';
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import { createArrayFrom1ToN } from '../../../utils/createArrayFrom1ToN';
|
|
||||||
|
|
||||||
function View({
|
function View({
|
||||||
layoutType,
|
layoutType,
|
||||||
|
|
Loading…
Reference in a new issue