Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion frontend/src/apis/getClubList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,8 @@ export const getClubList = async (
}

const result = await response.json();
return result.data.clubs;
return {
clubs: result.data.clubs,
totalCount: result.data.totalCount,
};
};
12 changes: 7 additions & 5 deletions frontend/src/hooks/queries/club/useGetCardList.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useQuery, keepPreviousData } from '@tanstack/react-query';
import { getClubList } from '@/apis/getClubList';
import { Club } from '@/types/club';
import { ClubSearchResponse } from '@/types/club.responses';
import convertToDriveUrl from '@/utils/convertGoogleDriveUrl';

export const useGetCardList = (
Expand All @@ -9,14 +9,16 @@ export const useGetCardList = (
category: string,
division: string,
) => {
return useQuery<Club[], unknown, Club[]>({
return useQuery<ClubSearchResponse, unknown, ClubSearchResponse>({
queryKey: ['clubs', keyword, recruitmentStatus, division, category],
queryFn: () => getClubList(keyword, recruitmentStatus, division, category),
Comment on lines +12 to 14
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

파라미터 순서 오류로 인한 검색 결과 오류가 발생합니다.

getClubList 함수 호출 시 divisioncategory 파라미터의 순서가 바뀌어 있습니다. API 함수의 시그니처는 getClubList(keyword, recruitmentStatus, category, division) 순서를 기대하지만, 현재 코드는 divisioncategory를 반대로 전달하고 있습니다. 이로 인해 검색 필터가 올바르게 작동하지 않습니다.

다음 diff를 적용하여 파라미터 순서를 수정하세요:

   return useQuery<ClubSearchResponse, unknown, ClubSearchResponse>({
-    queryKey: ['clubs', keyword, recruitmentStatus, division, category],
-    queryFn: () => getClubList(keyword, recruitmentStatus, division, category),
+    queryKey: ['clubs', keyword, recruitmentStatus, category, division],
+    queryFn: () => getClubList(keyword, recruitmentStatus, category, division),
     placeholderData: keepPreviousData,
📝 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
return useQuery<ClubSearchResponse, unknown, ClubSearchResponse>({
queryKey: ['clubs', keyword, recruitmentStatus, division, category],
queryFn: () => getClubList(keyword, recruitmentStatus, division, category),
return useQuery<ClubSearchResponse, unknown, ClubSearchResponse>({
queryKey: ['clubs', keyword, recruitmentStatus, category, division],
queryFn: () => getClubList(keyword, recruitmentStatus, category, division),
🤖 Prompt for AI Agents
In frontend/src/hooks/queries/club/useGetCardList.ts around lines 12 to 14, the
call to getClubList passes division and category in the wrong order causing
incorrect search filters; change the argument order so it matches the API
signature getClubList(keyword, recruitmentStatus, category, division) by
swapping the division and category arguments in the function call.

placeholderData: keepPreviousData,
select: (data) =>
data.map((club) => ({
select: (data) => ({
totalCount: data.totalCount,
clubs: (data.clubs.map((club) => ({
...club,
logo: convertToDriveUrl(club.logo),
})),
}))),
}),
});
};
24 changes: 22 additions & 2 deletions frontend/src/pages/MainPage/MainPage.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,23 @@ export const ContentWrapper = styled.div`
width: 100%;
`;

export const SectionBar = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
margin: 60px 8px 24px;

${media.mobile} {
margin: 32px 4px 16px;
}
`;

export const SectionTabs = styled.nav`
display: flex;
gap: 18px;
margin: 60px 8px 24px;

${media.mobile} {
gap: 16px;
margin: 32px 4px 16px;
}
`;

Expand Down Expand Up @@ -59,6 +68,17 @@ export const Tab = styled.button<{$active?: boolean}>`
}
`;

export const TotalCountResult = styled.span`
font-size: 18px;
font-weight: bold;
color: #787878;
padding-top: 13px;

${media.mobile} {
font-size: 12px;
}
`;

export const CardList = styled.div`
display: grid;
width: 100%;
Expand Down
25 changes: 16 additions & 9 deletions frontend/src/pages/MainPage/MainPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ const MainPage = () => {
useTrackPageView('MainPage');

const { selectedCategory } = useSelectedCategory();

const { keyword } = useSearchKeyword();
const { isSearching } = useSearchIsSearching();
const recruitmentStatus = 'all';
Expand All @@ -29,13 +28,14 @@ const MainPage = () => {
// TODO: 추후 확정되면 DivisionKey(중동/가동/과동) 같은 타입을
// types/club.ts에 정의해서 tabs 관리하도록 리팩터링하기

const {
data: clubs,
error,
isLoading,
} = useGetCardList(keyword, recruitmentStatus, division, searchCategory);
const isEmpty = !isLoading && (!clubs || clubs.length === 0);
const hasData = clubs && clubs.length > 0;
const { data, error, isLoading } =
useGetCardList(keyword, recruitmentStatus, division, searchCategory);
Comment on lines +31 to +32
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

파라미터 순서 오류로 인해 검색 결과가 잘못될 수 있습니다.

useGetCardList 훅의 시그니처는 (keyword, recruitmentStatus, category, division) 순서이지만, 호출 시 (keyword, recruitmentStatus, division, searchCategory) 순서로 전달하고 있습니다. 이로 인해 divisioncategory 값이 서로 바뀌어 검색 결과가 의도와 다르게 나올 수 있습니다.

다음과 같이 파라미터 순서를 수정하세요:

  const { data, error, isLoading } = 
-   useGetCardList(keyword, recruitmentStatus, division, searchCategory);
+   useGetCardList(keyword, recruitmentStatus, searchCategory, division);
🤖 Prompt for AI Agents
In frontend/src/pages/MainPage/MainPage.tsx around lines 31 to 32, the call to
useGetCardList passes parameters in the wrong order (keyword, recruitmentStatus,
division, searchCategory) while the hook expects (keyword, recruitmentStatus,
category, division); swap the third and fourth arguments so the category
(searchCategory) is passed as the third parameter and division as the fourth to
restore correct search behavior.


const clubs = data?.clubs || [];
const totalCount = data?.totalCount || 0;

const isEmpty = !isLoading && totalCount === 0;
const hasData = totalCount > 0;

const clubList = useMemo(() => {
if (!hasData) return null;
Expand All @@ -55,14 +55,21 @@ const MainPage = () => {
/>
<Styled.PageContainer>
<CategoryButtonList />
<Styled.SectionTabs>

<Styled.SectionBar>
<Styled.SectionTabs>
{tabs
.map((tab) =>(
<Styled.Tab key={tab} $active={active===tab} onClick={() => setActive(tab)}>
{tab}
</Styled.Tab>
))}
</Styled.SectionTabs>
<Styled.TotalCountResult role="status">
{`전체 ${isLoading ? 0 : totalCount}개의 동아리`}
</Styled.TotalCountResult>
Comment on lines +68 to +70
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

로딩 중 "0개"를 표시하면 사용자에게 혼란을 줄 수 있습니다.

로딩 중일 때 "전체 0개의 동아리"를 표시하는 것은 실제로 결과가 없는 것처럼 보일 수 있습니다. 로딩 중에는 개수를 표시하지 않거나 로딩 인디케이터를 표시하는 것이 더 나은 UX를 제공할 수 있습니다.

다음과 같이 수정하는 것을 고려해보세요:

  <Styled.TotalCountResult role="status">
-   {`전체 ${isLoading ? 0 : totalCount}개의 동아리`}
+   {isLoading ? '검색 중...' : `전체 ${totalCount}개의 동아리`}
  </Styled.TotalCountResult>
📝 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
<Styled.TotalCountResult role="status">
{`전체 ${isLoading ? 0 : totalCount}개의 동아리`}
</Styled.TotalCountResult>
<Styled.TotalCountResult role="status">
{isLoading ? '검색 중...' : `전체 ${totalCount}개의 동아리`}
</Styled.TotalCountResult>
🤖 Prompt for AI Agents
In frontend/src/pages/MainPage/MainPage.tsx around lines 68 to 70, the component
currently renders "전체 0개의 동아리" while isLoading is true which can mislead users;
change the rendering so that when isLoading is true you either render a loading
indicator/placeholder (e.g., "로딩 중..." or a spinner) or render nothing for the
count, and only show the totalCount once loading completes (isLoading ===
false). Ensure the accessible status element still exists (role="status") and
updates appropriately when the final count is available.

</Styled.SectionBar>

<Styled.ContentWrapper>
{isLoading ? (
<Spinner />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const CategoryButton = styled.button`
border: none;
background: none;
cursor: pointer;
padding: 8px 0px;
padding: 10px 0px;
transition: transform 0.1s ease;

&:active {
Expand All @@ -49,7 +49,7 @@ export const CategoryButton = styled.button`
font-weight: 500;
color: #787878;
margin-top: 8px;
line-height: 30px;
line-height: 17px;
white-space: nowrap;

@media (max-width: 768px) {
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/types/club.responses.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { Club } from './club';

export interface ClubSearchResponse {
clubs: Club[];
totalCount: number;
}