From c6b14f6f4d928c0d469721493ccf972d7f84d424 Mon Sep 17 00:00:00 2001 From: TaeeunKim Date: Fri, 15 Sep 2023 10:58:08 +0900 Subject: [PATCH 01/11] =?UTF-8?q?refactor:=20=EC=8A=A4=ED=81=AC=EB=A1=A4?= =?UTF-8?q?=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=EB=A5=BC=20=EC=97=98=EB=A6=AC?= =?UTF-8?q?=EB=A8=BC=ED=8A=B8=EC=97=90=20=EC=A0=91=EA=B7=BC=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EA=B3=A0=20ref=EB=A1=9C=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=ED=95=98=EA=B2=8C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/ScrollButton/ScrollButton.tsx | 9 +++++---- .../Product/ProductList/ProductList.tsx | 5 +++-- .../Recipe/RecipeList/RecipeList.tsx | 19 +++++++++++++------ frontend/src/hooks/common/useScroll.ts | 4 ++-- frontend/src/pages/HomePage.tsx | 7 +++---- frontend/src/pages/ProductListPage.tsx | 7 ++++--- frontend/src/pages/RecipePage.tsx | 8 +++++--- 7 files changed, 35 insertions(+), 24 deletions(-) diff --git a/frontend/src/components/Common/ScrollButton/ScrollButton.tsx b/frontend/src/components/Common/ScrollButton/ScrollButton.tsx index 09827b2b4..218f1799e 100644 --- a/frontend/src/components/Common/ScrollButton/ScrollButton.tsx +++ b/frontend/src/components/Common/ScrollButton/ScrollButton.tsx @@ -1,4 +1,5 @@ import { Button } from '@fun-eat/design-system'; +import type { RefObject } from 'react'; import { useState, useEffect } from 'react'; import { styled } from 'styled-components'; @@ -7,10 +8,11 @@ import SvgIcon from '../Svg/SvgIcon'; import { useScroll } from '@/hooks/common'; interface ScrollButtonProps { + targetRef?: RefObject; isRecipePage?: boolean; } -const ScrollButton = ({ isRecipePage = false }: ScrollButtonProps) => { +const ScrollButton = ({ targetRef, isRecipePage = false }: ScrollButtonProps) => { const { scrollToTop } = useScroll(); const [scrollTop, setScrollTop] = useState(false); @@ -19,9 +21,8 @@ const ScrollButton = ({ isRecipePage = false }: ScrollButtonProps) => { }; useEffect(() => { - const mainElement = document.getElementById('main'); - if (mainElement) { - scrollToTop(mainElement); + if (targetRef?.current) { + scrollToTop(targetRef.current); setScrollTop(false); } }, [scrollTop]); diff --git a/frontend/src/components/Product/ProductList/ProductList.tsx b/frontend/src/components/Product/ProductList/ProductList.tsx index 40b492f73..4e42cf9d0 100644 --- a/frontend/src/components/Product/ProductList/ProductList.tsx +++ b/frontend/src/components/Product/ProductList/ProductList.tsx @@ -1,4 +1,5 @@ import { Link } from '@fun-eat/design-system'; +import type { RefObject } from 'react'; import { useRef } from 'react'; import { Link as RouterLink } from 'react-router-dom'; import styled from 'styled-components'; @@ -13,14 +14,14 @@ import type { CategoryVariant, SortOption } from '@/types/common'; import displaySlice from '@/utils/displaySlice'; interface ProductListProps { + productListRef: RefObject; category: CategoryVariant; isHomePage?: boolean; selectedOption?: SortOption; } -const ProductList = ({ category, isHomePage, selectedOption }: ProductListProps) => { +const ProductList = ({ category, isHomePage, selectedOption, productListRef }: ProductListProps) => { const scrollRef = useRef(null); - const productListRef = useRef(null); const { categoryIds } = useCategoryValueContext(); diff --git a/frontend/src/components/Recipe/RecipeList/RecipeList.tsx b/frontend/src/components/Recipe/RecipeList/RecipeList.tsx index 35b3d4edf..24cfbd67e 100644 --- a/frontend/src/components/Recipe/RecipeList/RecipeList.tsx +++ b/frontend/src/components/Recipe/RecipeList/RecipeList.tsx @@ -1,4 +1,5 @@ import { Link, Text } from '@fun-eat/design-system'; +import type { RefObject } from 'react'; import { useRef } from 'react'; import { Link as RouterLink } from 'react-router-dom'; import styled from 'styled-components'; @@ -10,10 +11,11 @@ import { useInfiniteRecipesQuery } from '@/hooks/queries/recipe'; import type { SortOption } from '@/types/common'; interface RecipeListProps { + recipeRef: RefObject; selectedOption: SortOption; } -const RecipeList = ({ selectedOption }: RecipeListProps) => { +const RecipeList = ({ selectedOption, recipeRef }: RecipeListProps) => { const scrollRef = useRef(null); const { fetchNextPage, hasNextPage, data } = useInfiniteRecipesQuery(selectedOption.value); useIntersectionObserver(fetchNextPage, scrollRef, hasNextPage); @@ -25,8 +27,8 @@ const RecipeList = ({ selectedOption }: RecipeListProps) => { } return ( - <> - + + {recipes.map((recipe) => (
  • @@ -34,15 +36,20 @@ const RecipeList = ({ selectedOption }: RecipeListProps) => {
  • ))} -
    +
    - + ); }; export default RecipeList; -const RecipeListContainer = styled.ul` +const RecipeListContainer = styled.div` + height: calc(100% - 192px); + overflow-y: auto; +`; + +const RecipeListWrapper = styled.ul` & > li + li { margin-top: 40px; } diff --git a/frontend/src/hooks/common/useScroll.ts b/frontend/src/hooks/common/useScroll.ts index cfcd52a5e..0670ee1f0 100644 --- a/frontend/src/hooks/common/useScroll.ts +++ b/frontend/src/hooks/common/useScroll.ts @@ -1,8 +1,8 @@ import type { RefObject } from 'react'; const useScroll = () => { - const scrollToTop = (mainElement: HTMLElement) => { - mainElement.scrollTo(0, 0); + const scrollToTop = (targetElement: HTMLElement) => { + targetElement.scrollTo(0, 0); }; const scrollToPosition = (ref?: RefObject) => { diff --git a/frontend/src/pages/HomePage.tsx b/frontend/src/pages/HomePage.tsx index 9da58fc2f..51e248d00 100644 --- a/frontend/src/pages/HomePage.tsx +++ b/frontend/src/pages/HomePage.tsx @@ -4,8 +4,8 @@ import { Suspense } from 'react'; import { Link as RouterLink } from 'react-router-dom'; import styled from 'styled-components'; -import { CategoryMenu, SvgIcon, ScrollButton, Loading, ErrorBoundary, ErrorComponent } from '@/components/Common'; -import { PBProductList, ProductList } from '@/components/Product'; +import { CategoryMenu, SvgIcon, Loading, ErrorBoundary, ErrorComponent } from '@/components/Common'; +import { PBProductList } from '@/components/Product'; import { ProductRankingList, ReviewRankingList, RecipeRankingList } from '@/components/Rank'; import { PATH } from '@/constants/path'; import channelTalk from '@/service/channelTalk'; @@ -32,7 +32,7 @@ const HomePage = () => { }> - + {/* */} 전체 보기 @@ -91,7 +91,6 @@ const HomePage = () => { - ); }; diff --git a/frontend/src/pages/ProductListPage.tsx b/frontend/src/pages/ProductListPage.tsx index 5930a7958..0f63bf162 100644 --- a/frontend/src/pages/ProductListPage.tsx +++ b/frontend/src/pages/ProductListPage.tsx @@ -1,6 +1,6 @@ import { BottomSheet, Spacing, useBottomSheet } from '@fun-eat/design-system'; import { useQueryErrorResetBoundary } from '@tanstack/react-query'; -import { Suspense } from 'react'; +import { Suspense, useRef } from 'react'; import { useParams } from 'react-router-dom'; import styled from 'styled-components'; @@ -23,6 +23,7 @@ const PAGE_TITLE = { food: '공통 상품', store: 'PB 상품' }; const ProductListPage = () => { const { category } = useParams(); + const productListRef = useRef(null); const { ref, isClosing, handleOpenBottomSheet, handleCloseBottomSheet } = useBottomSheet(); const { selectedOption, selectSortOption } = useSortOption(PRODUCT_SORT_OPTIONS[0]); @@ -48,11 +49,11 @@ const ProductListPage = () => { - + - + { const { ref, isClosing, handleOpenBottomSheet, handleCloseBottomSheet } = useBottomSheet(); const { reset } = useQueryErrorResetBoundary(); + const recipeRef = useRef(null); + const handleOpenRegisterRecipeSheet = () => { setActiveSheet('registerRecipe'); handleOpenBottomSheet(); @@ -53,7 +55,7 @@ const RecipePage = () => { - + @@ -64,7 +66,7 @@ const RecipePage = () => { onClick={handleOpenRegisterRecipeSheet} /> - + {activeSheet === 'sortOption' ? ( Date: Fri, 15 Sep 2023 11:16:55 +0900 Subject: [PATCH 02/11] =?UTF-8?q?feat:=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EB=94=94=EC=9E=90=EC=9D=B8=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/Common/ScrollButton/ScrollButton.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/Common/ScrollButton/ScrollButton.tsx b/frontend/src/components/Common/ScrollButton/ScrollButton.tsx index 218f1799e..35bc3c1ed 100644 --- a/frontend/src/components/Common/ScrollButton/ScrollButton.tsx +++ b/frontend/src/components/Common/ScrollButton/ScrollButton.tsx @@ -33,10 +33,10 @@ const ScrollButton = ({ targetRef, isRecipePage = false }: ScrollButtonProps) => customWidth="45px" customHeight="45px" variant="filled" - color="gray5" + color="white" onClick={handleScroll} > - + ); }; @@ -48,6 +48,7 @@ const ScrollButtonWrapper = styled(Button)` bottom: ${({ isRecipePage }) => (isRecipePage ? '210px' : '90px')}; right: 20px; border-radius: 50%; + box-shadow: rgba(0, 0, 0, 0.2) 0px 1px 4px; @media screen and (min-width: 600px) { left: calc(50% + 234px); @@ -57,4 +58,8 @@ const ScrollButtonWrapper = styled(Button)` transform: scale(1.1); transition: all 200ms ease-in-out; } + + svg { + rotate: 90deg; + } `; From 34fe4f433fe726d227caca43dbff151c68f23ede Mon Sep 17 00:00:00 2001 From: TaeeunKim Date: Fri, 15 Sep 2023 11:31:05 +0900 Subject: [PATCH 03/11] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90=EB=8F=84=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/ScrollButton/ScrollButton.tsx | 2 +- frontend/src/pages/ProductDetailPage.tsx | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/Common/ScrollButton/ScrollButton.tsx b/frontend/src/components/Common/ScrollButton/ScrollButton.tsx index 35bc3c1ed..9c79b909b 100644 --- a/frontend/src/components/Common/ScrollButton/ScrollButton.tsx +++ b/frontend/src/components/Common/ScrollButton/ScrollButton.tsx @@ -8,7 +8,7 @@ import SvgIcon from '../Svg/SvgIcon'; import { useScroll } from '@/hooks/common'; interface ScrollButtonProps { - targetRef?: RefObject; + targetRef?: RefObject; isRecipePage?: boolean; } diff --git a/frontend/src/pages/ProductDetailPage.tsx b/frontend/src/pages/ProductDetailPage.tsx index acbcef743..dad7255e4 100644 --- a/frontend/src/pages/ProductDetailPage.tsx +++ b/frontend/src/pages/ProductDetailPage.tsx @@ -48,6 +48,8 @@ const ProductDetailPage = () => { const [activeSheet, setActiveSheet] = useState<'registerReview' | 'sortOption'>('sortOption'); + const productDetailPageRef = useRef(null); + if (!category) { return null; } @@ -74,7 +76,7 @@ const ProductDetailPage = () => { }; return ( - <> + @@ -122,7 +124,7 @@ const ProductDetailPage = () => { onClick={handleOpenRegisterReviewSheet} /> - + {activeSheet === 'registerReview' ? ( @@ -142,12 +144,21 @@ const ProductDetailPage = () => { /> )} - + ); }; export default ProductDetailPage; +const ProductDetailPageContainer = styled.div` + height: 100%; + overflow-y: auto; + + &::-webkit-scrollbar { + display: none; + } +`; + const SortButtonWrapper = styled.div` display: flex; justify-content: flex-end; From 218032e912d24f31c6b1c09123966c311c14ca91 Mon Sep 17 00:00:00 2001 From: TaeeunKim Date: Fri, 15 Sep 2023 11:37:35 +0900 Subject: [PATCH 04/11] =?UTF-8?q?refactor:=20hook=EC=9D=B4=20=EC=B5=9C?= =?UTF-8?q?=EC=83=81=EB=8B=A8=EC=97=90=20=EC=9E=88=EA=B2=8C=EB=81=94=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 --- frontend/src/pages/ProductDetailPage.tsx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/frontend/src/pages/ProductDetailPage.tsx b/frontend/src/pages/ProductDetailPage.tsx index dad7255e4..11f668dd2 100644 --- a/frontend/src/pages/ProductDetailPage.tsx +++ b/frontend/src/pages/ProductDetailPage.tsx @@ -36,20 +36,19 @@ const ProductDetailPage = () => { const { data: productDetail } = useProductDetailQuery(Number(productId)); const { reset } = useQueryErrorResetBoundary(); - const tabMenus = [`리뷰 ${productDetail.reviewCount}`, '꿀조합']; const { selectedTabMenu, isFirstTabMenu: isReviewTab, handleTabMenuClick, initTabMenu } = useTabMenu(); const tabRef = useRef(null); - const sortOptions = isReviewTab ? REVIEW_SORT_OPTIONS : RECIPE_SORT_OPTIONS; - const initialSortOption = isReviewTab ? REVIEW_SORT_OPTIONS[0] : RECIPE_SORT_OPTIONS[0]; - - const { selectedOption, selectSortOption } = useSortOption(initialSortOption); + const { selectedOption, selectSortOption } = useSortOption(REVIEW_SORT_OPTIONS[0]); const { ref, isClosing, handleOpenBottomSheet, handleCloseBottomSheet } = useBottomSheet(); - const [activeSheet, setActiveSheet] = useState<'registerReview' | 'sortOption'>('sortOption'); const productDetailPageRef = useRef(null); + const tabMenus = [`리뷰 ${productDetail.reviewCount}`, '꿀조합']; + const sortOptions = isReviewTab ? REVIEW_SORT_OPTIONS : RECIPE_SORT_OPTIONS; + const currentSortOption = isReviewTab ? REVIEW_SORT_OPTIONS[0] : RECIPE_SORT_OPTIONS[0]; + if (!category) { return null; } @@ -66,7 +65,7 @@ const ProductDetailPage = () => { const handleTabMenuSelect = (index: number) => { handleTabMenuClick(index); - selectSortOption(initialSortOption); + selectSortOption(currentSortOption); ReactGA.event({ category: '버튼', From 377a99324e55b490d7486069e224580d72cb3349 Mon Sep 17 00:00:00 2001 From: TaeeunKim Date: Fri, 15 Sep 2023 14:34:57 +0900 Subject: [PATCH 05/11] =?UTF-8?q?feat:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EC=97=90=EC=84=9C=EB=8F=84=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A1=A4=20=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/MemberRecipePage.tsx | 15 +++++++++++---- frontend/src/pages/MemberReviewPage.tsx | 15 +++++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/frontend/src/pages/MemberRecipePage.tsx b/frontend/src/pages/MemberRecipePage.tsx index 1b7d1eaa3..c4dafb772 100644 --- a/frontend/src/pages/MemberRecipePage.tsx +++ b/frontend/src/pages/MemberRecipePage.tsx @@ -1,15 +1,17 @@ import { Spacing } from '@fun-eat/design-system'; import { useQueryErrorResetBoundary } from '@tanstack/react-query'; -import { Suspense } from 'react'; +import { Suspense, useRef } from 'react'; +import styled from 'styled-components'; import { ErrorBoundary, ErrorComponent, Loading, ScrollButton, SectionTitle } from '@/components/Common'; import { MemberRecipeList } from '@/components/Members'; const MemberRecipePage = () => { const { reset } = useQueryErrorResetBoundary(); + const memberRecipeRef = useRef(null); return ( - <> + @@ -17,9 +19,14 @@ const MemberRecipePage = () => { - - + + ); }; export default MemberRecipePage; + +const MebmberRecipePageContainer = styled.div` + height: 100%; + overflow-y: auto; +`; diff --git a/frontend/src/pages/MemberReviewPage.tsx b/frontend/src/pages/MemberReviewPage.tsx index fe8584078..aa4473679 100644 --- a/frontend/src/pages/MemberReviewPage.tsx +++ b/frontend/src/pages/MemberReviewPage.tsx @@ -1,15 +1,17 @@ import { Spacing } from '@fun-eat/design-system'; import { useQueryErrorResetBoundary } from '@tanstack/react-query'; -import { Suspense } from 'react'; +import { Suspense, useRef } from 'react'; +import styled from 'styled-components'; import { ErrorBoundary, ErrorComponent, Loading, ScrollButton, SectionTitle } from '@/components/Common'; import { MemberReviewList } from '@/components/Members'; const MemberReviewPage = () => { const { reset } = useQueryErrorResetBoundary(); + const memberReviewRef = useRef(null); return ( - <> + @@ -17,9 +19,14 @@ const MemberReviewPage = () => { - - + + ); }; export default MemberReviewPage; + +const MebmberReviewPageContainer = styled.div` + height: 100%; + overflow-y: auto; +`; From a9a5bcf9d427b28c1c15cb6eaefa54fd050eb51e Mon Sep 17 00:00:00 2001 From: TaeeunKim Date: Fri, 15 Sep 2023 14:44:29 +0900 Subject: [PATCH 06/11] =?UTF-8?q?refactor:=20scrollTop=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=EA=B0=80=20ref=EB=A5=BC=20=EB=B0=9B=EB=8F=84=EB=A1=9D?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/Common/ScrollButton/ScrollButton.tsx | 8 ++++---- frontend/src/hooks/common/useScroll.ts | 12 ++++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/Common/ScrollButton/ScrollButton.tsx b/frontend/src/components/Common/ScrollButton/ScrollButton.tsx index 9c79b909b..5b3a19269 100644 --- a/frontend/src/components/Common/ScrollButton/ScrollButton.tsx +++ b/frontend/src/components/Common/ScrollButton/ScrollButton.tsx @@ -8,7 +8,7 @@ import SvgIcon from '../Svg/SvgIcon'; import { useScroll } from '@/hooks/common'; interface ScrollButtonProps { - targetRef?: RefObject; + targetRef: RefObject; isRecipePage?: boolean; } @@ -21,8 +21,8 @@ const ScrollButton = ({ targetRef, isRecipePage = false }: ScrollButtonProps) => }; useEffect(() => { - if (targetRef?.current) { - scrollToTop(targetRef.current); + if (targetRef) { + scrollToTop(targetRef); setScrollTop(false); } }, [scrollTop]); @@ -43,7 +43,7 @@ const ScrollButton = ({ targetRef, isRecipePage = false }: ScrollButtonProps) => export default ScrollButton; -const ScrollButtonWrapper = styled(Button)` +const ScrollButtonWrapper = styled(Button)>` position: fixed; bottom: ${({ isRecipePage }) => (isRecipePage ? '210px' : '90px')}; right: 20px; diff --git a/frontend/src/hooks/common/useScroll.ts b/frontend/src/hooks/common/useScroll.ts index 0670ee1f0..40777ad8d 100644 --- a/frontend/src/hooks/common/useScroll.ts +++ b/frontend/src/hooks/common/useScroll.ts @@ -1,13 +1,17 @@ import type { RefObject } from 'react'; const useScroll = () => { - const scrollToTop = (targetElement: HTMLElement) => { - targetElement.scrollTo(0, 0); + const scrollToTop = (ref: RefObject) => { + if (!ref.current) { + return; + } + + ref.current?.scrollTo(0, 0); }; - const scrollToPosition = (ref?: RefObject) => { + const scrollToPosition = (ref: RefObject) => { setTimeout(() => { - ref?.current?.scrollIntoView({ behavior: 'smooth' }); + ref.current?.scrollIntoView({ behavior: 'smooth' }); }, 100); }; From 70da0059440987f9476d58473210f0c4e6d26b55 Mon Sep 17 00:00:00 2001 From: TaeeunKim Date: Fri, 15 Sep 2023 16:12:03 +0900 Subject: [PATCH 07/11] =?UTF-8?q?refactor:=20=EC=8A=A4=ED=81=AC=EB=A1=A4?= =?UTF-8?q?=20=EB=B2=84=ED=8A=BC=EC=97=90=EC=84=9C=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20useEffect=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/Common/ScrollButton/ScrollButton.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/frontend/src/components/Common/ScrollButton/ScrollButton.tsx b/frontend/src/components/Common/ScrollButton/ScrollButton.tsx index 5b3a19269..6bfcc5095 100644 --- a/frontend/src/components/Common/ScrollButton/ScrollButton.tsx +++ b/frontend/src/components/Common/ScrollButton/ScrollButton.tsx @@ -1,6 +1,5 @@ import { Button } from '@fun-eat/design-system'; import type { RefObject } from 'react'; -import { useState, useEffect } from 'react'; import { styled } from 'styled-components'; import SvgIcon from '../Svg/SvgIcon'; @@ -14,18 +13,12 @@ interface ScrollButtonProps { const ScrollButton = ({ targetRef, isRecipePage = false }: ScrollButtonProps) => { const { scrollToTop } = useScroll(); - const [scrollTop, setScrollTop] = useState(false); const handleScroll = () => { - setScrollTop(true); - }; - - useEffect(() => { if (targetRef) { scrollToTop(targetRef); - setScrollTop(false); } - }, [scrollTop]); + }; return ( Date: Fri, 15 Sep 2023 16:13:10 +0900 Subject: [PATCH 08/11] =?UTF-8?q?refactor:=20useScroll=20=ED=9B=85=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/common/useScroll.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/frontend/src/hooks/common/useScroll.ts b/frontend/src/hooks/common/useScroll.ts index 40777ad8d..6cc68c4c1 100644 --- a/frontend/src/hooks/common/useScroll.ts +++ b/frontend/src/hooks/common/useScroll.ts @@ -2,17 +2,18 @@ import type { RefObject } from 'react'; const useScroll = () => { const scrollToTop = (ref: RefObject) => { - if (!ref.current) { - return; + if (ref.current) { + ref.current.scrollTo(0, 0); } - - ref.current?.scrollTo(0, 0); }; const scrollToPosition = (ref: RefObject) => { - setTimeout(() => { - ref.current?.scrollIntoView({ behavior: 'smooth' }); - }, 100); + if (ref.current) { + const timeout = setTimeout(() => { + ref.current?.scrollIntoView({ behavior: 'smooth' }); + clearTimeout(timeout); + }, 100); + } }; return { scrollToTop, scrollToPosition }; From 9ed121293b98cbd025bd10484c717afa377a508f Mon Sep 17 00:00:00 2001 From: TaeeunKim Date: Fri, 15 Sep 2023 16:13:35 +0900 Subject: [PATCH 09/11] =?UTF-8?q?refactor:=20useScrollRestoration=20?= =?UTF-8?q?=ED=9B=85=EC=9D=84=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=ED=8E=98=EC=9D=B4=EC=A7=80=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Product/ProductList/ProductList.tsx | 25 +++++---------- frontend/src/contexts/CategoryContext.tsx | 2 +- frontend/src/pages/ProductListPage.tsx | 32 +++++++++++++------ 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/frontend/src/components/Product/ProductList/ProductList.tsx b/frontend/src/components/Product/ProductList/ProductList.tsx index a04bd3ef5..114405aab 100644 --- a/frontend/src/components/Product/ProductList/ProductList.tsx +++ b/frontend/src/components/Product/ProductList/ProductList.tsx @@ -1,5 +1,4 @@ import { Link } from '@fun-eat/design-system'; -import type { RefObject } from 'react'; import { useRef } from 'react'; import { Link as RouterLink } from 'react-router-dom'; import styled from 'styled-components'; @@ -7,20 +6,18 @@ import styled from 'styled-components'; import ProductItem from '../ProductItem/ProductItem'; import { PATH } from '@/constants/path'; -import { useIntersectionObserver, useScrollRestoration } from '@/hooks/common'; +import { useIntersectionObserver } from '@/hooks/common'; import { useCategoryValueContext } from '@/hooks/context'; import { useInfiniteProductsQuery } from '@/hooks/queries/product'; import type { CategoryVariant, SortOption } from '@/types/common'; interface ProductListProps { - productListRef: RefObject; category: CategoryVariant; selectedOption?: SortOption; } -const ProductList = ({ category, selectedOption, productListRef }: ProductListProps) => { +const ProductList = ({ category, selectedOption }: ProductListProps) => { const scrollRef = useRef(null); - const { categoryIds } = useCategoryValueContext(); const { fetchNextPage, hasNextPage, data } = useInfiniteProductsQuery( @@ -30,13 +27,11 @@ const ProductList = ({ category, selectedOption, productListRef }: ProductListPr useIntersectionObserver(fetchNextPage, scrollRef, hasNextPage); - useScrollRestoration(categoryIds[category], productListRef); - const productList = data.pages.flatMap((page) => page.products); return ( - - + <> + {productList.map((product) => (
  • @@ -44,19 +39,15 @@ const ProductList = ({ category, selectedOption, productListRef }: ProductListPr
  • ))} -
    +
    - + ); }; -export default ProductList; -const ProductListContainer = styled.div` - height: calc(100% - 150px); - overflow-y: auto; -`; +export default ProductList; -const ProductListWrapper = styled.ul` +const ProductListContainer = styled.ul` display: flex; flex-direction: column; diff --git a/frontend/src/contexts/CategoryContext.tsx b/frontend/src/contexts/CategoryContext.tsx index 46e008a97..e77029003 100644 --- a/frontend/src/contexts/CategoryContext.tsx +++ b/frontend/src/contexts/CategoryContext.tsx @@ -8,7 +8,7 @@ const initialState = { store: 7, }; -type CategoryIds = { +export type CategoryIds = { [k in CategoryVariant]: number; }; diff --git a/frontend/src/pages/ProductListPage.tsx b/frontend/src/pages/ProductListPage.tsx index fe0f91892..05c2de50e 100644 --- a/frontend/src/pages/ProductListPage.tsx +++ b/frontend/src/pages/ProductListPage.tsx @@ -16,7 +16,9 @@ import { import { ProductTitle, ProductList } from '@/components/Product'; import { PRODUCT_SORT_OPTIONS } from '@/constants'; import { PATH } from '@/constants/path'; -import { useSortOption } from '@/hooks/common'; +import type { CategoryIds } from '@/contexts/CategoryContext'; +import { useScrollRestoration, useSortOption } from '@/hooks/common'; +import { useCategoryValueContext } from '@/hooks/context'; import { isCategoryVariant } from '@/types/common'; const PAGE_TITLE = { food: '공통 상품', store: 'PB 상품' }; @@ -29,6 +31,10 @@ const ProductListPage = () => { const { selectedOption, selectSortOption } = useSortOption(PRODUCT_SORT_OPTIONS[0]); const { reset } = useQueryErrorResetBoundary(); + const { categoryIds } = useCategoryValueContext(); + + useScrollRestoration(categoryIds[category as keyof CategoryIds], productListRef); + if (!category || !isCategoryVariant(category)) { return null; } @@ -44,14 +50,16 @@ const ProductListPage = () => { - - }> - - - - - - + + + }> + + + + + + + @@ -65,6 +73,7 @@ const ProductListPage = () => { ); }; + export default ProductListPage; const ProductListSection = styled.section` @@ -76,3 +85,8 @@ const SortButtonWrapper = styled.div` justify-content: flex-end; margin-top: 20px; `; + +const ProductListContainer = styled.div` + height: calc(100% - 150px); + overflow-y: auto; +`; From e8441febb8f4122b5f92f4d72be7a1f493aba12c Mon Sep 17 00:00:00 2001 From: TaeeunKim Date: Fri, 15 Sep 2023 16:20:04 +0900 Subject: [PATCH 10/11] =?UTF-8?q?refactor:=20recipeRef=EB=A5=BC=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Recipe/RecipeList/RecipeList.tsx | 19 ++++++------------- frontend/src/pages/RecipePage.tsx | 9 ++++++++- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/frontend/src/components/Recipe/RecipeList/RecipeList.tsx b/frontend/src/components/Recipe/RecipeList/RecipeList.tsx index 24cfbd67e..35b3d4edf 100644 --- a/frontend/src/components/Recipe/RecipeList/RecipeList.tsx +++ b/frontend/src/components/Recipe/RecipeList/RecipeList.tsx @@ -1,5 +1,4 @@ import { Link, Text } from '@fun-eat/design-system'; -import type { RefObject } from 'react'; import { useRef } from 'react'; import { Link as RouterLink } from 'react-router-dom'; import styled from 'styled-components'; @@ -11,11 +10,10 @@ import { useInfiniteRecipesQuery } from '@/hooks/queries/recipe'; import type { SortOption } from '@/types/common'; interface RecipeListProps { - recipeRef: RefObject; selectedOption: SortOption; } -const RecipeList = ({ selectedOption, recipeRef }: RecipeListProps) => { +const RecipeList = ({ selectedOption }: RecipeListProps) => { const scrollRef = useRef(null); const { fetchNextPage, hasNextPage, data } = useInfiniteRecipesQuery(selectedOption.value); useIntersectionObserver(fetchNextPage, scrollRef, hasNextPage); @@ -27,8 +25,8 @@ const RecipeList = ({ selectedOption, recipeRef }: RecipeListProps) => { } return ( - - + <> + {recipes.map((recipe) => (
  • @@ -36,20 +34,15 @@ const RecipeList = ({ selectedOption, recipeRef }: RecipeListProps) => {
  • ))} -
    +
    - + ); }; export default RecipeList; -const RecipeListContainer = styled.div` - height: calc(100% - 192px); - overflow-y: auto; -`; - -const RecipeListWrapper = styled.ul` +const RecipeListContainer = styled.ul` & > li + li { margin-top: 40px; } diff --git a/frontend/src/pages/RecipePage.tsx b/frontend/src/pages/RecipePage.tsx index b296fbe17..52a7f0928 100644 --- a/frontend/src/pages/RecipePage.tsx +++ b/frontend/src/pages/RecipePage.tsx @@ -55,7 +55,9 @@ const RecipePage = () => { - + + + @@ -103,6 +105,11 @@ const SortButtonWrapper = styled.div` margin: 20px 0; `; +const RecipeListWrapper = styled.div` + height: calc(100% - 192px); + overflow-y: auto; +`; + const RecipeRegisterButtonWrapper = styled.div` position: fixed; left: 20px; From c409ee1b0ab92a66e0bd507b6d4297e27895984d Mon Sep 17 00:00:00 2001 From: TaeeunKim Date: Fri, 15 Sep 2023 16:22:01 +0900 Subject: [PATCH 11/11] =?UTF-8?q?fix:=20if=EB=AC=B8=20setTimeout=20?= =?UTF-8?q?=EC=95=88=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/common/useScroll.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/src/hooks/common/useScroll.ts b/frontend/src/hooks/common/useScroll.ts index 6cc68c4c1..b340dcf22 100644 --- a/frontend/src/hooks/common/useScroll.ts +++ b/frontend/src/hooks/common/useScroll.ts @@ -8,12 +8,12 @@ const useScroll = () => { }; const scrollToPosition = (ref: RefObject) => { - if (ref.current) { - const timeout = setTimeout(() => { - ref.current?.scrollIntoView({ behavior: 'smooth' }); + const timeout = setTimeout(() => { + if (ref.current) { + ref.current.scrollIntoView({ behavior: 'smooth' }); clearTimeout(timeout); - }, 100); - } + } + }, 100); }; return { scrollToTop, scrollToPosition };