1- import { useLocation , useNavigate } from "react-router-dom" ;
1+ import { useNavigate , useParams } from "react-router-dom" ;
22import MainLayout from "../layout/MainLayout" ;
3- import { GetOrder } from "../../types/api/order" ;
3+ import { GetOneOrderResponse } from "../../types/api/order" ;
44import Font from "../atoms/fonts/Font" ;
5- import { fetchErrorMessages } from "../../constants/errorMessages" ;
5+ import {
6+ fetchErrorMessages ,
7+ cancelOrderErrorMessages ,
8+ } from "../../constants/errorMessages" ;
69import { formatToKoreanDateAndTime } from "../../utils/dateUtils" ;
710import Button from "../atoms/buttons/Button" ;
8- import { useState } from "react" ;
11+ import { useContext , useState } from "react" ;
12+ import { cancelOrder , getOneOrder } from "../../api/orders/ordersApi" ;
13+ import { toast } from "react-toastify" ;
14+ import { UserContext } from "../../store/UserContext" ;
15+ import { useQueryClient } from "@tanstack/react-query" ;
16+ import { createResourceQuery } from "../../hooks/useCustomQuery" ;
917
1018const MyDetailPage = ( ) => {
11- const location = useLocation ( ) ;
19+ const { orderId } = useParams < { orderId : string } > ( ) ;
20+ const queryClient = useQueryClient ( ) ;
21+
1222 const navigate = useNavigate ( ) ;
13- const state = location . state as { order : GetOrder } ;
14- const order = state . order ;
15- const [ isCancleModalOpen , setIsCancleModalOpen ] = useState ( false ) ;
23+ const { userId } = useContext ( UserContext ) ;
24+ const [ isCancelModalOpen , setIsCancelModalOpen ] = useState ( false ) ;
1625 const [ isShowModalOpen , setIsShowModalOpen ] = useState ( false ) ;
17- if ( ! order ) {
18- return < div > { fetchErrorMessages . noReservationData } </ div > ;
19- }
26+ const useOneOrder = createResourceQuery < GetOneOrderResponse > (
27+ `my-order-${ userId } ` , // 쿼리 키의 기본 이름
28+ ( orderId ) => getOneOrder ( orderId ) // fetchFn으로 getAllOrder 사용
29+ ) ;
30+ const { data, isLoading, isError } = useOneOrder ( orderId ) ;
2031
32+ const order = data ?. data ;
33+ if ( isLoading ) return < p > { fetchErrorMessages . isLoading } </ p > ;
34+ if ( isError ) return < p > { fetchErrorMessages . general } </ p > ;
35+ if ( ! order ) return < p > { fetchErrorMessages . noReservationData } </ p > ;
36+
37+ const handleCancelOrder = async ( ) => {
38+ try {
39+ const response = await cancelOrder ( orderId ! ) ;
40+ if ( response . code === 0 ) {
41+ toast . success ( cancelOrderErrorMessages . success ) ;
42+ } else {
43+ switch ( response . code ) {
44+ case 8 :
45+ toast . error ( cancelOrderErrorMessages . unauthorized ) ;
46+ break ;
47+ case 15 :
48+ toast . error ( cancelOrderErrorMessages . notFound ) ;
49+ break ;
50+ case 22 :
51+ toast . error ( cancelOrderErrorMessages . alreadyCanceled ) ;
52+ break ;
53+ case 6 :
54+ toast . error ( cancelOrderErrorMessages . internalServerError ) ;
55+ break ;
56+ default :
57+ toast . error ( "알 수 없는 오류가 발생했습니다." ) ;
58+ }
59+ }
60+ } catch ( error ) {
61+ console . log ( error ) ;
62+ toast . error ( "취소 처리 중 오류가 발생했습니다." ) ;
63+ }
64+ } ;
2165 // 모달 열기
22- const openCancleModal = ( ) => setIsCancleModalOpen ( true ) ;
66+ const openCancelModal = ( ) => setIsCancelModalOpen ( true ) ;
2367 const openShowModal = ( ) => setIsShowModalOpen ( true ) ;
2468
2569 // 모달 닫기
26- const closeCancleModal = ( ) => setIsCancleModalOpen ( false ) ;
70+ const closeCancelModal = ( ) => setIsCancelModalOpen ( false ) ;
2771 const closeShowModal = ( ) => setIsShowModalOpen ( false ) ;
2872
2973 // 예매 취소 확인
30- const handleCancelReservation = ( ) => {
31- closeCancleModal ( ) ; // 모달 닫기
74+ const handleCancelReservation = async ( ) => {
75+ closeCancelModal ( ) ; // 모달 닫기
76+ await handleCancelOrder ( ) ;
77+ await queryClient . invalidateQueries ( {
78+ queryKey : [ `my-orders-${ userId } ` ] ,
79+ } ) ; // orders 쿼리 무효화
3280 navigate ( "/mypage" ) ; // 마이페이지로 이동
3381 } ;
3482
@@ -123,15 +171,15 @@ const MyDetailPage = () => {
123171 { /* 예매 취소 버튼 */ }
124172 < div className = "fixed bottom-0 right-8 md:left-0 md:right-0 pb-4 flex justify-center" >
125173 < Button
126- onClick = { openCancleModal }
174+ onClick = { openCancelModal }
127175 className = "bg-se-500 text-white px-6 py-3 rounded-lg hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-300"
128176 >
129177 예매 취소
130178 </ Button >
131179 </ div >
132180 </ div >
133181 { /* 모달 */ }
134- { isCancleModalOpen && (
182+ { isCancelModalOpen && (
135183 < div className = "fixed inset-0 flex items-center justify-center bg-black/50 z-50" >
136184 < div className = "bg-white rounded-lg shadow-lg p-6 w-96" >
137185 < h2 className = "text-xl font-bold mb-4" > 예매 취소</ h2 >
@@ -141,15 +189,20 @@ const MyDetailPage = () => {
141189 < div className = "flex justify-end space-x-4" >
142190 < Button
143191 size = "sm"
144- onClick = { handleCancelReservation }
192+ onClick = { ( ) => {
193+ handleCancelReservation ( ) . catch ( ( error ) => {
194+ console . error ( "취소 처리 중 오류 발생:" , error ) ;
195+ toast . error ( "취소 처리 중 문제가 발생했습니다." ) ;
196+ } ) ;
197+ } }
145198 className = "px-4 py-2 rounded-lg bg-red-500 text-white hover:bg-red-600"
146199 >
147200 예매 취소
148201 </ Button >
149202 < Button
150203 size = "sm"
151204 variant = "secondary"
152- onClick = { closeCancleModal }
205+ onClick = { closeCancelModal }
153206 className = "px-4 py-2 rounded-lg border border-gray-300 hover:bg-gray-100"
154207 >
155208 뒤로 가기
0 commit comments