Skip to content

fix: 내 티켓 페이지 개선#148

Merged
Yejiin21 merged 9 commits intodevelopfrom
fix/#147/ticket-delete-error
May 29, 2025
Merged

fix: 내 티켓 페이지 개선#148
Yejiin21 merged 9 commits intodevelopfrom
fix/#147/ticket-delete-error

Conversation

@Yejiin21
Copy link
Copy Markdown
Contributor

@Yejiin21 Yejiin21 commented May 29, 2025

  • 주문 취소 API 에러 수정

  • 내 티켓 페이지 주문 취소 기능 추가

스크린샷 2025-05-29 오후 5 30 07 스크린샷 2025-05-29 오후 5 30 13

Summary by CodeRabbit

  • New Features

    • 마이티켓 페이지에서 여러 티켓을 선택해 한 번에 취소할 수 있는 기능이 추가되었습니다.
    • 티켓 취소 시 확인 모달이 표시되어, 선택한 티켓을 안전하게 취소할 수 있습니다.
    • 티켓 리스트가 개별적으로 관리되어, 취소 후 실시간으로 갱신됩니다.
  • UI 개선

    • 티켓 선택 및 취소 모드에서 시각적 강조 효과가 적용되어, 선택된 티켓을 쉽게 구분할 수 있습니다.
    • 티켓 레이아웃과 카드 컴포넌트에 외부 스타일 클래스 적용이 가능해졌습니다.
    • 티켓 페이지 상단 안내 문구가 취소 모드에 따라 동적으로 변경됩니다.
  • 기타 개선

    • 일부 입력값 및 타입이 명확하게 개선되어 안정성이 향상되었습니다.
    • 티켓 옵션 타입이 통합되어 코드 일관성이 높아졌습니다.
    • 티켓 취소 API 경로가 RESTful 방식으로 변경되어 안정성이 개선되었습니다.

@Yejiin21 Yejiin21 requested a review from hyeeuncho May 29, 2025 08:32
@Yejiin21 Yejiin21 self-assigned this May 29, 2025
@Yejiin21 Yejiin21 added 🛠️ BugFix 오류 해결 과정 기록 🔧 Feature 기능 구현 labels May 29, 2025
@Yejiin21 Yejiin21 linked an issue May 29, 2025 that may be closed by this pull request
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented May 29, 2025

Caution

Review failed

The pull request is closed.

## Walkthrough

티켓 취소 기능이 대폭 개선되어, 사용자가 여러 티켓을 선택해 한 번에 취소할 수 있는 모드와 UI가 추가되었습니다. API 경로가 RESTful 스타일로 변경되었고, 타입 선언 및 컴포넌트 인터페이스가 확장되었습니다. 코드 스타일과 타입 일관성도 강화되었습니다.

## Changes

| 파일/경로 요약                                                         | 변경 내용 요약                                                                                                    |
|------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|
| src/features/ticket/api/order.ts                                       | API import 스타일 변경, `cancelTickets` 함수의 엔드포인트를 RESTful 경로(`/orders/${orderId}/cancel`)로 변경         |
| src/features/ticket/hooks/useOrderHook.ts                              | 들여쓰기, 콤마 등 코드 스타일만 정비                                                                               |
| src/features/ticket/hooks/useTicketOptionHook.ts                       | import 정비, 타입 명시 강화, mutation 타입 변경(`TicketResponse``ApiResponse<null>`), ticketId null 체크 추가   |
| src/features/ticket/model/Order.ts                                     | `OrderTicketResponse` 인터페이스 추가, import 보강, 기존 인터페이스 포맷 정비                                      |
| src/features/ticket/model/ticketInformation.ts                         | `TicketOptionType` 타입 별도 선언 및 적용, `CreateTicketRequest`에서 시간 필드 제거, 포맷 정비                      |
| src/pages/menu/ui/MyTicketPage.ts                                     | 다중 선택 티켓 취소 모드, 상태 및 UI 추가, 로컬 티켓 상태 관리, 취소 모달 연동, 타입 개선 등 대규모 기능 확장        |
| src/shared/ui/EventCard.tsx                                            | `className` prop 추가 및 적용, 외부 스타일링 가능                                                                  |
| src/shared/ui/backgrounds/TicketHostLayout.tsx                         | `isCancelMode` prop 추가, 안내 메시지 조건부 변경                                                                  |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant MyTicketPage
    participant TicketHostLayout
    participant EmailDeleteModal
    participant API

    User->>MyTicketPage: "티켓 취소" 모드 진입 버튼 클릭
    MyTicketPage->>MyTicketPage: isCancelMode = true
    MyTicketPage->>TicketHostLayout: isCancelMode 전달
    User->>MyTicketPage: 여러 티켓 클릭(선택/해제)
    User->>MyTicketPage: "선택 티켓 취소" 버튼 클릭
    MyTicketPage->>MyTicketPage: 선택 티켓 없으면 alert
    MyTicketPage->>EmailDeleteModal: 모달 오픈
    User->>EmailDeleteModal: 취소 확정 클릭
    EmailDeleteModal->>MyTicketPage: onApprove 호출
    loop 선택된 각 티켓
        MyTicketPage->>API: cancelTickets(orderId)
    end
    API-->>MyTicketPage: 응답 반환
    MyTicketPage->>MyTicketPage: 티켓 목록에서 취소된 티켓 제거, 모달 닫기, 상태 초기화

Possibly related PRs

Suggested reviewers

  • hyeeuncho

Poem

🐇
티켓을 들고 깡총깡총
한 번에 취소, 이제는 가능!
여러 장 골라서 쿡쿡 눌러
모달 열고, 확인 누르면
내 티켓 목록이 산뜻하게
깔끔하게 정리되는
토끼도 좋아할 새 기능!
🥕


<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->

---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between dc514f5c6cdb23e9a319b729aa65d2b3df9c53ea and f55f997efb343952ea1593a159276ba59c0b1398.

</details>

<details>
<summary>📒 Files selected for processing (2)</summary>

* `src/features/event/model/FunnelContext.tsx` (1 hunks)
* `src/features/ticket/model/TicketContext.tsx` (0 hunks)

</details>

</details>
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=GoTogether-Inc/frontend&utm_content=148):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

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)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

@github-actions
Copy link
Copy Markdown

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/features/ticket/model/Order.ts (1)

9-27: 포괄적인 응답 타입 정의 추가

OrderTicketResponse 인터페이스가 잘 설계되었습니다. 이벤트 상세정보, 티켓 정보, 주문 상태를 포괄적으로 다루고 있어 타입 안전성이 크게 향상됩니다.

몇 가지 개선 제안:

  1. remainDays가 문자열 타입인데, 숫자 타입이 더 적절할 수 있습니다
  2. startDate에 대한 명확한 포맷 정의를 JSDoc으로 추가하는 것을 고려해보세요

다음과 같은 개선을 고려해보세요:

export interface OrderTicketResponse {
  id: number;
  event: {
    id: number;
    bannerImageUrl: string;
    title: string;
    hostChannelName: string;
    address: string;
+   /** ISO 8601 형식의 시작 날짜 */
    startDate: string;
+   /** 남은 일수 */
-   remainDays: string;
+   remainDays: number;
    hashtags: string[];
    onlineType: OnlineType;
  };
  ticketQrCode: string;
  ticketName: string;
  ticketPrice: number;
  orderStatus: 'COMPLETED' | 'PENDING' | 'CANCELED';
  checkIn: boolean;
}
src/shared/ui/backgrounds/TicketHostLayout.tsx (1)

56-56: 사용자 친화적인 조건부 텍스트 표시

취소 모드에 따른 조건부 텍스트 표시가 사용자 경험을 향상시킵니다. 명확한 안내 메시지를 제공합니다.

유지보수성 향상을 위해 텍스트를 상수로 분리하는 것을 고려해보세요.

다음과 같은 개선을 고려해보세요:

+const TICKET_MODE_MESSAGES = {
+  CANCEL: '취소할 티켓을 선택해주세요',
+  NORMAL: '티켓을 누르면 입장을 위한 QR코드를 확인할 수 있습니다.'
+} as const;

// ...

-{isCancelMode ? '취소할 티켓을 선택해주세요' : '티켓을 누르면 입장을 위한 QR코드를 확인할 수 있습니다.'}
+{isCancelMode ? TICKET_MODE_MESSAGES.CANCEL : TICKET_MODE_MESSAGES.NORMAL}
src/pages/menu/ui/MyTicketPage.tsx (1)

46-46: 더 나은 UX를 위해 alert 대신 Toast나 Modal 사용을 고려해보세요.

브라우저 기본 alert는 사용자 경험을 저해합니다.

-alert('취소할 티켓을 선택해주세요.');
+// Toast 컴포넌트 사용 예시
+showToast('취소할 티켓을 선택해주세요.', 'warning');
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b8153a7 and c37bf61.

📒 Files selected for processing (8)
  • src/features/ticket/api/order.ts (2 hunks)
  • src/features/ticket/hooks/useOrderHook.ts (1 hunks)
  • src/features/ticket/hooks/useTicketOptionHook.ts (1 hunks)
  • src/features/ticket/model/Order.ts (1 hunks)
  • src/features/ticket/model/ticketInformation.ts (3 hunks)
  • src/pages/menu/ui/MyTicketPage.tsx (3 hunks)
  • src/shared/ui/EventCard.tsx (3 hunks)
  • src/shared/ui/backgrounds/TicketHostLayout.tsx (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
src/features/ticket/hooks/useOrderHook.ts (2)
src/features/ticket/api/order.ts (3)
  • readTicket (4-17)
  • cancelTickets (26-29)
  • orderTickets (20-23)
src/features/ticket/model/orderInformation.ts (1)
  • OrderTicketRequest (3-8)
src/features/ticket/api/order.ts (1)
src/shared/types/api/http-client.ts (1)
  • axiosClient (6-13)
src/features/ticket/hooks/useTicketOptionHook.ts (3)
src/features/ticket/model/ticketInformation.ts (4)
  • TicketOptionResponse (26-33)
  • TicketOptionAnswerRequest (36-41)
  • TicketOptionAnswerResponse (48-53)
  • PersonalTicketOptionAnswerResponse (56-59)
src/features/ticket/api/ticketOption.ts (4)
  • readTicketOptions (5-8)
  • createTicketOptionAnswers (11-14)
  • readPurchaserAnswers (17-22)
  • readPersonalTicketOptionAnswers (25-30)
src/shared/types/api/apiResponse.ts (1)
  • ApiResponse (1-5)
src/features/ticket/model/Order.ts (1)
src/shared/types/baseEventType.ts (1)
  • OnlineType (1-1)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: storybook
🔇 Additional comments (15)
src/features/ticket/api/order.ts (2)

1-2: 일관성 개선: 단일 따옴표 사용

import 문에서 이중 따옴표를 단일 따옴표로 변경한 것은 코드 스타일 일관성을 위한 좋은 개선입니다.


27-27:

Details

❓ Verification inconclusive

RESTful API 엔드포인트로 개선됨

API 엔드포인트가 쿼리 파라미터 방식에서 RESTful 경로 파라미터 방식으로 변경되어 더 나은 API 설계를 따르고 있습니다. 백엔드 API가 이 변경사항을 지원하는지 확인해주세요.

다음 스크립트를 실행하여 이 함수의 사용처를 확인해보세요:


🏁 Script executed:

#!/bin/bash
# Description: cancelTickets 함수 사용처 확인
# Expected: 모든 호출부가 새로운 API 엔드포인트와 호환되는지 확인

rg -A 3 "cancelTickets" --type ts

Length of output: 939


RESTful API 엔드포인트 적용 확인

cancelTickets 함수와 그 호출부가 모두 새로운 경로(/orders/:orderId/cancel)로 변경된 것을 확인했습니다.

  • src/features/ticket/api/order.ts: cancelTickets 함수 정의
  • src/features/ticket/hooks/useOrderHook.ts: 해당 함수 호출부

백엔드 API가 이 경로를 정상 지원하는지 한 번 더 확인 부탁드립니다.

src/features/ticket/model/Order.ts (1)

1-1: 적절한 타입 import 추가

OnlineType import가 새로운 OrderTicketResponse 인터페이스에서 사용되어 타입 안전성을 제공합니다.

src/shared/ui/backgrounds/TicketHostLayout.tsx (2)

11-11: 취소 모드 지원을 위한 적절한 prop 추가

isCancelMode prop 추가가 잘 설계되었습니다. 선택적 boolean 타입으로 정의되어 기존 코드와의 호환성을 유지합니다.


19-19: 기본값 설정으로 호환성 보장

isCancelMode = false 기본값 설정으로 기존 컴포넌트 사용처와의 호환성을 보장합니다.

src/features/ticket/hooks/useOrderHook.ts (4)

7-11: 코드 포매팅 개선

일관된 들여쓰기와 쉼표 배치로 코드 가독성이 향상되었습니다.


15-20: 일관된 포매팅 적용

useTicketOrderDetail 훅의 포매팅이 다른 훅들과 일관성 있게 개선되었습니다.


24-33: useCancelTicket 훅 포매팅 개선

mutation 설정의 포매팅이 깔끔하게 정리되어 가독성이 향상되었습니다. 성공/실패 콜백 처리도 적절합니다.


37-43: useOrderTicket 훅 포매팅 완료

마지막 훅의 포매팅도 일관성 있게 개선되어 전체 파일의 코드 스타일이 통일되었습니다.

src/shared/ui/EventCard.tsx (1)

23-23: 좋은 개선입니다!

className prop 추가로 컴포넌트의 재사용성이 향상되었습니다. 외부에서 스타일을 주입할 수 있게 되어 MyTicketPage에서 선택된 카드의 시각적 피드백을 제공하는 데 활용되고 있습니다.

Also applies to: 39-39, 54-54

src/features/ticket/hooks/useTicketOptionHook.ts (2)

1-14: 타입 일관성이 개선되었습니다!

ApiResponse 타입 사용으로 API 응답 처리가 일관되게 되었습니다.

Also applies to: 27-27


43-46: 런타임 안전성이 향상되었습니다!

ticketId null 체크를 추가하여 더 명시적인 에러 처리가 가능해졌습니다. enabled 조건과 함께 이중 방어 역할을 합니다.

Also applies to: 57-60

src/features/ticket/model/ticketInformation.ts (1)

1-1: DRY 원칙을 잘 적용한 리팩토링입니다!

TicketOptionType 타입 별칭을 도입하여 코드 중복을 제거하고 유지보수성을 향상시켰습니다. 향후 옵션 타입이 변경되더라도 한 곳에서만 수정하면 됩니다.

Also applies to: 30-30, 51-51, 66-66

src/pages/menu/ui/MyTicketPage.tsx (2)

26-31: 데이터 동기화가 잘 구현되었습니다.

useEffect를 통해 서버 데이터와 로컬 상태를 동기화하여 취소된 티켓을 즉시 UI에서 제거할 수 있게 되었습니다.


84-86: 선택된 티켓의 시각적 피드백이 잘 구현되었습니다!

scale과 border를 이용한 선택 표시가 직관적입니다. transition 효과도 부드러운 UX를 제공합니다.

Comment on lines +3 to 12
export interface CreateTicketRequest {
eventId: number;
ticketType: string;
ticketName: string;
ticketDescription: string;
ticketPrice: number;
availableQuantity: number;
startDate: string;
endDate: string;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

API 스펙 변경이 반영되었습니다.

startTimeendTime 필드가 제거되었습니다. 이 변경사항이 백엔드 API와 일치하는지 확인이 필요합니다.

다음 스크립트를 실행하여 CreateTicketRequest 사용처를 확인합니다:


🏁 Script executed:

#!/bin/bash
# Description: CreateTicketRequest 타입 사용처 확인

# CreateTicketRequest를 사용하는 코드 검색
ast-grep --pattern 'CreateTicketRequest'

# startTime 또는 endTime을 참조하는 코드가 있는지 확인
rg -A 5 'startTime|endTime' --glob '**/*.{ts,tsx}'

Length of output: 8537


🏁 Script executed:

#!/bin/bash
# Show the contents of TicketContext.tsx to verify state shape
sed -n '1,200p' src/features/ticket/model/TicketContext.tsx

Length of output: 1307


startTime·endTime 제거 반영: UI 상태 타입 및 구현 동기화 필요

백엔드 API 스펙에 맞춰 CreateTicketRequest에서 startTime·endTime을 제거하셨으나, 아래 UI 코드들이 여전히 해당 필드를 사용하고 있어 타입 불일치 및 런타임 오류가 발생합니다. API용 타입과 폼용 상태를 분리하거나, UI 상태 타입을 별도로 선언하여 구현을 수정해주세요.

주의할 파일 및 위치:

  • src/features/ticket/model/TicketContext.tsx
    useState<CreateTicketRequest>({... startTime: '06:00', endTime: '23:00' })
  • src/features/ticket/ui/TicketDatePicker.tsx
    onDateChange 인자 · 훅 의존성 배열에 startTime, endTime 참조
  • src/pages/dashboard/ui/ticket/TicketCreatePage.tsx
    ticketData 상태에 startTime, endTime 할당
  • 필요 시 CreateTicketRequest 사용처 전체 점검

제안:

  • CreateTicketRequest는 API 호출용으로만 사용하고, 폼 상태는 별도 인터페이스(ex. TicketFormState)로 관리
  • 폼 상태에서 날짜·시간을 합쳐 startDate, endDate만 API에 전달하도록 매핑 로직 추가
🤖 Prompt for AI Agents
In src/features/ticket/model/ticketInformation.ts lines 3 to 12, the
CreateTicketRequest interface was updated to remove startTime and endTime fields
to match backend API changes. However, UI code in TicketContext.tsx,
TicketDatePicker.tsx, and TicketCreatePage.tsx still references these removed
fields, causing type mismatches and runtime errors. To fix this, create a
separate interface (e.g., TicketFormState) for the UI form state that includes
startTime and endTime, keep CreateTicketRequest for API calls only, and
implement mapping logic to combine date and time fields into startDate and
endDate before sending data to the API. Update all affected UI components to use
the new form state interface instead of CreateTicketRequest directly.

Comment on lines +137 to +143
Promise.all(selectedIds.map(id => cancelTicket(id))).then(() => {
setTickets(prev => prev.filter(ticket => !selectedIds.includes(ticket.id)));
setIsDeleteModalOpen(false);
setIsCancelMode(false);
setSelectedIds([]);
});
}}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

에러 처리와 로딩 상태를 추가해야 합니다.

현재 구현은 다음 문제점들이 있습니다:

  1. 일부 취소 실패 시 전체가 실패할 수 있음
  2. 취소 중 로딩 표시가 없음
  3. 실패한 티켓에 대한 롤백 처리 없음
+const [isCancelling, setIsCancelling] = useState(false);

 onClick={() => {
+  setIsCancelling(true);
-  Promise.all(selectedIds.map(id => cancelTicket(id))).then(() => {
-    setTickets(prev => prev.filter(ticket => !selectedIds.includes(ticket.id)));
-    setIsDeleteModalOpen(false);
-    setIsCancelMode(false);
-    setSelectedIds([]);
-  });
+  Promise.allSettled(selectedIds.map(id => 
+    new Promise((resolve) => {
+      cancelTicket(id, {
+        onSuccess: () => resolve({ id, success: true }),
+        onError: (error) => resolve({ id, success: false, error })
+      });
+    })
+  )).then(results => {
+    const successIds = results
+      .filter((result, index) => result.status === 'fulfilled' && result.value.success)
+      .map((_, index) => selectedIds[index]);
+    
+    const failedCount = selectedIds.length - successIds.length;
+    
+    if (successIds.length > 0) {
+      setTickets(prev => prev.filter(ticket => !successIds.includes(ticket.id)));
+    }
+    
+    if (failedCount > 0) {
+      showToast(`${failedCount}개의 티켓 취소에 실패했습니다.`, 'error');
+    }
+    
+    setIsCancelling(false);
+    setIsDeleteModalOpen(false);
+    setIsCancelMode(false);
+    setSelectedIds([]);
+  });
 }}

로딩 상태 표시를 위해 Modal에 isLoading={isCancelling} prop을 추가하는 것도 고려해보세요.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/pages/menu/ui/MyTicketPage.tsx around lines 137 to 143, the current
Promise.all call for cancelTicket lacks error handling, loading state
management, and rollback for failed cancellations. Introduce an isCancelling
state to track loading, set it to true before starting cancellations and false
after completion or error. Use Promise.allSettled to handle each cancellation
result individually, update tickets only for successfully cancelled ones, and
handle failures appropriately, possibly showing an error message. Also, pass
isCancelling as isLoading prop to the Modal to display loading status during
cancellation.

@github-actions
Copy link
Copy Markdown

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/pages/menu/ui/MyTicketPage.tsx (1)

152-158: ⚠️ Potential issue

에러 처리와 로딩 상태 개선이 필요합니다.

현재 Promise.all 구현은 이전 리뷰에서 지적된 문제점들이 여전히 존재합니다:

  1. 일부 취소 실패 시 전체가 실패할 수 있음
  2. 취소 중 로딩 표시가 없음
  3. 실패한 티켓에 대한 개별 처리 없음

이전 리뷰 제안사항을 적용하여 Promise.allSettled 사용과 로딩 상태 관리를 구현해주세요.

🧹 Nitpick comments (1)
src/pages/menu/ui/MyTicketPage.tsx (1)

26-49: 유효성 검사 로직이 우수하지만 UX 개선이 필요합니다.

이벤트 시작일 검증 로직이 잘 구현되어 있으나, alert() 사용은 사용자 경험 측면에서 개선이 필요합니다.

다음과 같이 토스트 메시지로 개선하는 것을 고려해보세요:

-        alert('이미 시작된 이벤트의 티켓은 취소할 수 없습니다.');
+        showToast('이미 시작된 이벤트의 티켓은 취소할 수 없습니다.', 'error');
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c37bf61 and dc514f5.

📒 Files selected for processing (1)
  • src/pages/menu/ui/MyTicketPage.tsx (3 hunks)
🔇 Additional comments (5)
src/pages/menu/ui/MyTicketPage.tsx (5)

3-3: 새로운 import들이 적절히 추가되었습니다.

티켓 취소 기능을 위한 필요한 훅, 타입, 컴포넌트들이 올바르게 import되었습니다.

Also applies to: 10-13


17-21: 상태 변수 선언이 적절합니다.

다중 티켓 취소 기능을 위한 상태 변수들이 적절한 타입으로 선언되었습니다. 특히 OrderTicketResponse 타입 사용으로 타입 안전성이 향상되었습니다.


51-55: 데이터 동기화 로직이 올바릅니다.

서버에서 받은 데이터를 로컬 상태로 동기화하는 useEffect가 적절히 구현되었습니다.


58-69: 취소 모드 UI가 잘 구현되었습니다.

조건부 렌더링과 버튼 라벨 변경 로직이 사용자 친화적으로 구현되었습니다. 모달이 열려있을 때 버튼을 숨기는 것도 좋은 UX입니다.


90-101: 선택 모드 상호작용이 직관적입니다.

취소 모드에서의 티켓 선택/해제 로직과 시각적 피드백(크기 조정, 테두리)이 사용자가 이해하기 쉽게 구현되었습니다.

Copy link
Copy Markdown
Member

@hyeeuncho hyeeuncho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

티켓 취소가 구매 당시에만 가능 했었는데 잘 구현해주셨네요~ 고예진 짱짱 최고

@Yejiin21 Yejiin21 merged commit 7e13702 into develop May 29, 2025
1 of 2 checks passed
@Yejiin21 Yejiin21 deleted the fix/#147/ticket-delete-error branch May 29, 2025 09:13
@github-actions
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🛠️ BugFix 오류 해결 과정 기록 🔧 Feature 기능 구현

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[fix] 구매 취소 API 에러 수정

2 participants