diff --git a/src/components/calendar/Calendar.jsx b/src/components/calendar/Calendar.jsx index 49343ba..c77fc57 100644 --- a/src/components/calendar/Calendar.jsx +++ b/src/components/calendar/Calendar.jsx @@ -1,7 +1,36 @@ import { CalendarMonthSelector } from "./CalendarMonthSelector"; import { CalendarGrid } from "./CalendarGrid"; +import { useCalendarStore } from "../../stores/CalendarStore"; +import { useEffect } from "react"; +import { useSearchParams } from "react-router-dom"; export const Calendar = () => { + const [searchParams, setQuery] = useSearchParams(); + const query = Object.fromEntries(searchParams.entries()); + const { selectedDate, setSelectedDate } = useCalendarStore((state) => state); + + // 초기 선택된 날짜가 쿼리로 들어왔을 때 + useEffect(() => { + const { year, month, day } = query; + if (!year || !month || !day) return; + + setSelectedDate({ + year: parseInt(year), + month: parseInt(month), + day: parseInt(day), + }); + }, []); + + // 날짜를 선택 할때 마다 쿼리를 변경 + useEffect(() => { + setQuery( + { ...selectedDate }, + { + replace: true, + } + ); + }, [selectedDate]); + return ( <> diff --git a/src/components/calendar/CalendarGrid.jsx b/src/components/calendar/CalendarGrid.jsx index 533dfe1..14e674c 100644 --- a/src/components/calendar/CalendarGrid.jsx +++ b/src/components/calendar/CalendarGrid.jsx @@ -1,6 +1,7 @@ import { CALENDAR_HEADER, getCalendarDaysInMonth, + getNow, isEqualDate, isSaturday, isSunday, @@ -28,26 +29,30 @@ const CalendarHeader = () => { }; const CalenderBody = () => { - let { setSelectedDate, selectedYearMonth } = useCalendarStore( - (state) => state - ); + let { setSelectedDate, selectedDate } = useCalendarStore((state) => state); // 선택된 달의 길이가 42인 날짜 배열 => ["", "" ,1 , 2, ... , "" ] - const days = getCalendarDaysInMonth({ ...selectedYearMonth }); + const days = getCalendarDaysInMonth({ ...selectedDate }); const handleClickCell = (day) => { if (!day) return; setSelectedDate({ - ...selectedYearMonth, + ...selectedDate, day, }); }; + const isCanWriteDiaryDay = (day) => { + const { year, month } = selectedDate; + const { year: nowYear, month: nowMonth, day: nowDay } = getNow(); + return !(year >= nowYear && month >= nowMonth && day > nowDay); + }; + return days.map((day, index) => ( )); }; @@ -68,21 +73,22 @@ const CalendarHeaderCell = ({ index, day, className }) => { ); }; -const CalendarBodyCell = ({ handleClickCell, day, index }) => { - let { selectedDate, selectedYearMonth } = useCalendarStore((state) => state); // 선택된 달의 길이가 42인 날짜 배열 => ["", "" ,1 , 2, ... , "" ] +const CalendarBodyCell = ({ handleClickCell, day, index, isCanWrite }) => { + let { selectedDate } = useCalendarStore((state) => state); // 선택된 달의 길이가 42인 날짜 배열 => ["", "" ,1 , 2, ... , "" ] let { isCanRender, isDiaryExistDay } = useFetchDiaryChecks(); const isSelectedCell = (day) => { return isEqualDate(selectedDate, { - ...selectedYearMonth, + ...selectedDate, day, }); }; return ( -
+
isCanWrite && handleClickCell(day)} className={ "relative flex justify-center w-16 h-16 mobile:w-10 mobile:h-10" } @@ -90,9 +96,7 @@ const CalendarBodyCell = ({ handleClickCell, day, index }) => { {!isCanRender && } {isCanRender && ( <> - + { ); }; -const CellWithCircle = ({ day, index, isSelectedCell, handleClickCell }) => { +const CellWithCircle = ({ day, index, isSelectedCell }) => { return (
handleClickCell(day)} className={`flex flex-col justify-center aspect-square items-center rounded-full cursor-pointer px-1 ${isSunday(index) && "text-red-600"} ${isSaturday(index) && "text-blue-600"} @@ -122,7 +125,7 @@ const CellWithCircle = ({ day, index, isSelectedCell, handleClickCell }) => { const Dot = ({ isVisible, isSelected }) => { return ( ); }; diff --git a/src/components/calendar/CalendarMonthSelector.jsx b/src/components/calendar/CalendarMonthSelector.jsx index 13e2533..1d07a0b 100644 --- a/src/components/calendar/CalendarMonthSelector.jsx +++ b/src/components/calendar/CalendarMonthSelector.jsx @@ -1,19 +1,30 @@ import { IoIosArrowBack, IoIosArrowForward } from "react-icons/io"; -import { getNextYearMonth, getPreYearMonth } from "../../utils/calendar/date"; +import { + getNextYearMonth, + getNow, + getPreYearMonth, +} from "../../utils/calendar/date"; import { useCalendarStore } from "../../stores/CalendarStore"; import { yearMonthToKoreanString } from "../../utils/api/dateConverter"; export const CalendarMonthSelector = () => { - let { selectedYearMonth, setSelectedYearMonth } = useCalendarStore( - (state) => state - ); + let { selectedDate, setSelectedDate } = useCalendarStore((state) => state); + + const { year: nextYear, month: nextMonth } = getNextYearMonth(selectedDate); + const { year: nowYear, month: nowMonth } = getNow(); + const isCanGoNextMonth = + nextYear < nowYear || (nextYear === nowYear && nextMonth <= nowMonth); const goPreMonth = () => { - setSelectedYearMonth(getPreYearMonth(selectedYearMonth)); + setSelectedDate({ ...getPreYearMonth(selectedDate), day: 1 }); }; const goNextMonth = () => { - setSelectedYearMonth(getNextYearMonth(selectedYearMonth)); + if (!isCanGoNextMonth) return; + + const { year: nextYear, month: nextMonth } = getNextYearMonth(selectedDate); + + setSelectedDate({ year: nextYear, month: nextMonth, day: 1 }); }; return ( @@ -32,11 +43,11 @@ export const CalendarMonthSelector = () => { "font-bold flex justify-center items-center text-nowrap w-0" } > - {yearMonthToKoreanString(selectedYearMonth)} + {yearMonthToKoreanString(selectedDate)}
diff --git a/src/hooks/diary/queries/useFetchDiaryChecks.js b/src/hooks/diary/queries/useFetchDiaryChecks.js index bf8e6f9..4e562c4 100644 --- a/src/hooks/diary/queries/useFetchDiaryChecks.js +++ b/src/hooks/diary/queries/useFetchDiaryChecks.js @@ -14,18 +14,20 @@ import useRequireAuth from "../../auth/useRequireAuth"; * }} */ const useFetchDiaryChecks = () => { - let { selectedDate, selectedYearMonth } = useCalendarStore((state) => state); + let { selectedDate } = useCalendarStore((state) => state); + const { year, month } = selectedDate; const { userId, isLogin } = useRequireAuth(); let { isFetching, isSuccess, data: diaryChecks, } = useQuery({ - queryKey: diaryCheckQueryKey(selectedYearMonth), + queryKey: diaryCheckQueryKey({ year, month }), queryFn: async () => { const response = await DiaryController.findCheckDiaries({ userId, - ...selectedYearMonth, + year, + month, }); return response.data.result; }, @@ -36,7 +38,7 @@ const useFetchDiaryChecks = () => { const isCanRender = !isFetching && isSuccess; const isDiaryExistDay = (day) => { - return diaryChecks?.[yearMonthToDashString({ ...selectedYearMonth })]?.[day] + return diaryChecks?.[yearMonthToDashString({ year, month })]?.[day] ?.isExist; }; @@ -51,8 +53,7 @@ const useFetchDiaryChecks = () => { }; }; -export const diaryCheckQueryKey = (selectedYearMonth) => { - const { year, month } = selectedYearMonth; +export const diaryCheckQueryKey = ({ year, month }) => { return ["diary", year, month]; }; diff --git a/src/hooks/diaryDetail/queries/useCreateDiary.js b/src/hooks/diaryDetail/queries/useCreateDiary.js index 7ffac03..c005db7 100644 --- a/src/hooks/diaryDetail/queries/useCreateDiary.js +++ b/src/hooks/diaryDetail/queries/useCreateDiary.js @@ -3,7 +3,6 @@ import { useMutation, useQueryClient, } from "@tanstack/react-query"; -import { delay } from "../../../utils/api/delay"; import { diaryCheckQueryKey } from "../../diary/queries/useFetchDiaryChecks"; import { dateToDashString, @@ -15,9 +14,7 @@ import DiaryController from "../../../apis/diary.controller"; import useRequireAuth from "../../auth/useRequireAuth"; const useCreateDiary = () => { - const { selectedDate, selectedYearMonth } = useCalendarStore( - (state) => state - ); + const { selectedDate } = useCalendarStore((state) => state); const { userId } = useRequireAuth(); let queryClient = useQueryClient(); @@ -32,15 +29,12 @@ const useCreateDiary = () => { }); }, onMutate: async (content) => { - queryClient.setQueryData( - diaryCheckQueryKey(selectedYearMonth), - (old) => ({ - [yearMonthToDashString(selectedYearMonth)]: { - ...old[yearMonthToDashString(selectedYearMonth)], - [selectedDate.day]: { isExist: true }, - }, - }) - ); + queryClient.setQueryData(diaryCheckQueryKey(selectedDate), (old) => ({ + [yearMonthToDashString(selectedDate)]: { + ...old[yearMonthToDashString(selectedDate)], + [selectedDate.day]: { isExist: true }, + }, + })); queryClient.setQueryData(diaryQueryKey(selectedDate), (old) => ({ ...old, diff --git a/src/hooks/diaryDetail/queries/useUpdateDiary.js b/src/hooks/diaryDetail/queries/useUpdateDiary.js index ed8a854..ef39a9e 100644 --- a/src/hooks/diaryDetail/queries/useUpdateDiary.js +++ b/src/hooks/diaryDetail/queries/useUpdateDiary.js @@ -4,7 +4,6 @@ import { useMutation, useQueryClient, } from "@tanstack/react-query"; -import { delay } from "../../../utils/api/delay"; import DiaryController from "../../../apis/diary.controller"; import { yearMonthToDashString } from "../../../utils/api/dateConverter"; import { diaryCheckQueryKey } from "../../diary/queries/useFetchDiaryChecks"; @@ -14,9 +13,7 @@ import useFetchDiary, { import useRequireAuth from "../../auth/useRequireAuth"; const useUpdateDiary = () => { - const { selectedDate, selectedYearMonth } = useCalendarStore( - (state) => state - ); + const { selectedDate } = useCalendarStore((state) => state); let queryClient = useQueryClient(); @@ -33,15 +30,12 @@ const useUpdateDiary = () => { }); }, onMutate: async (content) => { - queryClient.setQueryData( - diaryCheckQueryKey(selectedYearMonth), - (old) => ({ - [yearMonthToDashString(selectedYearMonth)]: { - ...old[yearMonthToDashString(selectedYearMonth)], - [selectedDate.day]: { isExist: true }, - }, - }) - ); + queryClient.setQueryData(diaryCheckQueryKey(selectedDate), (old) => ({ + [yearMonthToDashString(selectedDate)]: { + ...old[yearMonthToDashString(selectedDate)], + [selectedDate.day]: { isExist: true }, + }, + })); queryClient.setQueryData(diaryQueryKey(selectedDate), (old) => ({ ...old, diff --git a/src/pages/diarys/Diary.jsx b/src/pages/diarys/Diary.jsx index bc3890b..bf5c7ce 100644 --- a/src/pages/diarys/Diary.jsx +++ b/src/pages/diarys/Diary.jsx @@ -29,7 +29,7 @@ const Diary = () => { }; const useBottomSheetPosition = () => { - let { selectedDate, selectedYearMonth } = useCalendarStore((state) => state); + let { selectedDate } = useCalendarStore((state) => state); const [position, setPosition] = useState(BOTTOM_POSITION); @@ -47,7 +47,7 @@ const useBottomSheetPosition = () => { // 달이 변경되면 BottomSheet 의 위치를 초기화 useEffect(() => { setPosition(BOTTOM_POSITION); - }, [selectedYearMonth]); + }, [selectedDate.month]); return { position, setPosition, isDiaryExistDay }; }; diff --git a/src/pages/mypage/RecentDiaries.js b/src/pages/mypage/RecentDiaries.js index 8b94e6b..0a933f3 100644 --- a/src/pages/mypage/RecentDiaries.js +++ b/src/pages/mypage/RecentDiaries.js @@ -55,7 +55,7 @@ const MonthlyTitle = ({ year, month }) => { }; const DiaryItem = ({ diary }) => { - const { setSelectedYearMonth, setSelectedDate } = useCalendarStore( + const { setSelectedDate } = useCalendarStore( (state) => state ); @@ -65,7 +65,6 @@ const DiaryItem = ({ diary }) => { const [year, month, day] = createDate.split("-").map((i) => Number(i)); const onClick = () => { - setSelectedYearMonth({ year, month }); setSelectedDate({ year, month, day }); navigate(DIARY_PAGE_PATH); }; diff --git a/src/stores/CalendarStore.js b/src/stores/CalendarStore.js index 41875e5..2c02240 100644 --- a/src/stores/CalendarStore.js +++ b/src/stores/CalendarStore.js @@ -5,17 +5,10 @@ const { year, month, day } = getNow(); export const useCalendarStore = create((set) => ({ selectedDate: { year, month, day }, - selectedYearMonth: { year, month }, setSelectedDate: ({ year, month, day }) => { set((state) => ({ selectedDate: { year, month, day }, })); }, - - setSelectedYearMonth: ({ year, month }) => { - set((state) => ({ - selectedYearMonth: { year, month }, - })); - }, })); diff --git a/src/utils/calendar/date.js b/src/utils/calendar/date.js index 725987e..ef12467 100644 --- a/src/utils/calendar/date.js +++ b/src/utils/calendar/date.js @@ -2,8 +2,9 @@ import { range } from "../array/range"; export const CALENDAR_HEADER = ["일", "월", "화", "수", "목", "금", "토"]; +const now = new Date(); + export const getNow = () => { - const now = new Date(); return { year: now.getFullYear(), month: now.getMonth() + 1,