useMyClass.ts (1520B)
1 import { addYears, endOfDay, isFuture, set } from 'date-fns'; 2 import { useCallback, useMemo } from 'react'; 3 import { useCookies } from 'react-cookie'; 4 5 import { DEFAULT_CLASS_COOKIE_KEY } from 'common/constant'; 6 import { zodGradeClass } from 'common/utils/zod'; 7 8 import type { GradeClass } from 'common/types'; 9 10 // 学年終わりの 3月31日を返す 11 const getCookieExpires = (): Date => { 12 const march31thisYear = endOfDay(set(new Date(), { month: 2, date: 31 })); // 3月は month: 2 13 if (isFuture(march31thisYear)) { 14 return march31thisYear; // 今年の3月31日 15 } else { 16 return addYears(march31thisYear, 1); // 翌年の3月31日 17 } 18 }; 19 20 type Return = [GradeClass | null, (update: GradeClass) => void, () => void]; 21 22 const useMyClass = (): Return => { 23 const expires = useMemo(getCookieExpires, []); 24 25 const [cookies, setCookie, removeCookie] = useCookies([ 26 DEFAULT_CLASS_COOKIE_KEY, 27 ]); 28 const gradeClassValidation = zodGradeClass.safeParse(cookies.default_class); 29 30 const setValue = useCallback( 31 (update: GradeClass) => { 32 setCookie(DEFAULT_CLASS_COOKIE_KEY, update, { expires }); 33 }, 34 [expires, setCookie], 35 ); 36 const removeValue = useCallback( 37 () => removeCookie(DEFAULT_CLASS_COOKIE_KEY), 38 [removeCookie], 39 ); 40 41 if (gradeClassValidation.success) { 42 return [gradeClassValidation.data, setValue, removeValue]; 43 } else { 44 if (typeof cookies.default_class !== 'undefined') { 45 removeCookie(DEFAULT_CLASS_COOKIE_KEY); 46 } 47 return [null, setValue, removeValue]; 48 } 49 }; 50 51 export default useMyClass;