timetable-app

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

Lesson.tsx (3518B)


      1 import { useDisclosure } from '@mantine/hooks';
      2 import CommentIcon from '@mui/icons-material/CommentOutlined';
      3 import { Button } from '@mui/material';
      4 import { alpha, styled } from '@mui/material/styles';
      5 import { useAtomValue } from 'jotai';
      6 
      7 import useMySubject from 'client/hooks/useMySubject';
      8 
      9 import { gradeClassAtom } from '../../atoms';
     10 import useNote from '../../hooks/useNote';
     11 import useSpecialChange from '../../hooks/useSpecialChange';
     12 
     13 import BasisChip from './BasisChip';
     14 import DetailDialog from './DetailDialog';
     15 
     16 import type { Basis } from '../../types';
     17 import type { Course, DayPeriodJa, GradeClass, SchoolTime } from 'common/types';
     18 
     19 const ListItem = styled('li')(({ theme }) => ({
     20 	marginBottom: theme.spacing(1),
     21 	'&:last-child': { marginBottom: 0 },
     22 }));
     23 
     24 const PeriodSpan = styled('span')({
     25 	display: 'inline-block',
     26 	width: '1em',
     27 });
     28 const LessonSpan = styled('span')({
     29 	display: 'inline-block',
     30 	whiteSpace: 'nowrap',
     31 	flexGrow: 1,
     32 	overflowX: 'hidden',
     33 	textOverflow: 'ellipsis',
     34 });
     35 
     36 type LessonNameWithMySubjectProps = {
     37 	subjects: readonly string[];
     38 	gradeClass: GradeClass;
     39 	dayPeriod: DayPeriodJa;
     40 };
     41 
     42 function LessonNameWithMySubject({
     43 	gradeClass,
     44 	dayPeriod,
     45 	subjects,
     46 }: LessonNameWithMySubjectProps) {
     47 	const [mySubject] = useMySubject({ gradeClass, dayPeriod });
     48 	return <>{mySubject ?? subjects.join('/')}</>;
     49 }
     50 
     51 type Props = {
     52 	date: Date;
     53 	period: SchoolTime;
     54 	courses: Course[];
     55 	basis: Basis | null;
     56 };
     57 
     58 // TODO: refactor
     59 export default function Lesson({ date, period, courses, basis }: Props) {
     60 	const gradeClass = useAtomValue(gradeClassAtom);
     61 	const [open, handlers] = useDisclosure(false);
     62 
     63 	const shortNames = courses.map((c) => c.shortName);
     64 
     65 	const [specialChangeSubject] = useSpecialChange({
     66 		gradeClass,
     67 		date,
     68 		period,
     69 	});
     70 	const [note] = useNote({ gradeClass, date, period });
     71 
     72 	return (
     73 		<ListItem>
     74 			<Button
     75 				sx={(theme) => ({
     76 					[theme.breakpoints.up('xs')]: { fontSize: 24, px: 1 },
     77 					[theme.breakpoints.up('sm')]: { fontSize: 28, px: 2 },
     78 					padding: 0,
     79 					textAlign: 'left',
     80 					fontWeight: 'unset',
     81 					color: 'unset',
     82 					[theme.getColorSchemeSelector('light')]: {
     83 						backgroundColor: courses.length
     84 							? alpha(theme.palette.primary.light, 0.15)
     85 							: 'inherit',
     86 					},
     87 					[theme.getColorSchemeSelector('dark')]: {
     88 						backgroundColor: courses.length
     89 							? alpha(theme.palette.primary.dark, 0.4)
     90 							: 'inherit',
     91 					},
     92 					width: '100%',
     93 					textTransform: 'none',
     94 					flexDirection: 'row',
     95 					alignItems: 'center',
     96 					gap: 1,
     97 					overflow: 'clip',
     98 				})}
     99 				variant='text'
    100 				onClick={handlers.open}
    101 			>
    102 				<PeriodSpan>{period}.</PeriodSpan>
    103 				<LessonSpan>
    104 					{(() => {
    105 						if (specialChangeSubject) {
    106 							return specialChangeSubject;
    107 						} else if (gradeClass && basis?.type === 'dayPeriod') {
    108 							return (
    109 								<LessonNameWithMySubject
    110 									dayPeriod={basis.dayPeriod}
    111 									gradeClass={gradeClass}
    112 									subjects={shortNames}
    113 								/>
    114 							);
    115 						} else {
    116 							return shortNames.join('/');
    117 						}
    118 					})()}
    119 				</LessonSpan>
    120 
    121 				{note !== '' && <CommentIcon fontSize='small' />}
    122 
    123 				{specialChangeSubject ? (
    124 					<BasisChip data={{ type: 'temporary' }} date={date} period={period} />
    125 				) : (
    126 					basis && <BasisChip data={basis} date={date} period={period} />
    127 				)}
    128 			</Button>
    129 
    130 			<DetailDialog
    131 				open={open}
    132 				handleClose={handlers.close}
    133 				date={date}
    134 				period={period}
    135 				courses={courses}
    136 				basis={basis}
    137 			/>
    138 		</ListItem>
    139 	);
    140 }