timetable-app

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

useIndexAndDate.ts (1866B)


      1 import { addDays, isFuture, set } from 'date-fns';
      2 import { useCallback, useMemo, useState } from 'react';
      3 
      4 import { DATE_FORMAT } from 'common/constant';
      5 import formatDate from 'common/utils/formatDate';
      6 
      7 type BaseReturn = {
      8 	index: number;
      9 	date: Date | null;
     10 	dates: Date[];
     11 	setDate: (d: Date) => void;
     12 	setIndex: React.Dispatch<React.SetStateAction<number>>;
     13 };
     14 
     15 type Return = BaseReturn;
     16 
     17 const useIndexAndDate = (dateStrings: string[]): Return => {
     18 	const size = dateStrings.length;
     19 	const dates = useMemo(
     20 		() => dateStrings.map((v) => new Date(v)),
     21 		[dateStrings],
     22 	);
     23 
     24 	// 初期設定の日付: 16時以前なら当日; 16時以降なら翌日; その日の時間割がなければ最も近い未来の日付; 未来がなければ最も新しい日付
     25 	const [index, setIndex] = useState<number>(() => {
     26 		// 1. 16時以前なら当日、16時以降なら翌日
     27 		{
     28 			const todays16hour = set(new Date(), {
     29 				hours: 16,
     30 				minutes: 0,
     31 				seconds: 0,
     32 			});
     33 			const initialDate = isFuture(todays16hour)
     34 				? new Date() // 16時以前
     35 				: addDays(new Date(), 1); // 16時以降
     36 			const i = dateStrings.indexOf(formatDate(initialDate, DATE_FORMAT));
     37 			if (i !== -1) {
     38 				return i;
     39 			}
     40 		}
     41 
     42 		// 2. 最も近い未来の日付
     43 		{
     44 			const i = dateStrings.findIndex((v) => isFuture(new Date(v)));
     45 			if (i !== -1) {
     46 				return i;
     47 			}
     48 		}
     49 
     50 		// 3. 最も新しい(過去の)日付
     51 		return size - 1;
     52 	});
     53 
     54 	const dateString = dateStrings[index];
     55 	const date = useMemo(
     56 		() => (dateString ? new Date(dateString) : null),
     57 		[dateString],
     58 	);
     59 
     60 	const setDate = useCallback(
     61 		(d: Date) => {
     62 			const newIndex = dateStrings.indexOf(formatDate(d, DATE_FORMAT));
     63 			if (newIndex !== -1) {
     64 				setIndex(newIndex);
     65 			}
     66 		},
     67 		[dateStrings],
     68 	);
     69 
     70 	return {
     71 		index,
     72 		date,
     73 		dates,
     74 		setDate,
     75 		setIndex,
     76 	};
     77 };
     78 
     79 export default useIndexAndDate;