@@ -9,14 +9,16 @@ import { useOrderTicket } from "../../../features/ticket/hooks/useOrderHook";
99import { OrderTicketRequest } from "../../../features/ticket/model/orderInformation" ;
1010import { useTickets } from "../../../features/ticket/hooks/useTicketHook" ;
1111import { useCreateTicketOptionAnswers } from "../../../features/ticket/hooks/useTicketOptionHook" ;
12+ import { TicketOptionResponse } from "../../../features/ticket/model/ticketInformation" ;
1213
1314interface TicketOptionLayoutProps {
1415 children : React . ReactNode ;
1516 ticketAmount : number ;
1617 ticketInfo : OrderTicketRequest ;
18+ options : TicketOptionResponse [ ] ;
1719}
1820
19- const TicketOptionLayout = ( { children, ticketAmount, ticketInfo } : TicketOptionLayoutProps ) => {
21+ const TicketOptionLayout = ( { children, ticketAmount, ticketInfo, options } : TicketOptionLayoutProps ) => {
2022 const navigate = useNavigate ( ) ;
2123 const { currentPage, setCurrentPage, selectedOptions, resetOptions } = useTicketOptionStore ( ) ;
2224 const centerContent = `티켓 옵션 선택 (${ currentPage } /${ ticketAmount } )` ;
@@ -27,6 +29,7 @@ const TicketOptionLayout = ({ children, ticketAmount, ticketInfo }: TicketOption
2729 ( ticket ) => ticket . ticketId === ticketInfo . ticketId
2830 ) ;
2931 const { mutate : submitAnswers } = useCreateTicketOptionAnswers ( ) ;
32+ console . log ( selectedOptions )
3033
3134 //페이지
3235 const pageIndicator = Array ( ticketAmount ) . fill ( " . " ) ;
@@ -35,7 +38,28 @@ const TicketOptionLayout = ({ children, ticketAmount, ticketInfo }: TicketOption
3538 //버튼 텍스트
3639 const isLastPage = currentPage === ticketAmount ;
3740 const buttonText = isLastPage ? "결제하기" : "다음 티켓 옵션 선택하기" ;
41+
3842 const handleNextPage = ( ) => {
43+ const currentOptions = selectedOptions [ currentPage ] ;
44+ const requiredOptions = options . filter ( ( opt ) => opt . isMandatory ) ;
45+ const isValid = requiredOptions . every ( ( opt ) => {
46+ const answer = currentOptions ?. [ opt . id ] ;
47+ if ( opt . type === "TEXT" ) {
48+ return typeof answer === "string" && answer . trim ( ) !== "" ;
49+ }
50+ if ( opt . type === "SINGLE" ) {
51+ return typeof answer === "number" ;
52+ }
53+ if ( opt . type === "MULTIPLE" ) {
54+ return Array . isArray ( answer ) && answer . length > 0 ;
55+ }
56+ return false ;
57+ } ) ;
58+ if ( ! isValid ) {
59+ alert ( "필수 옵션을 모두 입력해주세요." ) ;
60+ return ;
61+ }
62+
3963 if ( isLastPage ) {
4064 const sendAnswersByPage = async ( ) => {
4165 for ( const pageIndex of Object . keys ( selectedOptions ) . sort ( ( a , b ) => Number ( a ) - Number ( b ) ) ) {
@@ -73,11 +97,7 @@ const TicketOptionLayout = ({ children, ticketAmount, ticketInfo }: TicketOption
7397 onSuccess : ( response ) => {
7498 if ( response . isSuccess && Array . isArray ( response . result ) ) {
7599 const orderIds = response . result ;
76- navigate ( '/payment/ticket-confirm' , {
77- state : { orderIds, ...ticketInfo }
78- } ) ;
79- } else {
80- alert ( "주문 정보를 불러올 수 없습니다." ) ;
100+ navigate ( '/payment/ticket-confirm' , { state : { orderIds } } ) ;
81101 }
82102 } ,
83103 } ) ;
@@ -128,23 +148,23 @@ const TicketOptionLayout = ({ children, ticketAmount, ticketInfo }: TicketOption
128148 </ div >
129149 </ div >
130150
131- < div className = "flex flex-col mt-8 mx-auto w-[85%]" >
132- < p className = "font-bold text-sm md:text-base" > 추가 옵션</ p >
133- < p className = "text-xs md:text-sm text-gray-500 mt-2" >
134- 구매하는 티켓에 추가적으로 선택할 수 있는 옵션들이 있습니다.
135- </ p >
136- </ div >
151+ < div className = "flex flex-col mt-8 mx-auto w-[85%]" >
152+ < p className = "font-bold text-sm md:text-base" > 추가 옵션</ p >
153+ < p className = "text-xs md:text-sm text-gray-500 mt-2" >
154+ 구매하는 티켓에 추가적으로 선택할 수 있는 옵션들이 있습니다.
155+ </ p >
156+ </ div >
137157
138- { /* 내용 영역 */ }
139- < div className = "flex flex-col w-[85%] mx-auto mt-4" >
140- { children }
141- < div className = "flex flex-grow" />
142- < div className = "w-full p-6" >
143- < Button label = { buttonText } onClick = { handleNextPage } className = "w-full h-12 rounded-full" />
158+ { /* 내용 영역 */ }
159+ < div className = "flex flex-col w-[85%] mx-auto mt-4" >
160+ { children }
161+ < div className = "flex flex-grow" />
162+ < div className = "w-full p-6" >
163+ < Button label = { buttonText } onClick = { handleNextPage } className = "w-full h-12 rounded-full" />
164+ </ div >
165+ </ div >
144166 </ div >
145- </ div >
146- </ div >
147- ) ;
167+ ) ;
148168} ;
149169
150170export default TicketOptionLayout ;
0 commit comments