Skip to content

Commit

Permalink
Refactor: 체험 등록/수정 예약 가능 시간 부분 리팩토링
Browse files Browse the repository at this point in the history
  • Loading branch information
eunji-0623 committed Aug 6, 2024
1 parent eaa7e38 commit f47e033
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 125 deletions.
35 changes: 26 additions & 9 deletions components/MyActivity/Register/DateInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ import { useState } from 'react';
import CustomCalendar from '@/components/CustomCalendar/CustomCalendar';
import useClickOutside from '@/hooks/useClickOutside';
import { useRecoilState } from 'recoil';
import { selectedDateState } from '@/states/registerState';
import { scheduleState, selectedDateState } from '@/states/registerState';
import { TimeSlotGroupProps } from './TimeSlot.types';
import { formatDate } from '@/utils/formatDate';

function Date({ index }: TimeSlotGroupProps) {
function Date({ id, disabled = false }: TimeSlotGroupProps) {
const [date, setDate] = useState<Date | null>(null);
const [showCalendar, setShowCalendar] = useState(false);
const [selectedDate, setSelectedDate] = useRecoilState(selectedDateState);
const [editSchedule, setEditSchedule] = useRecoilState(scheduleState);
const selectedItem = selectedDate.find((date) => date.id === id);
const placeholderDate =
selectedItem && selectedItem.date !== '' ? selectedItem.date : 'YY/MM/DD';

const handleInputClick = () => {
setShowCalendar(true);
Expand All @@ -19,9 +24,21 @@ function Date({ index }: TimeSlotGroupProps) {
setShowCalendar(false);

if (date) {
const updatedDate = [...selectedDate];
updatedDate[index] = date.toString();
setSelectedDate(updatedDate);
setSelectedDate((prevSelectedDate) =>
prevSelectedDate.map((selectedDate) =>
selectedDate.id === id
? { ...selectedDate, date: formatDate(date.toString()) }
: selectedDate
)
);
setEditSchedule((prevSchedule) => ({
...prevSchedule,
toAdd: prevSchedule.toAdd.map((schedule) =>
schedule.id === id
? { ...schedule, date: formatDate(date.toString()) }
: schedule
),
}));
}
};

Expand All @@ -39,10 +56,10 @@ function Date({ index }: TimeSlotGroupProps) {
value={date ? date.toDateString() : ''}
onClick={handleInputClick}
readOnly
className="w-full h-[56px] py-[8px] px-[16px] rounded-md border border-var-gray6 dark:border-var-dark3 bg-white dark:bg-var-dark2 dark:text-var-gray2"
placeholder={
selectedDate[index] !== '' ? selectedDate[index] : 'YY/MM/DD'
}
className="w-full h-[56px] py-[8px] px-[16px] rounded-md border border-var-gray6 dark:border-var-dark3
bg-white dark:bg-var-dark2 dark:text-var-gray2 disabled:bg-var-gray2"
placeholder={placeholderDate}
disabled={disabled}
/>
</div>
{showCalendar && (
Expand Down
73 changes: 32 additions & 41 deletions components/MyActivity/Register/RegisterForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,15 @@ import {
addressState,
bannerImageState,
detailImageState,
endTimeState,
selectedDateState,
startTimeState,
timeSlotCountState,
timeSlotState,
scheduleState,
} from '@/states/registerState';
import useRegisterActivity from '@/hooks/myActivity/useRegisterActivity';
import { formatDate } from '@/utils/formatDate';
import SidenNavigation from '@/components/SideNavigation/SideNavigation';
import AddressInput from '@/components/MyActivity/Register/AddressInput';
import { useEffect } from 'react';
import { RegisterFormProps } from './RegisterForm.types';
import { RegisterFormProps, SelectedDateProps } from './RegisterForm.types';
import useEditMyActivity from '@/hooks/myActivity/useEditMyActivity';
import useResetRegisterState from '@/hooks/myActivity/useResetRegisterState';
import { sideNavigationState } from '@/states/sideNavigationState';
Expand All @@ -42,11 +39,9 @@ function RegisterForm({ activityData, isEdit = false }: RegisterFormProps) {
const [bannerImage, setBannerImage] = useRecoilState(bannerImageState);
const [detailImage, setDetailImage] = useRecoilState(detailImageState);
const [selectedDate, setSelectedDate] = useRecoilState(selectedDateState);
const [timeSlots, setTimeSlots] = useRecoilState(timeSlotState);
const [timeSlotCount, setTimeSlotCount] = useRecoilState(timeSlotCountState);
const [startTime, setStartTime] = useRecoilState(startTimeState);
const [endTime, setEndTime] = useRecoilState(endTimeState);
const [address, setAddress] = useRecoilState(addressState);
const [editSchedules, setEditSchedules] = useRecoilState(scheduleState);

const {
register,
Expand All @@ -69,54 +64,50 @@ function RegisterForm({ activityData, isEdit = false }: RegisterFormProps) {
setDetailImage(activityData.subImages);
setAddress(activityData.address);
setTimeSlotCount(activityData.schedules.length);
const tempDate = [...selectedDate];
const tempStartTime = [...startTime];
const tempEndTime = [...endTime];
const tempTimeSlots: { id: number }[] = [];
const updatedDates: SelectedDateProps[] = activityData.schedules.map(
(schedule) => {
// endTime이 '00:00'인 경우 '24:00'으로 변환
const normalizedEndTime =
schedule.endTime === '00:00' ? '24:00' : schedule.endTime;

activityData.schedules.forEach((schedule, index) => {
tempDate[index] = schedule.date;
tempStartTime[index] = schedule.startTime;
tempEndTime[index] =
schedule.endTime === '00:00' ? '24:00' : schedule.endTime;
tempTimeSlots.push({ id: schedule.id });
});
tempTimeSlots.pop();

setSelectedDate(tempDate);
setStartTime(tempStartTime);
setEndTime(tempEndTime);
setTimeSlots(tempTimeSlots);
return {
date: schedule.date,
startTime: schedule.startTime,
endTime: normalizedEndTime,
id: schedule.id,
};
}
);
setSelectedDate(updatedDates);
}
}, [activityData]);

// api 호출 관련 hooks
const { postActivityMutation } = useRegisterActivity();
const { patchActivityMutation } = useEditMyActivity();

const formatSchedules = () =>
Array.from({ length: timeSlotCount }, (_, i) => ({
endTime: endTime[i] === '24:00' ? '00:00' : endTime[i],
startTime: startTime[i],
date: formatDate(selectedDate[i]),
const formatSchedules = () => {
return selectedDate.map((schedule, i) => ({
date: schedule.date,
startTime: schedule.startTime,
endTime: schedule.endTime === '24:00' ? '00:00' : schedule.endTime,
}));
};

// 수정 버튼 클릭 시
const onSubmitEdit = async (data: FieldValues) => {
if (!activityData) {
return;
}
const { title, description, price } = data;
const schedules = formatSchedules();
const subImageUrls = detailImage.map((image) => image.imageUrl);
const subImageIdsToRemove = [];
const scheduleIdsToRemove = [];
for (let i = 0; i < activityData.subImages.length; i++) {
subImageIdsToRemove.push(activityData.subImages[i].id);
}
for (let i = 0; i < activityData.schedules.length; i++) {
scheduleIdsToRemove.push(activityData.schedules[i].id);
}
const filteredIds = editSchedules.idsToRemove.filter((id) =>
activityData.schedules.some((schedule) => schedule.id === id)
);

patchActivityMutation.mutate({
activityId: activityData.id,
Expand All @@ -129,8 +120,8 @@ function RegisterForm({ activityData, isEdit = false }: RegisterFormProps) {
bannerImageUrl: bannerImage[0],
subImageIdsToRemove,
subImageUrlsToAdd: subImageUrls,
scheduleIdsToRemove,
schedulesToAdd: schedules,
scheduleIdsToRemove: filteredIds,
schedulesToAdd: editSchedules.toAdd,
},
});
};
Expand All @@ -157,9 +148,9 @@ function RegisterForm({ activityData, isEdit = false }: RegisterFormProps) {
const isTimeFieldValid = () =>
Array.from({ length: timeSlotCount }).every(
(_, i) =>
endTime[i] !== '00:00' &&
startTime[i] <= endTime[i] &&
selectedDate[i] !== ''
selectedDate[i].endTime !== '00:00' &&
selectedDate[i].startTime <= selectedDate[i].endTime &&
selectedDate[i].date !== ''
);

// form 제출이 가능한지 체크
Expand Down Expand Up @@ -252,7 +243,7 @@ function RegisterForm({ activityData, isEdit = false }: RegisterFormProps) {
errors={errors}
/>
<AddressInput />
<TimeSlot />
<TimeSlot isEdit={isEdit} />
<UploadBannerImage />
<UploadDetailImage />
</div>
Expand Down
7 changes: 7 additions & 0 deletions components/MyActivity/Register/RegisterForm.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,10 @@ export interface RegisterFormProps {
};
isEdit?: boolean;
}

export interface SelectedDateProps {
date: string;
startTime: string;
endTime: string;
id: number;
}
6 changes: 5 additions & 1 deletion components/MyActivity/Register/TimeDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function TimeDropdown({
handleChange,
startTime,
selectedTime,
disabled = false,
}: TimeDropdownProps) {
const [isOpen, setIsOpen] = useState(false);

Expand Down Expand Up @@ -46,8 +47,11 @@ function TimeDropdown({
<div ref={dropdownRef} className="relative">
<button
type="button"
className="flex justify-between items-center p:w-[140px] w-full h-[56px] py-[4px] px-[16px] m:px-[7px] rounded-md border border-var-gray6 dark:border-var-dark3 bg-white dark:bg-var-dark2 text-var-gray7 dark:text-var-gray2 text-left t:w-[104px] m:w-full"
className="flex justify-between items-center p:w-[140px] w-full h-[56px] py-[4px] px-[16px] m:px-[7px]
rounded-md border border-var-gray6 dark:border-var-dark3 bg-white dark:bg-var-dark2 text-var-gray7
dark:text-var-gray2 text-left t:w-[104px] m:w-full disabled:bg-var-gray2"
onClick={handleClickDropdown}
disabled={disabled}
>
<p>{selectedTime}</p>
<Image
Expand Down
Loading

0 comments on commit f47e033

Please sign in to comment.