diff --git a/design-system/ui/modals/QrModal.tsx b/design-system/ui/modals/QrModal.tsx
index 6ca2c6b0..bc6a61fb 100644
--- a/design-system/ui/modals/QrModal.tsx
+++ b/design-system/ui/modals/QrModal.tsx
@@ -20,6 +20,7 @@ interface QrModalProps {
ticketName: string; // 티켓 이름
price: number; // 티켓 가격
orderStatus: string; // 티켓 승인 여부
+ eventType: 'ONLINE' | 'OFFLINE'; // 이벤트 타입
isCheckIn: boolean; // 참가자 체크인 여부
isCountdownChecked: boolean;
remainDays: string; //d-day
@@ -37,10 +38,10 @@ const QrModal = ({
ticketName,
price,
orderStatus,
+ eventType,
isCheckIn,
isCountdownChecked,
remainDays,
-
onClick,
}: QrModalProps) => {
const formattedPrice = price.toLocaleString();
@@ -59,16 +60,19 @@ const QrModal = ({
- {ticketQrCode ? (
-

+ {eventType === 'ONLINE' ? (
+
+ 온라인 이벤트는
+
QR코드가 발급되지
+
않습니다.
+
+ ) : ticketQrCode ? (
+

) : (
- 주최자의 승인이 완료되면 QR이 발급됩니다.
+ 주최자의 승인이
+
완료되면 QR이
+
발급됩니다.
)}
@@ -81,19 +85,19 @@ const QrModal = ({
}
+ iconPath={

}
children={formattedDate}
className="text-11"
>
}
+ iconPath={

}
children={location}
className="text-11"
>
}
+ iconPath={

}
children={ticketName}
className="text-11"
>
@@ -101,13 +105,15 @@ const QrModal = ({
}
+ iconPath={
+

+ }
children={orderStatus === 'COMPLETED' ? '승인됨' : '대기 중'}
className="text-11"
>
}
+ iconPath={

}
children={isCheckIn ? '체크인 완료' : '체크인 미완료'}
className="text-11"
>
@@ -121,6 +127,5 @@ const QrModal = ({
);
-
};
export default QrModal;
diff --git a/src/features/event/hooks/usePresignedUrlHook.ts b/src/features/event/hooks/usePresignedUrlHook.ts
index 5cd6c989..a94074f7 100644
--- a/src/features/event/hooks/usePresignedUrlHook.ts
+++ b/src/features/event/hooks/usePresignedUrlHook.ts
@@ -9,7 +9,6 @@ const getPresignedUrl = async (dto: PresignedUrlRequest) => {
const response = await axiosClient.get>('/generate-presigned-url', {
params: dto,
});
- console.log('Presigned URL 응답:', response.data.result?.preSignedUrl);
return response.data.result?.preSignedUrl;
} catch (error) {
@@ -21,14 +20,12 @@ const getPresignedUrl = async (dto: PresignedUrlRequest) => {
export const putS3Image = async ({ url, file }: { url: string; file: File }) => {
try {
delete axiosClient.defaults.headers.common.Authorization;
- console.log('업로드할 URL:', url);
await axios.put(url, file, {
headers: {
'Content-Type': 'image/webp',
},
});
- } catch (error) {
- console.error('S3 업로드 실패:', error);
+ } catch {
alert('이미지 업로드에 실패했습니다.');
throw new Error('Failed to upload image');
}
@@ -45,7 +42,6 @@ export const uploadFile = async (file: File) => {
}
const url = presignedUrlResponse;
- console.log('Presigned URL:', url);
await putS3Image({ url, file: webFile });
diff --git a/src/features/event/ui/DatePicker.tsx b/src/features/event/ui/DatePicker.tsx
index ef37c313..da0f6555 100644
--- a/src/features/event/ui/DatePicker.tsx
+++ b/src/features/event/ui/DatePicker.tsx
@@ -27,24 +27,13 @@ const EventDatePicker = ({
isLabel = false,
}: DatePickerProps) => {
const [startDate, setStartDate] = useState(
- eventState?.startDate
- ? new Date(eventState.startDate)
- : initialStartDate
- ? new Date(initialStartDate)
- : new Date()
+ eventState?.startDate ? new Date(eventState.startDate) : initialStartDate ? new Date(initialStartDate) : new Date()
);
const [endDate, setEndDate] = useState(
- eventState?.endDate
- ? new Date(eventState.endDate)
- : initialEndDate
- ? new Date(initialEndDate)
- : new Date()
+ eventState?.endDate ? new Date(eventState.endDate) : initialEndDate ? new Date(initialEndDate) : new Date()
);
- console.log('startDate', startDate);
- console.log('endDate', endDate);
-
const [startTime, setStartTime] = useState(
extractTimeFromDateString(eventState?.startDate || initialStartDate, '06:00')
);
@@ -86,7 +75,6 @@ const EventDatePicker = ({
}
}, [eventState?.startDate, eventState?.endDate, initialStartDate, initialEndDate]);
-
const generateTimeOptions = () => {
const options = [];
for (let i = 0; i < 24; i++) {
diff --git a/src/features/event/ui/ShareEventModal.tsx b/src/features/event/ui/ShareEventModal.tsx
index 893c8d4e..da2cb8a6 100644
--- a/src/features/event/ui/ShareEventModal.tsx
+++ b/src/features/event/ui/ShareEventModal.tsx
@@ -66,8 +66,7 @@ const ShareEventModal = ({
const handleKakaoShare = async () => {
try {
await shareToKakao(title, description, eventImageUrl, eventUrl);
- } catch (error) {
- console.error('카카오 공유 실패:', error);
+ } catch {
alert('카카오 공유하기에 실패했습니다.');
}
};
@@ -89,8 +88,7 @@ const ShareEventModal = ({
navigator.clipboard
.writeText(eventUrl)
.then(() => alert('링크가 복사되었습니다!'))
- .catch(err => {
- console.error('복사 실패:', err);
+ .catch(() => {
alert('링크 복사에 실패했습니다.');
});
} else {
diff --git a/src/features/event/ui/TimePicker.tsx b/src/features/event/ui/TimePicker.tsx
index 42f3b02d..040e71bb 100644
--- a/src/features/event/ui/TimePicker.tsx
+++ b/src/features/event/ui/TimePicker.tsx
@@ -16,12 +16,8 @@ const parseUtcToKst = (utcString: string): Date => {
const TimePicker = ({ value, onChange }: TimePickerProps) => {
const initialKstDate = value ? parseUtcToKst(value) : new Date();
const [selectedDate, setSelectedDate] = useState(initialKstDate);
- const [selectedHour, setSelectedHour] = useState(
- initialKstDate.getHours().toString().padStart(2, '0')
- );
- const [selectedMinute, setSelectedMinute] = useState(
- initialKstDate.getMinutes().toString().padStart(2, '0')
- );
+ const [selectedHour, setSelectedHour] = useState(initialKstDate.getHours().toString().padStart(2, '0'));
+ const [selectedMinute, setSelectedMinute] = useState(initialKstDate.getMinutes().toString().padStart(2, '0'));
useEffect(() => {
if (value) {
@@ -47,7 +43,6 @@ const TimePicker = ({ value, onChange }: TimePickerProps) => {
const localString = `${year}-${month}-${day}T${hour}:${minute}:00`;
onChange(localString);
- console.log(localString);
}
}, [selectedDate, selectedHour, selectedMinute]);
diff --git a/src/features/ticket/hooks/useTicketOptionForm.ts b/src/features/ticket/hooks/useTicketOptionForm.ts
index 136aad35..260ec738 100644
--- a/src/features/ticket/hooks/useTicketOptionForm.ts
+++ b/src/features/ticket/hooks/useTicketOptionForm.ts
@@ -139,8 +139,6 @@ export const useTicketOptionForm = () => {
const handleSave = () => {
let isValid = true;
- console.log('Clicked!');
-
if (state.question.title.trim() === '') {
dispatch({
type: 'SET_WARNING',
diff --git a/src/features/ticket/hooks/useTicketOptionHook.ts b/src/features/ticket/hooks/useTicketOptionHook.ts
index d70b5143..984f8194 100644
--- a/src/features/ticket/hooks/useTicketOptionHook.ts
+++ b/src/features/ticket/hooks/useTicketOptionHook.ts
@@ -38,9 +38,6 @@ export const useTicketOptions = (ticketId: number) => {
export const useCreateTicketOptionAnswers = () => {
return useMutation, Error, TicketOptionAnswerRequest>({
mutationFn: createTicketOptionAnswers,
- onSuccess: () => {
- console.log('티켓 옵션 응답 전송 성공');
- },
onError: () => {
alert('티켓 옵션 응답 전송 중 오류가 발생했습니다.');
},
@@ -177,10 +174,6 @@ export const useAttachTicketOptionMutation = () => {
onSuccess: (_data, variables) => {
// 티켓별 옵션 목록 쿼리 리패칭
queryClient.invalidateQueries({ queryKey: ['attachedTicketOptions', variables.ticketId] });
- console.log('티켓 옵션이 성공적으로 부착되었습니다.');
- },
- onError: () => {
- console.log('티켓 옵션 부착에 실패했습니다. 다시 시도해주세요.');
},
});
};
@@ -194,10 +187,6 @@ export const useDetachTicketOptionMutation = () => {
onSuccess: (_data, variables) => {
// 티켓별 옵션 목록 쿼리 리패칭
queryClient.invalidateQueries({ queryKey: ['attachedTicketOptions', variables.ticketId] });
- console.log('티켓에 부착된 티켓 옵션이 성공적으로 부착 취소되었습니다.');
- },
- onError: () => {
- console.log('티켓에 부착된 티켓 옵션 부착 취소에 실패했습니다. 다시 시도해주세요.');
},
});
};
diff --git a/src/pages/dashboard/ui/EventDetailPage.tsx b/src/pages/dashboard/ui/EventDetailPage.tsx
index 29969ad7..aeb63b22 100644
--- a/src/pages/dashboard/ui/EventDetailPage.tsx
+++ b/src/pages/dashboard/ui/EventDetailPage.tsx
@@ -22,9 +22,8 @@ const EventDetailPage = () => {
const [referenceLinks, setReferenceLinks] = useState([]);
const queryClient = useQueryClient();
-
+
useEffect(() => {
- console.log(data?.result.bannerImageUrl)
if (data?.result) {
setHostChannelId(data.result.hostChannelId || 0);
setBannerImageUrl(prev => prev || data.result.bannerImageUrl || '');
@@ -73,7 +72,7 @@ const EventDetailPage = () => {
이벤트 상세 정보
-
+
diff --git a/src/pages/dashboard/ui/EventInfoPage.tsx b/src/pages/dashboard/ui/EventInfoPage.tsx
index 4f376c48..d2a66f24 100644
--- a/src/pages/dashboard/ui/EventInfoPage.tsx
+++ b/src/pages/dashboard/ui/EventInfoPage.tsx
@@ -66,8 +66,7 @@ const EventInfoPage = () => {
queryClient.invalidateQueries({ queryKey: ['eventDetail', data.result.id] });
navigate(`/dashboard/${data?.result.id}`);
},
- onError: error => {
- console.error('Error details:', error);
+ onError: () => {
alert('저장에 실패했습니다.');
},
});
@@ -93,7 +92,7 @@ const EventInfoPage = () => {
return (
//
-
+
이벤트 기본 정보
{
- console.error('호스트 삭제 실패:', error);
alert(`${error.message}`);
},
});
@@ -61,7 +60,7 @@ const HostSelectionPage = ({ onNext, currentStep, onValidationChange }: HostSele
채널 새로 만들기
diff --git a/src/pages/join/AuthCallback.tsx b/src/pages/join/AuthCallback.tsx
index 7532cd1c..1ed6d451 100644
--- a/src/pages/join/AuthCallback.tsx
+++ b/src/pages/join/AuthCallback.tsx
@@ -1,38 +1,35 @@
-import { useNavigate, useSearchParams } from "react-router-dom";
-import useAuthStore from "../../app/provider/authStore";
-import { useEffect } from "react";
-import { useUserInfo } from "../../features/join/hooks/useUserHook";
+import { useNavigate, useSearchParams } from 'react-router-dom';
+import useAuthStore from '../../app/provider/authStore';
+import { useEffect } from 'react';
+import { useUserInfo } from '../../features/join/hooks/useUserHook';
const AuthCallback = () => {
- const navigate = useNavigate();
- const [searchParams] = useSearchParams();
- const status = searchParams.get('status'); // 'new' or 'existing'
- const { login, setName, closeModal } = useAuthStore();
- const { data } = useUserInfo();
+ const navigate = useNavigate();
+ const [searchParams] = useSearchParams();
+ const status = searchParams.get('status'); // 'new' or 'existing'
+ const { login, setName, closeModal } = useAuthStore();
+ const { data } = useUserInfo();
- useEffect(() => {
- const handleAuth = async () => {
- if (!data) return;
- try {
- closeModal();
- if (status === 'new') {
- navigate('/join/agreement');
- } else {
- login();
- setName(data?.name || "사용자");
- navigate('/');
- }
- } catch (error) {
- console.error('인증 처리 실패', error);
- navigate('/');
- }
- };
- handleAuth();
- }, [data, navigate, login, status, setName, closeModal]);
+ useEffect(() => {
+ const handleAuth = async () => {
+ if (!data) return;
+ try {
+ closeModal();
+ if (status === 'new') {
+ navigate('/join/agreement');
+ } else {
+ login();
+ setName(data?.name || '사용자');
+ navigate('/');
+ }
+ } catch {
+ navigate('/');
+ }
+ };
+ handleAuth();
+ }, [data, navigate, login, status, setName, closeModal]);
- return 로그인 중입니다...
;
+ return 로그인 중입니다...
;
};
export default AuthCallback;
-
-
diff --git a/src/pages/join/InfoInputPage.tsx b/src/pages/join/InfoInputPage.tsx
index ce675e57..6ac65513 100644
--- a/src/pages/join/InfoInputPage.tsx
+++ b/src/pages/join/InfoInputPage.tsx
@@ -67,9 +67,8 @@ const InfoInputPage = () => {
}
);
},
- onError: err => {
+ onError: () => {
alert('정보 업데이트에 실패했습니다. 다시 시도해주세요.');
- console.error(err);
},
});
};
diff --git a/src/pages/join/LogoutPage.tsx b/src/pages/join/LogoutPage.tsx
index 403409d7..5a0557f8 100644
--- a/src/pages/join/LogoutPage.tsx
+++ b/src/pages/join/LogoutPage.tsx
@@ -11,7 +11,6 @@ const LogoutPage = () => {
const handleLogout = async () => {
try {
await axiosClient.post('/oauth/logout');
- console.log('이 에러는 토큰 만료로 인한 정상적인 동작입니다. 다시 로그인해주세요.');
logout();
navigate('/');
} catch (error: unknown) {
@@ -20,19 +19,14 @@ const LogoutPage = () => {
typeof error === 'object' &&
error !== null &&
'code' in error &&
- (
- (error as { code?: string }).code === 'TOKEN4001' ||
- (error as { code?: string }).code === 'TOKEN4004'
- )
+ ((error as { code?: string }).code === 'TOKEN4001' || (error as { code?: string }).code === 'TOKEN4004')
) {
// 토큰 만료로 인한 자동 로그아웃이므로 조용히 처리
- console.log('토큰 만료로 인한 자동 로그아웃', error);
alert('다시 로그인 해주세요.');
logout();
navigate('/');
} else {
// 실제 로그아웃 실패
- console.error('로그아웃 실패:', error);
alert('로그아웃에 실패했습니다. 다시 시도해주세요.');
navigate('/menu');
}
diff --git a/src/pages/menu/ui/MyTicketPage.tsx b/src/pages/menu/ui/MyTicketPage.tsx
index 97ea65bd..8d257869 100644
--- a/src/pages/menu/ui/MyTicketPage.tsx
+++ b/src/pages/menu/ui/MyTicketPage.tsx
@@ -61,7 +61,9 @@ const MyTicketPage = () => {
const handleEventCardClick = (ticket: OrderTicketResponse) => {
if (isCancelMode) {
- setSelectedIds(prev => (prev.includes(ticket.orderId) ? prev.filter(id => id !== ticket.orderId) : [...prev, ticket.orderId]));
+ setSelectedIds(prev =>
+ prev.includes(ticket.orderId) ? prev.filter(id => id !== ticket.orderId) : [...prev, ticket.orderId]
+ );
} else {
setSelectedTicket(null);
setPendingTicket(ticket);
@@ -94,7 +96,6 @@ const MyTicketPage = () => {
}
}, [selectedTicket]);
- console.log('isDoneEventModalOpen', isDoneEventModalOpen);
return (
{tickets.length > 0 && (
@@ -135,9 +136,10 @@ const MyTicketPage = () => {
hashtags={ticket.event.hashtags}
status={ticket.event.status}
onClick={() => handleEventCardClick(ticket)}
- className={`transition-transform duration-200 ${isCancelMode && selectedIds.includes(ticket.orderId) ? 'scale-95 border-2 border-pink-400' : ''
- }`}
- aspectRatio='md:aspect-[3/4.7] sm:aspect-[1/2]'
+ className={`transition-transform duration-200 ${
+ isCancelMode && selectedIds.includes(ticket.orderId) ? 'scale-95 border-2 border-pink-400' : ''
+ }`}
+ aspectRatio="md:aspect-[3/4.7] sm:aspect-[1/2]"
>

@@ -157,37 +159,39 @@ const MyTicketPage = () => {
-
)}
- {isModalOpen && selectedTicket && (selectedTicket.event.status !== 'DELETED' && selectedTicket.event.status !== 'COMPLETE') && (
-
- }
- ticketQrCode={selectedTicket.ticketQrCode}
- title={selectedTicket.event.title}
- hostName={selectedTicket.event.hostChannelName}
- date={selectedTicket.event.startDate}
- location={selectedTicket.event.address}
- ticketName={selectedTicket.ticketName}
- price={selectedTicket.ticketPrice}
- orderStatus={selectedTicket.orderStatus}
- isCheckIn={selectedTicket.checkIn}
- isCountdownChecked={true}
- remainDays={selectedTicket.event.remainDays}
- onClick={() => setIsModalOpen(false)}
- />
-
- )}
+ {isModalOpen &&
+ selectedTicket &&
+ selectedTicket.event.status !== 'DELETED' &&
+ selectedTicket.event.status !== 'COMPLETE' && (
+
+ }
+ ticketQrCode={selectedTicket.ticketQrCode}
+ title={selectedTicket.event.title}
+ hostName={selectedTicket.event.hostChannelName}
+ date={selectedTicket.event.startDate}
+ location={selectedTicket.event.address}
+ ticketName={selectedTicket.ticketName}
+ price={selectedTicket.ticketPrice}
+ orderStatus={selectedTicket.orderStatus}
+ eventType={selectedTicket.event.onlineType}
+ isCheckIn={selectedTicket.checkIn}
+ isCountdownChecked={true}
+ remainDays={selectedTicket.event.remainDays}
+ onClick={() => setIsModalOpen(false)}
+ />
+
+ )}
{isDoneEventModalOpen && selectedTicket && (
setIsDoneEventModalOpen(false)}>
{eventModalText}
- )
- }
+ )}
{isDeleteModalOpen && (
{
const navigate = useNavigate();
const { pathname } = useLocation();
@@ -70,10 +70,14 @@ const EventCard = ({
{/* 상세 정보 */}
-
{eventTitle}
+
+ {eventTitle}
+
{dDay !== 'false' && (
- {dDay}
+
+ {dDay}
+
)}
@@ -87,20 +91,13 @@ const EventCard = ({

-
- {onlineType === 'ONLINE' ? 'ONLINE' : location}
-
+
{onlineType === 'ONLINE' ? 'ONLINE' : location}
{/* 승인 여부 표시 */}
{children}
{/* 해시태그 */}
- {filteredHashtags && (
-
e.stopPropagation()}
- />
- )}
+ {filteredHashtags && e.stopPropagation()} />}
{/* 대시보드 버튼 */}
{isHostPage && (
@@ -138,14 +135,12 @@ const EventCard = ({
setIsModalOpen(false);
},
onError: (error: unknown) => {
- if (
- typeof error === 'object' &&
- error !== null &&
- 'code' in error &&
- (
- error as { code? : string}).code === "EVENT4002"
- ) {
- console.log('참여자로 인한 이벤트 삭제 실패');
+ if (
+ typeof error === 'object' &&
+ error !== null &&
+ 'code' in error &&
+ (error as { code?: string }).code === 'EVENT4002'
+ ) {
alert('구매자가 있는 이벤트는 삭제가 불가합니다.');
}
setIsModalOpen(false);
diff --git a/src/shared/ui/backgrounds/TicketOptionLayout.tsx b/src/shared/ui/backgrounds/TicketOptionLayout.tsx
index 36d6053c..0a3de664 100644
--- a/src/shared/ui/backgrounds/TicketOptionLayout.tsx
+++ b/src/shared/ui/backgrounds/TicketOptionLayout.tsx
@@ -1,150 +1,140 @@
-import { useNavigate } from "react-router-dom";
-import Header from "../../../../design-system/ui/Header";
-import ticket from "../../../../public/assets/dashboard/ticket/Ticket(horizon).svg";
-import Button from "../../../../design-system/ui/Button";
-import active from "../../../../public/assets/payment/Active.svg";
-import inactive from "../../../../public/assets/payment/Inactive.svg";
-import { useTicketOptionStore } from "../../../features/dashboard/model/store/TicketOptionStore";
-import { useOrderTicket } from "../../../features/ticket/hooks/useOrderHook";
-import { OrderTicketRequest } from "../../../features/ticket/model/orderInformation";
-import { useTickets } from "../../../features/ticket/hooks/useTicketHook";
-import { TicketOptionResponse } from "../../../features/ticket/model/ticketInformation";
-import { buildTicketOptionAnswers } from "../../../features/ticket/util/buildTicketOptionAnswers";
+import { useNavigate } from 'react-router-dom';
+import Header from '../../../../design-system/ui/Header';
+import ticket from '../../../../public/assets/dashboard/ticket/Ticket(horizon).svg';
+import Button from '../../../../design-system/ui/Button';
+import active from '../../../../public/assets/payment/Active.svg';
+import inactive from '../../../../public/assets/payment/Inactive.svg';
+import { useTicketOptionStore } from '../../../features/dashboard/model/store/TicketOptionStore';
+import { useOrderTicket } from '../../../features/ticket/hooks/useOrderHook';
+import { OrderTicketRequest } from '../../../features/ticket/model/orderInformation';
+import { useTickets } from '../../../features/ticket/hooks/useTicketHook';
+import { TicketOptionResponse } from '../../../features/ticket/model/ticketInformation';
+import { buildTicketOptionAnswers } from '../../../features/ticket/util/buildTicketOptionAnswers';
interface TicketOptionLayoutProps {
- children: React.ReactNode;
- ticketAmount: number;
- ticketInfo: OrderTicketRequest;
- options: TicketOptionResponse[];
+ children: React.ReactNode;
+ ticketAmount: number;
+ ticketInfo: OrderTicketRequest;
+ options: TicketOptionResponse[];
}
const TicketOptionLayout = ({ children, ticketAmount, ticketInfo, options }: TicketOptionLayoutProps) => {
- const navigate = useNavigate();
- const { currentPage, setCurrentPage, selectedOptions, resetOptions } = useTicketOptionStore();
- const centerContent = `티켓 옵션 선택 (${currentPage}/${ticketAmount})`;
+ const navigate = useNavigate();
+ const { currentPage, setCurrentPage, selectedOptions, resetOptions } = useTicketOptionStore();
+ const centerContent = `티켓 옵션 선택 (${currentPage}/${ticketAmount})`;
- const { mutate: orderTickets } = useOrderTicket();
- const { data: ticketData } = useTickets(ticketInfo.eventId);
- const ticketObj = ticketData?.result.find(
- (ticket) => ticket.ticketId === ticketInfo.ticketId
- );
+ const { mutate: orderTickets } = useOrderTicket();
+ const { data: ticketData } = useTickets(ticketInfo.eventId);
+ const ticketObj = ticketData?.result.find(ticket => ticket.ticketId === ticketInfo.ticketId);
- //페이지
- const pageIndicator = Array(ticketAmount).fill(" . ");
- pageIndicator[currentPage - 1] = " - ";
+ //페이지
+ const pageIndicator = Array(ticketAmount).fill(' . ');
+ pageIndicator[currentPage - 1] = ' - ';
- //버튼 텍스트
- const isLastPage = currentPage === ticketAmount;
- const buttonText = isLastPage ? "결제하기" : "다음 티켓 옵션 선택하기";
+ //버튼 텍스트
+ const isLastPage = currentPage === ticketAmount;
+ const buttonText = isLastPage ? '결제하기' : '다음 티켓 옵션 선택하기';
- const handleNextPage = () => {
- const currentOptions = selectedOptions[currentPage];
- const requiredOptions = options.filter((opt) => opt.isMandatory);
- const isValid = requiredOptions.every((opt) => {
- const answer = currentOptions?.[opt.id];
- if (opt.type === "TEXT") {
- return typeof answer === "string" && answer.trim() !== "";
- }
- if (opt.type === "SINGLE") {
- return typeof answer === "number";
- }
- if (opt.type === "MULTIPLE") {
- return Array.isArray(answer) && answer.length > 0;
- }
- return false;
- });
- if (!isValid) {
- alert("필수 옵션을 모두 입력해주세요.");
- return;
- }
+ const handleNextPage = () => {
+ const currentOptions = selectedOptions[currentPage];
+ const requiredOptions = options.filter(opt => opt.isMandatory);
+ const isValid = requiredOptions.every(opt => {
+ const answer = currentOptions?.[opt.id];
+ if (opt.type === 'TEXT') {
+ return typeof answer === 'string' && answer.trim() !== '';
+ }
+ if (opt.type === 'SINGLE') {
+ return typeof answer === 'number';
+ }
+ if (opt.type === 'MULTIPLE') {
+ return Array.isArray(answer) && answer.length > 0;
+ }
+ return false;
+ });
+ if (!isValid) {
+ alert('필수 옵션을 모두 입력해주세요.');
+ return;
+ }
- if (isLastPage) {
- if (isLastPage) {
- const sendAnswersByPage = async () => {
- const ticketOptionAnswers = buildTicketOptionAnswers(selectedOptions);
-
- console.log(ticketOptionAnswers)
-
- // 주문
- orderTickets(
- {
- ...ticketInfo,
- ticketOptionAnswers,
- },
- {
- onSuccess: (response) => {
- if (response.isSuccess && Array.isArray(response.result)) {
- const orderIds = response.result;
- resetOptions();
- navigate("/payment/ticket-confirm", { state: { orderIds } });
- }
- },
- }
- );
- };
- sendAnswersByPage();
+ if (isLastPage) {
+ if (isLastPage) {
+ const sendAnswersByPage = async () => {
+ const ticketOptionAnswers = buildTicketOptionAnswers(selectedOptions);
+ // 주문
+ orderTickets(
+ {
+ ...ticketInfo,
+ ticketOptionAnswers,
+ },
+ {
+ onSuccess: response => {
+ if (response.isSuccess && Array.isArray(response.result)) {
+ const orderIds = response.result;
+ resetOptions();
+ navigate('/payment/ticket-confirm', { state: { orderIds } });
+ }
+ },
}
+ );
+ };
+ sendAnswersByPage();
+ }
+ } else {
+ setCurrentPage(currentPage + 1);
+ }
+ };
- } else {
- setCurrentPage(currentPage + 1);
- }
- };
-
- return (
-
- {/* 헤더 영역 */}
-
- {/* 티켓 정보 영역 */}
-
-
-
-

-
-
{ticketObj?.ticketName}
-
-
-
-
-
{ticketObj?.ticketDescription}
-
+ return (
+
+ {/* 헤더 영역 */}
+
+ {/* 티켓 정보 영역 */}
+
+
+
+

+
+
{ticketObj?.ticketName}
+
+
+
+
{ticketObj?.ticketDescription}
+
+
-
-
추가 옵션
-
- 구매하는 티켓에 추가적으로 선택할 수 있는 옵션들이 있습니다.
-
-
+
+
추가 옵션
+
+ 구매하는 티켓에 추가적으로 선택할 수 있는 옵션들이 있습니다.
+
+
- {/* 내용 영역 */}
-
+ {/* 내용 영역 */}
+
+ {children}
+
+
+
- );
+
+
+ );
};
export default TicketOptionLayout;