Skip to content

Commit 3d994e7

Browse files
authored
feat(mobile): 날짜 선택 시, 지난 날짜를 선택할 수 없도록 제한합니다. (#124)
1 parent 68a1302 commit 3d994e7

File tree

3 files changed

+65
-13
lines changed

3 files changed

+65
-13
lines changed

apps/mobile/components/select-date/SelectDateCalendar.tsx

+11-9
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
import { MobileIconArrowLeftGray, MobileIconArrowRightGray } from "@setaday/icon";
44
import { useState } from "react";
5-
import { DAY, MAX_DATE, MONTH_NAMES } from "../../constants/selectDateConst";
5+
import { DAY, MAX_DATE, MONTH_NAMES, TODAYS_MONTH, TODAYS_YEAR } from "../../constants/selectDateConst";
66
import type { ClickDateProps, SelctDateCalendarProps, SelectedDateType } from "../../type/selectedDateType";
77
import { getCalendarDate } from "../../utils/getCalendarDate";
88

99
function SelectDateCalendar({ selectedDateNum, selectedDate, handleSelectDate }: SelctDateCalendarProps) {
10-
const [year, setYear] = useState(new Date().getFullYear());
11-
const [month, setMonth] = useState(new Date().getMonth() + 1);
10+
const [year, setYear] = useState(TODAYS_YEAR);
11+
const [month, setMonth] = useState(TODAYS_MONTH);
1212

1313
const ALL_DATE = getCalendarDate({ year, month });
1414

@@ -249,8 +249,9 @@ function SelectDateCalendar({ selectedDateNum, selectedDate, handleSelectDate }:
249249

250250
<div className="grid grid-cols-7 grid-rows-5 gap-y-[1.8rem]">
251251
{ALL_DATE.map(({ id, date, color }) =>
252-
date.map((curDate) => {
253-
const isActiveClick = id === "currentDate";
252+
date.map((curDate, idx) => {
253+
const isActiveClick = id === "validDate";
254+
254255
const idxOfStartDate = selectedDate.findIndex(
255256
({ startDate, startMonth, startYear }) =>
256257
startDate === curDate && startMonth === month && startYear === year
@@ -286,10 +287,11 @@ function SelectDateCalendar({ selectedDateNum, selectedDate, handleSelectDate }:
286287
const isRightSelection = !!(matchedObj && matchedObj.endDate > 0 && matchedObj.startDate > 0);
287288

288289
return (
289-
// biome-ignore lint/a11y/useKeyWithClickEvents: <explanation>
290-
<div
291-
key={id + curDate}
290+
<button
291+
// biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
292+
key={id + curDate + idx}
292293
className="flex items-center justify-center relative"
294+
type="button"
293295
onClick={() =>
294296
isActiveClick &&
295297
!isInRange &&
@@ -315,7 +317,7 @@ function SelectDateCalendar({ selectedDateNum, selectedDate, handleSelectDate }:
315317
>
316318
{curDate}
317319
</p>
318-
</div>
320+
</button>
319321
);
320322
})
321323
)}

apps/mobile/constants/selectDateConst.ts

+4
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,7 @@ export const MONTH_NAMES = [
1818
"November",
1919
"December",
2020
];
21+
22+
export const TODAYS_YEAR = new Date().getFullYear();
23+
export const TODAYS_MONTH = new Date().getMonth() + 1;
24+
export const TODAYS_DATE = new Date().getDate();

apps/mobile/utils/getCalendarDate.ts

+50-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { TODAYS_DATE, TODAYS_MONTH } from "../constants/selectDateConst";
2+
import { TODAYS_YEAR } from "./../constants/selectDateConst";
3+
14
export const getCalendarDate = ({
25
year,
36
month,
@@ -14,20 +17,63 @@ export const getCalendarDate = ({
1417
// 지난 달 마지막 날짜
1518
const lastEndDate = new Date(year, month - 1, 0).getDate();
1619

20+
const isCurrentMonth = year === TODAYS_YEAR && month === TODAYS_MONTH;
21+
const isPastYear = year < TODAYS_YEAR;
22+
const isFutureYear = year > TODAYS_YEAR;
23+
const isPastMonthsOfThisYear = year === TODAYS_YEAR && month < TODAYS_MONTH;
24+
const isFutureMonthsOfThisYear = year === TODAYS_YEAR && month > TODAYS_MONTH;
25+
1726
const DATE = Array.from({ length: endDate }, (_, idx) => idx + 1);
18-
const LAST_DATE = Array.from({ length: startDay }, (_, idx) => lastEndDate - (startDay - idx - 1));
19-
const NEXT_DATE = Array.from({ length: nextStartDay === 0 ? 0 : 7 - nextStartDay }, (_, idx) => idx + 1);
27+
28+
// 선택 제한 날짜
29+
const INVALID_DATE = DATE.filter((date) => {
30+
// 이번 년도, 이번 달의 경우 오늘의 날짜보다 작은 날짜는 선택 불가
31+
if (isCurrentMonth) {
32+
return date < TODAYS_DATE;
33+
}
34+
35+
// 지난 년도 || 이번 년도의 지난 달의 경우, 모든 날짜 선택 불가
36+
if (isPastYear || isPastMonthsOfThisYear) {
37+
return date;
38+
}
39+
});
40+
41+
// 선택 가능 날짜
42+
const VALID_DATE = DATE.filter((date) => {
43+
// 이번 년도, 이번 달의 경우 오늘의 날짜보다 크거나 같은 날짜 선택 가능
44+
if (isCurrentMonth) {
45+
return date >= TODAYS_DATE;
46+
}
47+
48+
// 다음 년도 || 이번 년도의 이후 달의 경우, 모든 날짜 선택 가능
49+
if (isFutureYear || isFutureMonthsOfThisYear) {
50+
return date;
51+
}
52+
});
53+
54+
// 오늘이 속한 달에 표시해야 할 지난 달의 날짜
55+
const LAST_MONTH_DATE = Array.from({ length: startDay }, (_, idx) => lastEndDate - (startDay - idx - 1));
56+
57+
// 오늘 이전의 모든 날짜 (올해 이하인 경우, 지난 달 날짜와 선택 불가 날짜를 포함 / 내년 이상인 경우 지난 달 날짜만 포함)
58+
const LAST_DATE = year <= TODAYS_YEAR ? [...LAST_MONTH_DATE, ...INVALID_DATE] : LAST_MONTH_DATE;
59+
60+
// 오늘이 속한 달에 표시해야 할 다음 달의 날짜
61+
const NEXT_MONTH_DATE = Array.from({ length: nextStartDay === 0 ? 0 : 7 - nextStartDay }, (_, idx) => idx + 1);
2062

2163
const ALL_DATE = [
2264
{
2365
id: "lastDate",
2466
date: LAST_DATE,
2567
color: "text-gray-4",
2668
},
27-
{ id: "currentDate", date: DATE, color: "text-gray-6" },
69+
{
70+
id: "validDate",
71+
date: VALID_DATE,
72+
color: "text-gray-6",
73+
},
2874
{
2975
id: "nextDate",
30-
date: NEXT_DATE,
76+
date: NEXT_MONTH_DATE,
3177
color: "text-gray-4",
3278
},
3379
];

0 commit comments

Comments
 (0)