Improve assignment cards for professor and student

This commit is contained in:
Leonardo Murça 2023-11-19 16:48:30 -03:00
parent ce0720ecdb
commit f7570c5847
7 changed files with 352 additions and 45 deletions

View file

@ -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>

View 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;

View 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;

View file

@ -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"

View file

@ -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)}
/> />

View file

@ -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,