Skip to content

Conversation

@yulrang
Copy link
Contributor

@yulrang yulrang commented Nov 13, 2024

🔖 Issue Ticket

#98

✍️ Description

기존 스태틱페이지 데이터 렌더링 + 인피니트쿼리 페이지 데이터 렌더링 방식에서
인피니트쿼리 페이지만 불러오도록 바꿨습니다

빌드를 자주하지 않으면 너무 데이터가 바뀌어 보이더라구여
크루가 생성되면 바로 보였으면 좋겠어서... 변경합니다~~

  • 파일명 변경, 이동

✅ Checklist

PR

  • Branch Convention 확인

    feat/ 피쳐, fix/ 버그 수정, refactor/ 개선

  • Base Branch 확인
  • 적절한 Label 지정
  • Assignee 및 Reviewer 지정

Test

  • 로컬 작동 확인

Summary by CodeRabbit

  • 새로운 기능

    • 홈 페이지 구성 요소가 개선되어 동적 데이터 검색 및 무한 스크롤 기능이 추가되었습니다.
    • 검색 입력 및 지역, 정렬 옵션을 위한 드롭다운이 포함된 사용자 인터페이스가 확장되었습니다.
  • 버그 수정

    • API 요청 시 응답이 undefined인 경우에 대한 오류 처리 로직이 추가되었습니다.
  • 문서화

    • 구성 요소의 import 경로가 업데이트되었습니다.

commit 51cfe2f
Author: Lee Youl <[email protected]>
Date:   Sat Nov 9 11:40:05 2024 +0900

    🐛 Fix: MockData 날짜 형식 수정

commit 7b68352
Author: Lee Youl <[email protected]>
Date:   Sat Nov 9 11:38:06 2024 +0900

    🐛 Fix: 이전날짜 선택 방지, isToday 날짜 비교 수정

commit f101987
Author: Lee Youl <[email protected]>
Date:   Sat Nov 9 11:19:20 2024 +0900

    🐛 Fix: 폼 동작 개선

commit c408058
Author: Lee Youl <[email protected]>
Date:   Sat Nov 9 10:51:40 2024 +0900

    🐛 Fix: isToday 함수 개선, 데이터 한국시간 기준으로 변경

commit 0683f5a
Author: Lee Youl <[email protected]>
Date:   Fri Nov 8 21:49:45 2024 +0900

    🐛 Fix: 버튼 링크로 교체

commit 43cdfa7
Author: Lee Youl <[email protected]>
Date:   Fri Nov 8 21:43:11 2024 +0900

    🚨 Fix: 린트 오류 제거

commit 9657201
Author: Lee Youl <[email protected]>
Date:   Fri Nov 8 21:34:56 2024 +0900

    🐛 Fix: 스크롤바 두개로 보이는 문제 수정

commit 63a8e1c
Author: Lee Youl <[email protected]>
Date:   Fri Nov 8 21:27:25 2024 +0900

    🐛 Fix: 유효성 검사 날짜 선택 오류 수정

commit 80f8554
Author: Lee Youl <[email protected]>
Date:   Fri Nov 8 21:24:46 2024 +0900

    🐛 Fix: 에러상태인데 새로 값 채울 때 에러 해제하기, 리팩토링

commit af9fb91
Author: Lee Youl <[email protected]>
Date:   Fri Nov 8 20:46:00 2024 +0900

    🐛 Fix: 크루 생성시 디테일 페이지로 이동, 리팩토링

commit f1fe204
Author: Lee Youl <[email protected]>
Date:   Fri Nov 8 20:31:17 2024 +0900

    🐛 Fix: 텍스트 수정(약속 잡기 > 약속 만들기)

commit 5cc6746
Author: Lee Youl <[email protected]>
Date:   Fri Nov 8 20:29:52 2024 +0900

    🐛 Fix: 드롭다운 값 선택시 포커스 아웃 되도록 수정
@yulrang yulrang self-assigned this Nov 13, 2024
@coderabbitai
Copy link

coderabbitai bot commented Nov 13, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

이 변경 사항은 HomePage 컴포넌트의 전면적인 개편을 포함하며, 기존의 비동기 데이터 가져오기 방식인 getCrewList를 제거하고 React 훅을 사용한 상태 관리 및 데이터 가져오기를 도입합니다. 새로운 구현은 useGetCrewListQuery를 통해 승무원 데이터를 가져오고, useInfiniteScroll을 활용하여 페이지네이션을 처리합니다. 상태 변수와 UI 구성 요소가 추가되어 사용자 상호작용을 지원하며, 검색 기능이 활성화되었습니다.

Changes

파일 경로 변경 요약
src/app/(crew)/page.tsx HomePage 컴포넌트의 데이터 가져오기 방식 변경, 상태 관리 및 UI 구성 요소 추가. getCrewList 제거, useGetCrewListQueryuseInfiniteScroll 사용.
src/app/_components/find-crew/find-crew.tsx FindCrew 컴포넌트 삭제, 관련 상태 및 함수 제거.
src/components/common/crew-list/crew-card-list.tsx MainCrewCardListProps 인터페이스의 data 속성 타입 변경, undefined 제거로 타입 안전성 향상.
src/types/crew-card.d.ts MainCrewListResponse 타입의 content 속성에서 undefined 제거, 항상 배열로 강제.
src/components/common/crew-list/crew-card-list.stories.tsx RenderCrewCardList 함수에서 initialData 매개변수 제거, 데이터 가져오기 방식 간소화.
src/utils/api.ts ApiError 클래스의 생성자에 타입 주석 추가, fetchApi 함수의 URL 처리 방식 변경.
src/app/(crew)/my-crew/page.tsx useGetCrewListQuery의 import 경로 변경, useInfiniteScrollCrewCardList import 제거.
src/_queries/crew/crew-list-queries.tsx getCrewList import 경로 변경, useGetCrewListQuery 함수에 오류 처리 추가.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant HomePage
    participant API
    participant CrewList

    User->>HomePage: 검색 입력
    HomePage->>CrewList: 검색 요청
    CrewList->>API: 데이터 요청
    API-->>CrewList: 데이터 응답
    CrewList-->>HomePage: 데이터 전달
    HomePage-->>User: 결과 표시
Loading

Possibly related PRs

Suggested reviewers

  • HaeJungg
  • Rangbyeolang
  • minkyung5x5

Poem

🐰 새로운 페이지가 열리고,
데이터가 춤추며 흐르네.
검색의 마법, 클릭의 기쁨,
승무원들과 함께하는 즐거움.
변화의 바람, 더 나은 내일,
우리 모두 함께, 기쁨을 나누네! 🌟

Warning

Rate limit exceeded

@yulrang has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 2 minutes and 33 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 3febcae and 268e90f.

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 eslint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/app/(crew)/page.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't determine the plugin "react-hooks" uniquely.

  • /node_modules/eslint-plugin-react-hooks/index.js (loaded in ".eslintrc.js")
  • /node_modules/eslint-config-next/node_modules/eslint-plugin-react-hooks/index.js (loaded in ".eslintrc.js » eslint-config-next/core-web-vitals » /node_modules/eslint-config-next/index.js » plugin:react-hooks/recommended")

Please remove the "plugins" setting from either config or remove either plugin installation.

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • 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 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.

@github-actions
Copy link

Copy link

@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

🧹 Outside diff range and nitpick comments (6)
src/types/crew-card.d.ts (1)

Line range hint 1-67: 인터페이스 문서화 개선 제안

각 인터페이스와 타입에 JSDoc 주석을 추가하여 사용 목적과 각 필드의 의미를 명확히 문서화하면 좋겠습니다.

예시:

+/**
+ * 크루 검색 조건을 정의하는 인터페이스
+ */
 export interface ConditionTypes {
   keyword: string;      // 검색 키워드
   mainLocation: string; // 주요 지역
   mainCategory: string; // 주요 카테고리
   subCategory: string;  // 서브 카테고리
   sortType: 'LATEST' | 'POPULAR'; // 정렬 방식
 }
src/components/common/crew-list/crew-card-list.tsx (2)

Line range hint 31-35: 타입 단언(Type Assertion) 개선 제안

현재 코드에서 타입 단언(as)을 사용하는 부분이 있습니다. 타입 가드를 사용하여 더 안전하게 리팩토링할 수 있습니다.

다음과 같이 개선해보세요:

-  const crewDataList =
-    (inWhere === 'my-crew'
-      ? data?.pages.flatMap((page) => page?.data as MyCrewList[])
-      : data?.pages?.flatMap((page) => page?.content as MainCrewList[])) ?? [];
+  const crewDataList = data.pages.flatMap((page) => {
+    if (inWhere === 'my-crew' && page.data) {
+      return page.data;
+    }
+    return page.content || [];
+  });

Line range hint 37-43: 에러 상태 처리 추가 필요

현재 로딩 상태와 빈 데이터 상태는 처리되어 있지만, 에러 상태에 대한 처리가 없습니다.

Props에 errorisError를 추가하고 에러 상태를 처리하는 것을 추천드립니다:

interface MainCrewCardListProps {
  data: InfiniteData<MainCrewListResponse>;
  isFetchingNextPage: boolean;
+ isError: boolean;
+ error?: Error;
  inWhere?: undefined;
}

// 컴포넌트 내부
+ if (isError) {
+   return (
+     <div className="flex justify-center py-10">
+       <p>데이터를 불러오는 중 오류가 발생했습니다.</p>
+     </div>
+   );
+ }
src/app/(crew)/page.tsx (3)

19-19: sort 상태의 타입을 string으로 변경 권장

sort 상태의 초기값이 'latest'로 설정되어 있으므로, 타입을 string | null에서 string으로 변경하여 불필요한 null 체크를 줄일 수 있습니다.

다음과 같이 수정할 수 있습니다:

- const [sort, setSort] = useState<string | null>('latest');
+ const [sort, setSort] = useState<string>('latest');

그리고 onChange 함수에서도 타입 캐스팅을 제거할 수 있습니다:

- setSort(newValue as string);
+ setSort(newValue);

55-64: 중복된 코드 함수로 추출 권장

setMainCategorysetSubCategoryonChange 핸들러에서 동일한 로직이 사용되고 있습니다. 중복 코드를 함수로 추출하여 코드의 재사용성과 가독성을 높일 수 있습니다.

예시:

const resetSearch = () => {
  if (searchRef.current) searchRef.current.value = '';
  if (search !== '') setSearch('');
};

// 사용 예시
setMainCategory((newValue) => {
  setMainCategory(newValue);
  resetSearch();
});

setSubCategory((newValue) => {
  setSubCategory(newValue);
  resetSearch();
});

89-89: flex-0 클래스 확인 필요

className에 사용된 flex-0 클래스는 Tailwind CSS에서 유효하지 않을 수 있습니다. 대신 flex-shrink-0 또는 flex-grow-0를 사용하는 것을 고려해주세요.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7c0c126 and 7642e5b.

📒 Files selected for processing (4)
  • src/app/(crew)/page.tsx (1 hunks)
  • src/app/_components/find-crew/find-crew.tsx (0 hunks)
  • src/components/common/crew-list/crew-card-list.tsx (1 hunks)
  • src/types/crew-card.d.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • src/app/_components/find-crew/find-crew.tsx
🔇 Additional comments (4)
src/types/crew-card.d.ts (1)

16-16: 타입 변경이 적절하나 영향도 확인 필요

undefined 타입을 제거한 것은 무한 쿼리 방식으로의 전환과 잘 부합합니다. 하지만 이 변경으로 인한 영향을 확인해야 합니다.

다음 스크립트로 영향을 받는 컴포넌트들을 확인하겠습니다:

✅ Verification successful

타입 변경이 안전하게 처리되었음을 확인

MainCrewListResponse 타입의 사용처를 분석한 결과, 모든 컴포넌트에서 이미 undefined 없이 배열로 처리하고 있습니다. 특히:

  • crew-queries.tsx의 무한 스크롤 구현에서 안전하게 처리됨
  • crew-card-list.tsx에서 flatMap을 통해 배열 처리가 올바르게 구현됨
  • API 호출 부분(get-crew-list.ts)에서도 타입이 일관되게 사용됨
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: MainCrewListResponse 타입을 사용하는 모든 컴포넌트 검색

# TypeScript 파일에서 MainCrewListResponse 사용 검색
rg -t typescript "MainCrewListResponse" -A 3

Length of output: 79


Script:

#!/bin/bash
# Search for MainCrewListResponse usage in all files
rg "MainCrewListResponse" -A 3

# Also search for content property access patterns
rg "\.content\b" --type-add 'ts:*.{ts,tsx}' --type-add 'dts:*.d.ts' --type ts --type dts -A 2

Length of output: 3847

src/components/common/crew-list/crew-card-list.tsx (1)

14-14: 타입 정의 변경에 따른 영향도 확인 필요

타입 정의가 더 엄격해졌습니다. 이는 타입 안정성을 향상시키지만, 이 컴포넌트를 사용하는 다른 부분들에서 타입 에러가 발생할 수 있습니다.

다음 스크립트로 영향을 받는 파일들을 확인해보세요:

✅ Verification successful

Let's check how CrewCardList is being used in these files to verify the impact.


Let's check the type definitions to fully understand the impact.


Let's try without the file type flag:


Based on the findings, I can now provide the final response:

타입 변경이 안전하게 적용될 수 있습니다

타입 변경 영향도를 분석한 결과, 다음과 같은 이유로 안전하게 적용될 수 있습니다:

  • useGetCrewListQuery의 구현에서 이미 undefined 응답을 에러로 처리하고 있어 실제로는 undefined가 전달되지 않습니다.
  • 실제 사용처인 HomePageMyCrewPage에서도 데이터가 있을 때만 CrewCardList를 렌더링하고 있습니다.
  • 스토리북 파일의 타입 불일치는 테스트 코드이므로 함께 수정하면 됩니다.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# CrewCardList 컴포넌트를 사용하는 모든 파일 검색
rg -l "CrewCardList"

Length of output: 300


Script:

#!/bin/bash
# Check how CrewCardList is imported and used in the identified files
echo "=== src/app/(crew)/page.tsx ==="
rg "CrewCardList" src/app/\(crew\)/page.tsx -A 5 -B 5

echo -e "\n=== src/app/(crew)/my-crew/page.tsx ==="
rg "CrewCardList" src/app/\(crew\)/my-crew/page.tsx -A 5 -B 5

echo -e "\n=== src/components/common/crew-list/profiles.stories.tsx ==="
rg "CrewCardList" src/components/common/crew-list/profiles.stories.tsx -A 5 -B 5

echo -e "\n=== src/components/common/crew-list/detail-crew-card.stories.tsx ==="
rg "CrewCardList" src/components/common/crew-list/detail-crew-card.stories.tsx -A 5 -B 5

echo -e "\n=== src/components/common/crew-list/crew-card-list.stories.tsx ==="
rg "CrewCardList" src/components/common/crew-list/crew-card-list.stories.tsx -A 5 -B 5

Length of output: 4590


Script:

#!/bin/bash
# Check MainCrewListResponse type definition and related types
echo "=== MainCrewListResponse type definition ==="
rg -t typescript "MainCrewListResponse" -A 10 -B 10

echo -e "\n=== Check useGetCrewListQuery implementation ==="
rg -t typescript "useGetCrewListQuery" -A 10 -B 10

Length of output: 384


Script:

#!/bin/bash
# Check MainCrewListResponse type definition and related types
echo "=== MainCrewListResponse type definition ==="
rg "MainCrewListResponse" -A 10 -B 10

echo -e "\n=== Check useGetCrewListQuery implementation ==="
rg "useGetCrewListQuery" -A 10 -B 10

# Also check the specific file where type might be defined
echo -e "\n=== Check types/crew-card.ts ==="
cat src/types/crew-card.ts

Length of output: 19807

src/app/(crew)/page.tsx (2)

16-16: HomePage 함수의 async 제거 확인

HomePage 함수에서 async를 제거하여 일반 함수로 변경한 것을 확인했습니다. 비동기 처리가 필요하지 않다면 적절한 수정입니다.


6-6: 데이터 페칭 훅 변경 사항 확인 필요

useGetCrewListQuery로 데이터 페칭 로직을 변경하셨습니다. 기존에 사용되던 getCrewList 함수 호출 부분이 모두 업데이트되었는지 확인해주세요.

다음 스크립트를 실행하여 코드베이스 전체에서 getCrewList 함수의 사용을 확인할 수 있습니다:

✅ Verification successful

Let me check the usage of both the new hook and the API function to verify the changes.


데이터 페칭 로직이 올바르게 업데이트되었습니다

getCrewList 함수는 useGetCrewListQuery 커스텀 훅 내부에서만 사용되고 있으며, 이 훅은 필요한 모든 컴포넌트에서 적절히 사용되고 있습니다. 다른 곳에서 직접적으로 getCrewList를 호출하는 부분은 없습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: 'getCrewList' 함수의 남은 사용 부분 확인

# 'getCrewList' 함수를 호출하는 부분 검색
rg 'getCrewList\('

Length of output: 263


Script:

#!/bin/bash
# Check usage of useGetCrewListQuery hook
rg "useGetCrewListQuery" -A 2

# Check the implementation and usage context of getCrewList
rg "getCrewList" -A 5

Length of output: 3059

@github-actions
Copy link

Copy link

@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

🧹 Outside diff range and nitpick comments (2)
src/components/common/crew-list/crew-card-list.stories.tsx (2)

Line range hint 32-43: 쿼리 매개변수 및 오류 처리 개선이 필요합니다.

현재 구현에서 다음과 같은 개선사항을 제안드립니다:

  1. 쿼리 매개변수가 하드코딩되어 있어 컴포넌트의 재사용성이 제한됩니다.
  2. 쿼리 실패에 대한 오류 처리가 없습니다.
  3. 초기 로딩 상태 처리가 누락되었습니다.

다음과 같이 개선하는 것을 추천드립니다:

-function RenderCrewCardList() {
+function RenderCrewCardList({
+  keyword = '',
+  mainLocation = '',
+  mainCategory = '',
+  subCategory = '',
+  sortType = 'LATEST'
+}: {
+  keyword?: string;
+  mainLocation?: string;
+  mainCategory?: string;
+  subCategory?: string;
+  sortType?: string;
+}) {
   const { data, ref, isFetchingNextPage } = useInfiniteScroll(
     useGetCrewListQuery({
-      keyword: '',
-      mainLocation: '',
-      mainCategory: '',
-      subCategory: '',
-      sortType: 'LATEST',
+      keyword,
+      mainLocation,
+      mainCategory,
+      subCategory,
+      sortType,
     }),
   );

+  if (error) {
+    return <div>데이터를 불러오는 중 오류가 발생했습니다.</div>;
+  }
+
+  if (!data && isLoading) {
+    return <div>로딩 중...</div>;
+  }
+
   if (!data) return null;
   return <CrewCardList data={data} ref={ref} isFetchingNextPage={isFetchingNextPage} />;
 }

48-50: 스토리북 테스트 케이스 보강이 필요합니다.

현재는 기본 케이스만 테스트하고 있습니다. 다양한 시나리오를 테스트하기 위해 추가 스토리를 작성하는 것이 좋겠습니다.

다음과 같은 테스트 케이스 추가를 제안드립니다:

export const WithKeywordSearch: Story = {
  render: () => <RenderCrewCardList keyword="프로그래밍" />,
};

export const WithLocationFilter: Story = {
  render: () => <RenderCrewCardList mainLocation="서울" />,
};

export const WithCategoryFilter: Story = {
  render: () => (
    <RenderCrewCardList 
      mainCategory="개발" 
      subCategory="웹개발"
    />
  ),
};
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7642e5b and 84780af.

📒 Files selected for processing (1)
  • src/components/common/crew-list/crew-card-list.stories.tsx (2 hunks)

@github-actions
Copy link

Copy link
Contributor

@HaeJungg HaeJungg 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

@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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 84780af and 47f45c4.

📒 Files selected for processing (1)
  • src/utils/api.ts (1 hunks)
🔇 Additional comments (1)
src/utils/api.ts (1)

Line range hint 3-13: 구현이 잘 되어있습니다!

타입 안정성이 잘 보장되어 있으며, 유효성 검사 오류를 처리하기 위한 구조가 명확합니다.


try {
const response = await fetch(`${url}`, fetchOptions); // API 요청 실행
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}${url}`, fetchOptions); // API 요청 실행
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

URL 구성 로직 개선이 필요합니다

현재 구현에는 다음과 같은 잠재적인 문제가 있을 수 있습니다:

  1. 환경 변수가 없거나 잘못된 경우에 대한 처리가 없습니다.
  2. 베이스 URL과 경로 사이에 중복된 슬래시가 발생할 수 있습니다.

다음과 같이 개선하는 것을 제안드립니다:

- const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}${url}`, fetchOptions);
+ const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL?.replace(/\/+$/, '') ?? '';
+ if (!baseUrl) {
+   throw new ApiError(500, 'API 기본 URL이 설정되지 않았습니다');
+ }
+ const cleanPath = url.replace(/^\/+/, '');
+ const response = await fetch(`${baseUrl}/${cleanPath}`, fetchOptions);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}${url}`, fetchOptions); // API 요청 실행
const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL?.replace(/\/+$/, '') ?? '';
if (!baseUrl) {
throw new ApiError(500, 'API 기본 URL이 설정되지 않았습니다');
}
const cleanPath = url.replace(/^\/+/, '');
const response = await fetch(`${baseUrl}/${cleanPath}`, fetchOptions);

@github-actions
Copy link

Copy link

@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: 3

🧹 Outside diff range and nitpick comments (4)
src/_queries/crew/get-crew-list-queries.tsx (1)

Line range hint 13-17: 에러 메시지 개선 제안

현재 에러 메시지가 너무 간단합니다. 문제 해결을 위해 더 자세한 컨텍스트를 포함하면 좋을 것 같습니다.

다음과 같이 개선하는 것을 제안드립니다:

           if (response === undefined) {
-            throw new Error('Response is null');
+            throw new Error(`크루 목록 조회 실패: 응답이 없습니다. 조건: ${JSON.stringify(condition)}`);
           }
src/app/(crew)/my-crew/page.tsx (1)

Line range hint 19-21: TODO 코멘트 구현 방향 제안

현재 TODO 코멘트는 데이터 페칭 구현에 대한 내용을 담고 있습니다. PR의 목적에 맞춰 다음과 같은 구현을 제안드립니다:

  1. useInfiniteScroll 훅에 적절한 파라미터를 전달하여 무한 스크롤 구현
  2. MyCrewListResponse 타입에 맞는 데이터 구조 확인

구체적인 구현 코드를 제공해드릴까요?

src/app/(crew)/page.tsx (2)

1-15: 임포트 구문 개선 제안

임포트 구문을 다음과 같이 논리적 그룹으로 구성하면 가독성이 향상될 것 같습니다:

  1. React/Next.js 관련
  2. 외부 라이브러리 (Mantine)
  3. 커스텀 훅/쿼리
  4. 컴포넌트
  5. 타입/데이터/에셋
'use client';

import { useRef, useState } from 'react';
import Image from 'next/image';

import { Divider, TextInput } from '@mantine/core';

import { useGetCrewListQuery } from '@/src/_queries/crew/get-crew-list-queries';
import { useInfiniteScroll } from '@/src/hooks/use-infinite-scroll';

import CategoryContainer from '@/src/app/_components/category/category-container';
import HeroCrew from '@/src/app/_components/hero/hero-crew';
import CrewCardList from '@/src/components/common/crew-list/crew-card-list';
import DropDown from '@/src/components/common/input/drop-down';

import { MainCrewListResponse } from '@/src/types/crew-card';
import regionData from '@/src/data/region.json';
import IcoSearch from '@/public/assets/icons/ic-search.svg';

16-22: 상태 관리 로직 분리 제안

현재 컴포넌트에 있는 여러 상태 관리 로직을 커스텀 훅으로 분리하면 다음과 같은 이점이 있습니다:

  • 컴포넌트 복잡도 감소
  • 상태 관리 로직 재사용 가능
  • 테스트 용이성 향상

다음과 같은 커스텀 훅을 생성하는 것을 제안드립니다:

// useCrewFilters.ts
export function useCrewFilters() {
  const [mainCategory, setMainCategory] = useState('');
  const [subCategory, setSubCategory] = useState('');
  const [sort, setSort] = useState<string | null>('latest');
  const [region, setRegion] = useState<string>('');
  const [search, setSearch] = useState('');
  const searchRef = useRef<HTMLInputElement>(null);

  return {
    filters: { mainCategory, subCategory, sort, region, search },
    setters: { setMainCategory, setSubCategory, setSort, setRegion, setSearch },
    searchRef
  };
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 47f45c4 and 8f150e0.

📒 Files selected for processing (4)
  • src/_queries/crew/get-crew-list-queries.tsx (1 hunks)
  • src/app/(crew)/my-crew/page.tsx (1 hunks)
  • src/app/(crew)/page.tsx (1 hunks)
  • src/components/common/crew-list/crew-card-list.stories.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/common/crew-list/crew-card-list.stories.tsx
🔇 Additional comments (5)
src/_queries/crew/get-crew-list-queries.tsx (2)

Line range hint 4-22: 구현이 PR 목표와 잘 부합합니다

무한 쿼리 구현이 잘 되어 있으며, 다음 사항들이 특히 좋습니다:

  • 페이지네이션 로직이 명확합니다
  • 정렬 조건이 쿼리 키에 포함되어 있어 정렬 변경 시 적절히 리패치됩니다
  • 실시간 크루 데이터 표시라는 PR의 목표를 잘 달성할 수 있는 구조입니다

2-2: 임포트 경로 변경 검증 필요

변경된 임포트 경로가 올바른지 확인이 필요합니다.

✅ Verification successful

임포트 경로가 정확히 설정되어 있음을 확인했습니다

파일 검색 결과, src/_apis/crew/get-crew-list.ts 파일이 존재하며, src/_queries/crew/get-crew-list-queries.tsx에서 상대 경로로 올바르게 참조하고 있습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the import path exists and is correct

# Check if the file exists at the new path
fd -p "_apis/crew/get-crew-list" --type f

# Check for any other potential references to this file
rg "from.*_apis/crew/get-crew-list"

Length of output: 217

src/app/(crew)/my-crew/page.tsx (2)

Line range hint 37-42: 주석 처리된 코드의 처리 방향 결정 필요

CrewCardList 컴포넌트가 주석 처리되어 있습니다. PR의 목적이 데이터 렌더링 방식을 변경하는 것이므로, 이 부분의 구현 계획을 명확히 할 필요가 있습니다.

  1. 해당 코드를 삭제할 예정인지
  2. 새로운 방식으로 구현할 예정인지
  3. 임시로 주석 처리한 것인지

명확한 방향성을 코멘트로 남겨주시면 좋겠습니다.

#!/bin/bash
# Description: CrewCardList 컴포넌트의 다른 사용처 확인

echo "CrewCardList 컴포넌트 사용 현황:"
rg "CrewCardList" --type ts

4-4: 임포트 경로 변경이 전체 코드베이스에 미치는 영향 확인 필요

임포트 경로가 변경되었습니다. 다른 파일들에서도 동일한 변경이 필요한지 확인이 필요합니다.

✅ Verification successful

임포트 경로 변경 검증 완료

검증 결과, 임포트 경로 @/src/_queries/crew/get-crew-list-queries는 현재 올바른 경로이며, 모든 파일에서 일관되게 사용되고 있습니다. 변경이 필요한 다른 파일은 없습니다.

  • src/app/(crew)/page.tsx
  • src/app/(crew)/my-crew/page.tsx
  • src/components/common/crew-list/crew-card-list.stories.tsx

모두 동일한 경로를 사용하고 있어 추가 수정이 필요하지 않습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: 이전 임포트 경로를 사용하는 파일들 검색

echo "이전 임포트 경로 사용 확인:"
rg "@/src/_queries/crew-queries" --type ts

Length of output: 2157


Script:

#!/bin/bash
# Search for any usage of crew-related queries
echo "크루 쿼리 사용 현황 확인:"
rg "useGetCrewList" --type ts

# Search for files in the queries directory
echo -e "\n쿼리 디렉토리 구조 확인:"
fd . "src/_queries" -t f

Length of output: 967

src/app/(crew)/page.tsx (1)

30-35: 검색 시 카테고리 초기화 동작 검토 필요

현재 검색 시 메인/서브 카테고리가 초기화되는데, 이는 사용자 경험 측면에서 예상치 못한 동작일 수 있습니다. 카테고리와 검색이 독립적으로 동작하도록 수정하는 것을 고려해보세요.

사용자 경험 관점에서 이 동작이 의도된 것인지 확인이 필요합니다.

Comment on lines +38 to +46
const { data, ref, isFetchingNextPage } = useInfiniteScroll(
useGetCrewListQuery({
keyword: search,
mainLocation: handleRegionChange(region),
mainCategory,
subCategory,
sortType: sort === 'latest' ? 'LATEST' : 'POPULAR',
}),
);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

데이터 페칭 에러 처리 보완 필요

무한 스크롤 구현은 잘 되어있지만, 다음 사항들을 고려해보시면 좋을 것 같습니다:

  • 데이터 로딩 상태 표시
  • 에러 발생 시 사용자 피드백
  • 재시도 메커니즘
const { data, error, isLoading, ref, isFetchingNextPage } = useInfiniteScroll(
  useGetCrewListQuery({
    keyword: search,
    mainLocation: handleRegionChange(region),
    mainCategory,
    subCategory,
    sortType: sort === 'latest' ? 'LATEST' : 'POPULAR',
  }),
);

// JSX에 에러 상태 추가
{error && <ErrorMessage error={error} onRetry={() => refetch()} />}
{isLoading && <LoadingSpinner />}

</div>
<div className="mt-8 px-3 md:px-8 lg:px-11.5">
{data && <CrewCardList data={data} ref={ref} isFetchingNextPage={isFetchingNextPage} />}
</div>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

데이터 로딩 상태 처리 개선 필요

현재 구현에서는 데이터가 없을 때의 상태 처리가 불충분합니다. 다음과 같은 상태들을 추가로 처리하면 좋을 것 같습니다:

  • 초기 로딩 상태
  • 데이터가 없는 경우
  • 에러 상태
- {data && <CrewCardList data={data} ref={ref} isFetchingNextPage={isFetchingNextPage} />}
+ {isLoading ? (
+   <LoadingSpinner />
+ ) : error ? (
+   <ErrorMessage error={error} />
+ ) : !data?.length ? (
+   <EmptyState message="검색 결과가 없습니다" />
+ ) : (
+   <CrewCardList data={data} ref={ref} isFetchingNextPage={isFetchingNextPage} />
+ )}

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

Comment on lines 71 to 87
ref={searchRef}
leftSectionPointerEvents="none"
onKeyDown={(e) => {
if (e.key === 'Enter') handleSearch();
}}
rightSection={
<button type="button" className="flex h-5 w-5" onClick={handleSearch}>
<Image src={IcoSearch} alt="search" width={20} height={20} className="-ml-1" />
</button>
}
placeholder="크루 이름, 위치를 검색하세요."
classNames={{
input:
'h-11 w-full rounded-xl border-0 pr-10 font-pretendard text-base font-medium text-gray-800 placeholder:text-gray-500',
}}
/>
</div>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

검색 입력 필드 접근성 개선 필요

검색 기능의 접근성을 높이기 위해 다음 사항들을 추가하면 좋을 것 같습니다:

  • aria-label 추가
  • 검색 버튼에 적절한 role 지정
  • 키보드 네비게이션 지원
<TextInput
  ref={searchRef}
  leftSectionPointerEvents="none"
+ aria-label="크루 검색"
  onKeyDown={(e) => {
    if (e.key === 'Enter') handleSearch();
  }}
  rightSection={
    <button
      type="button"
+     role="search"
+     aria-label="검색하기"
      className="flex h-5 w-5"
      onClick={handleSearch}
    >
      <Image src={IcoSearch} alt="search" width={20} height={20} className="-ml-1" />
    </button>
  }
  placeholder="크루 이름, 위치를 검색하세요."
  classNames={{
    input:
      'h-11 w-full rounded-xl border-0 pr-10 font-pretendard text-base font-medium text-gray-800 placeholder:text-gray-500',
  }}
/>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<TextInput
ref={searchRef}
leftSectionPointerEvents="none"
onKeyDown={(e) => {
if (e.key === 'Enter') handleSearch();
}}
rightSection={
<button type="button" className="flex h-5 w-5" onClick={handleSearch}>
<Image src={IcoSearch} alt="search" width={20} height={20} className="-ml-1" />
</button>
}
placeholder="크루 이름, 위치를 검색하세요."
classNames={{
input:
'h-11 w-full rounded-xl border-0 pr-10 font-pretendard text-base font-medium text-gray-800 placeholder:text-gray-500',
}}
/>
<TextInput
ref={searchRef}
leftSectionPointerEvents="none"
aria-label="크루 검색"
onKeyDown={(e) => {
if (e.key === 'Enter') handleSearch();
}}
rightSection={
<button
type="button"
role="search"
aria-label="검색하기"
className="flex h-5 w-5"
onClick={handleSearch}
>
<Image src={IcoSearch} alt="search" width={20} height={20} className="-ml-1" />
</button>
}
placeholder="크루 이름, 위치를 검색하세요."
classNames={{
input:
'h-11 w-full rounded-xl border-0 pr-10 font-pretendard text-base font-medium text-gray-800 placeholder:text-gray-500',
}}
/>

@github-actions
Copy link

Copy link

@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

🧹 Outside diff range and nitpick comments (2)
src/_queries/crew/crew-list-queries.tsx (1)

Line range hint 12-12: 페이지 크기를 설정 파일로 분리 제안

현재 페이지 크기가 6으로 하드코딩되어 있습니다. 이 값을 설정 파일로 분리하면 유지보수성이 향상될 것입니다.

+ // src/config/pagination.ts
+ export const CREW_LIST_PAGE_SIZE = 6;

- getCrewList(condition, { page: pageParam, size: 6, sort: [condition.sortType] })
+ getCrewList(condition, { page: pageParam, size: CREW_LIST_PAGE_SIZE, sort: [condition.sortType] })
src/app/(crew)/page.tsx (1)

24-28: 타입 안정성 개선이 필요합니다

handleRegionChange 함수의 타입 안정성을 높이기 위해 다음과 같은 개선을 제안드립니다:

- const handleRegionChange = (newValue: string) => {
+ const handleRegionChange = (newValue: string): string => {
+   type RegionData = {
+     main: {
+       value: string;
+       label: string;
+     };
+   };
    const selectedRegion = regionData.find(
+     (dataItem: RegionData) =>
      dataItem.main.value === newValue
    );
    if (selectedRegion?.main.label === '지역 전체') return '';
    return selectedRegion ? selectedRegion.main.label : '';
  };
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 8f150e0 and 3febcae.

📒 Files selected for processing (4)
  • src/_queries/crew/crew-list-queries.tsx (1 hunks)
  • src/app/(crew)/my-crew/page.tsx (0 hunks)
  • src/app/(crew)/page.tsx (1 hunks)
  • src/components/common/crew-list/crew-card-list.stories.tsx (3 hunks)
💤 Files with no reviewable changes (1)
  • src/app/(crew)/my-crew/page.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/common/crew-list/crew-card-list.stories.tsx
🔇 Additional comments (5)
src/_queries/crew/crew-list-queries.tsx (2)

Line range hint 12-17: 응답 값 검증 로직 추가 👍

undefined 응답에 대한 명시적인 에러 처리를 추가한 것이 좋습니다. 이는 런타임 에러를 방지하고 디버깅을 용이하게 만들어줄 것입니다.


2-2: API 파일 경로 변경 확인 필요

새로운 import 경로가 올바르게 설정되었는지 확인이 필요합니다.

✅ Verification successful

API 파일 경로가 정상적으로 변경되었습니다

getCrewList 함수가 새로운 경로에 올바르게 구현되어 있으며, 이전 경로를 참조하는 코드가 없음을 확인했습니다. 현재 import 문은 정확하게 설정되어 있습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence and usage of the new API file path

# Check if the new API file exists
fd "crew-list.ts" --type f

# Check for any remaining references to the old path
rg "get-crew-list"

Length of output: 73


Script:

#!/bin/bash
# Check the content of the API file to verify the export
cat src/_apis/crew/crew-list.ts

# Check for any files still using potential old paths
rg -l "_apis/crew/get-crew-list"

# Check for any files importing from crew-list
rg -l "from.*crew-list'"

Length of output: 1069

src/app/(crew)/page.tsx (3)

38-46: 에러 처리와 로딩 상태 관리가 필요합니다

기존 리뷰 코멘트에서 지적된 사항이 아직 해결되지 않았습니다. 다음 개선사항을 제안드립니다:

const { 
  data, 
  error, 
  isLoading, 
  ref, 
  isFetchingNextPage,
  refetch 
} = useInfiniteScroll(
  useGetCrewListQuery({
    keyword: search,
    mainLocation: handleRegionChange(region),
    mainCategory,
    subCategory,
    sortType: sort === 'latest' ? 'LATEST' : 'POPULAR',
  }),
);

71-87: 접근성 및 사용자 경험 개선이 필요합니다

기존 리뷰에서 지적된 접근성 문제가 해결되지 않았습니다. 추가로 검색 기능에 대한 사용자 피드백도 필요합니다:

 <TextInput
   ref={searchRef}
   leftSectionPointerEvents="none"
+  aria-label="크루 검색"
   onKeyDown={(e) => {
     if (e.key === 'Enter') handleSearch();
   }}
   rightSection={
-    <button type="button" className="flex h-5 w-5" onClick={handleSearch}>
+    <button
+      type="button"
+      role="search"
+      aria-label="검색하기"
+      className="flex h-5 w-5 items-center justify-center hover:opacity-80"
+      onClick={handleSearch}
+    >
       <Image src={IcoSearch} alt="search" width={20} height={20} className="-ml-1" />
     </button>
   }
   placeholder="크루 이름, 위치를 검색하세요."
+  aria-describedby="search-description"
   classNames={{
     input:
       'h-11 w-full rounded-xl border-0 pr-10 font-pretendard text-base font-medium text-gray-800 placeholder:text-gray-500',
   }}
 />
+ <span id="search-description" className="sr-only">
+   엔터 키를 누르거나 검색 버튼을 클릭하여 검색할 수 있습니다
+ </span>

119-119: 데이터 상태에 따른 UI 처리가 필요합니다

기존 리뷰에서 지적된 데이터 상태 처리가 아직 구현되지 않았습니다:

- {data && <CrewCardList data={data} ref={ref} isFetchingNextPage={isFetchingNextPage} />}
+ {isLoading ? (
+   <div className="flex justify-center py-8">
+     <LoadingSpinner />
+   </div>
+ ) : error ? (
+   <div className="flex flex-col items-center py-8">
+     <ErrorMessage
+       message="데이터를 불러오는 중 문제가 발생했습니다"
+       onRetry={refetch}
+     />
+   </div>
+ ) : !data?.length ? (
+   <div className="flex justify-center py-8">
+     <EmptyState message="검색 결과가 없습니다" />
+   </div>
+ ) : (
+   <CrewCardList
+     data={data}
+     ref={ref}
+     isFetchingNextPage={isFetchingNextPage}
+   />
+ )}

Copy link
Contributor

@minkyung5x5 minkyung5x5 left a comment

Choose a reason for hiding this comment

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

수고하셨습니다!!

@yulrang yulrang changed the title Feat/98/crew api 연결 : 이것먼저 리뷰 부탁드립니다~! Feat/98/crew api 연결 : 제가올린것중 이것먼저 리뷰 부탁드립니다~! Nov 13, 2024
@yulrang yulrang merged commit a8816c8 into develop Nov 13, 2024
@github-actions
Copy link

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

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants