Skip to content

Conversation

@layout-SY
Copy link
Collaborator

@layout-SY layout-SY commented Jun 2, 2025

구현내용

  • API 미구현으로 mock 데이터로 대체
    image

연관이슈

close #324

Summary by CodeRabbit

  • 신규 기능

    • 관리자 페이지에서 전체 유저 목록을 검색 및 페이지네이션과 함께 확인할 수 있는 화면이 추가되었습니다.
    • 유저 카드 컴포넌트가 도입되어 유저의 상태, 이메일, 닉네임, 포지션, 스킬, 신고 횟수 등 상세 정보를 한눈에 볼 수 있습니다.
    • 검색바와 검색 결과, 페이지네이션 기능이 개선되었습니다.
    • 유저 프리뷰 데이터를 별도로 조회하는 기능과 관련 훅이 추가되었습니다.
  • 버그 수정

    • 유저 프리뷰 및 전체 유저 데이터의 표시 방식이 일관성 있게 개선되었습니다.
  • 스타일

    • 관리자 페이지 UI가 테마 색상 기반으로 개선되고, 스크롤 영역 및 그리드 레이아웃 등 시각적 요소가 향상되었습니다.
    • 상태 및 보고 현황 표시 색상이 하드코딩에서 테마 색상으로 변경되었습니다.
  • 리팩터

    • 유저 상태, 신고 관련 데이터 구조 및 명칭이 더 명확하게 변경되었습니다.
    • 신고 관련 용어가 'imposed'에서 'reported' 및 'done'으로 변경되었습니다.
  • 문서화

    • 검색, 유저, 신고 관련 타입 및 인터페이스가 추가 및 정비되었습니다.
  • 테스트/목업

    • 전체 유저 목록 및 프리뷰를 위한 목업 데이터와 핸들러가 추가되었습니다.

@layout-SY layout-SY requested a review from YouD0313 June 2, 2025 16:10
@layout-SY layout-SY self-assigned this Jun 2, 2025
@layout-SY layout-SY added the ⛏기능 기능 구현에 대한 라벨 label Jun 2, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jun 2, 2025

"""

Walkthrough

이 변경사항은 관리자 회원 전체 조회 및 프리뷰 기능을 구현합니다. 회원 전체 목록 조회 페이지, 회원 프리뷰, 검색 및 페이지네이션, 스타일 컴포넌트, 관련 API 및 모델 정의, 그리고 목업 데이터와 핸들러가 추가 및 수정되었습니다.

Changes

파일/그룹 변경 요약
src/api/auth.api.ts, src/hooks/admin/useGetAllUsers.ts, src/hooks/admin/useGetAllUsersPreview.ts 회원 전체 조회 및 프리뷰 API 함수 및 커스텀 훅 추가/수정, 검색 파라미터 지원
src/models/auth.ts, src/models/search.ts 회원/검색 관련 모델, enum, 인터페이스 분리 및 추가
src/components/admin/userCard/UserCard.tsx, src/components/admin/userCard/UserCard.styled.ts 회원 카드 컴포넌트 및 스타일 신규 추가
src/pages/admin/adminAllUser/AdminAllUser.tsx, src/pages/admin/adminAllUser/AdminAllUser.styled.ts 전체 회원 조회 페이지 및 스타일 신규 구현
src/hooks/admin/useSearchBar.ts 검색/페이지네이션 상태 관리 훅 신규 추가
src/components/common/admin/searchBar/SearchBar.tsx 검색바 prop 구조 변경, 내부 상태 관리 개선, 공지 작성 링크 조건부 렌더링
src/components/admin/adminNotice/AdminNoticeList.tsx 검색/페이지네이션 상태 관리 훅 적용, prop 변경 반영
src/constants/admin/adminModal.ts 결과 없음 메시지 상수 추가
src/hooks/queries/user/keys.ts 회원 프리뷰 쿼리 키 추가
src/mock/mockAllUser.json, src/mock/userpage.ts, src/mock/browser.ts 회원 전체/프리뷰 목업 데이터 및 핸들러 추가/수정
src/components/admin/previewComponent/allUserPreview/AllUserPreview.tsx 회원 프리뷰 훅 및 렌더링 로직 변경
src/components/admin/previewComponent/reportsPreview/ReportsPreview.styled.ts, src/components/admin/previewComponent/reportsPreview/ReportsPreview.tsx, src/models/report.ts 신고 관련 명칭, 스타일, 모델 필드명 변경 (imposed → reported, isImposed → isDone)
src/components/admin/mainCard/MainCard.styled.ts, src/components/admin/previewComponent/inquiresPreview/InquiresPreview.styled.ts, src/style/theme.ts 스타일 색상 theme 적용 및 blue 컬러 추가

Sequence Diagram(s)

sequenceDiagram
  participant AdminPage as AdminAllUser
  participant SearchBar as SearchBar
  participant SearchHook as useSearchBar
  participant UserHook as useGetAllUsers
  participant API as getAllUsers

  AdminPage->>SearchHook: useSearchBar()로 검색/페이지 상태 관리
  AdminPage->>UserHook: useGetAllUsers(searchUnit)
  UserHook->>API: getAllUsers(params)
  API-->>UserHook: 전체 회원 데이터 반환
  UserHook-->>AdminPage: 회원 목록, 로딩 상태 전달
  SearchBar->>SearchHook: onGetKeyword(검색어)
  SearchHook-->>AdminPage: 검색어/페이지 변경 시 상태 업데이트
  AdminPage->>UserHook: 변경된 searchUnit으로 재조회
Loading

Assessment against linked issues

Objective (Issue) Addressed Explanation
전체 회원 조회 페이지 구현 (#324)
회원 개별 페이지 조회 (#324) 회원 개별 상세 페이지는 구현되지 않음.

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
신고 프리뷰 관련 명칭 및 스타일, 모델 필드명 변경 (src/components/admin/previewComponent/reportsPreview/ReportsPreview.styled.ts, src/components/admin/previewComponent/reportsPreview/ReportsPreview.tsx, src/models/report.ts) 회원 조회와 직접적 관련 없는 신고 프리뷰 명칭 및 스타일 변경이 포함됨.

Possibly related PRs

Suggested labels

🛠개선

Suggested reviewers

  • YouD0313

Poem

🐇
회원 목록이 쫘르륵,
검색과 페이지네이션도 척척!
프리뷰 카드 반짝반짝,
스타일도 테마에 맞춰 착착.
관리자 토끼가 춤을 춰요,
새로운 회원 페이지에서!
🎉
"""

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.

npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-06-05T12_12_56_543Z-debug-0.log


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 37c542f and 7d6e27d.

📒 Files selected for processing (4)
  • src/components/admin/adminNotice/AdminNoticeList.tsx (3 hunks)
  • src/components/common/admin/searchBar/SearchBar.tsx (3 hunks)
  • src/hooks/admin/useSearchBar.ts (1 hunks)
  • src/pages/admin/adminAllUser/AdminAllUser.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/hooks/admin/useSearchBar.ts
  • src/components/admin/adminNotice/AdminNoticeList.tsx
  • src/components/common/admin/searchBar/SearchBar.tsx
  • src/pages/admin/adminAllUser/AdminAllUser.tsx
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: accessibility-test
✨ Finishing Touches
  • 📝 Generate Docstrings

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

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

🧹 Nitpick comments (10)
src/hooks/admin/useGetAllUsersPreview.ts (1)

1-18: 훅 구현이 우수합니다.

React Query의 select 옵션을 사용하여 데이터를 효율적으로 제한하는 구현이 잘 되어 있습니다. slice(0, 5)는 5개 미만의 사용자가 있을 때도 올바르게 작동합니다.

다만 일관성을 위해 에러 처리 상태(isError, error)도 반환하는 것을 고려해보세요:

export const useGetAllUsersPreview = () => {
  const {
    data: allUserData,
    isLoading,
    isFetching,
+   isError,
+   error,
  } = useQuery({
    queryKey: [UserData.allUserPreview],
    queryFn: () => getAllUsersPreview(),
    select: (allUsers) => allUsers.slice(0, 5),
  });

- return { allUserData, isLoading, isFetching };
+ return { allUserData, isLoading, isFetching, isError, error };
};
src/hooks/admin/useSearchBar.ts (1)

13-20: URL 파라미터 동기화 로직 개선이 필요합니다.

URL에서 키워드를 읽어올 때 몇 가지 개선점이 있습니다:

  1. Line 18의 삼항 연산자가 불필요합니다 (이미 if문에서 searchKeyword의 존재를 확인했음)
  2. URL에 키워드가 있을 때 페이지를 1로 리셋하는 것을 고려해보세요

다음과 같이 개선할 수 있습니다:

  useEffect(() => {
    const searchKeyword = searchParams.get('keyword');

    if (searchKeyword) {
-     setSearchUnit((prev) => ({ ...prev, keyword: searchKeyword }));
-     setValue((prev) => (searchKeyword ? searchKeyword : prev));
+     setSearchUnit((prev) => ({ ...prev, keyword: searchKeyword, page: 1 }));
+     setValue(searchKeyword);
    }
  }, [searchParams]);
src/components/common/admin/searchBar/SearchBar.styled.ts (2)

25-29: 컴포넌트 네이밍을 명확히 해주세요.

AdminSearchBarBackIcon이라는 이름이 실제 용도를 정확히 반영하지 않습니다. 클리어 기능인지 뒤로가기 기능인지 명확하지 않습니다.

용도에 맞는 명확한 이름으로 변경하는 것을 권장합니다:

-export const AdminSearchBarBackIcon = styled.button`
+export const AdminSearchBarClearIcon = styled.button`
  svg {
    width: 1.5rem;
  }
`;

7-7: 하드코딩된 색상값을 테마 변수로 교체하세요.

Line 7에서 하드코딩된 색상값 #000000이 사용되었습니다. 일관성을 위해 테마 변수를 사용하는 것이 좋습니다.

- border: 1px solid #000000;
+ border: 1px solid ${({ theme }) => theme.color.black || '#000000'};
src/components/admin/userCard/UserCard.styled.ts (2)

4-4: 고정 너비 대신 최대 너비 사용을 고려하세요.

고정 너비(240px)는 반응형 디자인에 제약이 될 수 있습니다.

export const Container = styled.div`
- width: 240px;
+ max-width: 240px;
+ width: 100%;
  display: flex;
  flex-direction: column;
  border: 1px solid #000000;
  border-radius: ${({ theme }) => theme.borderRadius.primary};
  padding: 10px;
`;

58-58: 하드코딩된 테두리 색상을 테마 변수로 교체하세요.

스킬 태그의 테두리 색상도 테마 변수를 사용하는 것이 좋습니다.

export const SkillTag = styled.img`
  width: 29px;
  height: 29px;
- border: 1px solid #ccc;
+ border: 1px solid ${({ theme }) => theme.color.lightGrey || '#ccc'};
  border-radius: 50%;
`;
src/pages/admin/adminAllUser/AdminAllUser.styled.ts (1)

9-12: 매직 넘버를 상수로 분리하는 것을 고려해보세요.

calc(100vh - 200px)의 200px은 매직 넘버입니다. 헤더나 다른 고정 요소의 높이를 나타내는 것 같은데, 이를 명명된 상수로 분리하여 유지보수성을 높이는 것이 좋겠습니다.

+const HEADER_HEIGHT = '200px';
+
 export const ScrollArea = styled.div`
-  height: calc(100vh - 200px);
+  height: calc(100vh - ${HEADER_HEIGHT});
   overflow-y: auto;
   padding-bottom: 100px;
src/pages/admin/adminAllUser/AdminAllUser.tsx (2)

16-18: 로딩 조건을 최적화해보세요.

isLoading || isFetching 조건은 데이터 재페칭 시에도 전체 로딩 스피너를 표시합니다. 이는 사용자 경험을 저해할 수 있습니다. 초기 로딩과 재페칭을 구분하여 처리하는 것이 좋겠습니다.

- if (isLoading || isFetching) {
+ if (isLoading) {
   return <LoadingSpinner />;
 }

또는 재페칭 시에는 더 작은 로딩 인디케이터를 사용할 수 있습니다.


35-37: 타입 안전성을 개선해보세요.

allUserData.allUsers?.map에서 옵셔널 체이닝을 사용하고 있는데, 이미 20줄에서 allUserDataallUsers.length를 체크했으므로 불필요합니다. 타입 가드를 통해 더 명확하게 처리할 수 있습니다.

- {allUserData.allUsers?.map((userData) => (
+ {allUserData.allUsers.map((userData) => (
   <UserCard key={userData.id} userData={userData} />
 ))}

또는 타입 가드 함수를 만들어 사용:

const hasValidUserData = (data: typeof allUserData): data is NonNullable<typeof allUserData> & { allUsers: NonNullable<typeof allUserData.allUsers> } => {
  return data && data.allUsers && data.allUsers.length > 0;
};
src/components/common/admin/searchBar/SearchBar.tsx (1)

32-39: 불필요한 return 문을 제거해주세요.

handleSubmit 함수의 마지막 return;은 불필요합니다. 또한 else 블록도 생략할 수 있어 코드를 더 간결하게 만들 수 있습니다.

 if (keyword.trim() === '') {
   return handleModalOpen(MODAL_MESSAGE_CUSTOMER_SERVICE.noKeyword);
- } else {
+ }
   onGetKeyword(keyword);
   handleKeyword(keyword);
-   return;
- }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 02635be and 890fe34.

📒 Files selected for processing (20)
  • src/api/auth.api.ts (3 hunks)
  • src/components/admin/previewComponent/allUserPreview/AllUserPreview.tsx (2 hunks)
  • src/components/admin/previewComponent/reportsPreview/ReportsPreview.styled.ts (2 hunks)
  • src/components/admin/previewComponent/reportsPreview/ReportsPreview.tsx (1 hunks)
  • src/components/admin/userCard/UserCard.styled.ts (1 hunks)
  • src/components/admin/userCard/UserCard.tsx (1 hunks)
  • src/components/common/admin/searchBar/SearchBar.styled.ts (1 hunks)
  • src/components/common/admin/searchBar/SearchBar.tsx (1 hunks)
  • src/hooks/admin/useGetAllUsers.ts (1 hunks)
  • src/hooks/admin/useGetAllUsersPreview.ts (1 hunks)
  • src/hooks/admin/useSearchBar.ts (1 hunks)
  • src/hooks/queries/user/keys.ts (1 hunks)
  • src/mock/browser.ts (2 hunks)
  • src/mock/mockAllUser.json (1 hunks)
  • src/mock/userpage.ts (2 hunks)
  • src/models/auth.ts (2 hunks)
  • src/models/report.ts (1 hunks)
  • src/models/search.ts (1 hunks)
  • src/pages/admin/adminAllUser/AdminAllUser.styled.ts (1 hunks)
  • src/pages/admin/adminAllUser/AdminAllUser.tsx (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (8)
src/mock/browser.ts (1)
src/mock/userpage.ts (1)
  • userAllPreview (25-30)
src/components/admin/previewComponent/allUserPreview/AllUserPreview.tsx (2)
src/models/auth.ts (1)
  • AllUserPreview (34-40)
src/hooks/admin/useGetAllUsersPreview.ts (1)
  • useGetAllUsersPreview (5-17)
src/hooks/admin/useSearchBar.ts (1)
src/models/search.ts (1)
  • SearchType (1-4)
src/hooks/admin/useGetAllUsersPreview.ts (1)
src/api/auth.api.ts (1)
  • getAllUsersPreview (111-121)
src/api/auth.api.ts (3)
src/api/http.api.ts (1)
  • httpClient (80-80)
src/models/auth.ts (2)
  • ApiGetAllUsersPreview (31-33)
  • ApiGetAllUsers (42-44)
src/models/search.ts (1)
  • SearchType (1-4)
src/pages/admin/adminAllUser/AdminAllUser.tsx (3)
src/hooks/admin/useGetAllUsers.ts (1)
  • useGetAllUsers (6-17)
src/components/common/admin/title/AdminTitle.tsx (1)
  • AdminTitle (8-17)
src/pages/admin/adminAllUser/AdminAllUser.styled.ts (1)
  • SearchBar (5-7)
src/components/admin/userCard/UserCard.tsx (1)
src/models/auth.ts (1)
  • AllUser (46-50)
src/models/auth.ts (1)
src/models/apiCommon.ts (1)
  • ApiCommonType (1-4)
🪛 Biome (1.9.4)
src/components/admin/userCard/UserCard.tsx

[error] 38-40: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Run Chromatic
🔇 Additional comments (30)
src/hooks/queries/user/keys.ts (1)

68-68: 새로운 쿼리 키 추가가 올바르게 구현되었습니다.

allUserPreview 키가 기존 패턴과 일치하게 추가되었으며, 사용자 프리뷰 기능을 지원하기 위한 적절한 구현입니다.

src/mock/browser.ts (2)

21-21: Import 추가가 올바르게 구현되었습니다.

userAllPreview 모듈을 정확히 import하고 있으며, 기존 코드 패턴과 일치합니다.


61-61: Mock 핸들러가 올바르게 등록되었습니다.

userAllPreview 핸들러가 handlers 배열에 적절히 추가되어 사용자 프리뷰 API 목업을 지원합니다.

src/models/search.ts (1)

1-4: 검색 타입 인터페이스가 잘 정의되었습니다.

SearchType 인터페이스가 검색 키워드와 페이징 기능을 지원하기 위해 명확하게 정의되었습니다. 속성명이 직관적이고 타입이 적절합니다.

src/models/report.ts (2)

16-16: 속성명 변경이 의미를 더 명확하게 만듭니다.

imposedCountreportedCount로 변경하여 신고 건수를 더 직관적으로 표현합니다.


19-19: 상태 속성명이 더 명확해졌습니다.

isImposedisDone으로 변경하여 처리 완료 상태를 더 명확하게 나타냅니다.

src/components/admin/previewComponent/allUserPreview/AllUserPreview.tsx (3)

7-7: 새로운 프리뷰 훅 도입이 적절합니다.

전용 프리뷰 훅으로 변경하여 관심사가 잘 분리되었습니다.


10-10: 훅 사용법이 올바릅니다.

새로운 useGetAllUsersPreview 훅을 올바르게 구조분해할당으로 사용하고 있습니다.


22-22: 데이터 처리 로직 개선이 우수합니다.

이전의 조건부 슬라이싱 로직을 제거하고 훅에서 반환되는 모든 데이터를 직접 렌더링하는 것이 더 깔끔합니다. 데이터 제한은 이제 훅의 select 옵션에서 처리됩니다.

src/hooks/admin/useGetAllUsers.ts (4)

4-4: SearchType 타입 임포트가 적절합니다.

검색 기능 구현을 위한 타입 임포트가 올바릅니다.


6-6: 함수 시그니처 업데이트가 적절합니다.

검색 및 페이징 기능을 위해 searchUnit 매개변수를 추가한 것이 올바릅니다.


12-12: 동적 쿼리 키 구성이 우수합니다.

searchUnit.keywordsearchUnit.page를 쿼리 키에 포함시켜 검색 매개변수가 변경될 때 적절한 캐시 무효화와 새로운 데이터 페칭이 이루어지도록 구현되었습니다.


13-13: API 호출 구현이 올바릅니다.

searchUnit을 API 함수에 전달하여 검색 및 페이징 기능을 올바르게 구현했습니다.

src/components/admin/previewComponent/reportsPreview/ReportsPreview.tsx (2)

23-23: 속성명 변경이 적절합니다.

imposedCount에서 reportedCount로 변경하여 의미가 더 명확해졌습니다.


28-30: 상태 표시 로직 개선이 우수합니다.

isImposed에서 isDone으로 속성명을 변경하고 해당하는 UI 텍스트("검토 완료"/"검토 미완료")도 함께 업데이트하여 일관성을 유지했습니다.

src/mock/userpage.ts (3)

5-5: 새로운 목 데이터 import가 적절합니다.

더 상세한 사용자 데이터를 위한 mockAllUsers import가 올바르게 추가되었습니다.


25-30: 미리보기 엔드포인트 핸들러가 잘 구현되었습니다.

/users/preview 엔드포인트를 위한 새로운 핸들러가 적절하게 구현되어 있으며, 기존 mockUsers 데이터를 반환하여 미리보기 용도에 맞습니다.


35-35: 전체 사용자 데이터로의 업데이트가 적절합니다.

userAll 핸들러가 더 상세한 mockAllUsers 데이터를 반환하도록 업데이트되어 관리자 페이지의 요구사항에 부합합니다.

src/components/admin/previewComponent/reportsPreview/ReportsPreview.styled.ts (2)

24-27: 스타일드 컴포넌트 이름 변경이 적절합니다.

ImposedCount에서 ReportedCount로의 이름 변경이 신고 횟수의 의미를 더 명확하게 표현합니다.


52-55: 처리 상태 컴포넌트의 개선된 네이밍입니다.

IsImposed에서 IsDone으로의 이름 변경과 $isImposed에서 $isDone으로의 prop 변경이 처리 완료 상태를 더 직관적으로 표현합니다.

src/api/auth.api.ts (3)

3-3: 새로운 타입 import가 적절합니다.

미리보기 API와 검색 기능을 위한 타입들이 올바르게 import되었습니다.

Also applies to: 12-12


111-121: 미리보기 API 함수가 잘 구현되었습니다.

getAllUsersPreview 함수가 적절한 타입 정의와 에러 처리를 포함하여 올바르게 구현되었습니다.


123-131: 검색 파라미터를 지원하도록 개선되었습니다.

getAllUsers 함수가 SearchType 파라미터를 받도록 업데이트되어 검색과 페이징 기능을 지원할 수 있게 되었습니다.

src/components/admin/userCard/UserCard.tsx (1)

10-44: 사용자 카드 컴포넌트가 잘 구현되었습니다.

컴포넌트가 적절한 타입 정의, 조건부 렌더링, 그리고 명확한 구조로 구현되어 있습니다. 특히 신고 횟수에 대한 조건부 렌더링과 포지션 배열의 join 처리가 적절합니다.

🧰 Tools
🪛 Biome (1.9.4)

[error] 38-40: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

src/hooks/admin/useSearchBar.ts (1)

1-35: 전반적인 훅 구현이 좋습니다.

검색 상태 관리와 URL 동기화 로직이 잘 구현되어 있습니다. SearchType 인터페이스를 활용한 타입 안전성도 좋습니다.

src/components/common/admin/searchBar/SearchBar.styled.ts (1)

3-40: 전반적인 스타일 구현이 우수합니다.

테마 변수 활용과 반응형 레이아웃 구현이 잘 되어 있습니다. Flex 레이아웃을 적절히 활용했습니다.

src/components/admin/userCard/UserCard.styled.ts (1)

1-60: 전반적인 컴포넌트 구조가 우수합니다.

사용자 상태에 따른 조건부 스타일링과 스킬 태그 레이아웃이 잘 구현되어 있습니다.

src/mock/mockAllUser.json (1)

1-669: 전반적인 목 데이터 구조가 우수합니다.

API 응답 구조를 잘 모방하고 있으며, 페이지네이션 메타데이터와 함께 풍부한 사용자 프로필 데이터를 제공합니다. 다양한 사용자 상태와 스킬/포지션 조합으로 테스트에 유용할 것입니다.

src/models/auth.ts (2)

31-40: 인터페이스 구조가 잘 설계되었습니다.

preview와 전체 사용자 데이터를 분리한 구조가 좋습니다. API 응답과 데이터 모델을 명확하게 구분하여 타입 안전성을 높였습니다.


46-55: 타입 확장성이 우수합니다.

AllUserAllUserPreview를 확장하는 구조와 AllUserList로 래핑하는 패턴이 좋습니다. 페이지네이션 정보를 함께 제공하여 API 응답을 명확하게 표현했습니다.

Comment on lines 36 to 38
{userData.skill.map((skillTag) => (
<S.SkillTag src={skillTag.img} />
))}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

React key prop이 누락되었습니다.

스킬 태그를 렌더링하는 map 함수에서 각 요소에 대한 key prop이 누락되었습니다. 이는 React의 효율적인 리렌더링을 방해할 수 있습니다.

다음 diff를 적용하여 수정하세요:

-          {userData.skill.map((skillTag) => (
-            <S.SkillTag src={skillTag.img} />
-          ))}
+          {userData.skill.map((skillTag, index) => (
+            <S.SkillTag key={`skill-${skillTag.id || index}`} src={skillTag.img} />
+          ))}

스킬 태그에 고유한 ID가 있다면 skillTag.id를 사용하고, 없다면 index를 fallback으로 사용하세요.

📝 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
{userData.skill.map((skillTag) => (
<S.SkillTag src={skillTag.img} />
))}
{userData.skill.map((skillTag, index) => (
<S.SkillTag
key={`skill-${skillTag.id || index}`}
src={skillTag.img}
/>
))}
🤖 Prompt for AI Agents
In src/components/admin/userCard/UserCard.tsx around lines 36 to 38, the map
rendering skill tags is missing the React key prop, which is necessary for
efficient re-rendering. Fix this by adding a key prop to the <S.SkillTag>
component, using skillTag.id if it exists, or the index from the map function as
a fallback.

Comment on lines 20 to 23
export const AdminSearchBarInput = styled.input`
width: 100%;
font-size: 1.3rem;
`;
Copy link

@coderabbitai coderabbitai bot Jun 2, 2025

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

입력 필드 스타일링 개선이 필요합니다.

입력 필드에 기본적인 스타일링이 누락되어 있습니다.

다음과 같은 스타일을 추가하는 것을 권장합니다:

export const AdminSearchBarInput = styled.input`
  width: 100%;
  font-size: 1.3rem;
+ border: none;
+ outline: none;
+ background: transparent;
`;
📝 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
export const AdminSearchBarInput = styled.input`
width: 100%;
font-size: 1.3rem;
`;
export const AdminSearchBarInput = styled.input`
width: 100%;
font-size: 1.3rem;
border: none;
outline: none;
background: transparent;
`;
🤖 Prompt for AI Agents
In src/components/common/admin/searchBar/SearchBar.styled.ts around lines 20 to
23, the AdminSearchBarInput styled component lacks basic input field styling.
Add essential styles such as padding, border, border-radius, and focus outline
to improve usability and appearance. Ensure the input field looks consistent and
accessible by including these common style properties.

Copy link
Collaborator

Choose a reason for hiding this comment

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

css reset 돼있지않니?

Copy link

Choose a reason for hiding this comment

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

🧩 Analysis chain

@YouD0313, CSS reset 설정을 확인해보겠습니다.


🏁 Script executed:

#!/bin/bash

# package.json에서 CSS reset 관련 패키지 확인
echo "=== package.json에서 reset/normalize CSS 패키지 확인 ==="
cat package.json | jq '.dependencies, .devDependencies' | grep -i -E "(reset|normalize|sanitize)"

echo -e "\n=== index.html에서 CSS reset 확인 ==="
fd -name "index.html" --exec cat {} \; | grep -i -E "(reset|normalize)"

echo -e "\n=== 전역 스타일 파일들 확인 ==="
fd -e css -e ts -e tsx | grep -i -E "(global|reset|normalize|index)" | head -10

echo -e "\n=== styled-components 전역 스타일 확인 ==="
rg -A 10 -B 5 "createGlobalStyle|GlobalStyle" 

echo -e "\n=== 기존 input 스타일링 사례 확인 ==="
rg -A 5 -B 2 "styled\.input|styled\(.*input" 

Length of output: 16004


@YouD0313, 맞습니다! 확인해보니 프로젝트에서 이미 sanitize.css가 적용되어 있고, src/style/global.ts에서 추가적인 CSS reset도 구현되어 있네요.

// src/style/global.ts
import 'sanitize.css';

export const GlobalStyle = createGlobalStyle`
  * {
    margin: 0;
    padding:0;
    // ...
  }

그리고 AdminSearchBarWrapper에서 이미 border를 처리하고 있어서 input 자체에는 추가적인 border 스타일이 필요하지 않습니다. 제가 불필요한 제안을 드렸네요. 죄송합니다!

현재 구현이 적절해 보입니다. 🙂


✏️ Learnings added
Learnt from: YouD0313
PR: devpalsPlus/frontend#330
File: src/components/common/admin/searchBar/SearchBar.styled.ts:20-23
Timestamp: 2025-06-03T02:14:03.997Z
Learning: devpalsPlus 프로젝트에서는 sanitize.css와 GlobalStyle을 통해 CSS reset이 적용되어 있어, input 요소의 기본 border와 outline 스타일이 이미 정규화되어 있다.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

import { useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useModal } from '../../../../hooks/useModal';
import { MODAL_MESSAGE_CUSTOMER_SERVICE } from '../../../../constants/user/customerService';
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

적절한 도메인의 상수를 사용해주세요.

검색바 컴포넌트에서 고객 서비스 관련 상수(MODAL_MESSAGE_CUSTOMER_SERVICE)를 사용하고 있습니다. 또한 placeholder와 에러 메시지가 동일한 것은 UX 관점에서 혼란스러울 수 있습니다.

관리자 검색바 전용 상수를 만들어주세요:

// constants/admin/searchBar.ts
export const ADMIN_SEARCH_BAR_MESSAGES = {
  PLACEHOLDER: '검색어를 입력해주세요',
  NO_KEYWORD_ERROR: '검색어를 입력해주세요',
} as const;

그리고 적용:

- import { MODAL_MESSAGE_CUSTOMER_SERVICE } from '../../../../constants/user/customerService';
+ import { ADMIN_SEARCH_BAR_MESSAGES } from '../../../../constants/admin/searchBar';

- placeholder={MODAL_MESSAGE_CUSTOMER_SERVICE.noKeyword}
+ placeholder={ADMIN_SEARCH_BAR_MESSAGES.PLACEHOLDER}

- return handleModalOpen(MODAL_MESSAGE_CUSTOMER_SERVICE.noKeyword);
+ return handleModalOpen(ADMIN_SEARCH_BAR_MESSAGES.NO_KEYWORD_ERROR);

Also applies to: 56-56

🤖 Prompt for AI Agents
In src/components/common/admin/searchBar/SearchBar.tsx at lines 6 and 56,
replace the imported constant MODAL_MESSAGE_CUSTOMER_SERVICE with a new
admin-specific constant. Create a new file constants/admin/searchBar.ts
exporting ADMIN_SEARCH_BAR_MESSAGES with distinct placeholder and error message
values as suggested. Then update the SearchBar component to use
ADMIN_SEARCH_BAR_MESSAGES.PLACEHOLDER for the input placeholder and
ADMIN_SEARCH_BAR_MESSAGES.NO_KEYWORD_ERROR for the error message to improve UX
clarity.

@layout-SY layout-SY changed the title 관리자 "회원 전체 조회" 페이지 구현 관리자 "회원 전체 조회" 페이지 구현 ( issue #330 ) Jun 3, 2025
import { loginFormValues } from '../pages/login/Login';
import { registerFormValues } from '../pages/user/register/Register';
import { changePasswordFormValues } from '../pages/user/changePassword/ChangePassword';
import { SearchType } from '../models/search';
Copy link
Collaborator

Choose a reason for hiding this comment

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

type

width: 240px;
display: flex;
flex-direction: column;
border: 1px solid #000000;
Copy link
Collaborator

Choose a reason for hiding this comment

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

테마에 있는 색은 테마로 해주세욥ㅋㅋ

import React from 'react';
import * as S from './UserCard.styled';
import Avatar from '../../common/avatar/Avatar';
import { AllUser } from '../../../models/auth';
Copy link
Collaborator

Choose a reason for hiding this comment

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

type

Comment on lines 20 to 23
export const AdminSearchBarInput = styled.input`
width: 100%;
font-size: 1.3rem;
`;
Copy link
Collaborator

Choose a reason for hiding this comment

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

css reset 돼있지않니?

import { useQuery } from '@tanstack/react-query';
import { UserData } from '../queries/user/keys';
import { getAllUsers } from '../../api/auth.api';
import { SearchType } from '../../models/search';
Copy link
Collaborator

Choose a reason for hiding this comment

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

type

@@ -0,0 +1,34 @@
import { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { SearchType } from '../../models/search';
Copy link
Collaborator

Choose a reason for hiding this comment

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

type

@layout-SY layout-SY merged commit ab68b7d into develop Jun 5, 2025
4 checks passed
@layout-SY layout-SY deleted the feat/#324 branch June 5, 2025 13:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⛏기능 기능 구현에 대한 라벨

Projects

None yet

Development

Successfully merging this pull request may close these issues.

관리자 회원 조회 관련 페이지 구현

3 participants