Skip to content
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

feat: 태그 검색 기능 구현 #64

Merged
merged 25 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
92c3b11
refactor: 검색 api에서 태그 검색일때의 endpoint 추가
xodms0309 Mar 23, 2024
34a3314
feat: 태그 검색 기능 구현
xodms0309 Mar 23, 2024
95c3679
Merge remote-tracking branch 'origin/feat/v2' into feat/issue-60
xodms0309 Mar 27, 2024
6f9c62e
feat: 검색결과 없을 때 화면 구현
xodms0309 Mar 27, 2024
c5626f1
feat: 태그 검색 결과 리스트 컴포넌트 구현
xodms0309 Mar 27, 2024
902dda0
feat: Text 컴포넌트에서 외부 className을 받을 수 있게 수정
xodms0309 Mar 30, 2024
aa3bc0d
feat: 검색 페이지에서 태그 검색 결과일 경우 분기처리
xodms0309 Mar 30, 2024
8709619
feat: 더보기 버튼을 리스트 컴포넌트로 위치 이동
xodms0309 Mar 30, 2024
453b953
feat: 태그 검색을 일반 검색과 분리
xodms0309 Mar 30, 2024
c1f3f7d
feat: 상품 검색 더보기 페이지 구현
xodms0309 Mar 30, 2024
56bcc3b
feat: 태그 검색을 했을 때 input value 스타일 변경
xodms0309 Mar 31, 2024
d66ad0e
style: 사용 안하는 코드 import 제거
xodms0309 Mar 31, 2024
a3922e8
feat: ProductSearchResultList 스토리북 추가
xodms0309 Mar 31, 2024
e67a69a
fix: 검색이 되었을 때 resetQuery를 하도록 수정
xodms0309 Mar 31, 2024
f7199a5
style: fix lint error
xodms0309 Apr 7, 2024
fbc062e
feat: 태그 검색 페이지 분리
xodms0309 Apr 7, 2024
d0c4582
feat: 말풍선 아이콘 교체
xodms0309 Apr 7, 2024
fbdb3aa
feat: ProductItem 디자인 수정
xodms0309 Apr 7, 2024
185455e
Merge remote-tracking branch 'origin/feat/v2' into feat/issue-60
xodms0309 Apr 7, 2024
281395c
Merge remote-tracking branch 'origin/feat/v2' into feat/issue-60
xodms0309 Apr 8, 2024
ca2d24f
feat: ProductSearchResultList -> ProductSearchResultPreviewList로 이름 변경
xodms0309 Apr 8, 2024
e40319b
feat: 버튼 스타일 변경
xodms0309 Apr 8, 2024
5a08969
feat: ProductOverviewList로 교체
xodms0309 Apr 8, 2024
e423552
fix: 상품 상세 경로 수정
xodms0309 Apr 9, 2024
12546c7
refactor: 인자로 endpoint를 넘겨주게끔 변경
xodms0309 Apr 11, 2024
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
51 changes: 45 additions & 6 deletions .storybook/preview-body.html
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,55 @@
</clipPath>
</defs>
</symbol>
<symbol id="review2" viewBox="0 0 14 14">
<g strokeLinecap="round" strokeLinejoin="round" clipPath="url(#clip0_1222_34401)">
<symbol id="review2" viewBox="0 0 12 12" fill="none">
<g clip-path="url(#clip0_4627_11650)">
<path
d="M7.002 7.25a.25.25 0 0 1 0-.5m0 .5a.25.25 0 0 0 0-.5m-2.75.5a.25.25 0 0 1 0-.5m0 .5a.25.25 0 0 0 0-.5m5.5.5a.25.25 0 0 1 0-.5m0 .5a.25.25 0 1 0 0-.5"
d="M6.04793 0.650025C5.13272 0.650311 4.23471 0.898835 3.44956 1.36913C2.66442 1.83943 2.02154 2.51387 1.5894 3.32065C1.15725 4.12742 0.952032 5.0363 0.99559 5.95048C1.03915 6.86467 1.32985 7.74991 1.83675 8.51192L0.988281 10.7694L3.82947 10.2556C4.51362 10.5899 5.2644 10.7655 6.02586 10.7693C6.78732 10.7731 7.53981 10.6049 8.22724 10.2773C8.91465 9.94986 9.51934 9.47136 9.99603 8.87759C10.4728 8.28391 10.8095 7.5902 10.9808 6.84826C11.1521 6.10633 11.1539 5.33528 10.9857 4.59261C10.8176 3.84993 10.484 3.15477 10.0099 2.55897C9.53568 1.96315 8.93311 1.48206 8.24714 1.15153C7.56115 0.821004 6.8094 0.649576 6.04793 0.650025Z"
fill="#DDDDDD"
stroke="#DDDDDD"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M6.04799 5.90604C5.93951 5.90604 5.85156 5.8181 5.85156 5.70961C5.85156 5.60113 5.93951 5.51318 6.04799 5.51318"
stroke="white"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M6.04688 5.90604C6.15536 5.90604 6.2433 5.8181 6.2433 5.70961C6.2433 5.60113 6.15536 5.51318 6.04688 5.51318"
stroke="white"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M3.89174 5.90604C3.78326 5.90604 3.69531 5.8181 3.69531 5.70961C3.69531 5.60113 3.78326 5.51318 3.89174 5.51318"
stroke="white"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M3.89062 5.90604C3.99911 5.90604 4.08705 5.8181 4.08705 5.70961C4.08705 5.60113 3.99911 5.51318 3.89062 5.51318"
stroke="white"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M8.21205 5.90604C8.10357 5.90604 8.01562 5.8181 8.01562 5.70961C8.01562 5.60113 8.10357 5.51318 8.21205 5.51318"
stroke="white"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M8.21094 5.90604C8.31942 5.90604 8.40741 5.8181 8.40741 5.70961C8.40741 5.60113 8.31942 5.51318 8.21094 5.51318"
stroke="white"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path d="M6.998.56a6.44 6.44 0 0 0-5.36 10.007L.558 13.44l3.617-.654A6.44 6.44 0 1 0 6.998.56z" />
</g>
<defs>
<clipPath id="clip0_1222_34401">
<path fill="#fff" d="M0 0h14v14H0z" />
<clipPath id="clip0_4627_11650">
<rect width="11" height="11" fill="white" transform="translate(0.550781 0.209595)" />
</clipPath>
</defs>
</symbol>
Expand Down
Binary file added src/assets/search-notfound.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 47 additions & 6 deletions src/components/Common/Svg/SvgSprite.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,55 @@ const SvgSprite = () => {
</clipPath>
</defs>
</symbol>
<symbol id="review2" viewBox="0 0 14 14">
<g strokeLinecap="round" strokeLinejoin="round" clipPath="url(#clip0_1222_34401)">
<path d="M7.002 7.25a.25.25 0 0 1 0-.5m0 .5a.25.25 0 0 0 0-.5m-2.75.5a.25.25 0 0 1 0-.5m0 .5a.25.25 0 0 0 0-.5m5.5.5a.25.25 0 0 1 0-.5m0 .5a.25.25 0 1 0 0-.5" />
<path d="M6.998.56a6.44 6.44 0 0 0-5.36 10.007L.558 13.44l3.617-.654A6.44 6.44 0 1 0 6.998.56z" />
<symbol id="review2" viewBox="0 0 12 12" fill="none">
<g clipPath="url(#clip0_4627_11650)">
<path
d="M6.04793 0.650025C5.13272 0.650311 4.23471 0.898835 3.44956 1.36913C2.66442 1.83943 2.02154 2.51387 1.5894 3.32065C1.15725 4.12742 0.952032 5.0363 0.99559 5.95048C1.03915 6.86467 1.32985 7.74991 1.83675 8.51192L0.988281 10.7694L3.82947 10.2556C4.51362 10.5899 5.2644 10.7655 6.02586 10.7693C6.78732 10.7731 7.53981 10.6049 8.22724 10.2773C8.91465 9.94986 9.51934 9.47136 9.99603 8.87759C10.4728 8.28391 10.8095 7.5902 10.9808 6.84826C11.1521 6.10633 11.1539 5.33528 10.9857 4.59261C10.8176 3.84993 10.484 3.15477 10.0099 2.55897C9.53568 1.96315 8.93311 1.48206 8.24714 1.15153C7.56115 0.821004 6.8094 0.649576 6.04793 0.650025Z"
fill="#DDDDDD"
stroke="#DDDDDD"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M6.04799 5.90604C5.93951 5.90604 5.85156 5.8181 5.85156 5.70961C5.85156 5.60113 5.93951 5.51318 6.04799 5.51318"
stroke="white"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M6.04688 5.90604C6.15536 5.90604 6.2433 5.8181 6.2433 5.70961C6.2433 5.60113 6.15536 5.51318 6.04688 5.51318"
stroke="white"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M3.89174 5.90604C3.78326 5.90604 3.69531 5.8181 3.69531 5.70961C3.69531 5.60113 3.78326 5.51318 3.89174 5.51318"
stroke="white"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M3.89062 5.90604C3.99911 5.90604 4.08705 5.8181 4.08705 5.70961C4.08705 5.60113 3.99911 5.51318 3.89062 5.51318"
stroke="white"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M8.21205 5.90604C8.10357 5.90604 8.01562 5.8181 8.01562 5.70961C8.01562 5.60113 8.10357 5.51318 8.21205 5.51318"
stroke="white"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M8.21094 5.90604C8.31942 5.90604 8.40741 5.8181 8.40741 5.70961C8.40741 5.60113 8.31942 5.51318 8.21094 5.51318"
stroke="white"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
<defs>
<clipPath id="clip0_1222_34401">
<path fill="#fff" d="M0 0h14v14H0z" />
<clipPath id="clip0_4627_11650">
<rect width="11" height="11" fill="white" transform="translate(0.550781 0.209595)" />
</clipPath>
</defs>
</symbol>
Expand Down
5 changes: 4 additions & 1 deletion src/components/Common/Text/Text.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import cx from 'classnames';

import { text } from './text.css';
import type { TextElement, TextVariants, OverridableComponentPropsWithoutRef } from './text.types';

Expand All @@ -9,12 +11,13 @@ const Text = <T extends TextElement = 'p'>({
weight = 'regular',
color = 'default',
as,
className,
...props
}: TextProps<T>) => {
const Component = as || 'p';

return (
<Component className={text({ color, size, weight })} {...props}>
<Component className={cx(text({ color, size, weight }), className)} {...props}>
Copy link
Contributor

Choose a reason for hiding this comment

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

전 요 방법 좋아보입니다~

{children}
</Component>
);
Expand Down
5 changes: 3 additions & 2 deletions src/components/Product/ProductItem/ProductItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from './productItem.css';

import { SvgIcon } from '@/components/Common';
import { vars } from '@/styles/theme.css';
import type { Product } from '@/types/product';

interface ProductItemProps {
Expand Down Expand Up @@ -44,13 +45,13 @@ const ProductItem = ({ product }: ProductItemProps) => {
<div style={{ height: '8px' }} />
<div className={summaryWrapper}>
<div className={previewWrapper}>
<SvgIcon variant="star2" width={11} height={11} fill="none" stroke="#999" />
<SvgIcon variant="star2" width={11} height={11} fill={vars.colors.gray2} />
<span className={preview} aria-label={`${averageRating}점`}>
{averageRating.toFixed(1)}
</span>
</div>
<div className={previewWrapper}>
<SvgIcon variant="review2" width={11} height={11} fill="none" stroke="#999" />
<SvgIcon variant="review2" width={11} height={11} />
<span className={preview} aria-label={`리뷰 ${reviewCount}개`}>
{reviewCount}
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,23 @@ import type { Product } from '@/types/product';

interface ProductOverviewListProps {
products: Product[];
isSearchPage?: boolean;
}

const ProductOverviewList = ({ products }: ProductOverviewListProps) => {
const ProductOverviewList = ({ products, isSearchPage = false }: ProductOverviewListProps) => {
return (
<ul className={container}>
{products.map(({ id, image, name, price, averageRating }) => (
<li key={id}>
<Link to={`${PATH.PRODUCT_LIST}/detail/${id}`}>
<ProductOverviewItem image={image} name={name} price={price} rate={averageRating} />
</Link>
{isSearchPage && (
<>
<div style={{ height: '20px' }} />
<hr style={{ border: '0.5px solid #e6e6e6' }} />
</>
)}
Comment on lines +22 to +27
Copy link
Contributor

Choose a reason for hiding this comment

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

짱 👍

</li>
))}
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,16 @@ export const container = style({
flexDirection: 'column',
gap: 20,
});

export const showMoreButton = style({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: 38,
padding: '9px 0',
margin: '20px 0',
background: '#efefef',
fontSize: 14,
borderRadius: 6,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { Meta, StoryObj } from '@storybook/react';

import ProductSearchResultPreviewList from './ProductSearchResultPreviewList';

const meta: Meta<typeof ProductSearchResultPreviewList> = {
title: 'search/ProductSearchResultPreviewList',
component: ProductSearchResultPreviewList,
args: {
searchQuery: '꼬북칩',
},
};

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { useRef } from 'react';
import { Link } from 'react-router-dom';

import { showMoreLink } from './productSearchResultPreivewList.css';
import SearchNotFound from '../SearchNotFound/SearchNotFound';

import { Text } from '@/components/Common';
import { ProductOverviewList } from '@/components/Product';
import { PATH } from '@/constants/path';
import { useIntersectionObserver } from '@/hooks/common';
import { useInfiniteProductSearchResultsQuery } from '@/hooks/queries/search';
import displaySlice from '@/utils/displaySlice';


interface ProductSearchResultPreviewListProps {
searchQuery: string;
}

const ProductSearchResultPreviewList = ({ searchQuery }: ProductSearchResultPreviewListProps) => {
const { data: searchResponse, fetchNextPage, hasNextPage } = useInfiniteProductSearchResultsQuery(searchQuery);
const scrollRef = useRef<HTMLDivElement>(null);
useIntersectionObserver<HTMLDivElement>(fetchNextPage, scrollRef, hasNextPage);

if (!searchResponse) {
return null;
}

const products = searchResponse.pages.flatMap((page) => page.products);
const productToDisplay = displaySlice(true, products);

if (products.length === 0) {
return <SearchNotFound />;
}

return (
<>
<ProductOverviewList products={productToDisplay} />
<Link to={`${PATH.SEARCH}/products?query=${searchQuery}`} className={showMoreLink}>
<Text size="caption1" weight="medium" color="info">
더보기
</Text>
</Link>
<div ref={scrollRef} aria-hidden />
</>
);
};

export default ProductSearchResultPreviewList;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { vars } from '@/styles/theme.css';
import { style } from '@vanilla-extract/css';

export const showMoreLink = style({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: 44,
padding: '12px 0',
margin: '20px 0',
border: `1px solid ${vars.colors.border.default}`,
fontSize: 14,
borderRadius: 6,
});
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Link, Text } from '@fun-eat/design-system';
import { useRef } from 'react';
import { Link as RouterLink } from 'react-router-dom';
import { Link } from 'react-router-dom';
import { styled } from 'styled-components';

import SearchNotFound from '../SearchNotFound/SearchNotFound';

import { RecipeItem } from '@/components/Recipe';
import { PATH } from '@/constants/path';
import { useIntersectionObserver } from '@/hooks/common';
Expand All @@ -20,15 +21,15 @@ const RecipeSearchResultList = ({ searchQuery }: RecipeSearchResultListProps) =>
const recipes = searchResponse.pages.flatMap((page) => page.recipes);

if (recipes.length === 0) {
return <Text>검색한 꿀조합을 찾을 수 없습니다.</Text>;
return <SearchNotFound />;
}

return (
<>
<RecipeSearchResultListContainer>
{recipes.map((recipe) => (
<li key={recipe.id}>
<Link as={RouterLink} to={`${PATH.RECIPE}/${recipe.id}`}>
<Link to={`${PATH.RECIPE}/${recipe.id}`}>
<RecipeItem recipe={recipe} />
</Link>
</li>
Expand Down
20 changes: 17 additions & 3 deletions src/components/Search/SearchInput/SearchInput.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import type { ComponentPropsWithRef, ForwardedRef } from 'react';
import { forwardRef } from 'react';

import { iconWrapperButton, inputContainer, searchInput } from './searchInput.css';
import { iconWrapperButton, inputContainer, searchInput, tagInputWrapper } from './searchInput.css';

import { SvgIcon } from '@/components/Common';
import { Text, SvgIcon } from '@/components/Common';

interface SearchInputProps extends ComponentPropsWithRef<'input'> {
isInputSubmitted: boolean;
isTagSearch?: boolean;
}

const SearchInput = forwardRef(
({ value, isInputSubmitted, ...props }: SearchInputProps, ref: ForwardedRef<HTMLInputElement>) => {
(
{ value, isInputSubmitted, isTagSearch = false, ...props }: SearchInputProps,
ref: ForwardedRef<HTMLInputElement>
) => {
return (
<div className={inputContainer}>
<input
Expand All @@ -20,6 +24,16 @@ const SearchInput = forwardRef(
value={value}
{...props}
/>
{isTagSearch && isInputSubmitted && (
<div className={tagInputWrapper}>
<Text color="info" size="caption3">
{value}
</Text>
<button>
<SvgIcon variant="close2" stroke="#6B6B6B" width={8} height={8} />
</button>
</div>
)}
<button className={iconWrapperButton}>
{isInputSubmitted ? (
<SvgIcon variant="close2" width={13} height={13} stroke="#232527" />
Expand Down
Loading
Loading