diff --git a/src/components/Common/ShowAllButton/ShowAllButton.tsx b/src/components/Common/ShowAllButton/ShowAllButton.tsx
new file mode 100644
index 00000000..b82b31dc
--- /dev/null
+++ b/src/components/Common/ShowAllButton/ShowAllButton.tsx
@@ -0,0 +1,25 @@
+import { Link } from 'react-router-dom';
+
+import { moreIconWrapper, linkWrapper } from './showAllButton.css';
+
+import { SvgIcon, Text } from '@/components/Common';
+import { vars } from '@/styles/theme.css';
+
+interface ShowAllButtonProps {
+ link: string;
+}
+
+const ShowAllButton = ({ link }: ShowAllButtonProps) => {
+ return (
+
+
+
+
+
+ 전체보기
+
+
+ );
+};
+
+export default ShowAllButton;
diff --git a/src/components/Common/ShowAllButton/showAllButton.css.ts b/src/components/Common/ShowAllButton/showAllButton.css.ts
new file mode 100644
index 00000000..200e2c5d
--- /dev/null
+++ b/src/components/Common/ShowAllButton/showAllButton.css.ts
@@ -0,0 +1,20 @@
+import { vars } from '@/styles/theme.css';
+import { style } from '@vanilla-extract/css';
+
+export const linkWrapper = style({
+ display: 'flex',
+ flexDirection: 'column',
+ gap: 12,
+ alignItems: 'center',
+ width: 45,
+});
+
+export const moreIconWrapper = style({
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ width: 40,
+ height: 40,
+ borderRadius: '50%',
+ background: vars.colors.secondary1,
+});
diff --git a/src/components/Common/index.ts b/src/components/Common/index.ts
index ef1d5042..30b5d588 100644
--- a/src/components/Common/index.ts
+++ b/src/components/Common/index.ts
@@ -25,3 +25,5 @@ export { default as PageHeader } from './PageHeader/PageHeader';
export { default as Badge } from './Badge/Badge';
export { default as WriteButton } from './WriteButton/WriteButton';
export { default as Text } from './Text/Text';
+export { default as TopBar } from './TopBar/TopBar';
+export { default as ShowAllButton } from './ShowAllButton/ShowAllButton';
diff --git a/src/components/Product/ProductRecipeList/ProductRecipeList.tsx b/src/components/Product/ProductRecipeList/ProductRecipeList.tsx
index 8c5f0f24..385d8428 100644
--- a/src/components/Product/ProductRecipeList/ProductRecipeList.tsx
+++ b/src/components/Product/ProductRecipeList/ProductRecipeList.tsx
@@ -1,18 +1,17 @@
-import { Link } from 'react-router-dom';
+import { container, moreItem } from './productRecipeList.css';
-import { container, moreIcon, moreIconWrapper, moreItem, moreLink } from './productRecipeList.css';
-
-import { SvgIcon, Text } from '@/components/Common';
+import { ShowAllButton } from '@/components/Common';
import { DefaultRecipeItem } from '@/components/Recipe';
+import { PATH } from '@/constants/path';
import { useInfiniteProductRecipesQuery } from '@/hooks/queries/product';
-import { vars } from '@/styles/theme.css';
import displaySlice from '@/utils/displaySlice';
interface ProductRecipeListProps {
productId: number;
+ productName: string;
}
-const ProductRecipeList = ({ productId }: ProductRecipeListProps) => {
+const ProductRecipeList = ({ productId, productName }: ProductRecipeListProps) => {
// 상품에서 보여줄 꿀조합 정렬 조건
const { data } = useInfiniteProductRecipesQuery(productId, 'favoriteCount,desc');
@@ -32,15 +31,7 @@ const ProductRecipeList = ({ productId }: ProductRecipeListProps) => {
))}
{recipeToDisplay.length < recipes.length && (
- {/*링크는 상품이 포함된 꿀조합 검색결과로 가는 것이 맞을듯?*/}
-
-
-
-
-
- 전체보기
-
-
+
)}
diff --git a/src/components/Product/ProductRecipeList/productRecipeList.css.ts b/src/components/Product/ProductRecipeList/productRecipeList.css.ts
index 5c7824ba..a6930606 100644
--- a/src/components/Product/ProductRecipeList/productRecipeList.css.ts
+++ b/src/components/Product/ProductRecipeList/productRecipeList.css.ts
@@ -1,4 +1,3 @@
-import { vars } from '@/styles/theme.css';
import { style } from '@vanilla-extract/css';
export const container = style({
@@ -14,25 +13,3 @@ export const moreItem = style({
alignItems: 'center',
minWidth: 108,
});
-
-export const moreLink = style({
- display: 'flex',
- flexDirection: 'column',
- justifyContent: 'center',
- alignItems: 'center',
-});
-
-export const moreIconWrapper = style({
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- width: 40,
- height: 40,
- marginBottom: 12,
- borderRadius: '50%',
- background: vars.colors.secondary1,
-});
-
-export const moreIcon = style({
- transform: 'rotate(180deg)',
-});
diff --git a/src/components/Recipe/RecipeItem/RecipeItem.tsx b/src/components/Recipe/RecipeItem/RecipeItem.tsx
index e94712db..6bbf7de6 100644
--- a/src/components/Recipe/RecipeItem/RecipeItem.tsx
+++ b/src/components/Recipe/RecipeItem/RecipeItem.tsx
@@ -26,6 +26,7 @@ import {
RECIPE_CARD_DEFAULT_IMAGE_URL_4,
RECIPE_CARD_DEFAULT_IMAGE_URL_5,
} from '@/constants/image';
+import { PATH } from '@/constants/path';
import RecipeItemProvider from '@/contexts/RecipeItemContext';
import { useRecipeItemValueContext } from '@/hooks/context';
import type { Recipe } from '@/types/recipe';
@@ -50,7 +51,7 @@ const RecipeItem = ({ recipe, children }: RecipeItemProps) => {
return (
- {children}
+ {children}
);
};
diff --git a/src/components/Search/ProductSearchResultList/ProductSearchResultPreviewList.stories.tsx b/src/components/Search/ProductSearchResultPreviewList/ProductSearchResultPreviewList.stories.tsx
similarity index 100%
rename from src/components/Search/ProductSearchResultList/ProductSearchResultPreviewList.stories.tsx
rename to src/components/Search/ProductSearchResultPreviewList/ProductSearchResultPreviewList.stories.tsx
diff --git a/src/components/Search/ProductSearchResultList/ProductSearchResultPreviewList.tsx b/src/components/Search/ProductSearchResultPreviewList/ProductSearchResultPreviewList.tsx
similarity index 100%
rename from src/components/Search/ProductSearchResultList/ProductSearchResultPreviewList.tsx
rename to src/components/Search/ProductSearchResultPreviewList/ProductSearchResultPreviewList.tsx
diff --git a/src/components/Search/ProductSearchResultList/productSearchResultPreivewList.css.ts b/src/components/Search/ProductSearchResultPreviewList/productSearchResultPreivewList.css.ts
similarity index 100%
rename from src/components/Search/ProductSearchResultList/productSearchResultPreivewList.css.ts
rename to src/components/Search/ProductSearchResultPreviewList/productSearchResultPreivewList.css.ts
diff --git a/src/components/Search/RecipeSearchResultPreviewList/RecipeSearchResultPreviewList.tsx b/src/components/Search/RecipeSearchResultPreviewList/RecipeSearchResultPreviewList.tsx
new file mode 100644
index 00000000..b188fc6d
--- /dev/null
+++ b/src/components/Search/RecipeSearchResultPreviewList/RecipeSearchResultPreviewList.tsx
@@ -0,0 +1,43 @@
+import { useRef } from 'react';
+
+import { listWrapper } from './recipeSearchResultPreviewList.css';
+import SearchNotFound from '../SearchNotFound/SearchNotFound';
+
+import { ShowAllButton } from '@/components/Common';
+import { DefaultRecipeItem } from '@/components/Recipe';
+import { PATH } from '@/constants/path';
+import { useIntersectionObserver } from '@/hooks/common';
+import { useInfiniteRecipeSearchResultsQuery } from '@/hooks/queries/search';
+import displaySlice from '@/utils/displaySlice';
+
+interface RecipeSearchResultPreviewListProps {
+ searchQuery: string;
+}
+
+const RecipeSearchResultPreviewList = ({ searchQuery }: RecipeSearchResultPreviewListProps) => {
+ const { data: searchResponse, fetchNextPage, hasNextPage } = useInfiniteRecipeSearchResultsQuery(searchQuery);
+ const scrollRef = useRef(null);
+ useIntersectionObserver(fetchNextPage, scrollRef, hasNextPage);
+
+ const recipes = searchResponse.pages.flatMap((page) => page.recipes);
+
+ if (recipes.length === 0) {
+ return ;
+ }
+
+ return (
+
+ {displaySlice(false, recipes, 4).map((recipe, idx) => (
+ -
+ {idx < 4 ? (
+
+ ) : (
+
+ )}
+
+ ))}
+
+ );
+};
+
+export default RecipeSearchResultPreviewList;
diff --git a/src/components/Search/RecipeSearchResultPreviewList/recipeSearchResultPreviewList.css.ts b/src/components/Search/RecipeSearchResultPreviewList/recipeSearchResultPreviewList.css.ts
new file mode 100644
index 00000000..df2e9d1a
--- /dev/null
+++ b/src/components/Search/RecipeSearchResultPreviewList/recipeSearchResultPreviewList.css.ts
@@ -0,0 +1,8 @@
+import { style } from '@vanilla-extract/css';
+
+export const listWrapper = style({
+ display: 'flex',
+ gap: 10,
+ alignItems: 'center',
+ overflowY: 'scroll',
+});
diff --git a/src/components/Search/index.ts b/src/components/Search/index.ts
index 2c312d80..0c32f1b8 100644
--- a/src/components/Search/index.ts
+++ b/src/components/Search/index.ts
@@ -1,5 +1,5 @@
-export { default as ProductSearchResultPreviewList } from './ProductSearchResultList/ProductSearchResultPreviewList';
+export { default as ProductSearchResultPreviewList } from './ProductSearchResultPreviewList/ProductSearchResultPreviewList';
export { default as RecommendList } from './RecommendList/RecommendList';
-export { default as RecipeSearchResultList } from './RecipeSearchResultList/RecipeSearchResultList';
+export { default as RecipeSearchResultPreviewList } from './RecipeSearchResultPreviewList/RecipeSearchResultPreviewList';
export { default as TagSearchResultList } from './TagSearchResultList/TagSearchResultList';
export { default as SearchInput } from './SearchInput/SearchInput';
diff --git a/src/pages/ProductDetailPage/ProductDetailPage.tsx b/src/pages/ProductDetailPage/ProductDetailPage.tsx
index 0367084c..889e1abd 100644
--- a/src/pages/ProductDetailPage/ProductDetailPage.tsx
+++ b/src/pages/ProductDetailPage/ProductDetailPage.tsx
@@ -66,7 +66,7 @@ export const ProductDetailPage = () => {
}>
-
+
diff --git a/src/pages/ProductSearchListPage/ProductSearchListPage.tsx b/src/pages/ProductSearchListPage/ProductSearchListPage.tsx
index 828710b0..fa9f1b8b 100644
--- a/src/pages/ProductSearchListPage/ProductSearchListPage.tsx
+++ b/src/pages/ProductSearchListPage/ProductSearchListPage.tsx
@@ -3,7 +3,7 @@ import { useSearchParams } from 'react-router-dom';
import { container } from './productSearchListPage.css';
-import { PageHeader } from '@/components/Common';
+import { TopBar } from '@/components/Common';
import { ProductOverviewList } from '@/components/Product';
import { useIntersectionObserver } from '@/hooks/common';
import { useInfiniteProductSearchResultsQuery } from '@/hooks/queries/search';
@@ -24,7 +24,11 @@ export const ProductSearchListPage = () => {
return (
<>
-
+
+
+
+
+
diff --git a/src/components/Search/RecipeSearchResultList/RecipeSearchResultList.tsx b/src/pages/RecipeSearchListPage/RecipeSearchListPage.tsx
similarity index 50%
rename from src/components/Search/RecipeSearchResultList/RecipeSearchResultList.tsx
rename to src/pages/RecipeSearchListPage/RecipeSearchListPage.tsx
index bdc5134b..8c0b0e70 100644
--- a/src/components/Search/RecipeSearchResultList/RecipeSearchResultList.tsx
+++ b/src/pages/RecipeSearchListPage/RecipeSearchListPage.tsx
@@ -1,19 +1,18 @@
import { useRef } from 'react';
-import { Link } from 'react-router-dom';
-import { styled } from 'styled-components';
+import { useSearchParams } from 'react-router-dom';
-import SearchNotFound from '../SearchNotFound/SearchNotFound';
+import { listWrapper } from './recipeSearchListPage.css';
-import { RecipeItem } from '@/components/Recipe';
-import { PATH } from '@/constants/path';
+import { TopBar } from '@/components/Common';
+import { DefaultRecipeItem } from '@/components/Recipe';
+import SearchNotFound from '@/components/Search/SearchNotFound/SearchNotFound';
import { useIntersectionObserver } from '@/hooks/common';
import { useInfiniteRecipeSearchResultsQuery } from '@/hooks/queries/search';
-interface RecipeSearchResultListProps {
- searchQuery: string;
-}
+export const RecipeSearchListPage = () => {
+ const [searchParams, setSearchParams] = useSearchParams();
+ const searchQuery = searchParams.get('query') || '';
-const RecipeSearchResultList = ({ searchQuery }: RecipeSearchResultListProps) => {
const { data: searchResponse, fetchNextPage, hasNextPage } = useInfiniteRecipeSearchResultsQuery(searchQuery);
const scrollRef = useRef(null);
useIntersectionObserver(fetchNextPage, scrollRef, hasNextPage);
@@ -26,24 +25,19 @@ const RecipeSearchResultList = ({ searchQuery }: RecipeSearchResultListProps) =>
return (
<>
-
+
+
+
+
+
+
{recipes.map((recipe) => (
-
-
-
-
+
))}
-
+
>
);
};
-
-export default RecipeSearchResultList;
-
-const RecipeSearchResultListContainer = styled.ul`
- & > li + li {
- margin-top: 40px;
- }
-`;
diff --git a/src/pages/RecipeSearchListPage/recipeSearchListPage.css.ts b/src/pages/RecipeSearchListPage/recipeSearchListPage.css.ts
new file mode 100644
index 00000000..5b47dfb5
--- /dev/null
+++ b/src/pages/RecipeSearchListPage/recipeSearchListPage.css.ts
@@ -0,0 +1,8 @@
+import { style } from '@vanilla-extract/css';
+
+export const listWrapper = style({
+ display: 'grid',
+ gridTemplateColumns: '1fr 1fr',
+ gap: '16px 10px',
+ padding: '0 20px',
+});
diff --git a/src/pages/SearchPage/SearchPage.tsx b/src/pages/SearchPage/SearchPage.tsx
index 9f8562f7..d3b3a001 100644
--- a/src/pages/SearchPage/SearchPage.tsx
+++ b/src/pages/SearchPage/SearchPage.tsx
@@ -6,7 +6,7 @@ import { badgeContainer, searchWrapper, searchResultTitle, searchSection, subTit
import { Text, Badge, ErrorBoundary, ErrorComponent, Loading, PageHeader } from '@/components/Common';
import {
ProductSearchResultPreviewList,
- RecipeSearchResultList,
+ RecipeSearchResultPreviewList,
RecommendList,
SearchInput,
} from '@/components/Search';
@@ -87,7 +87,7 @@ export const SearchPage = () => {
}>
-
+
diff --git a/src/router/index.tsx b/src/router/index.tsx
index 8f0e1be1..843fabb2 100644
--- a/src/router/index.tsx
+++ b/src/router/index.tsx
@@ -213,6 +213,15 @@ const router = createBrowserRouter([
return { Component: ProductSearchListPage };
},
},
+ {
+ path: `${PATH.SEARCH}/recipes`,
+ async lazy() {
+ const { RecipeSearchListPage } = await import(
+ /* webpackChunkName: "RecipeSearchListPage" */ '@/pages/RecipeSearchListPage/RecipeSearchListPage'
+ );
+ return { Component: RecipeSearchListPage };
+ },
+ },
],
},
]);