timetable-app

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

DatePicker.tsx (2144B)


      1 import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
      2 import ChevronRightIcon from '@mui/icons-material/ChevronRight';
      3 import { Stack, IconButton, Typography } from '@mui/material';
      4 import { isSameDay } from 'date-fns';
      5 import { useCallback } from 'react';
      6 
      7 import IconButtonDatePicker from 'client/components/IconButtonDatePicker';
      8 import formatDate from 'common/utils/formatDate';
      9 
     10 import type { Dispatch, SetStateAction } from 'react';
     11 
     12 type Props = {
     13 	dates: Date[];
     14 	index: number;
     15 	setDate: (d: Date) => void;
     16 	setIndex: Dispatch<SetStateAction<number>>;
     17 };
     18 
     19 export default function DatePickerWithSideButton({
     20 	index,
     21 	dates,
     22 	setIndex,
     23 	setDate,
     24 }: Props) {
     25 	const date = dates[index] ?? new Date();
     26 	const dateString = formatDate(date, 'yyyy/MM/dd (EEEEE)');
     27 
     28 	const handleChange = (d: Date | null) => {
     29 		if (d == null) return;
     30 		setDate(d);
     31 	};
     32 
     33 	const minDate = dates[0];
     34 	const maxDate = dates[dates.length - 1];
     35 	const shouldDisableDate = useCallback(
     36 		(d1: Date) => dates.every((d2) => !isSameDay(d1, d2)),
     37 		[dates],
     38 	);
     39 
     40 	const canSelectToday = !shouldDisableDate(new Date());
     41 
     42 	return (
     43 		<Stack
     44 			direction='row'
     45 			justifyContent='space-between'
     46 			alignItems='center'
     47 			spacing={2}
     48 			width='100%'
     49 			px={2}
     50 		>
     51 			<IconButton
     52 				disabled={index <= 0}
     53 				onClick={() => setIndex((old) => old - 1)}
     54 				title='前の時間割'
     55 			>
     56 				<ChevronLeftIcon />
     57 			</IconButton>
     58 
     59 			<Stack direction='row' spacing={{ xs: 0, sm: 1 }} alignItems='center'>
     60 				<IconButtonDatePicker
     61 					value={date}
     62 					onChange={handleChange}
     63 					minDate={minDate}
     64 					maxDate={maxDate}
     65 					shouldDisableDate={shouldDisableDate}
     66 					showDaysOutsideCurrentMonth
     67 					slotProps={{
     68 						actionBar: {
     69 							actions: canSelectToday
     70 								? ['today', 'cancel', 'accept']
     71 								: ['cancel', 'accept'],
     72 						},
     73 					}}
     74 				/>
     75 				<Typography variant='h2' fontSize={{ xs: 18, sm: 20 }}>
     76 					{dateString}
     77 				</Typography>
     78 			</Stack>
     79 
     80 			<IconButton
     81 				disabled={index >= dates.length - 1}
     82 				onClick={() => setIndex((old) => old + 1)}
     83 				title='次の時間割'
     84 			>
     85 				<ChevronRightIcon />
     86 			</IconButton>
     87 		</Stack>
     88 	);
     89 }