-
Notifications
You must be signed in to change notification settings - Fork 3
Feat/98/crew api 연결 : 제가올린것중 이것먼저 리뷰 부탁드립니다~! #113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ff9d3f5
bc4056a
6ac757f
0936ad1
e64877f
ab7d7a9
b4a70ff
22f3307
60a3b12
1026125
56bea37
1d430b1
3a7ce8e
ecd941d
9a3f685
89632d1
04225e6
ae1729a
b4b356c
67886c3
3213309
b9b5cb5
5687085
c3382b1
be1480d
3c567f3
abdc917
7642e5b
84780af
47f45c4
8f150e0
3febcae
1ce21b6
268e90f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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<string | null>('latest'); | ||
| const [region, setRegion] = useState<string>(''); | ||
| const [search, setSearch] = useState(''); | ||
| const searchRef = useRef<HTMLInputElement>(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 <FindCrew initialData={infiniteData} />; | ||
| const { data, ref, isFetchingNextPage } = useInfiniteScroll( | ||
| useGetCrewListQuery({ | ||
| keyword: search, | ||
| mainLocation: handleRegionChange(region), | ||
| mainCategory, | ||
| subCategory, | ||
| sortType: sort === 'latest' ? 'LATEST' : 'POPULAR', | ||
| }), | ||
| ); | ||
|
|
||
| return ( | ||
| <div className="py-8 md:py-12.5"> | ||
| <div className="flex flex-col px-3 md:px-8 lg:px-11.5"> | ||
| <HeroCrew /> | ||
| <CategoryContainer | ||
| mainCategory={mainCategory} | ||
| subCategory={subCategory} | ||
| setMainCategory={(newValue) => { | ||
| setMainCategory(newValue); | ||
| if (searchRef.current) searchRef.current.value = ''; | ||
| if (search !== '') setSearch(''); | ||
| }} | ||
| setSubCategory={(newValue) => { | ||
| setSubCategory(newValue); | ||
| if (searchRef.current) searchRef.current.value = ''; | ||
| if (search !== '') setSearch(''); | ||
| }} | ||
| /> | ||
| </div> | ||
| <Divider mx={{ base: 0, md: 32, lg: 34 }} my={24} size={2} color="#E5E7EB" /> | ||
| <div className="px-3 md:px-8 lg:px-11.5"> | ||
| <div className="flex flex-col justify-between gap-2 md:flex-row md:gap-4"> | ||
| <div className="flex-1"> | ||
| <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" | ||
| aria-label="검색하기" | ||
| /> | ||
| </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> | ||
| <div className="flex-0 flex justify-between gap-2 md:basis-67 md:gap-4"> | ||
| <DropDown | ||
| name="region" | ||
| variant="default" | ||
| data={regionData.map((dataItem) => dataItem.main)} | ||
| placeholder="지역 전체" | ||
| value={region} | ||
| className="w-[130px]" | ||
| onChange={(newValue) => { | ||
| setRegion(newValue as string); | ||
| }} | ||
| /> | ||
| <DropDown | ||
| name="sort" | ||
| variant="sort" | ||
| data={[ | ||
| { value: 'latest', label: '최신순' }, | ||
| { value: 'best', label: '인기순' }, | ||
| ]} | ||
| placeholder="최신순" | ||
| value={sort} | ||
| className="w-[130px]" | ||
| onChange={(newValue) => { | ||
| setSort(newValue as string); | ||
| }} | ||
| /> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| <div className="mt-8 px-3 md:px-8 lg:px-11.5"> | ||
| {data && <CrewCardList data={data} ref={ref} isFetchingNextPage={isFetchingNextPage} />} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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} />
+ )}
|
||
| </div> | ||
| </div> | ||
| ); | ||
| } | ||
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -35,7 +35,7 @@ export async function fetchApi<T>( | |||||||||||||||
| }; | ||||||||||||||||
|
|
||||||||||||||||
| 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 요청 실행 | ||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 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
Suggested change
|
||||||||||||||||
|
|
||||||||||||||||
| if (!response.ok) { | ||||||||||||||||
| let errorDetail; | ||||||||||||||||
|
|
||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
데이터 페칭 에러 처리 보완 필요
무한 스크롤 구현은 잘 되어있지만, 다음 사항들을 고려해보시면 좋을 것 같습니다: