Refactor classroom view and a extract function

This commit is contained in:
Leonardo Murça 2022-08-11 18:49:27 -03:00
parent c1cf91dde6
commit ec083e97a4
7 changed files with 412 additions and 385 deletions

View file

@ -0,0 +1,203 @@
import {
Button,
Card,
Container,
Grid,
Link,
Skeleton,
Stack,
} from '@mui/material';
import AnnouncementCard from '../../../components/AnnouncementCard';
import { createArrayFrom1ToN } from '../../../utils/createArrayFrom1ToN';
import styles from './styles';
import jitsiLogo from '../../../assets/jitsi.svg';
function AnnouncementsTab({ layoutType, announcementsTabData }) {
const { container } = styles[layoutType];
if (layoutType === 'desktop') {
return announcementsTabData === null ? (
<Grid sx={container} container spacing={2}>
<Grid sx={{ padding: '0 !important' }} item xs={4}>
{createArrayFrom1ToN(2).map(i => (
<Skeleton
key={i}
variant="rectangular"
width="100%"
height={200}
sx={{ marginBottom: '30px' }}
/>
))}
</Grid>
<Grid sx={{ paddingTop: '0 !important' }} item xs={8}>
{createArrayFrom1ToN(4).map(i => (
<Skeleton
key={i}
variant="rectangular"
width="100%"
height={250}
sx={{ marginBottom: '30px' }}
/>
))}
</Grid>
</Grid>
) : (
<Grid sx={container} container spacing={2}>
<Grid sx={{ padding: '0 !important' }} item xs={4}>
<Stack gap="30px">
<Card
sx={{ width: '100%', padding: '20px' }}
elevation={4}
variant="elevation"
>
<Stack justifyContent="flex-start" spacing={1}>
<Container
disableGutters
sx={{ display: 'flex', justifyContent: 'row' }}
>
<img src={jitsiLogo} alt="Jitsi Meet" />
<h3 style={{ fontWeight: 500 }}>Jitsi</h3>
</Container>
<Button
variant="contained"
href="https://google.com"
target="__blank"
>
Entrar
</Button>
</Stack>
</Card>
<Card
sx={{ width: '100%', padding: '20px' }}
elevation={4}
variant="elevation"
>
<Stack justifyContent="flex-start" spacing={1}>
<h3 style={{ fontWeight: 500 }}>Próximas Atividades</h3>
{announcementsTabData.upcomingAssignments.map(ua => (
<Link sx={{ fontSize: '15px' }} key={ua.id}>
{ua.title}
</Link>
))}
</Stack>
</Card>
</Stack>
</Grid>
<Grid sx={{ paddingTop: '0 !important' }} item xs={8}>
<Stack
sx={{ width: '100%', paddingTop: 0 }}
alignItems="center"
justifyContent="center"
flexWrap="wrap"
direction="row"
gap="30px"
>
{announcementsTabData.announcements.map(announcement => (
<AnnouncementCard
key={announcement.id}
announcement={announcement}
/>
))}
</Stack>
</Grid>
</Grid>
);
} else if (layoutType === 'mobile') {
return announcementsTabData === null ? (
<Stack
alignItems="center"
justifyContent="center"
flexWrap="wrap"
direction="row"
gap="30px"
sx={{ marginTop: '30px' }}
>
{createArrayFrom1ToN(2).map(i => (
<Skeleton
key={i}
variant="rectangular"
width="100%"
height={200}
sx={{ marginBottom: '30px' }}
/>
))}
{createArrayFrom1ToN(4).map(i => (
<Skeleton
key={i}
variant="rectangular"
width="100%"
height={250}
sx={{ marginBottom: '30px' }}
/>
))}
</Stack>
) : (
<Stack
alignItems="center"
justifyContent="center"
flexWrap="wrap"
direction="row"
gap="30px"
sx={{ marginTop: '30px' }}
>
<Stack gap="30px">
<Card
sx={{ width: '100%', padding: '20px' }}
elevation={4}
variant="elevation"
>
<Stack justifyContent="flex-start" spacing={1}>
<Container
disableGutters
sx={{ display: 'flex', justifyContent: 'row' }}
>
<img src={jitsiLogo} alt="Jitsi Meet" />
<h3 style={{ fontWeight: 500 }}>Jitsi</h3>
</Container>
<Button
variant="contained"
href="https://google.com"
target="__blank"
>
Entrar
</Button>
</Stack>
</Card>
<Card
sx={{ width: '100%', padding: '20px' }}
elevation={4}
variant="elevation"
>
<Stack justifyContent="flex-start" spacing={1}>
<h3 style={{ fontWeight: 500 }}>Próximas Atividades</h3>
{announcementsTabData.upcomingAssignments.map(ua => (
<Link sx={{ fontSize: '15px' }} key={ua.id}>
{ua.title}
</Link>
))}
</Stack>
</Card>
</Stack>
<Stack
sx={{ width: '100%' }}
alignItems="center"
justifyContent="center"
flexWrap="wrap"
direction="row"
gap="30px"
>
{announcementsTabData.announcements.map(announcement => (
<AnnouncementCard
key={announcement.id}
announcement={announcement}
/>
))}
</Stack>
</Stack>
);
}
}
export default AnnouncementsTab;

View file

@ -0,0 +1,34 @@
// ========== Desktop ==========
const desktopContainer = {
width: '100%',
height: '100vh',
backgroundColor: '#red',
padding: 0,
margin: 0,
marginTop: '50px',
};
const desktop = {
container: desktopContainer,
};
// ========== Mobile ==========
const mobileContainer = {
width: '90%',
backgroundColor: '#red',
padding: 0,
marginTop: '30px',
paddingBottom: '100px',
};
const mobile = {
container: mobileContainer,
};
// ========== Unset ==========
const unset = {
container: null,
};
const styles = { desktop, mobile, unset };
export default styles;

View file

@ -0,0 +1,57 @@
import {
Avatar,
AvatarGroup,
Container,
Paper,
Skeleton,
Stack,
Tab,
Tabs,
Tooltip,
Typography,
} from '@mui/material';
import { TAB_OPTIONS } from '../tabOptions';
import styles from './styles';
function Header({
layoutType,
classroom,
selectedTabOption,
onSelectTabOption,
}) {
const { title, paper, tabs, avatar, tooltip } = styles[layoutType];
return classroom === null ? (
<Skeleton variant="rectangular" width="100%" height={240} />
) : (
<Container disableGutters>
<Paper sx={paper(classroom.color)} elevation={4} variant="elevation">
<h1 style={title}>{classroom.name}</h1>
<Stack alignItems="center" direction="row" spacing={1}>
<AvatarGroup total={classroom.teachers.length}>
{classroom.teachers.map(t => (
<Avatar key={t.name} alt={t.name} src={t.avatar} sx={avatar} />
))}
</AvatarGroup>
<Tooltip title={classroom.teachers.map(t => t.name).join(', ')}>
<Typography sx={tooltip} variant="body3" color="text.secondary">
{classroom.teachers.map(t => t.name).join(', ')}
</Typography>
</Tooltip>
</Stack>
<Tabs
value={selectedTabOption}
onChange={onSelectTabOption}
aria-label="Tabs para informações da disciplina"
variant="fullWidth"
sx={tabs}
>
{TAB_OPTIONS.map(option => (
<Tab key={option.value} label={option.lable} />
))}
</Tabs>
</Paper>
</Container>
);
}
export default Header;

View file

@ -0,0 +1,90 @@
// ========== Desktop ==========
const desktopTitle = {
fontWeight: 500,
};
const desktopPaper = classColor => ({
width: '100%',
borderTop: `5px solid ${classColor}`,
padding: '20px',
});
const desktopTabs = {
marginLeft: '-20px',
marginRight: '-20px',
marginBottom: '-20px',
marginTop: '30px',
};
const desktopAvatar = {
width: 30,
height: 30,
};
const desktopTooltip = {
overflow: 'hidden',
textOverflow: 'ellipsis',
display: '-webkit-box',
WebkitLineClamp: 2,
WebkitBoxOrient: 'vertical',
};
const desktop = {
title: desktopTitle,
paper: desktopPaper,
tabs: desktopTabs,
avatar: desktopAvatar,
tooltip: desktopTooltip,
};
// ========== Mobile ==========
const mobileTitle = {
fontWeight: 500,
fontSize: '25px',
};
const mobilePaper = classColor => ({
width: '100%',
borderTop: `5px solid ${classColor}`,
padding: '10px',
});
const mobileTabs = {
marginLeft: '-10px',
marginRight: '-10px',
marginBottom: '-10px',
marginTop: '30px',
};
const mobileAvatar = {
width: 30,
height: 30,
};
const mobileTooltip = {
overflow: 'hidden',
textOverflow: 'ellipsis',
display: '-webkit-box',
WebkitLineClamp: 2,
WebkitBoxOrient: 'vertical',
};
const mobile = {
title: mobileTitle,
paper: mobilePaper,
tabs: mobileTabs,
avatar: mobileAvatar,
tooltip: mobileTooltip,
};
// ========== Unset ==========
const unset = {
title: null,
paper: null,
tabs: null,
avatar: null,
tooltip: null,
};
const styles = { desktop, mobile, unset };
export default styles;

View file

@ -1,24 +1,9 @@
import {
Avatar,
AvatarGroup,
Button,
Card,
Container,
Grid,
Link,
Paper,
Skeleton,
Stack,
Tab,
Tabs,
Tooltip,
Typography,
} from '@mui/material';
import { TAB_OPTIONS } from './tabOptions';
import { Container } from '@mui/material';
import Header from './Header';
import AnnouncementsTab from './AnnouncementsTab';
import styles from './styles';
import AnnouncementCard from '../../components/AnnouncementCard';
import { createArrayFrom1ToN } from '../../utils/createArrayFrom1ToN';
import jitsiLogo from '../../assets/jitsi.svg';
function View({
layoutType,
@ -27,288 +12,21 @@ function View({
onSelectTabOption,
announcementsTabData,
}) {
const { title, container, paper, tabs, avatar, tooltip } = styles[layoutType];
if (layoutType === 'desktop') {
return (
<Container disableGutters sx={container}>
{classroom === null ? (
<Skeleton variant="rectangular" width="100%" height={240} />
) : (
<Container disableGutters>
<Paper
sx={paper(classroom.color)}
elevation={4}
variant="elevation"
>
<h1 style={title}>{classroom.name}</h1>
<Stack alignItems="center" direction="row" spacing={1}>
<AvatarGroup total={classroom.teachers.length}>
{classroom.teachers.map(t => (
<Avatar
key={t.name}
alt={t.name}
src={t.avatar}
sx={avatar}
/>
))}
</AvatarGroup>
<Tooltip title={classroom.teachers.map(t => t.name).join(', ')}>
<Typography
sx={tooltip}
variant="body3"
color="text.secondary"
>
{classroom.teachers.map(t => t.name).join(', ')}
</Typography>
</Tooltip>
</Stack>
<Tabs
value={selectedTabOption}
onChange={onSelectTabOption}
aria-label="Tabs para informações da disciplina"
variant="fullWidth"
sx={tabs}
>
{TAB_OPTIONS.map(option => (
<Tab key={option.value} label={option.lable} />
))}
</Tabs>
</Paper>
</Container>
)}
{announcementsTabData === null ? (
<Grid sx={container} container spacing={2}>
<Grid sx={{ padding: '0 !important' }} item xs={4}>
{createArrayFrom1ToN(2).map(i => (
<Skeleton
key={i}
variant="rectangular"
width="100%"
height={200}
sx={{ marginBottom: '30px' }}
/>
))}
</Grid>
<Grid sx={{ paddingTop: '0 !important' }} item xs={8}>
{createArrayFrom1ToN(4).map(i => (
<Skeleton
key={i}
variant="rectangular"
width="100%"
height={250}
sx={{ marginBottom: '30px' }}
/>
))}
</Grid>
</Grid>
) : (
<Grid sx={container} container spacing={2}>
<Grid sx={{ padding: '0 !important' }} item xs={4}>
<Stack gap="30px">
<Card
sx={{ width: '100%', padding: '20px' }}
elevation={4}
variant="elevation"
>
<Stack justifyContent="flex-start" spacing={1}>
<Container
disableGutters
sx={{ display: 'flex', justifyContent: 'row' }}
>
<img src={jitsiLogo} alt="Jitsi Meet" />
<h3 style={{ fontWeight: 500 }}>Jitsi</h3>
</Container>
<Button
variant="contained"
href="https://google.com"
target="__blank"
>
Entrar
</Button>
</Stack>
</Card>
<Card
sx={{ width: '100%', padding: '20px' }}
elevation={4}
variant="elevation"
>
<Stack justifyContent="flex-start" spacing={1}>
<h3 style={{ fontWeight: 500 }}>Próximas Atividades</h3>
{announcementsTabData.upcomingAssignments.map(ua => (
<Link sx={{ fontSize: '15px' }} key={ua.id}>
{ua.title}
</Link>
))}
</Stack>
</Card>
</Stack>
</Grid>
<Grid sx={{ paddingTop: '0 !important' }} item xs={8}>
<Stack
sx={{ width: '100%', paddingTop: 0 }}
alignItems="center"
justifyContent="center"
flexWrap="wrap"
direction="row"
gap="30px"
>
{announcementsTabData.announcements.map(announcement => (
<AnnouncementCard
key={announcement.id}
announcement={announcement}
/>
))}
</Stack>
</Grid>
</Grid>
)}
</Container>
);
} else if (layoutType === 'mobile') {
return (
<Container disableGutters sx={container}>
{classroom === null ? (
<Skeleton variant="rectangular" width="100%" height={240} />
) : (
<Container disableGutters>
<Paper
sx={paper(classroom.color)}
elevation={4}
variant="elevation"
>
<h1 style={title}>{classroom.name}</h1>
<Stack alignItems="center" direction="row" spacing={1}>
<AvatarGroup total={classroom.teachers.length}>
{classroom.teachers.map(t => (
<Avatar
key={t.name}
alt={t.name}
src={t.avatar}
sx={avatar}
/>
))}
</AvatarGroup>
<Tooltip title={classroom.teachers.map(t => t.name).join(', ')}>
<Typography
sx={tooltip}
variant="body3"
color="text.secondary"
>
{classroom.teachers.map(t => t.name).join(', ')}
</Typography>
</Tooltip>
</Stack>
<Tabs
value={selectedTabOption}
onChange={onSelectTabOption}
aria-label="Tabs para informações da disciplina"
variant="fullWidth"
sx={tabs}
>
{TAB_OPTIONS.map(option => (
<Tab key={option.value} label={option.lable} />
))}
</Tabs>
</Paper>
</Container>
)}
{announcementsTabData === null ? (
<Stack
alignItems="center"
justifyContent="center"
flexWrap="wrap"
direction="row"
gap="30px"
sx={{ marginTop: '30px' }}
>
{createArrayFrom1ToN(2).map(i => (
<Skeleton
key={i}
variant="rectangular"
width="100%"
height={200}
sx={{ marginBottom: '30px' }}
/>
))}
{createArrayFrom1ToN(4).map(i => (
<Skeleton
key={i}
variant="rectangular"
width="100%"
height={250}
sx={{ marginBottom: '30px' }}
/>
))}
</Stack>
) : (
<Stack
alignItems="center"
justifyContent="center"
flexWrap="wrap"
direction="row"
gap="30px"
sx={{ marginTop: '30px' }}
>
<Stack gap="30px">
<Card
sx={{ width: '100%', padding: '20px' }}
elevation={4}
variant="elevation"
>
<Stack justifyContent="flex-start" spacing={1}>
<Container
disableGutters
sx={{ display: 'flex', justifyContent: 'row' }}
>
<img src={jitsiLogo} alt="Jitsi Meet" />
<h3 style={{ fontWeight: 500 }}>Jitsi</h3>
</Container>
<Button
variant="contained"
href="https://google.com"
target="__blank"
>
Entrar
</Button>
</Stack>
</Card>
<Card
sx={{ width: '100%', padding: '20px' }}
elevation={4}
variant="elevation"
>
<Stack justifyContent="flex-start" spacing={1}>
<h3 style={{ fontWeight: 500 }}>Próximas Atividades</h3>
{announcementsTabData.upcomingAssignments.map(ua => (
<Link sx={{ fontSize: '15px' }} key={ua.id}>
{ua.title}
</Link>
))}
</Stack>
</Card>
</Stack>
<Stack
sx={{ width: '100%' }}
alignItems="center"
justifyContent="center"
flexWrap="wrap"
direction="row"
gap="30px"
>
{announcementsTabData.announcements.map(announcement => (
<AnnouncementCard
key={announcement.id}
announcement={announcement}
/>
))}
</Stack>
</Stack>
)}
</Container>
);
}
const { container } = styles[layoutType];
return (
<Container disableGutters sx={container}>
<Header
layoutType={layoutType}
classroom={classroom}
selectedTabOption={selectedTabOption}
onSelectTabOption={onSelectTabOption}
/>
<AnnouncementsTab
layoutType={layoutType}
announcementsTabData={announcementsTabData}
/>
</Container>
);
}
export default View;

View file

@ -31,14 +31,15 @@ function Classroom() {
setClassroom(result.data);
}
getClassroomById(params.id);
}, [fetchClassroomById, params]);
useEffect(() => {
if (classroom !== null) {
document.title = classroom.name;
function updateDocumentTitle() {
if (classroom !== null) {
document.title = classroom.name;
}
}
}, [classroom]);
getClassroomById(params.id);
updateDocumentTitle();
}, [fetchClassroomById, params, classroom]);
useEffect(() => {
async function getSelectedTabData() {

View file

@ -1,8 +1,4 @@
// ========== Desktop ==========
const desktopTitle = {
fontWeight: 500,
};
const desktopContainer = {
width: '100%',
height: '100vh',
@ -12,47 +8,11 @@ const desktopContainer = {
marginTop: '50px',
};
const desktopPaper = classColor => ({
width: '100%',
borderTop: `5px solid ${classColor}`,
padding: '20px',
});
const desktopTabs = {
marginLeft: '-20px',
marginRight: '-20px',
marginBottom: '-20px',
marginTop: '30px',
};
const desktopAvatar = {
width: 30,
height: 30,
};
const desktopTooltip = {
overflow: 'hidden',
textOverflow: 'ellipsis',
display: '-webkit-box',
WebkitLineClamp: 2,
WebkitBoxOrient: 'vertical',
};
const desktop = {
title: desktopTitle,
container: desktopContainer,
paper: desktopPaper,
tabs: desktopTabs,
avatar: desktopAvatar,
tooltip: desktopTooltip,
};
// ========== Mobile ==========
const mobileTitle = {
fontWeight: 500,
fontSize: '25px',
};
const mobileContainer = {
width: '90%',
backgroundColor: '#red',
@ -61,49 +21,13 @@ const mobileContainer = {
paddingBottom: '100px',
};
const mobilePaper = classColor => ({
width: '100%',
borderTop: `5px solid ${classColor}`,
padding: '10px',
});
const mobileTabs = {
marginLeft: '-10px',
marginRight: '-10px',
marginBottom: '-10px',
marginTop: '30px',
};
const mobileAvatar = {
width: 30,
height: 30,
};
const mobileTooltip = {
overflow: 'hidden',
textOverflow: 'ellipsis',
display: '-webkit-box',
WebkitLineClamp: 2,
WebkitBoxOrient: 'vertical',
};
const mobile = {
title: mobileTitle,
container: mobileContainer,
paper: mobilePaper,
tabs: mobileTabs,
avatar: mobileAvatar,
tooltip: mobileTooltip,
};
// ========== Unset ==========
const unset = {
title: null,
container: null,
paper: null,
tabs: null,
avatar: null,
tooltip: null,
};
const styles = { desktop, mobile, unset };