diff --git a/src/_apis/crew/get-crew-list.ts b/src/_apis/crew/crew-list.ts similarity index 100% rename from src/_apis/crew/get-crew-list.ts rename to src/_apis/crew/crew-list.ts diff --git a/src/_queries/crew-queries.tsx b/src/_queries/crew/crew-list-queries.tsx similarity index 86% rename from src/_queries/crew-queries.tsx rename to src/_queries/crew/crew-list-queries.tsx index d9c0a926..6d2ce1f2 100644 --- a/src/_queries/crew-queries.tsx +++ b/src/_queries/crew/crew-list-queries.tsx @@ -1,6 +1,5 @@ -import { UseInfiniteQueryOptions } from '@tanstack/react-query'; import { ConditionTypes, MainCrewListResponse, PageableTypes } from '@/src/types/crew-card'; -import { getCrewList } from '../_apis/crew/get-crew-list'; +import { getCrewList } from '../../_apis/crew/crew-list'; export function useGetCrewListQuery(condition: ConditionTypes) { return { diff --git a/src/app/(crew)/my-crew/page.tsx b/src/app/(crew)/my-crew/page.tsx index 2dcff0ac..976094b1 100644 --- a/src/app/(crew)/my-crew/page.tsx +++ b/src/app/(crew)/my-crew/page.tsx @@ -1,11 +1,7 @@ 'use client'; import { useState } from 'react'; -import { useGetCrewListQuery } from '@/src/_queries/crew-queries'; -import { useInfiniteScroll } from '@/src/hooks/use-infinite-scroll'; -import CrewCardList from '@/src/components/common/crew-list/crew-card-list'; import Tabs from '@/src/components/common/tab'; -import { MyCrewListResponse } from '@/src/types/crew-card'; export default function MyCrewPage() { const myPageTabs = [ diff --git a/src/app/(crew)/page.tsx b/src/app/(crew)/page.tsx index f819f5b1..5a4e86be 100644 --- a/src/app/(crew)/page.tsx +++ b/src/app/(crew)/page.tsx @@ -1,26 +1,130 @@ -import { getCrewList } from '@/src/_apis/crew/get-crew-list'; -import FindCrew from '../_components/find-crew/find-crew'; +'use client'; -export default async function HomePage() { - const initialData = await getCrewList( - { - keyword: '', - mainLocation: '', - mainCategory: '', - subCategory: '', - sortType: 'LATEST', - }, - { - page: 0, - size: 6, - sort: ['LATEST'], - }, - ); +import { useRef, useState } from 'react'; +import Image from 'next/image'; +import { Divider, TextInput } from '@mantine/core'; +import { useGetCrewListQuery } from '@/src/_queries/crew/crew-list-queries'; +import regionData from '@/src/data/region.json'; +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 IcoSearch from '@/public/assets/icons/ic-search.svg'; + +export default function HomePage() { + const [mainCategory, setMainCategory] = useState(''); + const [subCategory, setSubCategory] = useState(''); + const [sort, setSort] = useState('latest'); + const [region, setRegion] = useState(''); + const [search, setSearch] = useState(''); + const searchRef = useRef(null); + + const handleRegionChange = (newValue: string) => { + const selectedRegion = regionData.find((dataItem) => dataItem.main.value === newValue); + if (selectedRegion?.main.label === '지역 전체') return ''; + return selectedRegion ? selectedRegion.main.label : ''; + }; - const infiniteData = { - pages: [initialData], - pageParams: [], + const handleSearch = () => { + if (searchRef.current) { + setMainCategory(''); + setSubCategory(''); + setSearch(searchRef.current.value); + } }; - return ; + const { data, ref, isFetchingNextPage } = useInfiniteScroll( + useGetCrewListQuery({ + keyword: search, + mainLocation: handleRegionChange(region), + mainCategory, + subCategory, + sortType: sort === 'latest' ? 'LATEST' : 'POPULAR', + }), + ); + + return ( +
+
+ + { + setMainCategory(newValue); + if (searchRef.current) searchRef.current.value = ''; + if (search !== '') setSearch(''); + }} + setSubCategory={(newValue) => { + setSubCategory(newValue); + if (searchRef.current) searchRef.current.value = ''; + if (search !== '') setSearch(''); + }} + /> +
+ +
+
+
+ { + if (e.key === 'Enter') handleSearch(); + }} + rightSection={ + + } + 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', + }} + /> +
+
+ dataItem.main)} + placeholder="지역 전체" + value={region} + className="w-[130px]" + onChange={(newValue) => { + setRegion(newValue as string); + }} + /> + { + setSort(newValue as string); + }} + /> +
+
+
+
+ {data && } +
+
+ ); } diff --git a/src/app/_components/find-crew/find-crew.tsx b/src/app/_components/find-crew/find-crew.tsx deleted file mode 100644 index d5ec42d1..00000000 --- a/src/app/_components/find-crew/find-crew.tsx +++ /dev/null @@ -1,139 +0,0 @@ -'use client'; - -import { useEffect, useRef, useState } from 'react'; -import Image from 'next/image'; -import { Divider, TextInput } from '@mantine/core'; -import { InfiniteData } from '@tanstack/react-query'; -import { useGetCrewListQuery } from '@/src/_queries/crew-queries'; -import regionData from '@/src/data/region.json'; -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 IcoSearch from '@/public/assets/icons/ic-search.svg'; - -interface FindCrewProps { - initialData: InfiniteData; -} - -export default function FindCrew({ initialData }: FindCrewProps) { - const [data, setData] = useState>(initialData); - const [mainCategory, setMainCategory] = useState(''); - const [subCategory, setSubCategory] = useState(''); - const [sort, setSort] = useState('latest'); - const [region, setRegion] = useState(''); - const [search, setSearch] = useState(''); - const searchRef = useRef(null); - - const handleRegionChange = (newValue: string) => { - const selectedRegion = regionData.find((dataItem) => dataItem.main.value === newValue); - if (selectedRegion?.main.label === '지역 전체') return ''; - return selectedRegion ? selectedRegion.main.label : ''; - }; - - const handleSearch = () => { - if (searchRef.current) { - setMainCategory(''); - setSubCategory(''); - setSearch(searchRef.current.value); - } - }; - - const { - data: CrewCardListData, - ref, - isFetchingNextPage, - } = useInfiniteScroll( - useGetCrewListQuery({ - keyword: search, - mainLocation: handleRegionChange(region), - mainCategory, - subCategory, - sortType: sort === 'latest' ? 'LATEST' : 'POPULAR', - }), - ); - - useEffect(() => { - if (CrewCardListData) { - setData(CrewCardListData); - } - }, [CrewCardListData]); - - return ( -
-
- - { - setMainCategory(newValue); - if (searchRef.current) searchRef.current.value = ''; - if (search !== '') setSearch(''); - }} - setSubCategory={(newValue) => { - setSubCategory(newValue); - if (searchRef.current) searchRef.current.value = ''; - if (search !== '') setSearch(''); - }} - /> -
- -
-
-
- { - if (e.key === 'Enter') handleSearch(); - }} - rightSection={ - - } - 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', - }} - /> -
-
- dataItem.main)} - placeholder="지역 전체" - value={region} - className="w-[130px]" - onChange={(newValue) => { - setRegion(newValue as string); - }} - /> - { - setSort(newValue as string); - }} - /> -
-
-
-
- -
-
- ); -} diff --git a/src/components/common/crew-list/crew-card-list.stories.tsx b/src/components/common/crew-list/crew-card-list.stories.tsx index 94e77ad9..4e8952f6 100644 --- a/src/components/common/crew-list/crew-card-list.stories.tsx +++ b/src/components/common/crew-list/crew-card-list.stories.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; import type { Meta, StoryObj } from '@storybook/react'; import { InfiniteData } from '@tanstack/react-query'; -import { useGetCrewListQuery } from '@/src/_queries/crew-queries'; +import { useGetCrewListQuery } from '@/src/_queries/crew/crew-list-queries'; import { useInfiniteScroll } from '@/src/hooks/use-infinite-scroll'; import ClientProvider from '@/src/components/client-provider'; import { MainCrewListResponse } from '@/src/types/crew-card'; @@ -29,17 +29,8 @@ const meta: Meta = { export default meta; type Story = StoryObj; -function RenderCrewCardList({ - initialData, -}: { - initialData: InfiniteData; -}) { - const [data, setData] = useState>(initialData); - const { - data: CrewCardListData, - ref, - isFetchingNextPage, - } = useInfiniteScroll( +function RenderCrewCardList() { + const { data, ref, isFetchingNextPage } = useInfiniteScroll( useGetCrewListQuery({ keyword: '', mainLocation: '', @@ -49,16 +40,11 @@ function RenderCrewCardList({ }), ); - useEffect(() => { - if (CrewCardListData) { - setData(CrewCardListData); - } - }, [CrewCardListData]); - + if (!data) return null; return ; } export const Default: Story = { - render: () => , + render: () => , args: {}, }; diff --git a/src/components/common/crew-list/crew-card-list.tsx b/src/components/common/crew-list/crew-card-list.tsx index d182cdeb..fca949b8 100644 --- a/src/components/common/crew-list/crew-card-list.tsx +++ b/src/components/common/crew-list/crew-card-list.tsx @@ -11,7 +11,7 @@ import CrewCard from './crew-card'; // CrewCardListProps 타입을 구분하여 정의 interface MainCrewCardListProps { - data: InfiniteData; + data: InfiniteData; isFetchingNextPage: boolean; inWhere?: undefined; } diff --git a/src/types/crew-card.d.ts b/src/types/crew-card.d.ts index 426826bb..3c971e5e 100644 --- a/src/types/crew-card.d.ts +++ b/src/types/crew-card.d.ts @@ -13,7 +13,7 @@ export interface PageableTypes { } export type MainCrewListResponse = { - content: MainCrewList[] | undefined; + content: MainCrewList[]; hasNext: boolean; }; diff --git a/src/utils/api.ts b/src/utils/api.ts index c6b038db..5f876175 100644 --- a/src/utils/api.ts +++ b/src/utils/api.ts @@ -35,7 +35,7 @@ export async function fetchApi( }; try { - const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}${url}`, fetchOptions); + const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}${url}`, fetchOptions); // API 요청 실행 if (!response.ok) { let errorDetail;