timetable-app

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

commit 0e2118ac37f6d5e8bc0dc111d6fc9279f7670b9e
parent 1d4f29a482295539a7149d3404a3fafc73e30ee0
Author: Yuukin256 <52195426+Yuukin256@users.noreply.github.com>
Date:   Sun,  7 Apr 2024 23:20:59 +0900

「今日の時間割」「明日の時間割」ボタンを実装 (#39)


Diffstat:
Asrc/client/features/daily/components/JumpToTodayFab.tsx | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/client/features/daily/components/SetMyClassFab.tsx | 7+++----
Msrc/client/features/daily/index.tsx | 28++++++++++++++++++++++++----
3 files changed, 95 insertions(+), 8 deletions(-)

diff --git a/src/client/features/daily/components/JumpToTodayFab.tsx b/src/client/features/daily/components/JumpToTodayFab.tsx @@ -0,0 +1,68 @@ +import { Fab, Zoom } from '@mui/material'; +import { addDays, isFuture, set } from 'date-fns'; + +import formatDate from 'common/utils/formatDate'; + +import type { Dispatch, SetStateAction } from 'react'; + +type Props = { + index: number; + dateStrings: string[]; + setIndex: Dispatch<SetStateAction<number>>; +}; + +export default function JumpToTodayFab({ + index, + dateStrings, + setIndex, +}: Props) { + let type: 'today' | 'tomorrow' | null = null; + let targetDate: Date; + + // 16時以前なら当日、16時以降なら翌日 + const todays16hour = set(new Date(), { + hours: 16, + minutes: 0, + seconds: 0, + }); + if (isFuture(todays16hour)) { + // 16時以前 + type = 'today'; + targetDate = new Date(); + } else { + // 16時以降 + type = 'tomorrow'; + targetDate = addDays(new Date(), 1); + } + + const targetIndex = dateStrings.indexOf(formatDate(targetDate)); + + if (targetIndex === -1) { + return; + } + + const handleClick = () => setIndex(targetIndex); + + return ( + <Zoom in={index !== targetIndex}> + <Fab + onClick={handleClick} + color='primary' + variant='extended' + size='large' + sx={{ + position: 'absolute', + right: 0, + bottom: 0, + p: 2, + lineHeight: 1.3, + width: 'fit-content', + }} + > + {type === 'today' ? <>今日</> : <>明日</>}の + <br /> + 時間割 + </Fab> + </Zoom> + ); +} diff --git a/src/client/features/daily/components/SetMyClassFab.tsx b/src/client/features/daily/components/SetMyClassFab.tsx @@ -40,10 +40,9 @@ export default function SetMyClassFab() { variant='extended' size='medium' sx={{ - position: 'sticky', - bottom: 16, - marginLeft: 'auto', - marginRight: '16px', + position: 'absolute', + left: 0, + bottom: 0, width: 'fit-content', }} > diff --git a/src/client/features/daily/index.tsx b/src/client/features/daily/index.tsx @@ -6,6 +6,7 @@ import { Swiper, SwiperSlide } from 'swiper/react'; import { classAtom, gradeAtom } from './atoms'; import DatePicker from './components/DatePicker'; +import JumpToTodayFab from './components/JumpToTodayFab'; import Lessons from './components/Lessons'; import SetMyClassFab from './components/SetMyClassFab'; import useIndexAndDate from './hooks/useIndexAndDate'; @@ -26,11 +27,16 @@ type Props = { // TODO: jotai atom でデータ受け渡し export default function DailyView(props: Props) { - const [swiper, setSwiper] = useState<SwiperClass>(); - const { dates, index, setDate, setIndex } = useIndexAndDate( - useMemo(() => props.calendar.map(([date]) => date), [props.calendar]) + const dateStrings = useMemo( + () => props.calendar.map(([date]) => date), + [props.calendar], ); + const [swiper, setSwiper] = useState<SwiperClass>(); + + const { dates, index, setDate, setIndex } = useIndexAndDate(dateStrings); + const [initialIndex] = useState(index); + const handleSlideChange = (swiper: SwiperClass) => setIndex(swiper.activeIndex); @@ -77,7 +83,21 @@ export default function DailyView(props: Props) { )} </Box> - <SetMyClassFab /> + <Box + sx={{ + position: 'sticky', + bottom: 16, + marginLeft: '16px', + marginRight: '16px', + }} + > + <JumpToTodayFab + dateStrings={dateStrings} + index={index} + setIndex={setIndex} + /> + <SetMyClassFab /> + </Box> </Stack> </Provider> );