-
Notifications
You must be signed in to change notification settings - Fork 0
feat: 티켓 구매 API 연동 #93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
1695e67
db79fbc
4430085
9cc1d3e
73943f1
a47e060
3167e6e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,33 @@ | ||
| import { axiosClient } from "../../../shared/types/api/http-client" | ||
| export const readMyTickets = { | ||
| get: async (page: number = 0, size: number = 10) => { | ||
| import { OrderTicketRequest } from "../model/OrderCreation"; | ||
|
|
||
| export const readTicket = { | ||
| // 주문 티켓 전체 조회 | ||
| getAll: async (page: number = 0, size: number = 10) => { | ||
| const response = await axiosClient.get("/orders", { | ||
| params: { page, size }, | ||
| }); | ||
| return response.data; | ||
| }, | ||
| } | ||
| // 주문 상세 조회 | ||
| getDetail: async(ticketId: number, eventId: number) => { | ||
| const response = await axiosClient.get('/orders/purchase-confirmation',{ | ||
| params: {ticketId, eventId} | ||
| }); | ||
| return response.data; | ||
| } | ||
| } | ||
|
|
||
| // 티켓 구매 | ||
| export const orderTickets = async (data: OrderTicketRequest) => { | ||
| const response = await axiosClient.post("/orders", data); | ||
| return response.data; | ||
| } | ||
|
|
||
| // 티켓 취소 | ||
| export const cancleTickets = async (orderId: number) => { | ||
| const response = await axiosClient.post(`/orders/cancel?orderId=${orderId}`); | ||
| return response.data; | ||
| } | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| export interface OrderTicketRequest { | ||
| ticketId: number; | ||
| eventId: number; | ||
| ticketCnt: number; | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,20 +1,65 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useState } from 'react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useEffect, useState } from 'react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import Header from '../../../../../design-system/ui/Header'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import Search from '../../../../../design-system/icons/Search.svg'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useNavigate } from 'react-router-dom'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useLocation, useNavigate } from 'react-router-dom'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import EmailDeleteMoal from '../../../../widgets/dashboard/ui/EmailDeleteModal'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import PurchaseBanner from '../../../../widgets/dashboard/ui/TicketConfirmPage/PurchaseBanner'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import OrganizerInfo from '../../../../widgets/dashboard/ui/TicketConfirmPage/OrganizerInfo'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import LocationInfo from '../../../../widgets/dashboard/ui/TicketConfirmPage/LocationInfo'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import OrganizerInfo from '../../../../widgets/event/ui/OrganizerInfo'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import KakaoMap from '../../../../shared/ui/KakaoMap'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { cancleTickets, readTicket } from '../../../../features/ticket/api/order'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type Ticket = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: number; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| startDate: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| startTime: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ticketName: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ticketCnt: number; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| hostChannelName: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| hostChannelDescription: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| organizerEmail: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| organizerPhoneNumber: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eventAddress: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| location: { lng: number, lat: number }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| remainDays: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ticketQrCode: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| orderStatus: "COMPLETED" | "PENDING" | "CANCELED"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const TicketConfirmPage = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const navigate = useNavigate(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [isModalOpen, setIsModalOpen] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const location = useLocation(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const orderIds: number[] = location.state?.orderIds || []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const eventId = location.state?.eventId; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const ticketId = location.state?.ticketId; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
hyeeuncho marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log(ticketId, eventId, orderIds); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [ticket, setTicket] = useState<Ticket | null>(null); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const fetchOrderTicket = async () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const response = await readTicket.getDetail(ticketId, eventId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setTicket(response.result || []); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. API 응답 처리 검증 필요 API 응답에서 - setTicket(response.result || []);
+ setTicket(response.result || null);📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.error("구매한 티켓 정보 불러오기 실패:", error); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fetchOrderTicket(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, []); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+37
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. useEffect 의존성 배열에 ticketId와 eventId를 추가해야 합니다. useEffect의 의존성 배열이 비어 있어 컴포넌트가 마운트될 때만 한 번 실행됩니다. ticketId나 eventId가 변경될 경우에도 티켓 정보를 다시 불러와야 합니다. useEffect(() => {
+ if (!ticketId || !eventId) return;
+
const fetchOrderTicket = async () => {
try {
const response = await readTicket.getDetail(ticketId, eventId);
setTicket(response.result || []);
} catch (error) {
console.error("구매한 티켓 정보 불러오기 실패:", error);
}
};
fetchOrderTicket();
- }, []);
+ }, [ticketId, eventId]);📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const handlePreviousButton = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| navigate(-1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const cancleOrderTicket = async (orderIds: number[]) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (const orderId of orderIds) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const response = await cancleTickets(orderId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log("티켓 취소 API 응답:", response); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.error(`orderId ${orderId} 취소 실패:`, error); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
hyeeuncho marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Header | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -24,18 +69,28 @@ const TicketConfirmPage = () => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| centerContent="티켓 구매 확인" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rightContent={<img src={Search} alt="검색" className="w-4" />} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="bg-gray-100 p-3 min-h-screen flex flex-col gap-3"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PurchaseBanner setIsModalOpen={setIsModalOpen} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <OrganizerInfo /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <LocationInfo /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {ticket ? ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="bg-gray-100 p-3 min-h-screen flex flex-col gap-3"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PurchaseBanner setIsModalOpen={setIsModalOpen} title={ticket.title} startDate={ticket.startDate} startTime={ticket.startTime} ticketName={ticket.ticketName} quantity={orderIds.length} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <OrganizerInfo name={ticket.hostChannelName} description={ticket.hostChannelDescription} phone={ticket.organizerPhoneNumber} email={ticket.organizerEmail} bgColor='bg-white' /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="p-5 bg-white flex flex-col gap-2 rounded-[10px]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p className="font-bold md:text-2xl text-xl">오시는 길</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p>{ticket.eventAddress}</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <KakaoMap lat={ticket.location.lat} lng={ticket.location.lng} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) : ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p className="text-center text-gray-500">티켓 정보를 불러오는 중...</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {isModalOpen && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <EmailDeleteMoal | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mainText="WOOACON 2024의 일반 티켓 2매 구매를 취소하시겠습니까?. 취소 후에는 복구가 불가능합니다." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mainText={`${ticket?.title}의 ${ticket?.ticketName} ${orderIds.length}매 구매를 취소하시겠습니까?. 취소 후에는 복구가 불가능합니다.`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| approveButtonText="티켓 취소" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rejectButtonText="뒤로가기" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClose={() => setIsModalOpen(false)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClick={() => navigate('/menu/myticket')} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClick={() => { cancleOrderTicket(orderIds),navigate('/menu/myticket') }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -80,7 +80,6 @@ const EventDetailsPage = () => { | |
| fetchEventDetail(); | ||
| }, []); | ||
|
|
||
|
|
||
| return ( | ||
| <> | ||
| <Header | ||
|
|
||
This file was deleted.
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.