Skip to content

Commit 3bbd549

Browse files
authored
feat: 이벤트 생성 시간 방식 추가 (#266)
2 parents 2ab440f + 9d5d21e commit 3bbd549

File tree

3 files changed

+174
-57
lines changed

3 files changed

+174
-57
lines changed

service-manager/src/components/setting/SettingCreateTime.tsx

Lines changed: 76 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1-
import { Dispatch, useState } from 'react';
1+
import { ChangeEvent, Dispatch, useState, type SetStateAction } from 'react';
22
import DatePicker, { registerLocale, setDefaultLocale } from 'react-datepicker';
33
import { Button, InputText, Txt } from '@quokka/design-system';
44
import { ko } from 'date-fns/locale';
55

66
import 'react-datepicker/dist/react-datepicker.css';
77
import './DateTime.css';
88
import { useSectionTimeSettingCreate } from '../../hooks/react-query/useSectionTimeSetting';
9-
import { getFormalDateBy, isPastTime } from '../../functions/date';
10-
import { SetStateAction } from 'jotai';
9+
import {
10+
getFormalDateBy,
11+
isValidDate,
12+
isValidTime,
13+
} from '../../functions/date';
1114

1215
registerLocale('ko', ko);
1316
setDefaultLocale('ko');
@@ -28,14 +31,75 @@ const DateTimePicker = ({ date, setDate, title }: SettingTimeProps) => {
2831
const selectedHour = date.getHours().toString().padStart(2, '0');
2932
const selectedMinute = date.getMinutes().toString().padStart(2, '0');
3033

34+
const onHourChange = (e: ChangeEvent<HTMLInputElement>) => {
35+
const newHour = e.target.value;
36+
37+
if (!isValidTime(newHour)) {
38+
return alert('숫자만 입력 가능합니다.');
39+
}
40+
41+
if (Number(newHour) > 23) {
42+
return alert('유효한 시간이 아닙니다.');
43+
}
44+
45+
if (newHour !== selectedHour) {
46+
setDate(
47+
new Date(
48+
selectedYear,
49+
Number(selectedMonth) - 1,
50+
Number(selectedDay),
51+
Number(newHour),
52+
Number(selectedMinute),
53+
),
54+
);
55+
}
56+
};
57+
58+
const onMinuteChange = (e: ChangeEvent<HTMLInputElement>) => {
59+
const newMinute = e.target.value;
60+
61+
if (!isValidTime(newMinute)) {
62+
return alert('숫자만 입력 가능합니다.');
63+
}
64+
65+
if (Number(newMinute) > 59) {
66+
return alert('유효한 시간이 아닙니다.');
67+
}
68+
69+
if (newMinute !== selectedMinute) {
70+
setDate(
71+
new Date(
72+
selectedYear,
73+
Number(selectedMonth) - 1,
74+
Number(selectedDay),
75+
Number(selectedHour),
76+
Number(newMinute),
77+
),
78+
);
79+
}
80+
};
81+
3182
return (
3283
<div className="flex flex-col gap-4 flex-1 min-w-[25rem]">
3384
<Txt size="h3">{title}</Txt>
34-
<Txt
35-
size="h4"
36-
color="white"
37-
className="text-center p-4 bg-[linear-gradient(91deg,#0255D5_12.84%,#9CBBFF_104.56%)] rounded-md"
38-
>{`${selectedYear} : ${selectedMonth} : ${selectedDay} / ${selectedHour} : ${selectedMinute}`}</Txt>
85+
<div className="text-center p-4 bg-[linear-gradient(91deg,#0255D5_12.84%,#9CBBFF_104.56%)] rounded-md">
86+
<Txt size="h4" color="white">
87+
{`${selectedYear} : ${selectedMonth} : ${selectedDay} / `}
88+
</Txt>
89+
<input
90+
className="text-2xl font-semibold w-7 text-white bg-transparent"
91+
value={selectedHour}
92+
onChange={onHourChange}
93+
/>
94+
<Txt size="h4" color="white" className="pl-2 pr-2">
95+
:
96+
</Txt>
97+
<input
98+
className="text-2xl font-semibold w-7 text-white bg-transparent"
99+
value={selectedMinute}
100+
onChange={onMinuteChange}
101+
/>
102+
</div>
39103
<div className="flex justify-center">
40104
<DatePicker
41105
selected={date}
@@ -61,15 +125,7 @@ export const SettingCreateTime = () => {
61125
return;
62126
}
63127

64-
if (isPastTime(openDate)) {
65-
alert('OPEN 시간을 현재 시간보다 이전 시간으로 설정할 수 없습니다.');
66-
return;
67-
}
68-
69-
if (isPastTime(endDate)) {
70-
alert('CLOSE 시간을 현재 시간보다 이전 시간으로 설정할 수 없습니다.');
71-
return;
72-
}
128+
if (!isValidDate(openDate, endDate)) return;
73129

74130
createSettingTime({
75131
startAt: openDate,
@@ -79,18 +135,9 @@ export const SettingCreateTime = () => {
79135
};
80136

81137
const onSetCreateTime =
82-
(
83-
predicate: (date: Date) => boolean,
84-
errMsg: string,
85-
setDate: Dispatch<SetStateAction<Date>>,
86-
setDateType: 'open' | 'close',
87-
) =>
138+
(setDate: Dispatch<SetStateAction<Date>>, setDateType: 'open' | 'close') =>
88139
(date: Date | null) => {
89140
if (!date) return;
90-
if (predicate(date)) {
91-
alert(errMsg);
92-
return;
93-
}
94141
setDate(date);
95142
if (setDateType === 'open' && date > endDate) {
96143
setEndDate(date);
@@ -112,22 +159,12 @@ export const SettingCreateTime = () => {
112159
<div className="flex justify-around gap-8">
113160
<DateTimePicker
114161
date={openDate}
115-
setDate={onSetCreateTime(
116-
isPastTime,
117-
'현재 시간보다 이전 시간으로 설정할 수 없습니다.',
118-
setOpenDate,
119-
'open',
120-
)}
162+
setDate={onSetCreateTime(setOpenDate, 'open')}
121163
title="Open"
122164
/>
123165
<DateTimePicker
124166
date={endDate}
125-
setDate={onSetCreateTime(
126-
isPastTime,
127-
'현재 시간보다 이전 시간으로 설정할 수 없습니다.',
128-
setEndDate,
129-
'close',
130-
)}
167+
setDate={onSetCreateTime(setEndDate, 'close')}
131168
title="Close"
132169
/>
133170
</div>

service-manager/src/components/setting/SettingTime.tsx

Lines changed: 75 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect, useState } from 'react';
1+
import { ChangeEvent, useEffect, useState } from 'react';
22
import DatePicker, { registerLocale, setDefaultLocale } from 'react-datepicker';
33
import { Button, InputText, Txt } from '@quokka/design-system';
44
import { ko } from 'date-fns/locale';
@@ -12,7 +12,7 @@ import {
1212
useSettingPublishMutateBy,
1313
useSettingPublishQueryBy,
1414
} from '../../hooks/react-query/useSetting';
15-
import { isPastTime } from '../../functions/date';
15+
import { isValidDate, isValidTime } from '../../functions/date';
1616

1717
registerLocale('ko', ko);
1818
setDefaultLocale('ko');
@@ -33,14 +33,75 @@ const DateTimePicker = ({ date, setDate, title }: SettingTimeProps) => {
3333
const selectedHour = date.getHours().toString().padStart(2, '0');
3434
const selectedMinute = date.getMinutes().toString().padStart(2, '0');
3535

36+
const onHourChange = (e: ChangeEvent<HTMLInputElement>) => {
37+
const newHour = e.target.value;
38+
39+
if (!isValidTime(newHour)) {
40+
return alert('숫자만 입력 가능합니다.');
41+
}
42+
43+
if (Number(newHour) > 23) {
44+
return alert('유효한 시간이 아닙니다.');
45+
}
46+
47+
if (newHour !== selectedHour) {
48+
setDate(
49+
new Date(
50+
selectedYear,
51+
Number(selectedMonth) - 1,
52+
Number(selectedDay),
53+
Number(newHour),
54+
Number(selectedMinute),
55+
),
56+
);
57+
}
58+
};
59+
60+
const onMinuteChange = (e: ChangeEvent<HTMLInputElement>) => {
61+
const newMinute = e.target.value;
62+
63+
if (!isValidTime(newMinute)) {
64+
return alert('숫자만 입력 가능합니다.');
65+
}
66+
67+
if (Number(newMinute) > 59) {
68+
return alert('유효한 시간이 아닙니다.');
69+
}
70+
71+
if (newMinute !== selectedMinute) {
72+
setDate(
73+
new Date(
74+
selectedYear,
75+
Number(selectedMonth) - 1,
76+
Number(selectedDay),
77+
Number(selectedHour),
78+
Number(newMinute),
79+
),
80+
);
81+
}
82+
};
83+
3684
return (
3785
<div className="flex flex-col gap-4 flex-1 min-w-[25rem]">
3886
<Txt size="h3">{title}</Txt>
39-
<Txt
40-
size="h4"
41-
color="white"
42-
className="text-center p-4 bg-[linear-gradient(91deg,#0255D5_12.84%,#9CBBFF_104.56%)] rounded-md"
43-
>{`${selectedYear} : ${selectedMonth} : ${selectedDay} / ${selectedHour} : ${selectedMinute}`}</Txt>
87+
<div className="text-center p-4 bg-[linear-gradient(91deg,#0255D5_12.84%,#9CBBFF_104.56%)] rounded-md">
88+
<Txt size="h4" color="white">
89+
{`${selectedYear} : ${selectedMonth} : ${selectedDay} / `}
90+
</Txt>
91+
<input
92+
className="text-2xl font-semibold w-7 text-white bg-transparent"
93+
value={selectedHour}
94+
onChange={onHourChange}
95+
/>
96+
<Txt size="h4" color="white" className="pl-2 pr-2">
97+
:
98+
</Txt>
99+
<input
100+
className="text-2xl font-semibold w-7 text-white bg-transparent"
101+
value={selectedMinute}
102+
onChange={onMinuteChange}
103+
/>
104+
</div>
44105
<div className="flex justify-center">
45106
<DatePicker
46107
selected={date}
@@ -125,12 +186,9 @@ export const SettingTime = ({ eventId }: { eventId: string }) => {
125186
<DateTimePicker
126187
date={openDate}
127188
setDate={(date) => {
128-
if (event.eventStatus === 'CLOSED') return;
189+
if (event.eventStatus === 'CLOSED')
190+
return alert('종료된 이벤트는 수정할 수 없습니다.');
129191
if (!date) return;
130-
if (isPastTime(date)) {
131-
alert('현재 시간보다 이전 시간으로 설정할 수 없습니다.');
132-
return;
133-
}
134192
setOpenDate(date);
135193
if (date > endDate) setEndDate(date);
136194
}}
@@ -139,13 +197,9 @@ export const SettingTime = ({ eventId }: { eventId: string }) => {
139197
<DateTimePicker
140198
date={endDate}
141199
setDate={(date) => {
142-
if (event.eventStatus === 'CLOSED') return;
200+
if (event.eventStatus === 'CLOSED')
201+
return alert('종료된 이벤트는 수정할 수 없습니다.');
143202
if (!date) return;
144-
if (date < openDate) return;
145-
if (isPastTime(date)) {
146-
alert('현재 시간보다 이전 시간으로 설정할 수 없습니다.');
147-
return;
148-
}
149203
setEndDate(date);
150204
}}
151205
title="Close"
@@ -160,6 +214,9 @@ export const SettingTime = ({ eventId }: { eventId: string }) => {
160214
alert('제목을 입력해주세요.');
161215
return;
162216
}
217+
218+
if (!isValidDate(openDate, endDate)) return;
219+
163220
updateSettingTime({
164221
startAt: openDate,
165222
endAt: endDate,

service-manager/src/functions/date.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,26 @@ export const getFormalDateBy = (time: Date) => {
2121
export const isPastTime = (date: Date) => {
2222
return Date.now() > date.getTime();
2323
};
24+
25+
export const isValidDate = (openDate: Date, endDate: Date) => {
26+
if (isPastTime(openDate)) {
27+
alert('OPEN 시간을 현재 시간보다 이후로 설정해야 합니다.');
28+
return false;
29+
}
30+
31+
if (isPastTime(endDate)) {
32+
alert('CLOSE 시간을 현재 시간보다 이후로 설정해야 합니다.');
33+
return false;
34+
}
35+
36+
if (openDate >= endDate) {
37+
alert('CLOSE 시간을 OPEN 시간보다 이후로 설정해야 합니다.');
38+
return false;
39+
}
40+
41+
return true;
42+
};
43+
44+
export const isValidTime = (time: string) => {
45+
return !isNaN(Number(time));
46+
};

0 commit comments

Comments
 (0)