Skip to content

[fix] 지원서 미등록 시 alert 반복 버그 수정 및 외부 링크/지원서 분기 처리#605

Merged
oesnuj merged 4 commits intodevelop-fefrom
fix/#602-apply-alert-history-loop
Jul 28, 2025
Merged

[fix] 지원서 미등록 시 alert 반복 버그 수정 및 외부 링크/지원서 분기 처리#605
oesnuj merged 4 commits intodevelop-fefrom
fix/#602-apply-alert-history-loop

Conversation

@oesnuj
Copy link
Member

@oesnuj oesnuj commented Jul 28, 2025

#️⃣ 연관된 이슈

#602 지원서 없는 경우 뒤로가기 시 alert 반복 발생 버그 수정

📝 작업 내용

✅ 문제 원인

  • 기존에는 모집 기간이 진행 중인지 여부만 확인한 뒤, /application/:id로 바로 이동을 시도했습니다.
  • 하지만 모집 중인 동아리라도 모아동 지원서가 등록되지 않은 경우, 해당 페이지에서 alert이 뜨고 다시 상세 페이지로 리디렉션되는 문제가 있었고,
  • 이후 뒤로가기를 누르면 다시 /application/:id로 이동 → alert → 리디렉션이 반복되며
    alert이 무한 반복되는 UX 버그가 발생했습니다.

✅ 개선 내용

  • 입장 조건을 명확하게 분기하도록 로직을 수정했습니다:

    1. 모집 마감 여부 확인
      → 마감이면 alert 출력 후 상세페이지 유지

    2. 모아동 지원서 존재 여부 확인 (getApplication)
      → 존재하면 /application/:id로 이동

    3. 모아동 지원서가 없는 경우, 외부 지원 링크(externalApplicationUrl) 확인
      → 존재하면 새 창으로 외부 폼 이동
      → 없다면 안내 메시지 출력 후 상세페이지 유지


🫡 참고사항

  • 외부 지원 링크는 window.open(..., '_blank', 'noopener,noreferrer') 방식으로 보안 대응했습니다.

Summary by CodeRabbit

  • 신규 기능

    • 동아리 지원 버튼 클릭 시, 모집 기간이 종료된 경우 동아리명을 포함한 안내 메시지가 표시됩니다.
    • 외부 지원 URL이 등록된 경우, 지원 버튼 클릭 시 새 탭에서 해당 링크가 열립니다.
  • 버그 수정

    • 동아리 지원 버튼이 더 이상 외부에서 모집 여부를 전달받지 않고, 내부적으로 모집 기간을 판단하여 동작합니다.
  • 리팩터링

    • ClubApplyButton, ClubDetailFooter, ClubDetailHeader 컴포넌트의 props 및 내부 로직이 간소화되었습니다.
  • 타입 변경

    • 동아리 상세 정보에 외부 지원 URL(externalApplicationUrl) 속성이 추가되었습니다.

@oesnuj oesnuj self-assigned this Jul 28, 2025
@oesnuj oesnuj added 🐞 Bug Something isn't working 💻 FE Frontend 🛠Fix 기능이 의도한 대로 동작하지 않는 버그를 수정 labels Jul 28, 2025
@vercel
Copy link

vercel bot commented Jul 28, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
moadong ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 28, 2025 0:33am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 28, 2025

Warning

.coderabbit.yaml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
Validation error: Invalid regex pattern for base branch. Received: "**" at "reviews.auto_review.base_branches[0]"
⚙️ Configuration instructions
  • Please see the configuration documentation 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

Walkthrough

이 변경 사항은 동아리 상세 페이지의 지원 버튼(ClubApplyButton) 로직을 리팩토링하여, 외부에서 모집 상태를 전달받지 않고 내부적으로 동아리 상세 정보를 조회해 모집 기간과 지원 상태를 판별하도록 변경합니다. 관련 컴포넌트들의 props와 타입 정의도 이에 맞게 수정되었습니다.

Changes

Cohort / File(s) Change Summary
ClubApplyButton 리팩토링
frontend/src/pages/ClubDetailPage/components/ClubApplyButton/ClubApplyButton.tsx
isRecruiting prop 제거, 내부적으로 모집 기간 및 지원 상태를 비동기적으로 판단하도록 로직 전환. 버튼 클릭 시 모집 기간 체크, 기존 지원서 존재 여부 확인, 외부 지원 URL 처리 등 추가.
ClubDetailFooter props 정리
frontend/src/pages/ClubDetailPage/components/ClubDetailFooter/ClubDetailFooter.tsx
recruitmentForm, presidentPhoneNumber prop 제거. ClubApplyButton에 더 이상 isRecruiting prop 전달하지 않음.
ClubDetailHeader 모집 관련 로직 제거
frontend/src/pages/ClubDetailPage/components/ClubDetailHeader/ClubDetailHeader.tsx
모집 기간 파싱 및 마감 텍스트 계산 로직, 관련 prop 사용 및 유틸 import 제거. ClubApplyButtonisRecruiting prop 미전달.
ClubDetail 타입 확장
frontend/src/types/club.ts
ClubDetail 인터페이스에 externalApplicationUrl?: string 속성 추가.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ClubApplyButton
    participant useGetClubDetail
    participant getApplication
    participant Browser

    User->>ClubApplyButton: 버튼 클릭
    ClubApplyButton->>useGetClubDetail: 동아리 상세 정보 조회
    useGetClubDetail-->>ClubApplyButton: clubDetail 반환
    ClubApplyButton->>ClubApplyButton: 모집 기간 내 여부 판단
    alt 모집 기간 아님
        ClubApplyButton->>User: 모집 마감 알림
    else 모집 기간임
        ClubApplyButton->>getApplication: 기존 지원서 조회
        alt 지원서 존재
            ClubApplyButton->>Browser: 지원서 페이지로 이동
        else 지원서 없음
            alt externalApplicationUrl 존재
                ClubApplyButton->>Browser: 외부 지원 URL 새 탭 오픈
            else
                ClubApplyButton->>User: 모집 정보 확인 알림
            end
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15 minutes

Possibly related PRs

Suggested labels

📬 API

Suggested reviewers

  • seongwon030
  • lepitaaar

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/#602-apply-alert-history-loop

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • 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 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 for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for 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.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@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

🔭 Outside diff range comments (2)
frontend/src/pages/ClubDetailPage/components/ClubDetailFooter/ClubDetailFooter.tsx (1)

7-11: 사용하지 않는 props를 인터페이스에서 제거해야 합니다.

recruitmentFormpresidentPhoneNumber가 인터페이스에 정의되어 있지만 컴포넌트에서 사용되지 않습니다.

다음과 같이 수정하여 인터페이스를 정리하세요:

 interface ClubDetailFooterProps {
   recruitmentPeriod: string;
-  recruitmentForm: string;
-  presidentPhoneNumber: string;
 }
frontend/src/pages/ClubDetailPage/components/ClubDetailHeader/ClubDetailHeader.tsx (1)

5-14: 사용하지 않는 props를 인터페이스에서 제거해야 합니다.

recruitmentPeriod, recruitmentForm, presidentPhoneNumber가 인터페이스에 정의되어 있지만 컴포넌트에서 사용되지 않습니다.

다음과 같이 수정하여 인터페이스를 정리하세요:

 interface ClubDetailHeaderProps {
   name: string;
   category: string;
   division: string;
   tags: string[];
   logo: string;
-  recruitmentPeriod: string;
-  recruitmentForm?: string;
-  presidentPhoneNumber?: string;
 }
🧹 Nitpick comments (1)
frontend/src/pages/ClubDetailPage/components/ClubApplyButton/ClubApplyButton.tsx (1)

59-62: 하드코딩된 문자열을 상수로 분리해야 합니다.

'모집 마감' 문자열이 하드코딩되어 있어 유지보수성이 떨어집니다.

상수 파일에 정의하거나 유틸 함수에서 상수를 export하세요:

+ const RECRUITMENT_STATUS = {
+   CLOSED: '모집 마감',
+ } as const;

- if (deadlineText === '모집 마감') {
+ if (deadlineText === RECRUITMENT_STATUS.CLOSED) {
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 91a4ef2 and 2f18946.

📒 Files selected for processing (4)
  • frontend/src/pages/ClubDetailPage/components/ClubApplyButton/ClubApplyButton.tsx (2 hunks)
  • frontend/src/pages/ClubDetailPage/components/ClubDetailFooter/ClubDetailFooter.tsx (2 hunks)
  • frontend/src/pages/ClubDetailPage/components/ClubDetailHeader/ClubDetailHeader.tsx (2 hunks)
  • frontend/src/types/club.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
frontend/**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (frontend/.cursorrules)

frontend/**/*.{ts,tsx}: Replace magic numbers with named constants for clarity.
Replace complex or nested ternary operators with if/else statements or IIFEs for readability.
Assign complex boolean conditions to named variables.
Use consistent return types for similar functions and hooks.
Avoid hidden side effects; functions should only perform actions implied by their signature (Single Responsibility Principle).
Use unique, descriptive names for custom wrappers and functions to avoid ambiguity.
Define constants near related logic or ensure names link them clearly.

Files:

  • frontend/src/types/club.ts
  • frontend/src/pages/ClubDetailPage/components/ClubDetailFooter/ClubDetailFooter.tsx
  • frontend/src/pages/ClubDetailPage/components/ClubDetailHeader/ClubDetailHeader.tsx
  • frontend/src/pages/ClubDetailPage/components/ClubApplyButton/ClubApplyButton.tsx
frontend/**/*.tsx

📄 CodeRabbit Inference Engine (frontend/.cursorrules)

frontend/**/*.tsx: Abstract complex logic/interactions into dedicated components or higher-order components (HOCs).
Separate significantly different conditional UI/logic into distinct components.
Colocate simple, localized logic or use inline definitions to reduce context switching.
Choose field-level or form-level cohesion based on form requirements.
Break down broad state management into smaller, focused hooks or contexts.
Use component composition instead of props drilling.

Files:

  • frontend/src/pages/ClubDetailPage/components/ClubDetailFooter/ClubDetailFooter.tsx
  • frontend/src/pages/ClubDetailPage/components/ClubDetailHeader/ClubDetailHeader.tsx
  • frontend/src/pages/ClubDetailPage/components/ClubApplyButton/ClubApplyButton.tsx
🧠 Learnings (5)
📓 Common learnings
Learnt from: seongwon030
PR: Moadong/moadong#195
File: frontend/src/pages/AdminPage/AdminPage.tsx:7-7
Timestamp: 2025-03-19T05:18:07.818Z
Learning: AdminPage.tsx에서 현재 하드코딩된 클럽 ID('67d2e3b9b15c136c6acbf20b')는 로그인 기능 구현 후 동적으로 가져오는 방식으로 수정될 예정입니다.
Learnt from: seongwon030
PR: Moadong/moadong#548
File: frontend/src/pages/ClubDetailPage/ClubDetailPage.tsx:17-57
Timestamp: 2025-07-19T05:05:10.196Z
Learning: ClubDetailPage.tsx에서 notJoinedClubNames 배열의 하드코딩은 의도적인 설계 결정입니다. 개발자가 명시적으로 하드코딩을 선택했으므로 이에 대한 리팩토링 제안을 하지 않아야 합니다.
Learnt from: lepitaaar
PR: Moadong/moadong#406
File: backend/src/main/java/moadong/club/service/ClubApplyService.java:34-38
Timestamp: 2025-05-19T05:45:52.957Z
Learning: The code duplication between createClubApplication and editClubApplication methods in ClubApplyService.java is acknowledged but will be addressed in a future refactoring, as per the developer's plan.
Learnt from: Zepelown
PR: Moadong/moadong#406
File: backend/src/main/java/moadong/club/entity/ClubApplicationQuestion.java:32-33
Timestamp: 2025-05-15T12:03:57.356Z
Learning: 엔티티 클래스는 요청/응답 객체(DTO)에 의존해서는 안 됩니다. 계층 간 의존성 문제를 방지하기 위해 엔티티와 DTO는 분리되어야 합니다. 예를 들어, `ClubApplicationQuestion` 엔티티가 `ClubApplicationRequest.Options`와 같은 요청 객체를 직접 참조하는 대신, 엔티티 패키지 내에 `QuestionOptions`와 같은 별도의 클래스를 정의하고 사용해야 합니다. 이렇게 하면 요청 객체 변경이 데이터베이스 스키마나 엔티티 계층에 영향을 미치지 않습니다.
frontend/src/types/club.ts (2)

Learnt from: lepitaaar
PR: #406
File: backend/src/main/java/moadong/club/service/ClubApplyService.java:34-38
Timestamp: 2025-05-19T05:45:52.957Z
Learning: The code duplication between createClubApplication and editClubApplication methods in ClubApplyService.java is acknowledged but will be addressed in a future refactoring, as per the developer's plan.

Learnt from: seongwon030
PR: #548
File: frontend/src/pages/ClubDetailPage/ClubDetailPage.tsx:17-57
Timestamp: 2025-07-19T05:05:10.196Z
Learning: ClubDetailPage.tsx에서 notJoinedClubNames 배열의 하드코딩은 의도적인 설계 결정입니다. 개발자가 명시적으로 하드코딩을 선택했으므로 이에 대한 리팩토링 제안을 하지 않아야 합니다.

frontend/src/pages/ClubDetailPage/components/ClubDetailFooter/ClubDetailFooter.tsx (8)

Learnt from: seongwon030
PR: #195
File: frontend/src/pages/AdminPage/AdminPage.tsx:7-7
Timestamp: 2025-03-19T05:18:07.818Z
Learning: AdminPage.tsx에서 현재 하드코딩된 클럽 ID('67d2e3b9b15c136c6acbf20b')는 로그인 기능 구현 후 동적으로 가져오는 방식으로 수정될 예정입니다.

Learnt from: seongwon030
PR: #548
File: frontend/src/pages/ClubDetailPage/ClubDetailPage.tsx:17-57
Timestamp: 2025-07-19T05:05:10.196Z
Learning: ClubDetailPage.tsx에서 notJoinedClubNames 배열의 하드코딩은 의도적인 설계 결정입니다. 개발자가 명시적으로 하드코딩을 선택했으므로 이에 대한 리팩토링 제안을 하지 않아야 합니다.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Use component composition instead of props drilling.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Separate significantly different conditional UI/logic into distinct components.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Choose field-level or form-level cohesion based on form requirements.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Colocate simple, localized logic or use inline definitions to reduce context switching.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Abstract complex logic/interactions into dedicated components or higher-order components (HOCs).

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.{ts,tsx} : Replace magic numbers with named constants for clarity.

frontend/src/pages/ClubDetailPage/components/ClubDetailHeader/ClubDetailHeader.tsx (10)

Learnt from: seongwon030
PR: #548
File: frontend/src/pages/ClubDetailPage/ClubDetailPage.tsx:17-57
Timestamp: 2025-07-19T05:05:10.196Z
Learning: ClubDetailPage.tsx에서 notJoinedClubNames 배열의 하드코딩은 의도적인 설계 결정입니다. 개발자가 명시적으로 하드코딩을 선택했으므로 이에 대한 리팩토링 제안을 하지 않아야 합니다.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Separate significantly different conditional UI/logic into distinct components.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Colocate simple, localized logic or use inline definitions to reduce context switching.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Abstract complex logic/interactions into dedicated components or higher-order components (HOCs).

Learnt from: seongwon030
PR: #195
File: frontend/src/pages/AdminPage/AdminPage.tsx:7-7
Timestamp: 2025-03-19T05:18:07.818Z
Learning: AdminPage.tsx에서 현재 하드코딩된 클럽 ID('67d2e3b9b15c136c6acbf20b')는 로그인 기능 구현 후 동적으로 가져오는 방식으로 수정될 예정입니다.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.{ts,tsx} : Replace magic numbers with named constants for clarity.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Use component composition instead of props drilling.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.{ts,tsx} : Replace complex or nested ternary operators with if/else statements or IIFEs for readability.

Learnt from: lepitaaar
PR: #406
File: backend/src/main/java/moadong/club/service/ClubApplyService.java:34-38
Timestamp: 2025-05-19T05:45:52.957Z
Learning: The code duplication between createClubApplication and editClubApplication methods in ClubApplyService.java is acknowledged but will be addressed in a future refactoring, as per the developer's plan.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.{ts,tsx} : Define constants near related logic or ensure names link them clearly.

frontend/src/pages/ClubDetailPage/components/ClubApplyButton/ClubApplyButton.tsx (9)

Learnt from: seongwon030
PR: #195
File: frontend/src/pages/AdminPage/AdminPage.tsx:7-7
Timestamp: 2025-03-19T05:18:07.818Z
Learning: AdminPage.tsx에서 현재 하드코딩된 클럽 ID('67d2e3b9b15c136c6acbf20b')는 로그인 기능 구현 후 동적으로 가져오는 방식으로 수정될 예정입니다.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Separate significantly different conditional UI/logic into distinct components.

Learnt from: lepitaaar
PR: #406
File: backend/src/main/java/moadong/club/service/ClubApplyService.java:34-38
Timestamp: 2025-05-19T05:45:52.957Z
Learning: The code duplication between createClubApplication and editClubApplication methods in ClubApplyService.java is acknowledged but will be addressed in a future refactoring, as per the developer's plan.

Learnt from: seongwon030
PR: #548
File: frontend/src/pages/ClubDetailPage/ClubDetailPage.tsx:17-57
Timestamp: 2025-07-19T05:05:10.196Z
Learning: ClubDetailPage.tsx에서 notJoinedClubNames 배열의 하드코딩은 의도적인 설계 결정입니다. 개발자가 명시적으로 하드코딩을 선택했으므로 이에 대한 리팩토링 제안을 하지 않아야 합니다.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Abstract complex logic/interactions into dedicated components or higher-order components (HOCs).

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.{ts,tsx} : Use consistent return types for similar functions and hooks.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Use component composition instead of props drilling.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Colocate simple, localized logic or use inline definitions to reduce context switching.

Learnt from: CR
PR: Moadong/moadong#0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.tsx : Break down broad state management into smaller, focused hooks or contexts.

🔇 Additional comments (5)
frontend/src/types/club.ts (1)

26-26: 외부 지원서 URL 지원을 위한 타입 추가가 적절합니다.

externalApplicationUrl 옵셔널 프로퍼티 추가로 외부 지원서 링크 처리가 가능해졌습니다.

frontend/src/pages/ClubDetailPage/components/ClubDetailFooter/ClubDetailFooter.tsx (1)

28-28: ClubApplyButton의 props 제거가 적절합니다.

모집 상태 로직이 ClubApplyButton 내부로 이동하여 컴포넌트 간 결합도가 낮아졌습니다.

frontend/src/pages/ClubDetailPage/components/ClubDetailHeader/ClubDetailHeader.tsx (1)

32-32: ClubApplyButton의 props 제거가 적절합니다.

모집 상태 판단 로직이 ClubApplyButton으로 중앙화되어 관심사 분리가 잘 이루어졌습니다.

frontend/src/pages/ClubDetailPage/components/ClubApplyButton/ClubApplyButton.tsx (2)

72-72: 외부 링크 보안 처리가 적절합니다.

window.opennoopener,noreferrer 속성을 사용하여 보안 취약점을 방지한 것이 좋습니다.


64-76: 무한 alert 루프 버그 수정이 잘 구현되었습니다.

PR 목표에 따라 지원서 존재 여부를 먼저 확인한 후 외부 링크 처리로 분기하여 무한 alert 루프를 해결했습니다. 로직 흐름이 명확하고 적절합니다.

Copy link
Member

@seongwon030 seongwon030 left a comment

Choose a reason for hiding this comment

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

정말 고생하셨습니다

Copy link
Member

@Zepelown Zepelown left a comment

Choose a reason for hiding this comment

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

찾기 어려운 버그였는데 정말 고생 많으셨습니다!

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

Labels

🐞 Bug Something isn't working 💻 FE Frontend 🛠Fix 기능이 의도한 대로 동작하지 않는 버그를 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments