1- import { useState } from 'react' ;
1+ import { useMemo , useState } from 'react' ;
22import { createEvent } from '../api/events' ;
33import type { CreateEventRequest , CreateEventResponse } from '../types' ;
44
@@ -35,10 +35,21 @@ const EventCreateForm = ({ onCreated, onCancel }: Props) => {
3535 } ;
3636
3737 const nowLocal = new Date ( ) ;
38- const minStartLocal = new Date ( nowLocal . getTime ( ) + 60_000 )
38+ // Policy: start can be chosen from 2 days after now.
39+ const minStartLocal = new Date ( nowLocal . getTime ( ) + 2 * 24 * 60 * 60 * 1000 )
3940 . toISOString ( )
4041 . slice ( 0 , 16 ) ;
4142
43+ // Policy: end can be chosen from 1 day after start.
44+ const minEndLocal = useMemo ( ( ) => {
45+ if ( ! startAt ) return '' ;
46+ const s = new Date ( startAt ) ;
47+ if ( Number . isNaN ( s . getTime ( ) ) ) return '' ;
48+ return new Date ( s . getTime ( ) + 24 * 60 * 60 * 1000 )
49+ . toISOString ( )
50+ . slice ( 0 , 16 ) ;
51+ } , [ startAt ] ) ;
52+
4253 const fmtLocal = ( dtLocal : string ) => {
4354 if ( ! dtLocal ) return '' ;
4455 // Convert yyyy-mm-ddThh:mm to a readable label in ko-KR.
@@ -164,9 +175,41 @@ const EventCreateForm = ({ onCreated, onCancel }: Props) => {
164175 // Calculate per-option image index mapping (shared image_files array)
165176 let runningOptImageIndex = optionImageBaseIndex ;
166177
178+ // ===== Date validation per policy =====
179+ if ( ! startAt || ! endAt ) {
180+ throw new Error ( '시작 시각과 종료 시각을 입력해주세요.' ) ;
181+ }
182+ const sLocal = new Date ( startAt ) ;
183+ const eLocal = new Date ( endAt ) ;
184+ if ( Number . isNaN ( sLocal . getTime ( ) ) || Number . isNaN ( eLocal . getTime ( ) ) ) {
185+ throw new Error ( '날짜 형식이 올바르지 않습니다.' ) ;
186+ }
187+
188+ const minStart = new Date ( nowLocal . getTime ( ) + 2 * 24 * 60 * 60 * 1000 ) ;
189+ if ( sLocal . getTime ( ) < minStart . getTime ( ) ) {
190+ throw new Error (
191+ '시작 시각은 현재 시각 기준 2일 이후부터 선택할 수 있어요.'
192+ ) ;
193+ }
194+ const minEnd = new Date ( sLocal . getTime ( ) + 24 * 60 * 60 * 1000 ) ;
195+ if ( eLocal . getTime ( ) < minEnd . getTime ( ) ) {
196+ throw new Error (
197+ '종료 시각은 시작 시각 기준 1일 이후로만 선택할 수 있어요.'
198+ ) ;
199+ }
200+
201+ const policyNote =
202+ '※ 날짜 제한: 시작 시각은 현재 시각 기준 2일 이후부터, 종료 시각은 시작 시각 기준 1일 이후부터 선택할 수 있습니다.' ;
203+ const mergedDescription = ( ( ) => {
204+ const base = description ?. trim ( ) ?? '' ;
205+ if ( ! base ) return policyNote ;
206+ if ( base . includes ( '※ 날짜 제한:' ) ) return base ;
207+ return `${ base } \n\n${ policyNote } ` ;
208+ } ) ( ) ;
209+
167210 const payload : CreateEventRequest = {
168211 title : t ,
169- description : description || undefined ,
212+ description : mergedDescription || undefined ,
170213 start_at : toISO ( startAt ) ,
171214 end_at : toISO ( endAt ) ,
172215 images : images . length > 0 ? images : undefined ,
@@ -251,7 +294,7 @@ const EventCreateForm = ({ onCreated, onCancel }: Props) => {
251294 required
252295 />
253296 < p className = "page-sub" style = { { margin : 0 } } >
254- 현재 시각 기준 1분 이후부터 선택할 수 있어요.
297+ 현재 시각 기준 2일 이후부터 선택할 수 있어요.
255298 { minStartLocal ? ` (최소: ${ fmtLocal ( minStartLocal ) } )` : '' }
256299 </ p >
257300 </ div >
@@ -273,12 +316,12 @@ const EventCreateForm = ({ onCreated, onCancel }: Props) => {
273316 className = "input"
274317 type = "datetime-local"
275318 value = { endAt }
276- min = { startAt || minStartLocal }
319+ min = { minEndLocal || startAt || minStartLocal }
277320 onChange = { ( e ) => setEndAt ( e . target . value ) }
278321 required
279322 />
280323 < p className = "page-sub" style = { { margin : 0 } } >
281- 시작 시각 이후로만 선택할 수 있어요.
324+ 시작 시각 기준 1일 이후로만 선택할 수 있어요.
282325 </ p >
283326 </ div >
284327
0 commit comments