diff --git a/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts b/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts index 7ed9ba5f..6290a048 100644 --- a/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts +++ b/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts @@ -9,6 +9,7 @@ import { ActivityDetailEdit, Schedule } from '@/types/activityDetailType'; import { AxiosError } from 'axios'; import { toast } from 'sonner'; import { notFound } from 'next/navigation'; +import { validateSchedules } from '../../utils/dateValidatoin'; interface SubImageType { id?: number; @@ -208,6 +209,11 @@ export const useEditActivityForm = () => { const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); + const validationMessage = validateSchedules(dates); + if (validationMessage) { + toast.error(validationMessage); + return; + } try { await mutation.mutateAsync(); } catch (error) { diff --git a/src/app/(with-header)/myactivity/components/ScheduleSelect.tsx b/src/app/(with-header)/myactivity/components/ScheduleSelect.tsx index c00f2cdd..c64fd3f5 100644 --- a/src/app/(with-header)/myactivity/components/ScheduleSelect.tsx +++ b/src/app/(with-header)/myactivity/components/ScheduleSelect.tsx @@ -19,7 +19,6 @@ interface ScheduleSelectProps { export function ScheduleSelect({ index, isRemovable, - onRemove, onDateChange, onStartTimeChange, @@ -29,9 +28,9 @@ export function ScheduleSelect({ endTime, }: ScheduleSelectProps) { return ( -
-
-
+
+
+
-
+
-
+
{isRemovable && ( -
+
diff --git a/src/app/(with-header)/myactivity/components/ScheduleSelectForm.tsx b/src/app/(with-header)/myactivity/components/ScheduleSelectForm.tsx index 8115b04e..4e63ec11 100644 --- a/src/app/(with-header)/myactivity/components/ScheduleSelectForm.tsx +++ b/src/app/(with-header)/myactivity/components/ScheduleSelectForm.tsx @@ -1,5 +1,6 @@ 'use client'; +import { toast } from 'sonner'; import { ScheduleSelect } from './ScheduleSelect'; import { Schedule } from '@/types/activityDetailType'; @@ -14,6 +15,17 @@ interface ScheduleSelectFormProps { ) => void; } +function isPastDate(dateStr: string) { + const selected = new Date(dateStr); + const today = new Date(); + today.setHours(0, 0, 0, 0); + return selected < today; +} + +function isInvalidTimeRange(start: string, end: string) { + return start >= end; +} + export function ScheduleSelectForm({ dates, onAddDate, @@ -23,17 +35,18 @@ export function ScheduleSelectForm({ return (
-

예약 가능한 시간대

+

예약 가능한 시간대

+ {dates.map((dateSlot, idx) => (
1} onAddDate={onAddDate} onRemove={onRemoveDate} - onDateChange={(index, value) => onDateChange(index, 'date', value)} - onStartTimeChange={(index, value) => - onDateChange(index, 'startTime', value) - } - onEndTimeChange={(index, value) => - onDateChange(index, 'endTime', value) - } + onDateChange={(index, value) => { + if (isPastDate(value)) { + toast.error('오늘 이전 날짜는 선택할 수 없습니다.'); + return; + } + onDateChange(index, 'date', value); + }} + onStartTimeChange={(index, value) => { + const end = dates[index].endTime; + if (end && isInvalidTimeRange(value, end)) { + toast.error('시작 시간은 종료 시간보다 빨라야 합니다.'); + return; + } + onDateChange(index, 'startTime', value); + }} + onEndTimeChange={(index, value) => { + const start = dates[index].startTime; + if (start && isInvalidTimeRange(start, value)) { + toast.error('종료 시간은 시작 시간보다 늦어야 합니다.'); + return; + } + onDateChange(index, 'endTime', value); + }} date={dateSlot.date} startTime={dateSlot.startTime} endTime={dateSlot.endTime} />
))} -
); } diff --git a/src/app/(with-header)/myactivity/utils/dateValidatoin.ts b/src/app/(with-header)/myactivity/utils/dateValidatoin.ts new file mode 100644 index 00000000..6aa91ce6 --- /dev/null +++ b/src/app/(with-header)/myactivity/utils/dateValidatoin.ts @@ -0,0 +1,31 @@ +import { Schedule } from '@/types/activityDetailType'; + +export function validateSchedules(schedules: Schedule[]) { + const today = new Date(); + today.setHours(0, 0, 0, 0); + + for (let i = 0; i < schedules.length; i++) { + const { date, startTime, endTime } = schedules[i]; + + if (!date || !startTime || !endTime) { + return `날짜와 시간이 모두 입력되어야 합니다!`; + } + + const selectedDate = new Date(date); + if (selectedDate < today) { + return `오늘보다 이전 날짜는 선택할 수 없습니다!`; + } + + const [startHour, startMinute] = startTime.split(':').map(Number); + const [endHour, endMinute] = endTime.split(':').map(Number); + + const startMinutes = startHour * 60 + startMinute; + const endMinutes = endHour * 60 + endMinute; + + if (startMinutes >= endMinutes) { + return `종료 시간은 시작 시간보다 늦어야 합니다!`; + } + } + + return null; +}