Skip to content

Comments

[feature] 관리자페이지 수정하기 api 연동#195

Merged
seongwon030 merged 33 commits intodevelop/fefrom
feature/#194-clubdetail-edit-api-FE-24
Mar 19, 2025
Merged

[feature] 관리자페이지 수정하기 api 연동#195
seongwon030 merged 33 commits intodevelop/fefrom
feature/#194-clubdetail-edit-api-FE-24

Conversation

@seongwon030
Copy link
Member

@seongwon030 seongwon030 commented Mar 14, 2025

#️⃣연관된 이슈

ex) #194

📝작업 내용

상세정보 소개글 ul 스타일 설정 a609192

SideBar에 동아리 이름 적용 5da3cbe

관리자 페이지 default값 가져오기

관리자 페이지 수정 및 수정하기 버튼 추가

소개글 수정 탭 api 연결 43bd993

중점적으로 리뷰받고 싶은 부분(선택)

리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

ex) 메서드 XXX의 이름을 더 잘 짓고 싶은데 혹시 좋은 명칭이 있을까요?

논의하고 싶은 부분(선택)

현재 클럽상세조회 api와 클럽상세정보 수정 api에서의 동아리 회장이름과 넘버 필드명이 다릅니다.
백엔드에서 고치면 해결할 예정입니다.

🫡 참고사항

Summary by CodeRabbit

  • 새로운 기능

    • 관리 페이지에서 클럽 정보를 동적으로 업데이트할 수 있는 기능이 강화되어, 업데이트 후 사용자에게 알림 및 피드백이 제공됩니다.
    • 클럽 상세 정보 및 소개 페이지가 실시간 데이터 반영과 로딩/오류 처리를 통해 개선되었습니다.
  • 스타일 개선

    • 버튼에 애니메이션 효과가 추가되어 상호작용 시 부드럽고 시각적인 피드백을 제공합니다.
    • 편집 탭과 리스트 레이아웃의 스타일이 개선되어 사용자 인터페이스가 전반적으로 향상되었습니다.

@seongwon030 seongwon030 added ✨ Feature 기능 개발 📬 API 서버 API 통신 작업 💻 FE Frontend labels Mar 14, 2025
@seongwon030 seongwon030 self-assigned this Mar 14, 2025
@netlify
Copy link

netlify bot commented Mar 14, 2025

Deploy Preview for moadong ready!

Name Link
🔨 Latest commit 145d1ed
🔍 Latest deploy log https://app.netlify.com/sites/moadong/deploys/67da5f36159b6f000867b194
😎 Deploy Preview https://deploy-preview-195--moadong.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@seongwon030 seongwon030 linked an issue Mar 14, 2025 that may be closed by this pull request
2 tasks
- 동적 데이터 패칭을 위해 loading과 error추가
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 19, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

이 Pull Request는 클럽 상세 정보 업데이트와 관련된 API 및 UI 컴포넌트들을 업데이트합니다. 새로운 비동기 API 함수와 custom hook들이 추가되어 클럽 설명 및 상세 정보를 수정할 수 있게 되었으며, AdminPage와 관련 컴포넌트들이 데이터 로딩, 에러 처리 및 동적 데이터 전달을 지원하도록 개선되었습니다. 또한, 버튼 컴포넌트와 스타일, 타입 정의 등이 업데이트되었습니다.

Changes

파일 경로 (요약) 변경 요약
frontend/src/apis/updateClubDescription.ts
frontend/src/apis/updateClubDetail.ts
클럽 설명 및 상세 정보를 업데이트하기 위한 새로운 비동기 API 함수 추가(에러 처리 포함)
frontend/src/hooks/queries/club/useGetClubDetail.ts
frontend/src/hooks/queries/club/useUpdateClubDescription.ts
frontend/src/hooks/queries/club/useUpdateClubDetail.ts
클럽 정보 조회 및 수정 작업을 위한 custom hook 추가 및 타입 안정성 개선
frontend/src/pages/AdminPage/AdminPage.tsx
frontend/src/pages/AdminPage/components/SideBar/SideBar.tsx
frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx
frontend/src/pages/AdminPage/tabs/RecruitEditTab/RecruitEditTab.tsx
frontend/src/pages/AdminPage/tabs/RecruitEditTab/RecruitEditTab.styles.ts
AdminPage 및 관련 탭에서 클럽 정보 로딩, 업데이트 처리, 컨텍스트 전달 및 스타일/UI 개선
frontend/src/components/common/Button/Button.tsx 버튼 컴포넌트에 애니메이션 옵션(animated prop) 추가 및 관련 스타일/상태 변경 적용
frontend/src/pages/ClubDetailPage/components/InfoBox/InfoBox.tsx
frontend/src/pages/ClubDetailPage/components/IntroduceBox/IntroduceBox.styles.ts
클럽 세부 정보 관련 프로퍼티 명칭 수정 및 리스트 스타일(ol, ul 패딩) 개선
frontend/src/types/club.ts ClubDetail 인터페이스의 프로퍼티 명칭 수정(presidentNameclubPresidentName, presidentPhoneNumbertelephoneNumber) 및 새 인터페이스 ClubDescription 추가

Sequence Diagram(s)

sequenceDiagram
    participant U as 사용자
    participant A as AdminPage/ClubInfoEditTab/RecruitEditTab
    participant H as useUpdateClubDetail/Description
    participant API as API 서버

    U->>A: 업데이트 버튼 클릭
    A->>H: handleUpdateClub 호출
    H->>API: PUT 요청 전송 (클럽 상세/설명 업데이트)
    API-->>H: 응답(성공/오류)
    H-->>A: 결과 반환 및 쿼리 무효화
    A-->>U: 업데이트 결과 피드백
Loading

Assessment against linked issues

Objective (FE-24) Addressed Explanation
상세페이지 수정하기 API 연동

Poem

나는 작은 토끼, 코드 숲을 누비며
새 기능들이 반짝이는 길을 달려요 🥕
API와 훅이 손잡고 춤을 추니,
클럽 정보가 새롭게 피어나네요.
즐겁게 뛰노는 이 변화, 모두 환영해요! 🐰


🪧 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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

seongwon030 and others added 2 commits March 19, 2025 13:56
- 기존 애니메이션 버튼 컴포넌트 제거
- ButtonProps에 불리언 타입으로 animated 추가
@seongwon030
Copy link
Member Author

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

🪧 Tips

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 19, 2025

🧩 Analysis chain

@seongwon030 I'll review your pull request. Let me gather the necessary information about the changes first.


🏁 Script executed:

#!/bin/bash
# Get basic information about the PR
gh pr view 195 --json title,state,baseRefName,headRefName,additions,deletions,changedFiles,files

# Get a list of files changed in this PR
gh pr view 195 --json files --jq '.files[].path'

# Display commit messages to understand the changes
git log --oneline main..HEAD

Length of output: 2665


@seongwon030 I'm currently examining the key files in your PR to understand the admin page API integration. Looking at your API implementations, hooks, and UI components to provide a thorough review.


🏁 Script executed:

#!/bin/bash
# Let's examine the new API files
echo "===== updateClubDescription.ts ====="
cat frontend/src/apis/updateClubDescription.ts

echo -e "\n===== updateClubDetail.ts ====="
cat frontend/src/apis/updateClubDetail.ts

# Check the React Query hooks
echo -e "\n===== useUpdateClubDescription.ts ====="
cat frontend/src/hooks/queries/club/useUpdateClubDescription.ts

echo -e "\n===== useUpdateClubDetail.ts ====="
cat frontend/src/hooks/queries/club/useUpdateClubDetail.ts

echo -e "\n===== useGetClubDetail.ts changes ====="
cat frontend/src/hooks/queries/club/useGetClubDetail.ts

# Look at the main admin page components
echo -e "\n===== AdminPage.tsx changes ====="
cat frontend/src/pages/AdminPage/AdminPage.tsx

echo -e "\n===== ClubInfoEditTab.tsx ====="
cat frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx

echo -e "\n===== RecruitEditTab.tsx ====="
cat frontend/src/pages/AdminPage/tabs/RecruitEditTab/RecruitEditTab.tsx

# Check the Button component changes
echo -e "\n===== Button.tsx changes ====="
cat frontend/src/components/common/Button/Button.tsx

# Check type definition changes
echo -e "\n===== club.ts type changes ====="
cat frontend/src/types/club.ts

Length of output: 19422


@seongwon030 PR 리뷰가 완료되었습니다. 관리자 페이지의 API 연동 작업에 대해 아래와 같은 피드백을 드립니다.

잘 구현된 부분 👍

  • API 구현이 적절한 에러 처리와 함께 잘 되어 있습니다
  • React Query를 활용한 데이터 관리와 mutation 처리가 잘 구현되었습니다
  • 사용자 경험을 고려하여 성공/실패 시 적절한 알림을 제공합니다
  • Button 컴포넌트의 애니메이션 기능이 사용자 경험을 향상시킵니다

개선이 필요한 부분 🔧

  1. AdminPage.tsx에 하드코딩된 클럽 ID가 있습니다:

    const { data: clubDetail, isLoading, error } = useGetClubDetail('67d2e3b9b15c136c6acbf20b');

    이 값은 동적으로 받아오는 것이 좋을 것 같습니다.

  2. ClubInfoEditTab.tsx에 수정이 필요한 FIXME 주석이 있습니다:

    // [x] FIXME: 동아리회장 이름, 번호 필드명 수정해야 함

    PR 설명에서 언급하신 대로 백엔드에서 필드명 일관성 문제가 해결될 예정인 것으로 보입니다.

  3. RecruitEditTab.tsx의 에러 처리가 더 구체적일 수 있습니다:

    if (clubUpdateResult.status === 'fulfilled' && descriptionUpdateResult.status === 'fulfilled') {
      alert('동아리 정보가 성공적으로 수정되었습니다.');
    } else {
      alert(`동아리 정보 수정에 실패했습니다`);
    }

    어떤 작업이 실패했는지 더 구체적인 오류 메시지를 제공하면 좋을 것 같습니다.

  4. 일부 컴포넌트에서 로딩 상태 처리가 더 개선될 수 있습니다. 특히 API 호출 중에 버튼 비활성화나 로딩 인디케이터를 추가하면 좋을 것 같습니다.

전반적으로 API 연동이 잘 구현되었으며, 사용자 경험도 좋게 설계되어 있습니다. 위에서 언급한 작은 개선점들이 반영된다면 더 완성도 높은 코드가 될 것 같습니다. 수고하셨습니다! 🌟

혹시 추가 질문이 있으시면 편하게 물어봐주세요.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: 1

🧹 Nitpick comments (11)
frontend/src/hooks/queries/club/useUpdateClubDescription.ts (1)

1-22: React Query를 활용한 훅 구현이 잘 되었습니다.

useUpdateClubDescription 훅은 React Query의 useMutation을 효과적으로 활용하여 클럽 설명 업데이트 기능을 잘 구현했습니다. 성공 시 쿼리 캐시를 무효화하여 최신 데이터를 가져오는 로직도 적절합니다.

다만, 에러 처리 부분은 개선할 여지가 있습니다. 현재는 콘솔에만 오류를 기록하고 있는데, 사용자에게 알림을 표시하거나 특정 오류 유형에 따라 다른 처리를 하는 방식으로 확장하면 좋을 것 같습니다.

에러 처리 개선 예시:

  onError: (error) => {
    console.error('Error updating club detail:', error);
+   // 사용자에게 오류 알림 표시 (예: 토스트 메시지)
+   // showToast('클럽 설명 업데이트 중 오류가 발생했습니다.');
+   
+   // 또는 오류 유형에 따라 다른 처리
+   // if (error instanceof NetworkError) {
+   //   // 네트워크 오류 처리
+   // } else if (error instanceof ValidationError) {
+   //   // 유효성 검사 오류 처리
+   // }
  },
frontend/src/hooks/queries/club/useUpdateClubDetail.ts (1)

1-22: Partial 타입을 활용한 효율적인 업데이트 훅 구현이 돋보입니다.

useUpdateClubDetail 훅은 Partial<ClubDetail> 타입을 사용하여 클럽 정보의 일부만 업데이트할 수 있도록 유연하게 설계되었습니다. React Query의 mutation 기능을 활용한 구현과 성공 시 쿼리 캐시 무효화 로직이 적절합니다.

다만, 이전 훅과 마찬가지로 에러 처리 부분은 개선할 여지가 있습니다. 단순히 콘솔 로깅만 하는 것보다 사용자에게 피드백을 제공하거나 특정 오류 상황에 대응하는 로직을 추가하면 더 좋을 것 같습니다.

에러 처리 개선 예시:

  onError: (error) => {
    console.error('Error updating club detail:', error);
+   // 오류 유형에 따른 처리 추가
+   // if (error.status === 400) {
+   //   // 잘못된 요청 처리
+   // } else if (error.status === 401) {
+   //   // 인증 오류 처리
+   // }
+   
+   // 사용자에게 알림 표시
+   // notifyError('클럽 정보 업데이트에 실패했습니다.');
  },
frontend/src/pages/AdminPage/AdminPage.tsx (2)

16-19: 로딩 및 에러 상태 처리

데이터 로딩 상태와 에러 상태에 대한 처리가 적절히 구현되었습니다. 사용자 경험을 더 향상시키기 위해 로딩 중인 상태에서는 스켈레톤 UI나 스피너 컴포넌트를 사용하는 것을 고려해 보세요.

- if (!clubDetail) {
-   return <div>Loading...</div>;
- }
+ if (isLoading || !clubDetail) {
+   return <LoadingSpinner />; // 로딩 스피너 컴포넌트 사용
+ }

26-26: 조건부 체이닝 연산자 간소화

clubDetail이 존재하지 않는 경우 이미 이전 조건문에서 처리되므로, 여기서 조건부 체이닝 연산자(?.)를 사용할 필요가 없습니다.

- <SideBar clubName={clubDetail?.name || ''} />
+ <SideBar clubName={clubDetail.name} />
frontend/src/apis/updateClubDetail.ts (1)

15-21: 에러 처리 개선 가능

JSON 파싱 에러를 try-catch로 잘 처리하고 있으나, 이전 리뷰에서 논의된 것처럼 코드를 더 간결하게 만들 수 있습니다. result 변수를 let 대신 const로 선언하고, 파싱 실패 시 바로 에러를 던지는 방식으로 리팩토링할 수 있을 것입니다.

-  let result;
-  try {
-    result = await response.json();
-  } catch (error) {
-    console.error('📌 JSON 파싱 실패:', error);
-    result = null;
-  }

+  try {
+    const result = await response.json();
+    
+    if (!response.ok) {
+      const errorMessage = result?.message
+        ? `Failed to update club (HTTP ${response.status}): ${result.message}`
+        : `Failed to update club (HTTP ${response.status})`;
+
+      throw new Error(errorMessage);
+    }
+
+    if (!result?.data) {
+      console.error('📌 API 응답에 data 필드가 없음:', result);
+      throw new Error('Unexpected API response: Missing data field');
+    }
+  } catch (error) {
+    if (error instanceof Error) {
+      throw error;
+    }
+    console.error('📌 JSON 파싱 실패:', error);
+    throw new Error('Failed to parse API response');
+  }
frontend/src/apis/updateClubDescription.ts (1)

15-34: 코드 중복 리팩토링 필요

이 함수의 에러 처리 로직이 updateClubDetail.ts의 코드와 거의 동일합니다. 공통 유틸리티 함수로 추출하여 코드 중복을 줄일 수 있을 것입니다.

+// frontend/src/utils/apiUtils.ts (새 파일 생성)
+export const handleApiResponse = async (response: Response): Promise<any> => {
+  try {
+    const result = await response.json();
+    
+    if (!response.ok) {
+      const errorMessage = result?.message
+        ? `API request failed (HTTP ${response.status}): ${result.message}`
+        : `API request failed (HTTP ${response.status})`;
+
+      throw new Error(errorMessage);
+    }
+
+    if (!result?.data) {
+      console.error('📌 API 응답에 data 필드가 없음:', result);
+      throw new Error('Unexpected API response: Missing data field');
+    }
+    
+    return result.data;
+  } catch (error) {
+    if (error instanceof Error) {
+      throw error;
+    }
+    console.error('📌 JSON 파싱 실패:', error);
+    throw new Error('Failed to parse API response');
+  }
+};

그리고 API 함수에서 이 유틸리티 사용:

-  let result;
-  try {
-    result = await response.json();
-  } catch (error) {
-    console.error('📌 JSON 파싱 실패:', error);
-    result = null;
-  }
-
-  if (!response.ok) {
-    const errorMessage = result?.message
-      ? `Failed to update club (HTTP ${response.status}): ${result.message}`
-      : `Failed to update club (HTTP ${response.status})`;
-
-    throw new Error(errorMessage);
-  }
-
-  if (!result?.data) {
-    console.error('📌 API 응답에 data 필드가 없음:', result);
-    throw new Error('Unexpected API response: Missing data field');
-  }
+  await handleApiResponse(response);
frontend/src/components/common/Button/Button.tsx (1)

44-52: 컴포넌트 구현 개선

Button 컴포넌트가 animated 속성을 기본값 false로 포함하도록 업데이트된 것은 좋은 접근법입니다. 기존 코드와의 호환성을 유지하면서 새 기능을 추가할 수 있습니다.

애니메이션 기능이 추가되었으므로, 이 기능을 사용하는 컴포넌트에 대해 설명하는 주석을 추가하는 것이 좋겠습니다:

 /**
+ * Button 컴포넌트
+ * 
+ * @param width - 버튼의 너비 (기본값: auto)
+ * @param children - 버튼 내부 컨텐츠
+ * @param onClick - 클릭 이벤트 핸들러
+ * @param animated - 애니메이션 효과 활성화 여부 (기본값: false)
+ */
 const Button = ({
   width,
   children,
   onClick,
   animated = false,
 }: ButtonProps) => (
   <StyledButton width={width} onClick={onClick} animated={animated}>
     {children}
   </StyledButton>
 );
frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx (2)

24-25: 하드코딩된 배열 관리
divisionscategories가 하드코딩 상태인데, 만약 변경 가능성이 높다면 상수 파일로 분리하거나 추후 서버 API를 통해 동적으로 받는 방안을 고려하길 권장합니다.


44-85: 업데이트 로직과 알림 처리
handleUpdateClub 함수 내에서 방어 코드(if (!clubDetail) return;)가 존재해 예외 처리가 잘 되어 있습니다. 또한, updateClub 호출 시 성공/실패 시나리오를 alert로 알려주는 방식은 간단하고 명확합니다.

기능 확장을 고려한다면 사용자 경험 측면에서 alert 대신 Toast 컴포넌트 같은 UI 요소를 활용하는 방법도 좋겠습니다.

frontend/src/pages/AdminPage/tabs/RecruitEditTab/RecruitEditTab.styles.ts (1)

16-22: 미리보기 컨테이너 구성
에디터와 미리보기를 가로로 나란히 배치하기 위한 flex-direction: row; 사용이 적절합니다. 반응형 구현을 고려한다면, 모바일 화면 등에 대한 대응도 추가로 검토해보면 좋겠습니다.

frontend/src/pages/AdminPage/tabs/RecruitEditTab/RecruitEditTab.tsx (1)

53-112: Promise.allSettled로 이중 업데이트 처리
클럽 정보와 소개글을 병렬로 처리하고, 실패 시 alert로 처리하는 로직이 명확하여 가독성이 좋습니다. 다만, 일부만 실패하는 상황에서 세부적인 재시도 또는 롤백 전략이 필요할 수 있으니 참고하십시오.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 958f114 and 17bbab8.

📒 Files selected for processing (15)
  • frontend/src/apis/updateClubDescription.ts (1 hunks)
  • frontend/src/apis/updateClubDetail.ts (1 hunks)
  • frontend/src/components/common/Button/Button.tsx (2 hunks)
  • frontend/src/hooks/queries/club/useGetClubDetail.ts (1 hunks)
  • frontend/src/hooks/queries/club/useUpdateClubDescription.ts (1 hunks)
  • frontend/src/hooks/queries/club/useUpdateClubDetail.ts (1 hunks)
  • frontend/src/pages/AdminPage/AdminPage.tsx (1 hunks)
  • frontend/src/pages/AdminPage/components/SideBar/SideBar.tsx (2 hunks)
  • frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.styles.ts (1 hunks)
  • frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx (3 hunks)
  • frontend/src/pages/AdminPage/tabs/RecruitEditTab/RecruitEditTab.styles.ts (2 hunks)
  • frontend/src/pages/AdminPage/tabs/RecruitEditTab/RecruitEditTab.tsx (1 hunks)
  • frontend/src/pages/ClubDetailPage/components/InfoBox/InfoBox.tsx (1 hunks)
  • frontend/src/pages/ClubDetailPage/components/IntroduceBox/IntroduceBox.styles.ts (1 hunks)
  • frontend/src/types/club.ts (1 hunks)
🔇 Additional comments (27)
frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.styles.ts (1)

3-7: 잘 구현된 스타일 컴포넌트입니다.

TitleButtonContainer 스타일드 컴포넌트가 제목과 버튼을 수평으로 배치하면서 공간을 효율적으로 활용할 수 있도록 적절히 구현되었습니다. flex 속성을 사용해 레이아웃을 명확하게 정의한 점이 좋습니다.

frontend/src/pages/ClubDetailPage/components/IntroduceBox/IntroduceBox.styles.ts (1)

36-37: 스타일 일관성 개선이 잘 이루어졌습니다.

순서 있는 리스트(ol)와 순서 없는 리스트(ul) 모두에 동일한 패딩을 적용함으로써 일관된 시각적 경험을 제공하는 좋은 개선입니다. 사용자 인터페이스 일관성 측면에서 중요한 디테일을 잘 고려하셨습니다.

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

23-24: 프로퍼티 이름이 업데이트되었습니다.

클럽 정보의 프로퍼티 이름이 presidentName에서 clubPresidentName으로, presidentPhoneNumber에서 telephoneNumber로 변경되었습니다. 이 변경은 타입 파일의 ClubDetail 인터페이스 변경과 일치합니다.

frontend/src/hooks/queries/club/useGetClubDetail.ts (1)

3-3: 제네릭 타입 매개변수 추가로 타입 안전성 향상

useQuery 훅에 <ClubDetail> 타입 매개변수를 추가하여 API 응답이 ClubDetail 인터페이스에 맞는지 컴파일 시점에 확인할 수 있게 되었습니다. 이는 타입 안전성을 향상시키는 좋은 개선사항입니다.

Also applies to: 6-6

frontend/src/pages/AdminPage/components/SideBar/SideBar.tsx (2)

6-8: SideBarProps 인터페이스 추가

SideBarProps 인터페이스를 추가하여 컴포넌트의 프로퍼티 타입을 명확하게 정의했습니다. 이는 타입스크립트의 장점을 잘 활용한 접근 방식입니다.


16-16: 하드코딩된 클럽 이름을 동적 값으로 변경

하드코딩된 클럽 이름("WAP")을 동적인 clubName prop으로 변경했습니다. 이로써 컴포넌트의 재사용성이 향상되었고, 다양한 클럽 이름을 표시할 수 있게 되었습니다.

Also applies to: 29-29

frontend/src/pages/AdminPage/AdminPage.tsx (1)

28-28: 컨텍스트를 통한 클럽 상세 정보 전달

Outlet 컴포넌트의 context prop을 통해 클럽 상세 정보를 하위 컴포넌트에 전달하는 방식이 적절합니다. 이를 통해 하위 라우트에서 클럽 정보에 쉽게 접근할 수 있습니다.

frontend/src/types/club.ts (2)

16-17: 필드 이름 변경에 대한 올바른 대응

백엔드 API 필드 이름 변경에 맞게 presidentName에서 clubPresidentName으로, presidentPhoneNumber에서 telephoneNumber로 변경이 잘 이루어졌습니다. PR 설명에서 언급한 API 필드 불일치 문제를 해결하는 좋은 접근법입니다.


22-25: 새 인터페이스 추가 적절함

ClubDescription 인터페이스 추가는 클럽 설명 업데이트 기능에 적합한 타입 정의입니다. 클럽 ID와 설명을 포함하여 API 요청에 필요한 데이터 구조를 명확하게 정의하고 있습니다.

frontend/src/apis/updateClubDetail.ts (2)

4-6: API 함수 정의 적절

Partial<ClubDetail> 타입을 매개변수로 사용하여 클럽 정보 일부만 업데이트할 수 있도록 하는 유연한 접근방식이 좋습니다. 이전 리뷰에서 논의된 것처럼 나중에 타입 리팩토링이 필요할 수 있지만, 현재 구현은 적절합니다.


23-34: 에러 메시지 처리 잘 구현됨

응답 코드와 에러 메시지를 결합하여 유용한 정보를 제공하는 방식이 잘 구현되었습니다. 또한 data 필드 유무를 확인하여 예상치 못한 API 응답을 처리하는 것은 좋은 방어적 프로그래밍 접근법입니다.

frontend/src/apis/updateClubDescription.ts (1)

4-13: API 엔드포인트 및 매개변수 적절

ClubDescription 타입을 매개변수로 사용하여 클럽 설명 업데이트 함수를 잘 구현했습니다. API 엔드포인트 경로가 명확하고 HTTP 메소드 및 헤더 설정이 적절합니다.

frontend/src/components/common/Button/Button.tsx (3)

4-9: 인터페이스 개선 사항

ButtonProps 인터페이스가 export로 변경되고 animated 속성이 추가된 것은 좋은 개선입니다. 애니메이션을 선택적으로 적용할 수 있는 유연성을 제공합니다.


11-15: 애니메이션 효과 추가

pulse 키프레임 애니메이션을 추가한 것은 사용자 경험 향상에 좋은 기여입니다. 스케일 변경과 배경색 전환이 자연스러운 효과를 줍니다.


29-40: 조건부 애니메이션 적용 잘 구현됨

animated 속성에 따라 애니메이션을 조건부로 적용하는 방식이 잘 구현되었습니다. hover 상태와 active 상태 모두에 애니메이션 효과를 일관되게 적용했습니다.

frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx (5)

2-7: 모듈 임포트 구성이 적절합니다
React Router와 리소스 훅을 활용하여 필요한 기능들을 잘 불러오고 있습니다.


13-14: Context 활용과 Mutation 훅 분리가 깔끔합니다
useOutletContextclubDetail을 받아오고, useUpdateClubDetail 훅을 별도로 선언하여 로직을 분리한 점이 재사용과 유지보수에 유리해 보입니다.


19-21: 초기 상태값 설정 주의
introduction, selectedDivision, selectedCategory를 빈 문자열로 초기화한 것은 합리적입니다. 다만, 서버에서 해당 필드가 누락되어 null이나 undefined로 내려올 수 있는 경우를 고려해야 합니다.

서버 응답이 예상과 다를 때도 안정적으로 처리될 수 있는지 확인하고, 필요하다면 안전한 디폴트 값을 추가해주세요.


28-41: useEffect 통한 상태 동기화
clubDetail이 들어오면 해당 값을 상태로 업데이트하는 로직이 잘 구성되었습니다. 하지만 FIXME 코멘트에 언급된 필드명 수정 사항이 향후 반영되지 않으면, 다른 파일과의 호환성 문제나 충돌이 발생할 수 있습니다.

다른 컴포넌트나 API 요청에서 동일한 필드를 사용하는지 확인하고, 전체적으로 통일된 이름을 적용할지 결정하면 좋겠습니다.


133-137: 소개 글 최대 글자 수 주의
maxLength를 20자로 줄인 점은 UI 차원에서 간단하지만, 이미 서버에 20자 초과로 저장된 소개 글이 있을 경우 편집 시 잘려 나갈 가능성을 유념해야 합니다.

서버 측 혹은 기존 데이터가 20자를 초과할 때 어떤 방식으로 처리가 될지 확인해 보세요.

frontend/src/pages/AdminPage/tabs/RecruitEditTab/RecruitEditTab.styles.ts (4)

5-5: 세로 레이아웃 전환
flex-direction: column;을 적용해 내용이 세로로 배치되어 가독성이 한층 좋아졌습니다.


10-14: 버튼 컨테이너 스타일 정의
EditButtonContainer에서 justify-content: space-between을 사용해 양쪽 버튼 배치가 가능해졌고, 인터페이스가 보다 직관적입니다.


28-28: 에디터 최소 높이 확보
min-height: 400px;으로 에디터 영역이 너무 작아지지 않도록 기본 크기를 보장하는 접근이 좋습니다.


62-62: 에디터 확장성 향상
flex-grow: 1;을 적용해 화면 크기에 따라 에디터가 유연하게 확장할 수 있게 구성한 점이 훌륭합니다.

frontend/src/pages/AdminPage/tabs/RecruitEditTab/RecruitEditTab.tsx (3)

1-2: 불필요한 의존성 없이 필요한 모듈만 임포트
React, styled 컴포넌트, Mutation 훅 등을 적절히 조합해, 각 기능의 책임을 명확히 분리한 구성이 보기 좋습니다.

Also applies to: 6-7, 9-12


15-22: 상태 정의 및 Mutation 훅 설정
useOutletContext로 받아온 clubDetail을 바탕으로 여러 mutation 훅 (useUpdateClubDetail, useUpdateClubDescription)을 분리해 사용하는 것은 유지보수에 유리합니다.


41-51: 기본 데이터 세팅 주의
parseRecruitmentPeriod로 날짜를 변환해 상태로 세팅하고, recruitmentTargetdescription을 초기에 채우는 로직이 합리적입니다. null이면 어떻게 될지 다시 한번 확인해 주세요.

@seongwon030 seongwon030 linked an issue Mar 19, 2025 that may be closed by this pull request
2 tasks
@seongwon030 seongwon030 merged commit f71664f into develop/fe Mar 19, 2025
5 checks passed
@seongwon030 seongwon030 deleted the feature/#194-clubdetail-edit-api-FE-24 branch March 19, 2025 06:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📬 API 서버 API 통신 작업 💻 FE Frontend ✨ Feature 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[chore] FE-36 coderabbitai 적용해보기 [feature] FE-24 관리자페이지 수정하기 api 연동

3 participants