From 5cddeb4646fc09c6734a2bd02e2a79e79a4684ad Mon Sep 17 00:00:00 2001 From: Dobbymin Date: Sat, 28 Sep 2024 21:09:04 +0900 Subject: [PATCH] =?UTF-8?q?Feat(challenge-list):=20=EC=B9=B4=ED=85=8C?= =?UTF-8?q?=EA=B3=A0=EB=A6=AC=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=B1=8C?= =?UTF-8?q?=EB=A6=B0=EC=A7=80=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EB=B3=B4?= =?UTF-8?q?=EA=B8=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/challenge-list/index.tsx | 116 +++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/pages/challenge-list/index.tsx diff --git a/src/pages/challenge-list/index.tsx b/src/pages/challenge-list/index.tsx new file mode 100644 index 0000000..5452826 --- /dev/null +++ b/src/pages/challenge-list/index.tsx @@ -0,0 +1,116 @@ +import { useCallback, useEffect, useState } from 'react'; + +import Contents from './components/contents'; +import { useGetChallengeList } from '@/apis/challenge-list/getChallengeList.api'; +import { Tab, Tabs } from '@/components/common/tabs'; +import { TabPanel } from '@/components/common/tabs/tap-panels'; +import TopBar from '@/components/features/layout/top-bar'; +import { Box, Spinner } from '@chakra-ui/react'; +import styled from '@emotion/styled'; + +type Challenge = { + id: number; + title: string; + content: string; + participantCount: number; + category: 'HEALTH' | 'ECHO' | 'SHARE' | 'VOLUNTEER' | 'ETC'; + startDate: string; + endDate: string; +}; + +const ChallengeList = () => { + const [activeTab, setActiveTab] = useState(0); + const [allData, setAllData] = useState([]); + const [page, setPage] = useState(0); + + const categoryList = [ + { label: '건강', data: 'HEALTH' }, + { label: '에코', data: 'ECHO' }, + { label: '나눔', data: 'SHARE' }, + { label: '봉사', data: 'VOLUNTEER' }, + ]; + + const { data, isLoading } = useGetChallengeList(page, 20); + + useEffect(() => { + if (data) { + setAllData((prevData) => [...prevData, ...data.data.data]); + } + }, [data]); + + const handleSelectedTab = (value: number) => { + setActiveTab(value); + sessionStorage.setItem('activeTab', String(value)); + }; + + const filteredData = allData.filter( + (item) => item.category === categoryList[activeTab].data + ); + + const loadNextPage = useCallback(() => { + if (data?.data.hasNext && !isLoading) { + setPage((prevPage) => prevPage + 1); + } + }, [data, isLoading]); + + useEffect(() => { + const handleScroll = () => { + if ( + window.innerHeight + document.documentElement.scrollTop !== + document.documentElement.offsetHeight + ) + return; + loadNextPage(); + }; + window.addEventListener('scroll', handleScroll); + return () => window.removeEventListener('scroll', handleScroll); + }, [loadNextPage]); + + return ( + <> + + + + {categoryList.map((category, index) => ( + + ))} + + + {categoryList.map((_, index) => ( + + <> + {filteredData.map((challenge) => ( + + ))} + + + ))} + + {isLoading && } + + + ); +}; + +export default ChallengeList; + +const ChallengeListLayout = styled.div` + display: block; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100%; + margin: 0 1.5rem; + padding-bottom: 6rem; +`; + +const TabPanelsLayout = styled(Box)` + margin: 1rem 0; +`;