diff --git a/src/components/Members/MemberRecipeList/MemberRecipeList.tsx b/src/components/Members/MemberRecipeList/MemberRecipeList.tsx
index 740daddff..445dd9e33 100644
--- a/src/components/Members/MemberRecipeList/MemberRecipeList.tsx
+++ b/src/components/Members/MemberRecipeList/MemberRecipeList.tsx
@@ -3,7 +3,6 @@ import { useRef } from 'react';
import { Link as RouterLink } from 'react-router-dom';
import styled from 'styled-components';
-import { RecipeItem } from '@/components/Recipe';
import { PATH } from '@/constants/path';
import { useIntersectionObserver } from '@/hooks/common';
import { useInfiniteMemberRecipeQuery } from '@/hooks/queries/members';
@@ -50,7 +49,7 @@ const MemberRecipeList = ({ isPreview = false }: MemberRecipeListProps) => {
{recipeToDisplay?.map((recipe) => (
-
+ {/* */}
))}
diff --git a/src/components/Product/ProductRecipeList/ProductRecipeList.tsx b/src/components/Product/ProductRecipeList/ProductRecipeList.tsx
index 6a943c664..8c5f0f241 100644
--- a/src/components/Product/ProductRecipeList/ProductRecipeList.tsx
+++ b/src/components/Product/ProductRecipeList/ProductRecipeList.tsx
@@ -3,7 +3,7 @@ import { Link } from 'react-router-dom';
import { container, moreIcon, moreIconWrapper, moreItem, moreLink } from './productRecipeList.css';
import { SvgIcon, Text } from '@/components/Common';
-import { RecipeItem } from '@/components/Recipe';
+import { DefaultRecipeItem } from '@/components/Recipe';
import { useInfiniteProductRecipesQuery } from '@/hooks/queries/product';
import { vars } from '@/styles/theme.css';
import displaySlice from '@/utils/displaySlice';
@@ -27,7 +27,7 @@ const ProductRecipeList = ({ productId }: ProductRecipeListProps) => {
{recipeToDisplay.map((recipe) => (
-
-
+
))}
{recipeToDisplay.length < recipes.length && (
diff --git a/src/components/Rank/RecipeRankingItem/RecipeRankingItem.stories.tsx b/src/components/Rank/RecipeRankingItem/RecipeRankingItem.stories.tsx
deleted file mode 100644
index 5651b94c2..000000000
--- a/src/components/Rank/RecipeRankingItem/RecipeRankingItem.stories.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react';
-
-import RecipeRankingItem from './RecipeRankingItem';
-
-import mockRecipeRankingList from '@/mocks/data/recipeRankingList.json';
-
-const meta: Meta = {
- title: 'recipe/RecipeRankingItem',
- component: RecipeRankingItem,
- args: {
- recipe: mockRecipeRankingList.recipes[0],
- },
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Default: Story = {};
diff --git a/src/components/Rank/RecipeRankingItem/RecipeRankingItem.tsx b/src/components/Rank/RecipeRankingItem/RecipeRankingItem.tsx
deleted file mode 100644
index 5b3569473..000000000
--- a/src/components/Rank/RecipeRankingItem/RecipeRankingItem.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import { buttonWrapper, imageWrapper, recipeImage, recipeTitle, info } from './recipeRankingItem.css';
-
-import { RecipeFavoriteButton } from '@/components/Recipe';
-import { RECIPE_CARD_DEFAULT_IMAGE_URL } from '@/constants/image';
-import type { RecipeRanking } from '@/types/ranking';
-import { getRelativeDate } from '@/utils/date';
-
-interface RecipeRankingItemProps {
- recipe: RecipeRanking;
-}
-
-const RecipeRankingItem = ({ recipe }: RecipeRankingItemProps) => {
- const { id, image, title, author, favorite, createdAt } = recipe;
-
- return (
- <>
-
-
-
e.preventDefault()}>
-
-
-
-
- {title}
-
-
- {author} 님 · {getRelativeDate(createdAt)}
-
- >
- );
-};
-
-export default RecipeRankingItem;
diff --git a/src/components/Rank/RecipeRankingItem/recipeRankingItem.css.ts b/src/components/Rank/RecipeRankingItem/recipeRankingItem.css.ts
deleted file mode 100644
index c29b7b202..000000000
--- a/src/components/Rank/RecipeRankingItem/recipeRankingItem.css.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { style } from '@vanilla-extract/css';
-
-export const imageWrapper = style({
- position: 'relative',
-});
-
-export const recipeImage = style({
- width: '100%',
- height: 'auto',
- minWidth: 163,
- borderRadius: '6px',
- objectFit: 'cover',
- aspectRatio: '1 / 1',
-});
-
-export const buttonWrapper = style({
- position: 'absolute',
- top: 8,
- right: 8,
-});
-
-export const recipeTitle = style({
- fontSize: 14,
- fontWeight: 600,
- color: '#232527',
-});
-
-export const info = style({
- fontSize: 12,
- color: '#808080',
-});
diff --git a/src/components/Rank/RecipeRankingList/RecipeRankingList.tsx b/src/components/Rank/RecipeRankingList/RecipeRankingList.tsx
index 038bdcf61..f2560075e 100644
--- a/src/components/Rank/RecipeRankingList/RecipeRankingList.tsx
+++ b/src/components/Rank/RecipeRankingList/RecipeRankingList.tsx
@@ -1,8 +1,8 @@
import { Link } from 'react-router-dom';
import { container } from './recipeRankingList.css';
-import RecipeRankingItem from '../RecipeRankingItem/RecipeRankingItem';
+import { DefaultRecipeItem } from '@/components/Recipe';
import { PATH } from '@/constants/path';
import { useGA } from '@/hooks/common';
import { useRecipeRankingQuery } from '@/hooks/queries/rank';
@@ -22,7 +22,7 @@ const RecipeRankingList = () => {
{recipeResponse.recipes.map((recipe) => (
-
-
+
))}
diff --git a/src/components/Rank/index.ts b/src/components/Rank/index.ts
index ac811ad50..341b6b1f9 100644
--- a/src/components/Rank/index.ts
+++ b/src/components/Rank/index.ts
@@ -2,5 +2,4 @@ export { default as ReviewRankingItem } from './ReviewRankingItem/ReviewRankingI
export { default as ReviewRankingList } from './ReviewRankingList/ReviewRankingList';
export { default as ProductRankingItem } from './ProductRankingItem/ProductRankingItem';
export { default as ProductRankingList } from './ProductRankingList/ProductRankingList';
-export { default as RecipeRankingItem } from './RecipeRankingItem/RecipeRankingItem';
export { default as RecipeRankingList } from './RecipeRankingList/RecipeRankingList';
diff --git a/src/components/Recipe/RecipeFavoriteButton/recipeFavoriteButton.css.ts b/src/components/Recipe/RecipeFavoriteButton/recipeFavoriteButton.css.ts
index 72d7e5fe7..02ed8b060 100644
--- a/src/components/Recipe/RecipeFavoriteButton/recipeFavoriteButton.css.ts
+++ b/src/components/Recipe/RecipeFavoriteButton/recipeFavoriteButton.css.ts
@@ -2,6 +2,5 @@ import { style } from '@vanilla-extract/css';
export const container = style({
display: 'flex',
- gap: 6,
alignItems: 'center',
});
diff --git a/src/components/Recipe/RecipeItem/RecipeItem.stories.tsx b/src/components/Recipe/RecipeItem/RecipeItem.stories.tsx
index 351a3a0d5..05e67bdec 100644
--- a/src/components/Recipe/RecipeItem/RecipeItem.stories.tsx
+++ b/src/components/Recipe/RecipeItem/RecipeItem.stories.tsx
@@ -1,18 +1,42 @@
import type { Meta, StoryObj } from '@storybook/react';
-import RecipeItem from './RecipeItem';
+import RecipeItem, {
+ DefaultRecipeItem,
+ RecipeItemWithDiskIcon,
+ RecipeItemWithDiskIconAndContent,
+ RecipeItemWithProductDetailImage,
+} from './RecipeItem';
import mockRecipe from '@/mocks/data/recipes.json';
const meta: Meta = {
title: 'recipe/RecipeItem',
component: RecipeItem,
- args: {
- recipe: mockRecipe.recipes[0],
- },
};
export default meta;
type Story = StoryObj;
-export const Default: Story = {};
+export const Default: Story = {
+ render: () => {
+ return ;
+ },
+};
+
+export const Recipe: Story = {
+ render: () => {
+ return ;
+ },
+};
+
+export const MyPage: Story = {
+ render: () => {
+ return ;
+ },
+};
+
+export const Search: Story = {
+ render: () => {
+ return ;
+ },
+};
diff --git a/src/components/Recipe/RecipeItem/RecipeItem.tsx b/src/components/Recipe/RecipeItem/RecipeItem.tsx
index 56481bee8..e94712db3 100644
--- a/src/components/Recipe/RecipeItem/RecipeItem.tsx
+++ b/src/components/Recipe/RecipeItem/RecipeItem.tsx
@@ -1,75 +1,236 @@
import { Skeleton } from '@fun-eat/design-system';
-import { memo, useState } from 'react';
+import type { PropsWithChildren } from 'react';
+import { useState } from 'react';
import { Link } from 'react-router-dom';
import {
+ ellipsis,
favoriteButtonWrapper,
imageWrapper,
productButtonWrapper,
- recipeAuthor,
- recipeContent,
+ productCircleListWrapper,
+ productCircleWrapper,
+ productImage,
recipeImage,
- recipeTitle,
+ recipeProductsCount,
+ thirdProductImage,
} from './recipeItem.css';
import RecipeFavoriteButton from '../RecipeFavoriteButton/RecipeFavoriteButton';
import RecipeProductButton from '../RecipeProductButton/RecipeProductButton';
-import { RECIPE_CARD_DEFAULT_IMAGE_URL } from '@/constants/image';
-import { PATH } from '@/constants/path';
-import type { MemberRecipe, Recipe } from '@/types/recipe';
+import { Text } from '@/components/Common';
+import {
+ RECIPE_CARD_DEFAULT_IMAGE_URL_1,
+ RECIPE_CARD_DEFAULT_IMAGE_URL_2,
+ RECIPE_CARD_DEFAULT_IMAGE_URL_3,
+ RECIPE_CARD_DEFAULT_IMAGE_URL_4,
+ RECIPE_CARD_DEFAULT_IMAGE_URL_5,
+} from '@/constants/image';
+import RecipeItemProvider from '@/contexts/RecipeItemContext';
+import { useRecipeItemValueContext } from '@/hooks/context';
+import type { Recipe } from '@/types/recipe';
+import { getRelativeDate } from '@/utils/date';
+import displaySlice from '@/utils/displaySlice';
+
+const defaultImages = [
+ RECIPE_CARD_DEFAULT_IMAGE_URL_1,
+ RECIPE_CARD_DEFAULT_IMAGE_URL_2,
+ RECIPE_CARD_DEFAULT_IMAGE_URL_3,
+ RECIPE_CARD_DEFAULT_IMAGE_URL_4,
+ RECIPE_CARD_DEFAULT_IMAGE_URL_5,
+];
interface RecipeItemProps {
- recipe: Recipe | MemberRecipe;
- isMemberPage?: boolean;
- hasFavoriteButton?: boolean;
- hasProductButton?: boolean;
- hasContent?: boolean;
+ recipe: Recipe;
+ children?: React.ReactNode;
}
-const RecipeItem = ({
- recipe,
- isMemberPage = false,
- hasFavoriteButton = false,
- hasProductButton = false,
- hasContent = false,
-}: RecipeItemProps) => {
+const RecipeItem = ({ recipe, children }: RecipeItemProps) => {
+ const { id } = recipe;
+
+ return (
+
+ {children}
+
+ );
+};
+
+const ImageAndFavoriteButton = ({ children }: PropsWithChildren) => {
+ const {
+ recipe: { id, image, title, favorite },
+ } = useRecipeItemValueContext();
const [isImageLoading, setIsImageLoading] = useState(true);
- const { id, image, title, content, favorite, products } = recipe;
- const author = 'author' in recipe ? recipe.author : null;
+ const randomIndex = Math.floor(Math.random() * defaultImages.length);
+ const defaultImage = defaultImages[randomIndex];
+
+ return (
+
+
image && setIsImageLoading(false)}
+ />
+ {isImageLoading && image &&
}
+
e.preventDefault()}>
+
+
+ {children}
+
+ );
+};
+
+const ProductButton = () => {
+ const {
+ recipe: { products },
+ } = useRecipeItemValueContext();
+
+ if (!products) {
+ return null;
+ }
return (
<>
-
- {!isMemberPage && (
-
-
image && setIsImageLoading(false)}
- />
- {isImageLoading && image &&
}
- {hasFavoriteButton && (
-
e.preventDefault()}>
-
-
- )}
- {hasProductButton && (
-
e.preventDefault()}>
-
-
- )}
-
- )}
-
- {title}
- {author && `${author.nickname} 님`}
- {hasContent && {content}
}
-
+ e.preventDefault()}>
+
+
>
);
};
-export default memo(RecipeItem);
+const ProductCircleButton = () => {
+ const {
+ recipe: { products },
+ } = useRecipeItemValueContext();
+
+ if (!products) {
+ return null;
+ }
+
+ return (
+
+ {displaySlice(true, products, 3).map(({ id, image }, idx) => (
+ -
+ 3 && idx === 2 ? thirdProductImage : productImage}
+ />
+ {idx === 2 && (
+
+ +{products.length - 3}
+
+ )}
+
+ ))}
+
+ );
+};
+
+const Title = () => {
+ const {
+ recipe: { title },
+ } = useRecipeItemValueContext();
+
+ return (
+
+ {title}
+
+ );
+};
+
+const Author = () => {
+ const {
+ recipe: { author },
+ } = useRecipeItemValueContext();
+
+ return {`${author.nickname} 님`};
+};
+
+const AuthorAndCreatedDate = () => {
+ const {
+ recipe: { author, createdAt },
+ } = useRecipeItemValueContext();
+
+ return (
+
+ {`${author.nickname} 님 · ${getRelativeDate(createdAt)}`}
+
+ );
+};
+
+const Content = () => {
+ const {
+ recipe: { content },
+ } = useRecipeItemValueContext();
+
+ return (
+
+ {content}
+
+ );
+};
+
+RecipeItem.ImageAndFavoriteButton = ImageAndFavoriteButton;
+RecipeItem.ProductButton = ProductButton;
+RecipeItem.ProductCircleButton = ProductCircleButton;
+RecipeItem.Title = Title;
+RecipeItem.Author = Author;
+RecipeItem.AuthorAndCreatedDate = AuthorAndCreatedDate;
+RecipeItem.Content = Content;
+
+export default RecipeItem;
+
+export const DefaultRecipeItem = ({ recipe }: RecipeItemProps) => {
+ return (
+
+
+
+
+
+
+ );
+};
+
+export const RecipeItemWithDiskIcon = ({ recipe }: RecipeItemProps) => {
+ return (
+
+
+
+
+
+
+
+
+ );
+};
+
+export const RecipeItemWithProductDetailImage = ({ recipe }: RecipeItemProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export const RecipeItemWithDiskIconAndContent = ({ recipe }: RecipeItemProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/components/Recipe/RecipeItem/recipeItem.css.ts b/src/components/Recipe/RecipeItem/recipeItem.css.ts
index 2922fec9f..75d9c8f94 100644
--- a/src/components/Recipe/RecipeItem/recipeItem.css.ts
+++ b/src/components/Recipe/RecipeItem/recipeItem.css.ts
@@ -1,7 +1,9 @@
+import { vars } from '@/styles/theme.css';
import { style } from '@vanilla-extract/css';
export const imageWrapper = style({
position: 'relative',
+ lineHeight: 0,
});
export const recipeImage = style({
@@ -17,33 +19,53 @@ export const favoriteButtonWrapper = style({
position: 'absolute',
top: 8,
right: 8,
- zIndex: 100,
});
export const productButtonWrapper = style({
position: 'absolute',
bottom: 8,
left: 8,
- zIndex: 100,
});
-export const recipeTitle = style({
- color: '#232527',
- fontSize: 14,
- fontWeight: 600,
- whiteSpace: 'nowrap',
- overflow: 'hidden',
- textOverflow: 'ellipsis',
+export const productCircleWrapper = style({
+ position: 'absolute',
+ bottom: 10,
+ left: 10,
+ display: 'flex',
});
-export const recipeAuthor = style({
- color: '#3D3D3D',
- fontSize: 11,
+export const productCircleListWrapper = style({
+ position: 'relative',
+ width: '100%',
+ height: '40px',
+ marginRight: '-10px',
+ borderRadius: '50%',
+ border: `2px solid ${vars.colors.border.light}`,
+ boxSizing: 'content-box',
+});
+
+export const productImage = style({
+ width: '40px',
+ height: '40px',
+ borderRadius: '50%',
+});
+
+export const thirdProductImage = style({
+ width: '40px',
+ height: '40px',
+ borderRadius: '50%',
+ filter: 'brightness(50%)',
+});
+
+export const recipeProductsCount = style({
+ position: 'absolute',
+ top: '50%',
+ left: '50%',
+ transform: 'translate( -50%, -50% )',
+ color: vars.colors.white,
});
-export const recipeContent = style({
- color: '#808080',
- fontSize: 11,
+export const ellipsis = style({
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
diff --git a/src/components/Recipe/RecipeList/RecipeList.tsx b/src/components/Recipe/RecipeList/RecipeList.tsx
index 03ca65a42..59a249c30 100644
--- a/src/components/Recipe/RecipeList/RecipeList.tsx
+++ b/src/components/Recipe/RecipeList/RecipeList.tsx
@@ -1,7 +1,7 @@
import { useRef } from 'react';
import { container } from './recipeList.css';
-import RecipeItem from '../RecipeItem/RecipeItem';
+import { RecipeItemWithDiskIconAndContent } from '../RecipeItem/RecipeItem';
import { useIntersectionObserver } from '@/hooks/common';
import { useInfiniteRecipesQuery } from '@/hooks/queries/recipe';
@@ -27,7 +27,7 @@ const RecipeList = ({ selectedOption }: RecipeListProps) => {
{recipes.map((recipe) => (
-
-
+
))}
diff --git a/src/components/Recipe/index.ts b/src/components/Recipe/index.ts
index 168646a41..0d99c3ec9 100644
--- a/src/components/Recipe/index.ts
+++ b/src/components/Recipe/index.ts
@@ -9,3 +9,8 @@ export { default as CommentItem } from './CommentItem/CommentItem';
export { default as CommentForm } from './CommentForm/CommentForm';
export { default as CommentList } from './CommentList/CommentList';
export { default as RecipeProductButton } from './RecipeProductButton/RecipeProductButton';
+
+export { DefaultRecipeItem } from './RecipeItem/RecipeItem';
+export { RecipeItemWithDiskIcon } from './RecipeItem/RecipeItem';
+export { RecipeItemWithProductDetailImage } from './RecipeItem/RecipeItem';
+export { RecipeItemWithDiskIconAndContent } from './RecipeItem/RecipeItem';
diff --git a/src/constants/image.ts b/src/constants/image.ts
index ce86c786c..864e1ad9b 100644
--- a/src/constants/image.ts
+++ b/src/constants/image.ts
@@ -1,5 +1,10 @@
const IMAGE_BASE_URL = 'https://image.funeat.site/prod/';
export const REVIEW_CARD_DEFAULT_IMAGE_URL = `${IMAGE_BASE_URL}review-card-default.png`;
-export const RECIPE_CARD_DEFAULT_IMAGE_URL = `${IMAGE_BASE_URL}recipe-card-default.png`;
export const RECIPE_RANK_DEFAULT_IMAGE_URL = `${IMAGE_BASE_URL}recipe-rank-default.png`;
+
+export const RECIPE_CARD_DEFAULT_IMAGE_URL_1 = `${IMAGE_BASE_URL}recipe-card-default_1.png`;
+export const RECIPE_CARD_DEFAULT_IMAGE_URL_2 = `${IMAGE_BASE_URL}recipe-card-default_2.png`;
+export const RECIPE_CARD_DEFAULT_IMAGE_URL_3 = `${IMAGE_BASE_URL}recipe-card-default_3.png`;
+export const RECIPE_CARD_DEFAULT_IMAGE_URL_4 = `${IMAGE_BASE_URL}recipe-card-default_4.png`;
+export const RECIPE_CARD_DEFAULT_IMAGE_URL_5 = `${IMAGE_BASE_URL}recipe-card-default_5.png`;
diff --git a/src/contexts/RecipeItemContext.tsx b/src/contexts/RecipeItemContext.tsx
new file mode 100644
index 000000000..026234852
--- /dev/null
+++ b/src/contexts/RecipeItemContext.tsx
@@ -0,0 +1,21 @@
+import { createContext } from 'react';
+
+import type { Recipe } from '@/types/recipe';
+
+interface RecipeItemValue {
+ recipe: Recipe;
+ children?: React.ReactNode;
+}
+
+export const RecipeItemValueContext = createContext(null);
+
+const RecipeItemProvider = ({ children, recipe }: RecipeItemValue) => {
+ const recipeItemValue = {
+ recipe,
+ children,
+ };
+
+ return {children};
+};
+
+export default RecipeItemProvider;
diff --git a/src/hooks/context/index.ts b/src/hooks/context/index.ts
index 56470cfbb..8b138cb7d 100644
--- a/src/hooks/context/index.ts
+++ b/src/hooks/context/index.ts
@@ -4,3 +4,4 @@ export { default as useReviewFormActionContext } from './useReviewFormActionCont
export { default as useReviewFormValueContext } from './useReviewFormValueContext';
export { default as useRecipeFormActionContext } from './useRecipeFormActionContext';
export { default as useRecipeFormValueContext } from './useRecipeFormValueContext';
+export { default as useRecipeItemValueContext } from './useRecipeItemValueContext';
diff --git a/src/hooks/context/useRecipeItemValueContext.ts b/src/hooks/context/useRecipeItemValueContext.ts
new file mode 100644
index 000000000..aee1b2ce1
--- /dev/null
+++ b/src/hooks/context/useRecipeItemValueContext.ts
@@ -0,0 +1,14 @@
+import { useContext } from 'react';
+
+import { RecipeItemValueContext } from '@/contexts/RecipeItemContext';
+
+const useRecipeItemValueContext = () => {
+ const RecipeItemValue = useContext(RecipeItemValueContext);
+ if (RecipeItemValue === null || RecipeItemValue === undefined) {
+ throw new Error('useRecipeItemValueContext는 RecipeItem Provider 안에서 사용해야 합니다.');
+ }
+
+ return RecipeItemValue;
+};
+
+export default useRecipeItemValueContext;
diff --git a/src/mocks/data/recipeRankingList.json b/src/mocks/data/recipeRankingList.json
index 9950e4233..fef638dff 100644
--- a/src/mocks/data/recipeRankingList.json
+++ b/src/mocks/data/recipeRankingList.json
@@ -4,7 +4,10 @@
"id": 1,
"image": "https://image.funeat.site/prod/0e3ba79c-578b-42c5-b951-fb0f50ce57cdIMG_8613.webp",
"title": "초특급불닭콘치즈",
- "author": "funeat",
+ "author": {
+ "nickname": "1번 글",
+ "profileImage": "https://github.com/woowacourse-teams/2023-fun-eat/assets/78616893/991f7b69-53bf-4d03-96e1-988c34d010ed"
+ },
"favorite": false,
"createdAt": "2023-08-09T10:10:10"
},
@@ -12,7 +15,10 @@
"id": 2,
"image": "https://image.funeat.site/prod/1ff85060-4ce9-4c3f-9044-87cbb993716caaa.webp",
"title": "초특급불닭콘치즈",
- "author": "funeat",
+ "author": {
+ "nickname": "1번 글",
+ "profileImage": "https://github.com/woowacourse-teams/2023-fun-eat/assets/78616893/991f7b69-53bf-4d03-96e1-988c34d010ed"
+ },
"favorite": true,
"createdAt": "2023-08-09T10:10:10"
},
@@ -20,7 +26,10 @@
"id": 3,
"image": "https://image.funeat.site/prod/240a51fa-9fad-4199-807b-891ccfa59f8aIMG_6598.webp",
"title": "초특급불닭콘치즈",
- "author": "funeat",
+ "author": {
+ "nickname": "1번 글",
+ "profileImage": "https://github.com/woowacourse-teams/2023-fun-eat/assets/78616893/991f7b69-53bf-4d03-96e1-988c34d010ed"
+ },
"favorite": true,
"createdAt": "2023-08-09T10:10:10"
},
@@ -28,7 +37,10 @@
"id": 4,
"image": "https://image.funeat.site/prod/0e3ba79c-578b-42c5-b951-fb0f50ce57cdIMG_8613.webp",
"title": "초특급불닭콘치즈",
- "author": "funeat",
+ "author": {
+ "nickname": "1번 글",
+ "profileImage": "https://github.com/woowacourse-teams/2023-fun-eat/assets/78616893/991f7b69-53bf-4d03-96e1-988c34d010ed"
+ },
"favorite": false,
"createdAt": "2023-08-09T10:10:10"
}
diff --git a/src/mocks/data/recipes.json b/src/mocks/data/recipes.json
index 4260a3242..1d27d2422 100644
--- a/src/mocks/data/recipes.json
+++ b/src/mocks/data/recipes.json
@@ -34,6 +34,27 @@
"name": "콘치즈",
"price": 1500,
"averageRating": 4.0
+ },
+ {
+ "id": 3,
+ "image": "https://arqachylpmku8348141.cdn.ntruss.com/app/product/mst_product/8801056232979_L.jpg",
+ "name": "콘치즈",
+ "price": 1500,
+ "averageRating": 4.0
+ },
+ {
+ "id": 4,
+ "image": "https://arqachylpmku8348141.cdn.ntruss.com/app/product/mst_product/8801056232979_L.jpg",
+ "name": "콘치즈",
+ "price": 1500,
+ "averageRating": 4.0
+ },
+ {
+ "id": 5,
+ "image": "https://arqachylpmku8348141.cdn.ntruss.com/app/product/mst_product/8801056232979_L.jpg",
+ "name": "콘치즈",
+ "price": 1500,
+ "averageRating": 4.0
}
]
},
diff --git a/src/types/ranking.ts b/src/types/ranking.ts
index 6d0f3b1ff..44dab5540 100644
--- a/src/types/ranking.ts
+++ b/src/types/ranking.ts
@@ -12,12 +12,3 @@ export interface ReviewRanking {
categoryType: CategoryVariant;
tags: Tag[];
}
-
-export interface RecipeRanking {
- id: number;
- image: string | null;
- title: string;
- author: string;
- favorite: boolean;
- createdAt: string;
-}
diff --git a/src/types/recipe.ts b/src/types/recipe.ts
index f8f843af3..1e5179cdb 100644
--- a/src/types/recipe.ts
+++ b/src/types/recipe.ts
@@ -24,8 +24,8 @@ export interface Recipe {
author: Member;
createdAt: string;
favorite: boolean;
- content: string;
- products: RecipeProduct[];
+ content?: string;
+ products?: RecipeProduct[];
}
export type MemberRecipe = Recipe;
diff --git a/src/types/response.ts b/src/types/response.ts
index 14ce316a0..52b455deb 100644
--- a/src/types/response.ts
+++ b/src/types/response.ts
@@ -1,5 +1,5 @@
import type { Product } from './product';
-import type { ProductRanking, RecipeRanking, ReviewRanking } from './ranking';
+import type { ProductRanking, ReviewRanking } from './ranking';
import type { Comment, MemberRecipe, Recipe } from './recipe';
import type { MemberReview, Review } from './review';
import type { ProductSearchResult, ProductSearchAutocomplete } from './search';
@@ -61,5 +61,5 @@ export interface ProductRankingResponse {
}
export interface RecipeRankingResponse {
- recipes: RecipeRanking[];
+ recipes: Recipe[];
}