roomescape-refactored/frontend/src/pages/MyReservationPage.tsx
pricelees ef58752cec [#35] 결제 스키마 재정의 & 예약 조회 페이지 개선 (#36)
<!-- 제목 양식 -->
<!-- [이슈번호] 작업 요약 (예시: [#10] Gitea 템플릿 생성) -->

## 📝 관련 이슈 및 PR

**PR과 관련된 이슈 번호**
- #35

##  작업 내용
<!-- 어떤 작업을 했는지 알려주세요! -->
- 운영을 고려하여 조금 더 디테일한 정보가 담기도록 결제 스키마 개선(결제수단, 금액, 카드 사용시 카드번호, 할부 정보 등)
- 회원의 예약 조회 페이지 개선 및 회원의 예약 취소 기능 도입

## 🧪 테스트
<!-- 어떤 테스트를 생각했고 진행했는지 알려주세요! -->
- 현재 테스트가 과연 신뢰성이 있는가 의문. 추후 전체적인 작업 후 전체 테스트를 재조정할 예정

## 📚 참고 자료 및 기타
<!-- 참고한 자료, 또는 논의할 사항이 있다면 알려주세요! -->

Reviewed-on: #36
Co-authored-by: pricelees <priceelees@gmail.com>
Co-committed-by: pricelees <priceelees@gmail.com>
2025-08-22 06:43:16 +00:00

91 lines
2.8 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { cancelWaiting, fetchMyReservations } from '@_api/reservation/reservationAPI';
import type { MyReservationRetrieveResponse } from '@_api/reservation/reservationTypes';
import { ReservationStatus } from '@_api/reservation/reservationTypes';
import { isLoginRequiredError } from '@_api/apiClient';
const MyReservationPage: React.FC = () => {
const [reservations, setReservations] = useState<MyReservationRetrieveResponse[]>([]);
const navigate = useNavigate();
const handleError = (err: any) => {
if (isLoginRequiredError(err)) {
alert('로그인이 필요해요.');
navigate('/login', { state: { from: location } });
} else {
const message = err.response?.data?.message || '알 수 없는 오류가 발생했습니다.';
alert(message);
console.error(err);
}
};
useEffect(() => {
fetchMyReservations()
.then(res => setReservations(res.reservations))
.catch(handleError);
}, []);
const _cancelWaiting = (id: string) => {
cancelWaiting(id)
.then(() => {
alert('예약 대기가 취소되었습니다.');
setReservations(reservations.filter(r => r.id.toString() !== id));
})
.catch(handleError);
};
const getStatusText = (status: ReservationStatus, rank: number) => {
if (status === ReservationStatus.CONFIRMED) {
return '예약';
}
if (status === ReservationStatus.CONFIRMED_PAYMENT_REQUIRED) {
return '예약 - 결제 필요';
}
if (status === ReservationStatus.WAITING) {
return `${rank}번째 예약 대기`;
}
return '';
};
return (
<div className="content-container">
<h2 className="content-container-title"> </h2>
<div className="table-container"></div>
<table className="table">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th> </th>
<th>paymentKey</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{reservations.map(r => (
<tr key={r.id}>
<td>{r.themeName}</td>
<td>{r.date}</td>
<td>{r.time}</td>
<td>{getStatusText(r.status, r.rank)}</td>
<td>
{r.status === ReservationStatus.WAITING &&
<button className="btn btn-danger" onClick={() => _cancelWaiting(r.id.toString())}></button>}
</td>
<td>{r.paymentKey}</td>
<td>{r.amount}</td>
<td></td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default MyReservationPage;