Conversation
Walkthrough이번 PR은 여러 컴포넌트와 API 함수의 수정 및 추가를 포함합니다.
Changes
Sequence Diagram(s)sequenceDiagram
participant U as 사용자
participant MP as MyTicketPage
participant API as readMyTickets (API)
participant AC as axiosClient
U->>MP: 페이지 로드
MP->>API: 티켓 데이터 요청 (page, size)
API->>AC: GET /orders 요청
AC-->>API: 응답 데이터 반환
API-->>MP: 티켓 목록 전달
MP->>U: 업데이트된 티켓 목록 렌더링
Suggested reviewers
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (4)
src/features/ticket/api/order.ts (1)
1-14: 티켓 조회 API 기능이 잘 구현되었습니다.티켓 조회를 위한 API 클라이언트 함수가 적절하게 구현되었습니다. 페이지네이션 파라미터와 에러 처리가 포함되어 있어 좋습니다.
한 가지 개선할 점은 응답 데이터에 대한 타입 정의를 추가하는 것입니다. 타입 정의를 통해 코드 자동완성과 타입 안정성을 높일 수 있습니다:
import { axiosClient } from "../../../shared/types/api/http-client" +interface TicketResponse { + content: Array<{ + id: number; + eventName: string; + eventDate: string; + location: string; + status: string; + // 기타 필요한 필드들 + }>; + totalElements: number; + totalPages: number; + size: number; + number: number; +} export const readMyTickets = { - get: async (page: number = 0, size: number = 10) => { + get: async (page: number = 0, size: number = 10): Promise<TicketResponse> => { try { const response = await axiosClient.get("/orders", { params: { page, size }, }); return response.data; } catch (error) { console.error("티켓 조회 중 오류 발생:", error); throw error; } }, }design-system/ui/modals/QrModal.tsx (1)
90-90: 승인 상태 로직의 개선이 이루어졌습니다.
orderStatus값에 따른 조건부 렌더링으로 변경되어, 상태가 'COMPLETED'일 때만 '승인됨'을 표시하는 방식이 명확해졌습니다.추가적으로 orderStatus가 'COMPLETED', 'PENDING', 'CANCELED' 등 여러 값을 가질 수 있으므로, 이에 따른 다양한 상태 표시를 고려해 볼 수 있습니다.
- children={orderStatus === 'COMPLETED' ? '승인됨' : '대기 중'} + children={ + orderStatus === 'COMPLETED' + ? '승인됨' + : orderStatus === 'PENDING' + ? '대기 중' + : orderStatus === 'CANCELED' + ? '취소됨' + : '알 수 없음' + }src/pages/menu/ui/MyTicketPage.tsx (2)
35-45: API 데이터 가져오기 구현이 잘되어 있습니다.useEffect를 사용하여 컴포넌트 마운트 시 티켓 데이터를 불러오는 로직이 잘 구현되어 있습니다. 에러 처리도 포함되어 있어 좋습니다.
사용자에게 로딩 상태와 에러 상태를 표시하는 기능이 추가되면 더 좋을 것 같습니다.
const MyTicketPage = () => { const [isModalOpen, setIsModalOpen] = useState(false); const [myTickets, setMyTickets] = useState<Ticket[]>([]); const [selectedTicket, setSelectedTicket] = useState<Ticket | null>(null); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState<string | null>(null); useEffect(() => { const fetchMyTickets = async () => { + setIsLoading(true); + setError(null); try { const response = await readMyTickets.get(0, 10); setMyTickets(response.result || []); } catch (error) { console.error("티켓 목록 불러오기 실패:", error); + setError("티켓을 불러오는 중 오류가 발생했습니다. 다시 시도해 주세요."); } finally { + setIsLoading(false); } }; fetchMyTickets(); }, []);
51-80: 티켓 정보 표시 로직이 효율적으로 구현되었습니다.각 티켓 정보를 EventCard 컴포넌트를 통해 표시하고, 상태에 따라 적절한 이미지를 표시하는 로직이 잘 구현되어 있습니다.
티켓이 없을 때의 상태를 처리하는 코드를 추가하면 더 좋을 것 같습니다.
<div className="grid grid-cols-2 gap-4 mx-6 mt-28 md:grid-cols-2 lg:grid-cols-2 pb-4"> + {myTickets.length === 0 ? ( + <div className="col-span-2 flex flex-col items-center justify-center py-10"> + <img src={ticketImg} alt="티켓" className="w-10 h-10 mb-2 opacity-50" /> + <p className="text-gray-500 text-sm">보유한 티켓이 없습니다.</p> + </div> + ) : ( {myTickets.map((ticket, index) => ( // 기존 코드 ))} + )} </div>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
public/assets/menu/completed.svgis excluded by!**/*.svgpublic/assets/menu/pending.svgis excluded by!**/*.svg
📒 Files selected for processing (6)
design-system/ui/modals/QrModal.tsx(4 hunks)src/features/dashboard/ui/ResponseFilter.tsx(1 hunks)src/features/dashboard/ui/ResponsesList.tsx(1 hunks)src/features/ticket/api/order.ts(1 hunks)src/pages/menu/ui/MyTicketPage.tsx(1 hunks)src/shared/ui/EventCard.tsx(3 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
src/pages/menu/ui/MyTicketPage.tsx (1)
src/features/ticket/api/order.ts (1)
readMyTickets(2-14)
🔇 Additional comments (13)
src/features/dashboard/ui/ResponsesList.tsx (1)
5-5: import 경로 업데이트가 잘 되었습니다.
createFieldMappings함수의 import 경로를 공유 라이브러리로 변경한 것은 좋은 리팩토링입니다. 이는 코드 재사용성과 유지보수성을 향상시킵니다.src/features/dashboard/ui/ResponseFilter.tsx (1)
4-4: import 경로 변경이 일관되게 적용되었습니다.
createFieldMappings함수의 import 경로를ResponsesList.tsx파일과 동일하게 공유 라이브러리로 변경한 것은 좋은 패턴입니다. 공통 기능을 중앙화하여 관리하는 접근 방식은 유지보수성을 높입니다.src/shared/ui/EventCard.tsx (5)
4-5: 이벤트 카드 UI 향상을 위한 이미지 추가가 좋습니다.날짜와 위치 정보에 적절한 아이콘을 추가하여 시각적으로 구분이 쉬워졌습니다.
16-16: 컴포넌트 확장성 개선이 잘 되었습니다.
children속성을 추가하여 EventCard 컴포넌트의 재사용성과 확장성을 높였습니다. 이를 통해 티켓 상태와 같은 추가 정보를 유연하게 표시할 수 있게 되었습니다.
19-19: 컴포넌트 파라미터에 children 추가가 잘 되었습니다.함수 시그니처에
children속성을 추가하여 인터페이스와 일관성을 유지했습니다.
39-47: 날짜와 위치 정보 표시 방식 개선이 잘 되었습니다.이벤트 날짜와 위치 정보를 텍스트만 표시하던 방식에서 아이콘과 함께 표시하도록 개선하여 시각적인 가독성이 향상되었습니다.
49-51: children 렌더링 부분이 적절히 구현되었습니다.컴포넌트의 확장성을 위해 추가된
children을 렌더링하는 부분이 적절한 위치에 배치되었습니다. 이를 통해 티켓 승인 상태 등의 추가 정보를 표시할 수 있게 되었습니다.design-system/ui/modals/QrModal.tsx (3)
21-21: boolean 타입에서 string 타입으로의 변경이 적절합니다.
isApproved속성을orderStatus문자열로 변경함으로써 승인 상태를 더 세부적으로 표현할 수 있게 되었습니다. 이제 단순히 승인/미승인이 아닌 다양한 상태값을 처리할 수 있습니다.
24-24: remainDays 속성의 Union 타입 정의가 명확합니다.타입 안전성을 위해
remainDays를 명확한 Union 타입으로 제한한 것이 좋습니다. 이렇게 하면 타입 오류를 컴파일 시점에 잡을 수 있습니다.
63-63: Countdown 컴포넌트에 동적 값 전달 방식이 개선되었습니다.하드코딩된 문자열 대신
remainDays값을 직접 전달하여 유연성이 향상되었습니다.src/pages/menu/ui/MyTicketPage.tsx (3)
13-28: Ticket 타입이 명확하게 정의되었습니다.Union 타입을 포함한 구체적인 속성 타입들로 Ticket 타입이 잘 정의되어 있습니다. 이는 타입 안전성을 보장하고 코드의 가독성을 높여줍니다.
32-33: 상태 관리가 적절하게 구현되었습니다.티켓 목록과 선택된 티켓을 위한 상태가 명확하게 구분되어 있습니다. 선택된 티켓의 타입을
Ticket | null로 설정한 것은 초기 상태와 선택 취소 상태를 처리하기에 좋은 방식입니다.
83-104: 모달 표시 로직이 적절하게 수정되었습니다.선택된 티켓이 있을 때만 모달이 표시되도록 조건이 추가되어 로직이 개선되었습니다. 또한 QrModal에 선택된 티켓의 정보를 적절히 전달하고 있습니다.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
src/pages/menu/ui/MyTicketPage.tsx (2)
51-80: 티켓 카드 렌더링 기능 향상티켓 카드 렌더링이 잘 구현되었습니다. 티켓 정보와 상태가 시각적으로 표시되고 있습니다. 그러나 데이터가 없는 경우에 대한 처리가 필요합니다.
다음과 같이 개선해 보세요:
<div className="grid grid-cols-2 gap-4 mx-6 mt-28 md:grid-cols-2 lg:grid-cols-2 pb-4"> + {isLoading && ( + <div className="col-span-2 text-center py-8"> + <p>티켓을 불러오는 중입니다...</p> + </div> + )} + + {!isLoading && error && ( + <div className="col-span-2 text-center py-8 text-red-500"> + <p>{error}</p> + </div> + )} + + {!isLoading && !error && myTickets.length === 0 && ( + <div className="col-span-2 text-center py-8"> + <p>구매한 티켓이 없습니다.</p> + </div> + )} + + {!isLoading && !error && myTickets.length > 0 && myTickets.map((ticket, index) => ( // 기존 코드 유지 ))} </div>
35-45: 페이지네이션 기능 추가 필요현재 코드는 첫 페이지 10개의 티켓만 가져오고 있습니다. API가 페이지네이션을 지원하므로 사용자가 더 많은 티켓을 볼 수 있도록 페이지네이션 기능을 추가하는 것이 좋습니다.
다음과 같이 구현을 고려해 보세요:
+ const [page, setPage] = useState(0); + const [hasMore, setHasMore] = useState(true); + const pageSize = 10; useEffect(() => { const fetchMyTickets = async () => { setIsLoading(true); try { - const response = await readMyTickets.get(0, 10); + const response = await readMyTickets.get(page, pageSize); - setMyTickets(response.result || []); + const newTickets = response.result || []; + setMyTickets(page === 0 ? newTickets : [...myTickets, ...newTickets]); + setHasMore(newTickets.length === pageSize); } catch (error) { console.error("티켓 목록 불러오기 실패:", error); setError("티켓 정보를 불러오는 중 오류가 발생했습니다."); } finally { setIsLoading(false); } }; fetchMyTickets(); - }, []); + }, [page]); + const loadMore = () => { + if (hasMore && !isLoading) { + setPage(prevPage => prevPage + 1); + } + };그리고 컴포넌트 하단에 "더 보기" 버튼이나 무한 스크롤 구현을 추가하세요.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
design-system/ui/modals/QrModal.tsx(4 hunks)src/pages/menu/ui/MyTicketPage.tsx(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- design-system/ui/modals/QrModal.tsx
🧰 Additional context used
🧬 Code Definitions (1)
src/pages/menu/ui/MyTicketPage.tsx (1)
src/features/ticket/api/order.ts (1)
readMyTickets(2-14)
🔇 Additional comments (4)
src/pages/menu/ui/MyTicketPage.tsx (4)
3-12: import 추가가 잘 되었습니다.필요한 모든 컴포넌트와 함수를 import했습니다. useEffect와 readMyTickets API 함수 추가가 적절합니다. 상태 이미지(completed, pending, ticket)도 잘
추가되었습니다.
13-28: Ticket 타입 정의가 잘 설계되었습니다.Ticket 타입이 필요한 모든 속성을 포함하고 있으며, 문자열 리터럴 타입을 사용하여 orderStatus의 가능한 값을 명확하게 정의한 것이 좋습니다.
32-34: 상태 관리가 적절하게 설정되었습니다.티켓 목록과 선택된 티켓을 위한 상태가 잘 정의되었습니다. 타입 지정이 명확하게 되어 있습니다.
83-104: 모달 구현이 잘 되어있습니다.선택된 티켓이 있을 때만 모달을 표시하는 조건부 렌더링이 적절합니다. 선택된 티켓의 모든 정보가 QrModal에 잘 전달되고 있습니다.
| const fetchMyTickets = async () => { | ||
| try { | ||
| const response = await readMyTickets.get(0, 10); | ||
| setMyTickets(response.result || []); | ||
| } catch (error) { | ||
| console.error("티켓 목록 불러오기 실패:", error); | ||
| } | ||
| }; | ||
| fetchMyTickets(); |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
API 에러 처리 개선 필요
현재 코드는 API 오류를 콘솔에만 기록하고 있습니다. 사용자 경험을 향상시키기 위해 오류 메시지를 표시하고 재시도 기능을 제공하는 것이 좋습니다.
API가 실패할 때 어떤 종류의 에러를 반환하는지 확인하고, 각 에러 유형에 맞는 사용자 친화적인 메시지를 표시하는 것이 좋습니다. 다음과 같은 쉘 스크립트로 API 응답을 확인해볼 수 있습니다:
🏁 Script executed:
#!/bin/bash
# API 오류 응답 형식 확인
# API 호출 예시 코드 검색
rg -A 3 -B 3 "catch \(error\)" --glob "src/features/ticket/api/*.ts"
# 오류 처리 관련 다른 참조 검색
rg "axiosClient" --glob "src/**/*.ts" | grep -i "error"Length of output: 546
API 에러 처리 개선 요청
현재 MyTicketPage.tsx의 fetchMyTickets 함수에서 API 호출 실패 시 단순히 콘솔에 에러만 기록하고 있습니다.
이와 유사하게 src/features/ticket/api/order.ts에서도 에러를 콘솔에 기록한 후 에러를 재던지는 방식으로 처리되고 있음을 확인했습니다.
다음 사항들을 개선해주시기 바랍니다:
- API 오류 발생 시 사용자에게 친절한 메시지(예: “티켓 목록을 불러오지 못했습니다. 다시 시도해주세요.”)를 UI에 표시
- 재시도 기능 또는 오류 복구 기능 구현
- API로부터 반환되는 구체적인 오류 코드나 메시지에 따라 사용자에게 적절히 안내하도록 에러 핸들링 로직 개선
이와 같이 에러 처리를 개선하여 사용자 경험을 높일 필요가 있습니다.
| useEffect(() => { | ||
| const fetchMyTickets = async () => { | ||
| try { | ||
| const response = await readMyTickets.get(0, 10); | ||
| setMyTickets(response.result || []); | ||
| } catch (error) { | ||
| console.error("티켓 목록 불러오기 실패:", error); | ||
| } | ||
| }; | ||
| fetchMyTickets(); | ||
| }, []); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
티켓 데이터 로딩 로직 개선 필요
useEffect를 사용한 데이터 로딩이 기본적으로 잘 구현되었습니다. 하지만 몇 가지 개선할 점이 있습니다:
- 로딩 상태 표시 기능이 없습니다.
- 데이터가 없는 경우에 대한 처리가 없습니다.
- 오류 발생 시 사용자에게 알림을 주는 기능이 없습니다.
다음과 같이 개선해 보세요:
+ const [isLoading, setIsLoading] = useState(false);
+ const [error, setError] = useState<string | null>(null);
useEffect(() => {
const fetchMyTickets = async () => {
+ setIsLoading(true);
+ setError(null);
try {
const response = await readMyTickets.get(0, 10);
setMyTickets(response.result || []);
} catch (error) {
console.error("티켓 목록 불러오기 실패:", error);
+ setError("티켓 정보를 불러오는 중 오류가 발생했습니다.");
} finally {
+ setIsLoading(false);
}
};
fetchMyTickets();
}, []);There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
design-system/ui/modals/QrModal.tsx (1)
13-13: Props 인터페이스에 ticketQrCode 속성 추가
ticketQrCode문자열 속성을 이용해 QR 코드를 더 유연하게 관리할 수 있게 되었습니다. 단, 이 속성이 비어있거나 유효하지 않은 형식일 때의 대체 UI 처리가 필요합니다.다음과 같이 QR 코드가 없는 경우에 대한 대체 UI를 추가하는 것을 고려해보세요:
- <img src={`data:image/png;base64,${ticketQrCode}`} alt="QR Code" className="w-60 h-60" /> + {ticketQrCode ? ( + <img src={`data:image/png;base64,${ticketQrCode}`} alt="QR Code" className="w-60 h-60" /> + ) : ( + <div className="w-60 h-60 flex items-center justify-center bg-gray-200 rounded"> + <span className="text-gray-500">QR 코드 없음</span> + </div> + )}src/pages/menu/ui/MyTicketPage.tsx (1)
1-107: 전체적인 페이지 구현에 대한 제안티켓 조회 API 연동이 잘 구현되어 있습니다. 하지만 사용자 경험 개선을 위해 다음 사항을 고려해보세요:
- 페이지네이션 또는 무한 스크롤 기능 구현
- 티켓 필터링 기능 (상태별, 날짜별 등)
- 티켓 검색 기능
이 페이지는 사용자가 자신의 구매 내역을 확인하는 중요한 페이지입니다. 티켓 수가 많아질수록 페이지네이션이나 무한 스크롤과 같은 기능이 필요할 것입니다. 또한 티켓 상태별로 필터링하거나 검색하는 기능을 추가하면 사용자 경험이 향상될 것입니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
design-system/ui/modals/QrModal.tsx(3 hunks)src/pages/menu/ui/MyTicketPage.tsx(1 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
src/pages/menu/ui/MyTicketPage.tsx (1)
src/features/ticket/api/order.ts (1)
readMyTickets(2-14)
🔇 Additional comments (10)
design-system/ui/modals/QrModal.tsx (4)
21-22: Boolean 타입에서 string 타입으로 상태 관리 개선
isApproved불리언 타입에서orderStatus문자열 타입으로 변경함으로써 더 다양한 상태를 표현할 수 있게 되었습니다. 이는 좋은 개선입니다.
24-24: D-day 표시를 위한 remainDays 속성 추가남은 날짜를 표시하기 위한
remainDays속성을 추가한 것은 좋은 개선입니다.
59-61: QR 코드 렌더링 방식 개선base64 인코딩된 QR 코드 이미지를 렌더링하는 방식으로 변경되었습니다. 이는 서버에서 전달받은 QR 코드 데이터를 직접 표시할 수 있어 효율적입니다.
92-92:Details
✅ Verification successful
주문 상태 표시 로직 개선
현재 코드는 'COMPLETED' 상태만 확인하여 '승인됨' 또는 '대기 중'으로 표시하고 있습니다. 하지만 Ticket 타입에는 'CANCELED' 상태도 정의되어 있습니다.
다음과 같이 취소된 상태도 명확히 표시하는 것이 사용자 경험을 향상시킬 수 있습니다:
- children={orderStatus === 'COMPLETED' ? '승인됨' : '대기 중'} + children={ + orderStatus === 'COMPLETED' + ? '승인됨' + : orderStatus === 'CANCELED' + ? '취소됨' + : '대기 중' + }
🌐 Web query:
주문 상태(orderStatus)를 '승인됨', '대기 중', '취소됨'과 같이 표시하는 UI 패턴 모범 사례는?💡 Result:
주문 상태를 '승인됨', '대기 중', '취소됨'으로 표시하는 UI 패턴의 모범 사례는 사용자 인지 부하를 최소화하면서 정보 전달을 명확하게 하는 데 초점을 맞춥니다. 검증된 디자인 원칙과 실제 사례를 종합하면 다음과 같은 접근 방식을 추천합니다:
1. 시각적 계층 구조 강화
- 색상 코드화: 상태별 직관적인 색상 할당(예: 승인됨=초록색 🟢, 대기 중=주황색 🟠, 취소됨=회색 ⚪) [3][7]
- 아이콘 통합: 텍스트 라벨과 함께 의미 전달을 강화하는 아이콘 사용(체크마크 ✓, 시간 아이콘 ⏳, 엑스 표시 ❌) [5][7]
- 텍스트 강조: 볼드체와 적절한 폰트 사이즈로 상태 정보 우선 노출
<!-- 샘플 코드 --> <div class="status-badge approved"> <i class="icon-check"></i> 승인됨 </div>2. 컨텍스트 기반 디스플레이
테이블 뷰 예시:
주문번호 상품명 금액 상태 #12345 스마트폰 999,000 승인됨 ✅ #12346 노트북 2,300,000 대기 중 ⏳ 카드 뷰 예시:
📦 주문 #12347 상품: 무선 이어폰 진행 상태: ▼ 취소됨 (2025-04-02 10:00)3. 상태 전환 시각화
- 진행 표시줄: 단계별 프로세스 표기(예: 결제대기 → 승인검토 → 완료) [5][9]
- 히스토리 타임라인: 상태 변경 내역을 역순으로 표시하는 인터랙티브 컴포넌트
4. 상호작용 최적화
- 호버 효과: 상태 영역 호버 시 상세 설명 툴팁 표시 [5][7]
- 필터링 기능: 상태별 주문 목록 필터링 바 구현
- 실시간 업데이트: Websocket을 활용한 상태 변화 시 배지 색상/아이콘 애니메이션 [9]
5. 접근성 보장
- ARIA 라벨: 스크린 리더 사용자를 위한 상태 설명 추가
- 대비 비율: WCAG 2.1 AA 기준 명도대비 4.5:1 이상 유지 [7]
- 다중 표기: 색각 이상 사용자를 위한 패턴/도형 조합(줄무늬, 도트) 활용
6. 반응형 디자인
- 모바일 최적화: 40px 이상의 터치 영역 확보 [3]
- 프로그레시브 디스클로저: 모바일 화면에서 ▼ 아이콘 탭 시 상세 정보 확장
7. 상태별 동작 제안
- 승인됨: 배송추적 버튼 노출
- 대기 중: 추가서류 제출 가이드 표시
- 취소됨: 재주문 CTAs(행동유도버튼) 제공 [7][8]
이 패턴들은 아마존의 주문 관리 시스템[3], 페이팔 결제 플로우[8], AWS 승인 시스템[10] 등에서 검증된 방식을 종합해 개발되었습니다. 실제 구현 시 사용자 테스트를 통해 색상/아이콘 조합의 인식도를 검증하고, 팀의 디자인 시스템 가이드라인과 통합하는 것이 중요합니다[9].
Citations:
- 1: https://www.jaenung.net/tree/13591
- 2: https://jobcan-global-wf.zendesk.com/hc/ko/articles/4407707403417-%EC%8A%B9%EC%9D%B8-%EC%B7%A8%EC%86%8C%ED%95%98%EA%B8%B0
- 3: https://faveshop.kr/blog/%EC%87%BC%ED%95%91%EB%AA%B0-ui-ux-%EB%94%94%EC%9E%90%EC%9D%B8-%EC%8B%9C-%EA%B3%A0%EB%A0%A4%ED%95%B4%EC%95%BC-%ED%95%A0-%ED%95%B5%EC%8B%AC-%EA%B0%80%EC%9D%B4%EB%93%9C%EB%9D%BC%EC%9D%B8
- 4: https://suppy1231.tistory.com/entry/%EC%9D%B8%EC%8A%A4%ED%83%80%EA%B7%B8%EB%9E%A8-%EA%B4%91%EA%B3%A0-%EC%8A%B9%EC%9D%B8-%EB%8C%80%EA%B8%B0-%EC%A4%91-%EC%B7%A8%EC%86%8C%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95-%E2%80%93-%EA%B0%84%EB%8B%A8%ED%95%9C-%EB%8B%A8%EA%B3%84%EB%B3%84-%EA%B0%80%EC%9D%B4%EB%93%9C
- 5: https://story.pxd.co.kr/718
- 6: https://blog.naver.com/tpdns1078/221842554852
- 7: https://blog.naver.com/jieunlee486/222903745614
- 8: https://www.paypal.com/kr/cshelp/article/%EC%8A%B9%EC%9D%B8%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B4%EB%A9%B0-%EB%82%B4%EA%B0%80-%EC%B7%A8%EC%86%8C%ED%95%A0-%EC%88%98-%EC%9E%88%EB%82%98%EC%9A%94-help121
- 9: https://payproglobal.com/ko/%EB%8B%B5%EB%B3%80/saas-ui-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EC%9D%B4%EB%9E%80/
- 10: https://docs.aws.amazon.com/ko_kr/workdocs/latest/userguide/cancel-approval.html
주문 상태 표시 로직 개선 적용 권고
현재 코드에서는 'COMPLETED' 상태에 대해서만 '승인됨'을 표시하고 있어 'CANCELED' 상태가 반영되지 않습니다. 최근 UI 모범 사례에 따르면 주문 상태를 '승인됨', '대기 중', '취소됨'으로 명확하게 구분하는 것이 사용자 인지 부하를 줄이고 정보 전달을 명확하게 하는 데 도움이 됩니다.
다음과 같이 변경하는 것을 권장합니다:
- children={orderStatus === 'COMPLETED' ? '승인됨' : '대기 중'} + children={ + orderStatus === 'COMPLETED' + ? '승인됨' + : orderStatus === 'CANCELED' + ? '취소됨' + : '대기 중' + }이와 함께 필요하다면 상태별 색상 코드, 아이콘, 텍스트 강조 등 시각적 계층 구조 강화 요소도 고려하여 전반적인 UX를 개선할 수 있습니다.
src/pages/menu/ui/MyTicketPage.tsx (6)
12-27: Ticket 타입 정의 추가티켓 정보를 구조화하기 위한 타입 정의가 잘 되어 있습니다. 명확한 속성 타입과 특히 'COMPLETED' | 'PENDING' | 'CANCELED'와 같이 구체적인 유니온 타입을 사용한 점이 좋습니다.
31-32: 상태 관리 로직 추가티켓 목록과 선택된 티켓을 위한 상태 관리가 적절히 구현되었습니다.
34-44: API 데이터 로딩 로직 개선 필요현재 코드는 API 호출 시 발생할 수 있는 다양한 상황(로딩 상태, 오류 상태, 데이터 없음 등)을 제대로 처리하지 않고 있습니다.
34-44: API 에러 처리 개선 필요API 호출 실패 시 단순히 콘솔에 에러만 기록하고 있어 사용자 경험이 좋지 않습니다.
50-77: 이벤트 카드 렌더링 로직 개선티켓 정보를 이벤트 카드에 표시하는 로직이 잘 구현되어 있습니다. 특히 티켓 상태에 따라 다른 아이콘을 표시하는 부분이 좋습니다.
다만, 티켓 목록이 비어있는 경우에 대한 처리가 없습니다. 다음과 같이 개선해 보세요:
<div className="grid grid-cols-2 gap-4 mx-6 mt-28 md:grid-cols-2 lg:grid-cols-2 pb-4"> + {myTickets.length === 0 ? ( + <div className="col-span-2 flex flex-col items-center justify-center p-10"> + <img src={ticketImg} alt="티켓" className="w-16 h-16 mb-4 opacity-50" /> + <p className="text-gray-500 text-center">보유한 티켓이 없습니다.</p> + </div> + ) : ( {myTickets.map((ticket, index) => ( // 기존 코드 유지 ))} + )} </div>
82-99: QR 모달 연동 구현선택된 티켓 정보가 있을 때만 모달을 표시하도록 조건부 렌더링이 잘 구현되어 있으며, QrModal 컴포넌트에 티켓 데이터가 올바르게 전달되고 있습니다.
내 티켓 조회 페이지 API 연동
티켓 상세 조회 API 연동(QR코드)
Summary by CodeRabbit