commit 0e2118ac37f6d5e8bc0dc111d6fc9279f7670b9e
parent 1d4f29a482295539a7149d3404a3fafc73e30ee0
Author: Yuukin256 <52195426+Yuukin256@users.noreply.github.com>
Date: Sun, 7 Apr 2024 23:20:59 +0900
「今日の時間割」「明日の時間割」ボタンを実装 (#39)
Diffstat:
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>
);