From 8165738dbe177e8bf5ade3a74014cc63a6c09fdf Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Tue, 23 Jan 2024 15:25:28 +0900 Subject: [PATCH 01/13] =?UTF-8?q?feat:=20qa=20=EA=B0=80=EB=8A=A5=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=ED=8F=AC=EC=8A=A4=ED=8A=B8=20=EA=B0=AF?= =?UTF-8?q?=EC=88=98=20=EB=AA=A9=EC=9C=BC=EB=A1=9C=20=EB=84=A3=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/index.tsx | 2 +- src/pages/result/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/index.tsx b/src/pages/index.tsx index b93e4b8d..870d31a2 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -19,7 +19,7 @@ const Home: NextPage = () => { const router = useRouter() // TODO: 포스트 전체 갯수 내려달라고 요청해놓았습니다 - const postsCount = 0 + const postsCount = 10 return ( diff --git a/src/pages/result/index.tsx b/src/pages/result/index.tsx index 49110eae..1b4826fb 100644 --- a/src/pages/result/index.tsx +++ b/src/pages/result/index.tsx @@ -77,7 +77,7 @@ const ResultPage: NextPage = ({ }) // TODO: 포스트 전체 갯수 내려달라고 요청해놓았습니다 - const postsCount = 0 + const postsCount = 10 const handleChangeSearchOptions: OnChangeSearchOptions = (name, value) => { const nextSearchOptions = { From 31897d5ed9b2f4b59a14c6ac64cdf8977a0bc56c Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Tue, 23 Jan 2024 15:50:05 +0900 Subject: [PATCH 02/13] =?UTF-8?q?feat:=20=EA=B2=B0=EA=B3=BC=EB=AC=BC=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80,=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/Header/index.tsx | 9 +- src/components/home/CategorySlider/index.tsx | 6 +- .../result/CategoryHeader/index.tsx | 6 +- src/components/result/CategoryHeader/types.ts | 2 +- src/pages/categories/[categoryCode].tsx | 185 ++++++++++++++++++ src/pages/result/index.tsx | 2 +- 6 files changed, 201 insertions(+), 9 deletions(-) create mode 100644 src/pages/categories/[categoryCode].tsx diff --git a/src/components/common/Header/index.tsx b/src/components/common/Header/index.tsx index 3974bb94..8205de05 100644 --- a/src/components/common/Header/index.tsx +++ b/src/components/common/Header/index.tsx @@ -11,7 +11,7 @@ import { Styled } from './styled' import { CommonModal } from '../CommonModal' import { Dialog } from '../Dialog' import { searchKeywordAtom } from '@atoms' -import { IMAGE, OAUTH_URL } from '@constants' +import { IMAGE, OAUTH_URL, SORT_OPTIONS } from '@constants' import { useModal, useAuth } from '@hooks' const PREVENT_ACTIVE_PATHS = ['/post'] @@ -36,7 +36,12 @@ const Header = (): ReactElement => { const handleSubmitValue = (value?: string) => { if (value) { setSearchKeyword(value) - router.push(`/result?${new URLSearchParams([['searchKeyword', value]])}`) + router.push( + `/result?${new URLSearchParams([ + ['searchKeyword', value], + ['sort', SORT_OPTIONS[0].code] + ])}` + ) } } diff --git a/src/components/home/CategorySlider/index.tsx b/src/components/home/CategorySlider/index.tsx index 917bdb89..14d8ddf2 100644 --- a/src/components/home/CategorySlider/index.tsx +++ b/src/components/home/CategorySlider/index.tsx @@ -4,6 +4,7 @@ import { useState, useEffect, useRef, useCallback } from 'react' import type { ReactElement, TouchEventHandler } from 'react' import { Styled } from './styled' import { useGetCategoriesQuery } from '@apis/post' +import { SORT_OPTIONS } from '@constants/app' const CategorySlider = (): ReactElement => { const containerRef = useRef(null) @@ -112,7 +113,10 @@ const CategorySlider = (): ReactElement => { {getCategoryQuery.data?.map(({ code, name, imageUrl }) => { return ( - + { return ( - - "{searchResult}"의 검색결과 - + {resultMessage} {postsCount}개 diff --git a/src/components/result/CategoryHeader/types.ts b/src/components/result/CategoryHeader/types.ts index 3ab37494..6f601d53 100644 --- a/src/components/result/CategoryHeader/types.ts +++ b/src/components/result/CategoryHeader/types.ts @@ -1,4 +1,4 @@ export type ResultHeaderProps = { - searchResult: string + resultMessage: string postsCount: number } diff --git a/src/pages/categories/[categoryCode].tsx b/src/pages/categories/[categoryCode].tsx new file mode 100644 index 00000000..a29c8a4d --- /dev/null +++ b/src/pages/categories/[categoryCode].tsx @@ -0,0 +1,185 @@ +import { css } from '@emotion/react' +import styled from '@emotion/styled' +import type { GetServerSideProps, NextPage } from 'next' +import { useRouter } from 'next/router' +import { useState } from 'react' +import type { + SearchOptionsState, + OnChangeSearchOptions +} from '@components/result/SearchOptions/types' +import { useGetCategoriesQuery, useGetInfinitePostsQuery } from '@apis' +import { + SearchOptions, + ResultHeader, + CategorySlideFilter, + ProductList +} from '@components' +import type { SortOptionCodes, TradeTypeCodes } from '@types' +import { removeNullish } from '@utils' + +const DEFAULT_POST_PAGE_NUMBER = 8 + +type CategoriesProps = { + category?: string + sort?: SortOptionCodes + minPrice?: number + maxPrice?: number + tradeType?: TradeTypeCodes +} +export const getServerSideProps: GetServerSideProps = async ({ + query +}) => ({ + props: { + category: query.categoryCode as string, + sort: (query.sort as SortOptionCodes) || 'CREATED_DATE_DESC', + minPrice: Number(query.min_price), + maxPrice: Number(query.max_price), + tradeType: (query.tradeType as TradeTypeCodes) || null + } +}) + +const Categories: NextPage = ({ + category, + sort, + minPrice, + maxPrice, + tradeType +}: CategoriesProps) => { + const getCategoriesQuery = useGetCategoriesQuery() + const router = useRouter() + const [searchOptions, setSearchOptions] = useState({ + category, + sort: 'CREATED_DATE_DESC', + priceRange: {} + }) + + const searchParams = removeNullish({ + minPrice: searchOptions.priceRange?.min ?? minPrice, + maxPrice: searchOptions.priceRange?.max ?? maxPrice, + tradeType: searchOptions.tradeType ?? tradeType, + sort: searchOptions.sort ?? sort + }) + + const categories = + getCategoriesQuery.data?.map(({ code, name }) => ({ code, name })) || [] + const currentCategory = categories.find( + ({ code }) => code === searchOptions.category + ) + + const infinitePosts = useGetInfinitePostsQuery({ + lastId: null, + limit: DEFAULT_POST_PAGE_NUMBER, + ...searchParams + }) + + // TODO: 포스트 전체 갯수 내려달라고 요청해놓았습니다 + const postsCount = 10 + + const handleChangeSearchOptions: OnChangeSearchOptions = (name, value) => { + const categoryCode = name === 'category' ? value : searchOptions.category + const nextSearchOptions = { + ...searchOptions, + [name]: value + } + setSearchOptions(nextSearchOptions) + + const params = Object.entries(searchParams).map(([key, value]) => [ + `${key}`, + String(value) + ]) + + router.push(`/categories/${categoryCode}?${new URLSearchParams(params)}`) + } + + return ( + + + + + + handleChangeSearchOptions('category', code) + } + /> + + + {postsCount > 0 ? ( + + ) : ( + + 검색 결과 없음 + + 찾으시는 검색 결과가 없어요 + + + )} + + + ) +} + +const ResultWrapper = styled.div` + width: 100%; + max-width: 1200px; + ${({ theme }): string => theme.mediaQuery.tablet} { + padding-right: 24px; + padding-left: 24px; + } + ${({ theme }): string => theme.mediaQuery.mobile} { + padding-right: 16px; + padding-left: 16px; + } +` + +const Layout = styled.div` + display: flex; + justify-content: center; + + width: 100%; + margin-top: 68px; +` + +const CategorySliderWrapper = styled.div` + /* TODO: useMedia를 사용한 조건부 렌더링시 hydration 에러가 발생해 스타일로 우선 적용 했습니다. */ + ${({ theme }) => theme.mediaQuery.tablet} { + display: none; + } +` + +const Placeholder = styled.div` + width: 100%; + height: 100%; + margin: 120px 0; + + text-align: center; +` + +const PlaceholderTitle = styled.p` + margin-bottom: 8px; + + ${({ theme }) => theme.fonts.subtitle01B} +` + +const PlaceholderDescription = styled.p` + ${({ theme }) => css` + color: ${theme.colors.grayScale70}; + + ${theme.fonts.body01M}; + `} +` + +export default Categories diff --git a/src/pages/result/index.tsx b/src/pages/result/index.tsx index 1b4826fb..cb1e65a3 100644 --- a/src/pages/result/index.tsx +++ b/src/pages/result/index.tsx @@ -99,7 +99,7 @@ const ResultPage: NextPage = ({ Date: Tue, 23 Jan 2024 16:13:46 +0900 Subject: [PATCH 03/13] =?UTF-8?q?design:=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=EC=9D=B4=EB=AF=B8=EC=A7=80=EB=8A=94=20=EC=84=B9?= =?UTF-8?q?=EC=85=98=EC=9D=80=20=ED=81=B4=EB=A6=AC=EB=90=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8A=94=20=EC=9D=B4=EC=8A=88=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/CategorySlider/index.tsx | 4 +- src/components/home/CategorySlider/styled.ts | 42 +++++++++++--------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/components/home/CategorySlider/index.tsx b/src/components/home/CategorySlider/index.tsx index 14d8ddf2..8f570b75 100644 --- a/src/components/home/CategorySlider/index.tsx +++ b/src/components/home/CategorySlider/index.tsx @@ -85,7 +85,7 @@ const CategorySlider = (): ReactElement => { onTouchMove={isDrag ? onDragMove : undefined} onTouchStart={onDragStart}> {isDesktop && ( - + <> {isFirstCategory ? (
) : ( @@ -106,7 +106,7 @@ const CategorySlider = (): ReactElement => { onClick={handleRightArrowClick} /> )} - + )} diff --git a/src/components/home/CategorySlider/styled.ts b/src/components/home/CategorySlider/styled.ts index 4c4ea1b7..21a74054 100644 --- a/src/components/home/CategorySlider/styled.ts +++ b/src/components/home/CategorySlider/styled.ts @@ -4,6 +4,7 @@ import { IconButton } from '@offer-ui/react' import Image from 'next/image' import Link from 'next/link' import type { CateGoryBoxWrapperProps } from './types' +import { theme } from '@styles' export const CategoryHeader = styled.div` ${({ theme }): string => theme.fonts.headline02B} @@ -81,43 +82,46 @@ export const CateGoryBox = styled.div` } ` -export const ArrowBox = styled.div` +const arrowStyle = css` position: absolute; - z-index: 999; - display: flex; - align-self: center; - justify-content: space-between; - - width: 100%; - margin-bottom: 30px; -` + top: 32px; + z-index: ${theme.zIndex.common}; -export const LeftArrow = styled(IconButton)` width: 24px; height: 24px; border-radius: 100%; - background-color: ${({ theme }): string => theme.colors.white}; + background-color: ${theme.colors.white}; filter: drop-shadow(0 2px 6px rgb(0 0 0 / 25%)); ` -export const RightArrow = styled(IconButton)` - width: 24px; - height: 24px; - border-radius: 100%; +export const LeftArrow = styled(IconButton)` + left: 0; + + ${arrowStyle} +` - background-color: ${({ theme }): string => theme.colors.white}; +export const RightArrow = styled(IconButton)` + right: 0; - filter: drop-shadow(0 2px 6px rgb(0 0 0 / 25%)); + ${arrowStyle} transform: scaleX(-1); ` -export const CategoryItem = styled.div` +export const CategoryItem = styled.button` + display: flex; + justify-content: center; + width: 100%; max-width: 108px; height: 118px; + border: none; + + background: transparent; + + cursor: pointer; transition: 0.5s; @@ -142,6 +146,7 @@ export const CategoryImgWrapper = styled.div` width: 108px; height: 86px; + cursor: pointer; ${({ theme }) => css` border-radius: ${theme.radius.round12}; @@ -192,7 +197,6 @@ export const Styled = { CateGoryBoxWrapper, CateGoryBox, CategoryLink, - ArrowBox, LeftArrow, RightArrow, CategoryItem, From 63151c9988b73dfa1cfcdf68b62a4b869dc58f13 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 24 Jan 2024 01:26:17 +0900 Subject: [PATCH 04/13] =?UTF-8?q?feat:=20URLSearchParams=20->=20toQueryStr?= =?UTF-8?q?ing=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/CategorySlider/index.tsx | 7 ++++--- src/pages/categories/[categoryCode].tsx | 11 ++++------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/components/home/CategorySlider/index.tsx b/src/components/home/CategorySlider/index.tsx index 8f570b75..9baa8263 100644 --- a/src/components/home/CategorySlider/index.tsx +++ b/src/components/home/CategorySlider/index.tsx @@ -5,6 +5,7 @@ import type { ReactElement, TouchEventHandler } from 'react' import { Styled } from './styled' import { useGetCategoriesQuery } from '@apis/post' import { SORT_OPTIONS } from '@constants/app' +import { toQueryString } from '@utils/format' const CategorySlider = (): ReactElement => { const containerRef = useRef(null) @@ -114,9 +115,9 @@ const CategorySlider = (): ReactElement => { return ( + href={`/categories/${code}?${toQueryString({ + sort: SORT_OPTIONS[0].code + })}`}> [ - `${key}`, - String(value) - ]) - - router.push(`/categories/${categoryCode}?${new URLSearchParams(params)}`) + router.push( + `/categories/${categoryCode}?${toQueryString({ ...searchParams })}` + ) } return ( From 313f7f5a94812bfe40e532c7d75cbce49a3c11bb Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 24 Jan 2024 01:54:53 +0900 Subject: [PATCH 05/13] =?UTF-8?q?feat:=20PostSection=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/PostSection/index.tsx | 46 ++++++++++++++++++++ src/components/common/PostSection/styled.ts | 38 ++++++++++++++++ src/components/common/PostSection/types.ts | 12 +++++ src/components/common/index.ts | 1 + src/components/home/ProductList/types.ts | 6 +-- src/components/result/SearchOptions/types.ts | 3 +- 6 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 src/components/common/PostSection/index.tsx create mode 100644 src/components/common/PostSection/styled.ts create mode 100644 src/components/common/PostSection/types.ts diff --git a/src/components/common/PostSection/index.tsx b/src/components/common/PostSection/index.tsx new file mode 100644 index 00000000..d4ff6c6a --- /dev/null +++ b/src/components/common/PostSection/index.tsx @@ -0,0 +1,46 @@ +import { Styled } from './styled' +import type { PostSectionProps } from './types' +import { useGetCategoriesQuery } from '@apis/post' +import { SearchOptions, CategorySlideFilter, ProductList } from '@components' + +export const PostSection = ({ + infinitePosts, + postsCount = 0, + searchOptions, + onChangeSearchOption +}: PostSectionProps) => { + const getCategoriesQuery = useGetCategoriesQuery() + const categories = + getCategoriesQuery.data?.map(({ code, name }) => ({ + code, + name + })) || [] + + return ( + <> + + onChangeSearchOption('category', code)} + /> + + + {postsCount > 0 ? ( + + ) : ( + + 검색 결과 없음 + + 찾으시는 검색 결과가 없어요 + + + )} + + ) +} diff --git a/src/components/common/PostSection/styled.ts b/src/components/common/PostSection/styled.ts new file mode 100644 index 00000000..34cff31e --- /dev/null +++ b/src/components/common/PostSection/styled.ts @@ -0,0 +1,38 @@ +import { css } from '@emotion/react' +import styled from '@emotion/styled' + +const CategorySliderWrapper = styled.div` + /* TODO: useMedia를 사용한 조건부 렌더링시 hydration 에러가 발생해 스타일로 우선 적용 했습니다. */ + ${({ theme }) => theme.mediaQuery.tablet} { + display: none; + } +` + +const Placeholder = styled.div` + width: 100%; + height: 100%; + margin: 120px 0; + + text-align: center; +` + +const PlaceholderTitle = styled.p` + margin-bottom: 8px; + + ${({ theme }) => theme.fonts.subtitle01B} +` + +const PlaceholderDescription = styled.p` + ${({ theme }) => css` + color: ${theme.colors.grayScale70}; + + ${theme.fonts.body01M}; + `} +` + +export const Styled = { + CategorySliderWrapper, + Placeholder, + PlaceholderTitle, + PlaceholderDescription +} diff --git a/src/components/common/PostSection/types.ts b/src/components/common/PostSection/types.ts new file mode 100644 index 00000000..2d0a6df9 --- /dev/null +++ b/src/components/common/PostSection/types.ts @@ -0,0 +1,12 @@ +import type { + SearchOptionsState, + OnChangeSearchOptions +} from '../../result/SearchOptions/types' +import type { ProductListProps } from '@components/home' + +export type PostSectionProps = { + postsCount?: number + infinitePosts: ProductListProps + searchOptions: SearchOptionsState + onChangeSearchOption: OnChangeSearchOptions +} diff --git a/src/components/common/index.ts b/src/components/common/index.ts index 34c9d8bb..8111c6fb 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -3,3 +3,4 @@ export * from './CommonModal' export * from './Header' export * from './AlertModal' export * from './Dialog' +export * from './PostSection' diff --git a/src/components/home/ProductList/types.ts b/src/components/home/ProductList/types.ts index ccd76216..40f23696 100644 --- a/src/components/home/ProductList/types.ts +++ b/src/components/home/ProductList/types.ts @@ -3,14 +3,10 @@ import type { InfiniteData, InfiniteQueryObserverResult } from '@tanstack/react-query' -import type { GetPostsReq, GetPostsRes } from '@apis/post' +import type { GetPostsRes } from '@apis/post' export type ProductListProps = { postData?: GetPostsRes[] - filterOption?: Pick< - GetPostsReq, - 'sort' | 'category' | 'minPrice' | 'maxPrice' - > hasNextPage?: boolean fetchNextPage?( options?: FetchNextPageOptions diff --git a/src/components/result/SearchOptions/types.ts b/src/components/result/SearchOptions/types.ts index 9a25f870..9bd9f4c4 100644 --- a/src/components/result/SearchOptions/types.ts +++ b/src/components/result/SearchOptions/types.ts @@ -9,14 +9,15 @@ export type SearchOptionsState = { max?: number } } + export type OnChangeSearchOptions = ( name: KeyOf, value: ValueOf ) => void export type SearchOptionsProps = { - categories: Pick[] postsCount?: number + categories: Pick[] searchOptions: SearchOptionsState onChangeSearchOption: OnChangeSearchOptions } From b73e651f2e3ba8b727c293546ae6fc11f2750ba0 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 24 Jan 2024 01:56:18 +0900 Subject: [PATCH 06/13] =?UTF-8?q?feat:=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20PostSection=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9=20&=20find=ED=95=A8=EC=88=98=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/categories/[categoryCode].tsx | 74 +++---------------------- src/utils/common/index.ts | 2 +- 2 files changed, 10 insertions(+), 66 deletions(-) diff --git a/src/pages/categories/[categoryCode].tsx b/src/pages/categories/[categoryCode].tsx index bf89af0b..d14ced55 100644 --- a/src/pages/categories/[categoryCode].tsx +++ b/src/pages/categories/[categoryCode].tsx @@ -1,4 +1,3 @@ -import { css } from '@emotion/react' import styled from '@emotion/styled' import type { GetServerSideProps, NextPage } from 'next' import { useRouter } from 'next/router' @@ -8,14 +7,9 @@ import type { OnChangeSearchOptions } from '@components/result/SearchOptions/types' import { useGetCategoriesQuery, useGetInfinitePostsQuery } from '@apis' -import { - SearchOptions, - ResultHeader, - CategorySlideFilter, - ProductList -} from '@components' +import { PostSection, ResultHeader } from '@components' import type { SortOptionCodes, TradeTypeCodes } from '@types' -import { removeNullish, toQueryString } from '@utils' +import { find, removeNullish, toQueryString } from '@utils' const DEFAULT_POST_PAGE_NUMBER = 8 @@ -62,9 +56,7 @@ const Categories: NextPage = ({ const categories = getCategoriesQuery.data?.map(({ code, name }) => ({ code, name })) || [] - const currentCategory = categories.find( - ({ code }) => code === searchOptions.category - ) + const currentCategory = find(categories, { code: searchOptions.category }) const infinitePosts = useGetInfinitePostsQuery({ lastId: null, @@ -95,35 +87,16 @@ const Categories: NextPage = ({ postsCount={postsCount} resultMessage={currentCategory?.name || '전체'} /> - - - handleChangeSearchOptions('category', code) - } - /> - - - {postsCount > 0 ? ( - - ) : ( - - 검색 결과 없음 - - 찾으시는 검색 결과가 없어요 - - - )} ) @@ -150,33 +123,4 @@ const Layout = styled.div` margin-top: 68px; ` -const CategorySliderWrapper = styled.div` - /* TODO: useMedia를 사용한 조건부 렌더링시 hydration 에러가 발생해 스타일로 우선 적용 했습니다. */ - ${({ theme }) => theme.mediaQuery.tablet} { - display: none; - } -` - -const Placeholder = styled.div` - width: 100%; - height: 100%; - margin: 120px 0; - - text-align: center; -` - -const PlaceholderTitle = styled.p` - margin-bottom: 8px; - - ${({ theme }) => theme.fonts.subtitle01B} -` - -const PlaceholderDescription = styled.p` - ${({ theme }) => css` - color: ${theme.colors.grayScale70}; - - ${theme.fonts.body01M}; - `} -` - export default Categories diff --git a/src/utils/common/index.ts b/src/utils/common/index.ts index 3b13e510..cecf87df 100644 --- a/src/utils/common/index.ts +++ b/src/utils/common/index.ts @@ -2,7 +2,7 @@ export const noop = (): void => undefined export const find = ( arr: T, - target: UnknownObject + target: UnknownObject ): T extends readonly any[] ? ValueOf : undefined => { const result = arr.find(item => { const splittedArr = splitObject(item) From 4c35bbbb97fb9894708bdd7e33def11a53103f45 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 24 Jan 2024 01:58:43 +0900 Subject: [PATCH 07/13] =?UTF-8?q?feat:=20result=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20PostSection=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/result/index.tsx | 74 +++++--------------------------------- 1 file changed, 8 insertions(+), 66 deletions(-) diff --git a/src/pages/result/index.tsx b/src/pages/result/index.tsx index 95894238..95e0af71 100644 --- a/src/pages/result/index.tsx +++ b/src/pages/result/index.tsx @@ -1,4 +1,3 @@ -import { css } from '@emotion/react' import styled from '@emotion/styled' import { useAtomValue } from 'jotai' import type { GetServerSideProps, NextPage } from 'next' @@ -8,14 +7,9 @@ import type { SearchOptionsState, OnChangeSearchOptions } from '@components/result/SearchOptions/types' -import { useGetCategoriesQuery, useGetInfinitePostsQuery } from '@apis' +import { useGetInfinitePostsQuery } from '@apis' import { searchKeywordAtom } from '@atoms' -import { - SearchOptions, - ResultHeader, - CategorySlideFilter, - ProductList -} from '@components' +import { ResultHeader, PostSection } from '@components' import type { SortOptionCodes, TradeTypeCodes } from '@types' import { toQueryString, removeNullish } from '@utils' @@ -50,7 +44,6 @@ const ResultPage: NextPage = ({ maxPrice, tradeType }: ResultPageProps) => { - const getCategoriesQuery = useGetCategoriesQuery() const router = useRouter() const searchKeyword = useAtomValue(searchKeywordAtom) const [searchOptions, setSearchOptions] = useState({ @@ -67,9 +60,6 @@ const ResultPage: NextPage = ({ searchKeyword: currentKeyword }) - const categories = - getCategoriesQuery.data?.map(({ code, name }) => ({ code, name })) || [] - const infinitePosts = useGetInfinitePostsQuery({ lastId: null, limit: DEFAULT_POST_PAGE_NUMBER, @@ -96,35 +86,16 @@ const ResultPage: NextPage = ({ postsCount={postsCount} resultMessage={`"${currentKeyword}"의 검색결과`} /> - - - handleChangeSearchOptions('category', code) - } - /> - - - {postsCount > 0 ? ( - - ) : ( - - 검색 결과 없음 - - 찾으시는 검색 결과가 없어요 - - - )} ) @@ -151,33 +122,4 @@ const Layout = styled.div` margin-top: 68px; ` -const CategorySliderWrapper = styled.div` - /* TODO: useMedia를 사용한 조건부 렌더링시 hydration 에러가 발생해 스타일로 우선 적용 했습니다. */ - ${({ theme }) => theme.mediaQuery.tablet} { - display: none; - } -` - -const Placeholder = styled.div` - width: 100%; - height: 100%; - margin: 120px 0; - - text-align: center; -` - -const PlaceholderTitle = styled.p` - margin-bottom: 8px; - - ${({ theme }) => theme.fonts.subtitle01B} -` - -const PlaceholderDescription = styled.p` - ${({ theme }) => css` - color: ${theme.colors.grayScale70}; - - ${theme.fonts.body01M}; - `} -` - export default ResultPage From 1e7fbda04f32a79ce47bfbc28834097a0d68f7aa Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 24 Jan 2024 02:11:18 +0900 Subject: [PATCH 08/13] =?UTF-8?q?feat:=20routing=ED=95=A0=20category=20?= =?UTF-8?q?=EA=B0=80=EC=A0=B8=EC=98=A4=EB=8A=94=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/result/SearchOptions/types.ts | 4 +++- src/pages/categories/[categoryCode].tsx | 25 +++++++++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/components/result/SearchOptions/types.ts b/src/components/result/SearchOptions/types.ts index 9bd9f4c4..39f5479f 100644 --- a/src/components/result/SearchOptions/types.ts +++ b/src/components/result/SearchOptions/types.ts @@ -10,8 +10,10 @@ export type SearchOptionsState = { } } +export type SearchOptionsStateKeys = KeyOf + export type OnChangeSearchOptions = ( - name: KeyOf, + name: SearchOptionsStateKeys, value: ValueOf ) => void diff --git a/src/pages/categories/[categoryCode].tsx b/src/pages/categories/[categoryCode].tsx index d14ced55..f709ec81 100644 --- a/src/pages/categories/[categoryCode].tsx +++ b/src/pages/categories/[categoryCode].tsx @@ -4,7 +4,8 @@ import { useRouter } from 'next/router' import { useState } from 'react' import type { SearchOptionsState, - OnChangeSearchOptions + OnChangeSearchOptions, + SearchOptionsStateKeys } from '@components/result/SearchOptions/types' import { useGetCategoriesQuery, useGetInfinitePostsQuery } from '@apis' import { PostSection, ResultHeader } from '@components' @@ -20,6 +21,7 @@ type CategoriesProps = { maxPrice?: number tradeType?: TradeTypeCodes } + export const getServerSideProps: GetServerSideProps = async ({ query }) => ({ @@ -32,6 +34,9 @@ export const getServerSideProps: GetServerSideProps = async ({ } }) +// TODO: 포스트 전체 갯수 내려달라고 요청해놓았습니다 +const POSTS_COUNT_MOCK = 10 + const Categories: NextPage = ({ category, sort, @@ -39,13 +44,14 @@ const Categories: NextPage = ({ maxPrice, tradeType }: CategoriesProps) => { - const getCategoriesQuery = useGetCategoriesQuery() - const router = useRouter() const [searchOptions, setSearchOptions] = useState({ category, sort: 'CREATED_DATE_DESC', priceRange: {} }) + const router = useRouter() + + const getCategoriesQuery = useGetCategoriesQuery() const searchParams = removeNullish({ minPrice: searchOptions.priceRange?.min ?? minPrice, @@ -64,11 +70,10 @@ const Categories: NextPage = ({ ...searchParams }) - // TODO: 포스트 전체 갯수 내려달라고 요청해놓았습니다 - const postsCount = 10 + const getNextCategoryCode = (name: SearchOptionsStateKeys) => + name === 'category' ? name : searchOptions.category const handleChangeSearchOptions: OnChangeSearchOptions = (name, value) => { - const categoryCode = name === 'category' ? value : searchOptions.category const nextSearchOptions = { ...searchOptions, [name]: value @@ -76,7 +81,9 @@ const Categories: NextPage = ({ setSearchOptions(nextSearchOptions) router.push( - `/categories/${categoryCode}?${toQueryString({ ...searchParams })}` + `/categories/${getNextCategoryCode(name)}?${toQueryString({ + ...searchParams + })}` ) } @@ -84,7 +91,7 @@ const Categories: NextPage = ({ From 5f42b77e2955d0577c851d50073a18de93dc7d8d Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 24 Jan 2024 02:43:13 +0900 Subject: [PATCH 09/13] =?UTF-8?q?feat:=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=EC=84=A0=ED=83=9D=EC=8B=9C=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=ED=83=88=20=EC=9D=B4=EC=8A=88=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/result/SearchOptions/types.ts | 3 ++- src/pages/categories/[categoryCode].tsx | 12 ++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/components/result/SearchOptions/types.ts b/src/components/result/SearchOptions/types.ts index 39f5479f..958d6120 100644 --- a/src/components/result/SearchOptions/types.ts +++ b/src/components/result/SearchOptions/types.ts @@ -11,10 +11,11 @@ export type SearchOptionsState = { } export type SearchOptionsStateKeys = KeyOf +export type SearchOptionStateValues = ValueOf export type OnChangeSearchOptions = ( name: SearchOptionsStateKeys, - value: ValueOf + value: SearchOptionStateValues ) => void export type SearchOptionsProps = { diff --git a/src/pages/categories/[categoryCode].tsx b/src/pages/categories/[categoryCode].tsx index f709ec81..47890444 100644 --- a/src/pages/categories/[categoryCode].tsx +++ b/src/pages/categories/[categoryCode].tsx @@ -5,7 +5,8 @@ import { useState } from 'react' import type { SearchOptionsState, OnChangeSearchOptions, - SearchOptionsStateKeys + SearchOptionsStateKeys, + SearchOptionStateValues } from '@components/result/SearchOptions/types' import { useGetCategoriesQuery, useGetInfinitePostsQuery } from '@apis' import { PostSection, ResultHeader } from '@components' @@ -70,10 +71,13 @@ const Categories: NextPage = ({ ...searchParams }) - const getNextCategoryCode = (name: SearchOptionsStateKeys) => - name === 'category' ? name : searchOptions.category + const getNextCategoryCode = ( + name: SearchOptionsStateKeys, + value: SearchOptionStateValues + ) => (name === 'category' ? value : searchOptions.category) const handleChangeSearchOptions: OnChangeSearchOptions = (name, value) => { + const nextCategoryCode = getNextCategoryCode(name, value) const nextSearchOptions = { ...searchOptions, [name]: value @@ -81,7 +85,7 @@ const Categories: NextPage = ({ setSearchOptions(nextSearchOptions) router.push( - `/categories/${getNextCategoryCode(name)}?${toQueryString({ + `/categories/${nextCategoryCode}?${toQueryString({ ...searchParams })}` ) From 88a568082c2fbab83a1f32e192b21fb577915a86 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 24 Jan 2024 02:56:16 +0900 Subject: [PATCH 10/13] =?UTF-8?q?feat:=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=EC=98=B5=EC=85=98=20=EB=B3=80=EA=B2=BD=EC=8B=9C=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B0=ED=8C=85=20=EC=9D=B4=EC=8A=88=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/result/SearchOptions/types.ts | 7 ++----- src/pages/categories/[categoryCode].tsx | 18 +++++++----------- src/utils/format/index.ts | 6 ++++-- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/components/result/SearchOptions/types.ts b/src/components/result/SearchOptions/types.ts index 958d6120..9bd9f4c4 100644 --- a/src/components/result/SearchOptions/types.ts +++ b/src/components/result/SearchOptions/types.ts @@ -10,12 +10,9 @@ export type SearchOptionsState = { } } -export type SearchOptionsStateKeys = KeyOf -export type SearchOptionStateValues = ValueOf - export type OnChangeSearchOptions = ( - name: SearchOptionsStateKeys, - value: SearchOptionStateValues + name: KeyOf, + value: ValueOf ) => void export type SearchOptionsProps = { diff --git a/src/pages/categories/[categoryCode].tsx b/src/pages/categories/[categoryCode].tsx index 47890444..916b90ec 100644 --- a/src/pages/categories/[categoryCode].tsx +++ b/src/pages/categories/[categoryCode].tsx @@ -4,9 +4,7 @@ import { useRouter } from 'next/router' import { useState } from 'react' import type { SearchOptionsState, - OnChangeSearchOptions, - SearchOptionsStateKeys, - SearchOptionStateValues + OnChangeSearchOptions } from '@components/result/SearchOptions/types' import { useGetCategoriesQuery, useGetInfinitePostsQuery } from '@apis' import { PostSection, ResultHeader } from '@components' @@ -71,22 +69,20 @@ const Categories: NextPage = ({ ...searchParams }) - const getNextCategoryCode = ( - name: SearchOptionsStateKeys, - value: SearchOptionStateValues - ) => (name === 'category' ? value : searchOptions.category) - const handleChangeSearchOptions: OnChangeSearchOptions = (name, value) => { - const nextCategoryCode = getNextCategoryCode(name, value) const nextSearchOptions = { ...searchOptions, [name]: value } + const { category, priceRange, ...params } = nextSearchOptions + setSearchOptions(nextSearchOptions) router.push( - `/categories/${nextCategoryCode}?${toQueryString({ - ...searchParams + `/categories/${category}?${toQueryString({ + ...params, + minPrice: priceRange.min, + maxPrice: priceRange.max })}` ) } diff --git a/src/utils/format/index.ts b/src/utils/format/index.ts index fb3a31e3..5ee8f3a0 100644 --- a/src/utils/format/index.ts +++ b/src/utils/format/index.ts @@ -53,12 +53,14 @@ export const toLocaleCurrency = (value: number): string => { } export const toQueryString = (object: { - [key: string]: string | number + [key: string]: string | number | undefined }): URLSearchParams => { const searchParams = new URLSearchParams() Object.entries(object).forEach(([key, value]) => { - searchParams.set(String(key), String(value)) + if (value) { + searchParams.set(String(key), String(value)) + } }) return searchParams From 10a0518bb595ccbf5c825758c1ccb154bb80a345 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 24 Jan 2024 03:15:05 +0900 Subject: [PATCH 11/13] =?UTF-8?q?feat:=20routing,=20setState=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/categories/[categoryCode].tsx | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/pages/categories/[categoryCode].tsx b/src/pages/categories/[categoryCode].tsx index 916b90ec..9c421053 100644 --- a/src/pages/categories/[categoryCode].tsx +++ b/src/pages/categories/[categoryCode].tsx @@ -69,15 +69,11 @@ const Categories: NextPage = ({ ...searchParams }) - const handleChangeSearchOptions: OnChangeSearchOptions = (name, value) => { - const nextSearchOptions = { - ...searchOptions, - [name]: value - } - const { category, priceRange, ...params } = nextSearchOptions - - setSearchOptions(nextSearchOptions) - + const searchByCategory = ({ + category, + priceRange, + ...params + }: SearchOptionsState) => { router.push( `/categories/${category}?${toQueryString({ ...params, @@ -87,6 +83,16 @@ const Categories: NextPage = ({ ) } + const handleChangeSearchOptions: OnChangeSearchOptions = (name, value) => { + const newSearchOptions = { + ...searchOptions, + [name]: value + } + + setSearchOptions(newSearchOptions) + searchByCategory(newSearchOptions) + } + return ( From fae61bf8cd8541ca8de84f5f2324bcd66c3a6c65 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 24 Jan 2024 03:17:33 +0900 Subject: [PATCH 12/13] =?UTF-8?q?feat:=20result=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EA=B2=BD=EB=A1=9C=20=EC=9D=B4=ED=83=88=20=EC=9D=B4?= =?UTF-8?q?=EC=8A=88=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/result/index.tsx | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/pages/result/index.tsx b/src/pages/result/index.tsx index 95e0af71..4c2d27da 100644 --- a/src/pages/result/index.tsx +++ b/src/pages/result/index.tsx @@ -14,6 +14,8 @@ import type { SortOptionCodes, TradeTypeCodes } from '@types' import { toQueryString, removeNullish } from '@utils' const DEFAULT_POST_PAGE_NUMBER = 8 +// TODO: 포스트 전체 갯수 내려달라고 요청해놓았습니다 +const POST_COUNT_MOCK = 10 type ResultPageProps = { keyword?: string @@ -66,24 +68,31 @@ const ResultPage: NextPage = ({ ...searchParams }) - // TODO: 포스트 전체 갯수 내려달라고 요청해놓았습니다 - const postsCount = 10 + const searchByResult = ({ priceRange, ...params }: SearchOptionsState) => { + router.push( + `/result?${toQueryString({ + ...params, + minPrice: priceRange.min, + maxPrice: priceRange.max + })}` + ) + } const handleChangeSearchOptions: OnChangeSearchOptions = (name, value) => { - const nextSearchOptions = { + const newSearchOptions = { ...searchOptions, [name]: value } - setSearchOptions(nextSearchOptions) - router.push(`/result?${toQueryString(searchParams)}`) + setSearchOptions(newSearchOptions) + searchByResult(newSearchOptions) } return ( From 00a45270540f601ce797d1664fc65bbb2478099a Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 24 Jan 2024 03:20:55 +0900 Subject: [PATCH 13/13] =?UTF-8?q?chore:=20=EA=B0=80=EB=8F=85=EC=84=B1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=B3=80=EC=88=98=EB=AA=85=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/categories/[categoryCode].tsx | 9 ++++----- src/pages/index.tsx | 11 ++++++----- src/pages/result/index.tsx | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/pages/categories/[categoryCode].tsx b/src/pages/categories/[categoryCode].tsx index 9c421053..65eeb7f0 100644 --- a/src/pages/categories/[categoryCode].tsx +++ b/src/pages/categories/[categoryCode].tsx @@ -11,7 +11,9 @@ import { PostSection, ResultHeader } from '@components' import type { SortOptionCodes, TradeTypeCodes } from '@types' import { find, removeNullish, toQueryString } from '@utils' -const DEFAULT_POST_PAGE_NUMBER = 8 +const DEFAULT_PER_PAGE = 8 +// TODO: 포스트 전체 갯수 내려달라고 요청해놓았습니다 +const POSTS_COUNT_MOCK = 10 type CategoriesProps = { category?: string @@ -33,9 +35,6 @@ export const getServerSideProps: GetServerSideProps = async ({ } }) -// TODO: 포스트 전체 갯수 내려달라고 요청해놓았습니다 -const POSTS_COUNT_MOCK = 10 - const Categories: NextPage = ({ category, sort, @@ -65,7 +64,7 @@ const Categories: NextPage = ({ const infinitePosts = useGetInfinitePostsQuery({ lastId: null, - limit: DEFAULT_POST_PAGE_NUMBER, + limit: DEFAULT_PER_PAGE, ...searchParams }) diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 870d31a2..3144c422 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -7,6 +7,10 @@ import { ProductList } from '../components/home/ProductList' import { useGetInfinitePostsQuery } from '@apis/post' import { CategorySlider, HomeBanner } from '@components' +const DEFAULT_PER_PAGE = 8 +// TODO: 포스트 전체 갯수 내려달라고 요청해놓았습니다 +const POSTS_COUNTS_MOCK = 10 + const Home: NextPage = () => { const { data: postList, @@ -14,20 +18,17 @@ const Home: NextPage = () => { hasNextPage } = useGetInfinitePostsQuery({ lastId: null, - limit: 8 + limit: DEFAULT_PER_PAGE }) const router = useRouter() - // TODO: 포스트 전체 갯수 내려달라고 요청해놓았습니다 - const postsCount = 10 - return ( 새로운 상품 - {postsCount > 0 ? ( + {POSTS_COUNTS_MOCK > 0 ? (