diff --git a/src/constants/nav-bar/index.ts b/src/constants/nav-bar/index.ts index cf55564..84c8764 100644 --- a/src/constants/nav-bar/index.ts +++ b/src/constants/nav-bar/index.ts @@ -3,31 +3,32 @@ import DashboardIcon from '@/assets/nav-icon/DashBoard.svg'; import MainIcon from '@/assets/nav-icon/Home.svg'; import ChallengeIcon from '@/assets/nav-icon/My-Challenge.svg'; import RankIcon from '@/assets/nav-icon/Ranking.svg'; +import { RouterPath } from '@/routes/path'; export const navBarData = [ { title: 'challenge', icon: ChallengeIcon, - path: '/challenge', + path: `/${RouterPath.challenge}/${RouterPath.myChallenge}`, }, { title: 'shorts', icon: ShortsIcon, - path: '/shorts', + path: `/${RouterPath.shorts}`, }, { title: 'main', icon: MainIcon, - path: '/', + path: `${RouterPath.root}`, }, { title: 'rank', icon: RankIcon, - path: '/rank', + path: `/${RouterPath.rank}`, }, { title: 'dashboard', icon: DashboardIcon, - path: '/dashboard', + path: `/${RouterPath.dashboard}`, }, ]; diff --git a/src/pages/challenge-detail/index.tsx b/src/pages/challenge-detail/index.tsx index d3961ee..7f32080 100644 --- a/src/pages/challenge-detail/index.tsx +++ b/src/pages/challenge-detail/index.tsx @@ -22,7 +22,7 @@ const ChallengeDetailPage = () => { const [activeTab, setActiveTab] = useState(() => { // 세션 스토리지에 저장된 값 | 기본값 0 - const savedTab = sessionStorage.getItem('activeTab'); + const savedTab = sessionStorage.getItem('challengeDetailActiveTab'); return savedTab ? Number(savedTab) : 0; }); const [data, setData] = useState(undefined); @@ -38,13 +38,19 @@ const ChallengeDetailPage = () => { }, { label: '리뷰', - panel: data ? : null, + panel: data ? ( + + ) : null, }, ]; const handleSelectedTab = (value: number) => { setActiveTab(value); - sessionStorage.setItem('activeTab', String(value)); + sessionStorage.setItem('challengeDetailActiveTab', String(value)); }; useEffect(() => { @@ -60,13 +66,6 @@ const ChallengeDetailPage = () => { fetchChallengeDetail(); }, [challengeGroupId]); - // 챌린지 리뷰 페이지에 필요한 챌린지 제목 세션 스토리지에 저장 - useEffect(() => { - if (data?.title) { - sessionStorage.setItem('challengeGroupTitle', data.title); - } - }, [data?.title]); - return ( <> diff --git a/src/pages/challenge-detail/ranking-section/index.tsx b/src/pages/challenge-detail/ranking-section/index.tsx index 3451d16..f98adea 100644 --- a/src/pages/challenge-detail/ranking-section/index.tsx +++ b/src/pages/challenge-detail/ranking-section/index.tsx @@ -51,7 +51,7 @@ export const RankingSection = ({ id }: RankingSectionProps) => { }, [inView, hasNext, isFetching, id, page]); return ( - + {rankingList.length > 0 ? ( // 랭킹 있을 때 <> @@ -77,6 +77,6 @@ export const RankingSection = ({ id }: RankingSectionProps) => { )} {isFetching ? '로딩 중...' : ' '} - + ); }; diff --git a/src/pages/challenge-detail/ranking-section/styles.ts b/src/pages/challenge-detail/ranking-section/styles.ts index 18e486c..8f719bb 100644 --- a/src/pages/challenge-detail/ranking-section/styles.ts +++ b/src/pages/challenge-detail/ranking-section/styles.ts @@ -6,7 +6,7 @@ export const Text = styled.span<{ fontWeight?: string; color?: string }>` color: ${(props) => props.color || null}; `; -export const RankingWrapper = styled.div` +export const Wrapper = styled.div` padding: 16px 16px; display: flex; flex-direction: column; diff --git a/src/pages/challenge-detail/review-section/index.tsx b/src/pages/challenge-detail/review-section/index.tsx index 4edddf4..f1ca71d 100644 --- a/src/pages/challenge-detail/review-section/index.tsx +++ b/src/pages/challenge-detail/review-section/index.tsx @@ -7,14 +7,17 @@ import { getReview, getChallegeAvgScore } from '@/apis/review/review.api'; import { type ReviewData } from '@/apis/review/review.response'; import { StarRating } from '@/components/common/star-rating'; import ReviewItem from '@/pages/review/components/review-item'; +import { RouterPath } from '@/routes/path'; import * as Base from '@/styles/baseStyles'; import { formatToFixed, formatWithComma } from '@/utils/formatters'; -interface Props { +interface ReviewSectionProps { id: number; + category: string; + title: string; } -export const ReviewSection = ({ id }: Props) => { +export const ReviewSection = ({ id, category, title }: ReviewSectionProps) => { const DATA_SIZE = 5; // 가져올 리뷰 개수 const [reviewList, setReviewList] = useState([]); const [avgRating, setAvgRating] = useState(); @@ -63,7 +66,11 @@ export const ReviewSection = ({ id }: Props) => { {formattedAvgRating} {avgRating && } navigate(`/challenge/${id}/review`)} + onClick={() => + navigate( + `/${RouterPath.challenge}/review?id=${id}&category=${category}&title=${title}` + ) + } > {formattedTotalRatings}개 모두 보기{' '} diff --git a/src/pages/challenge-detail/review-section/styles.ts b/src/pages/challenge-detail/review-section/styles.ts index 5ee8279..26ac496 100644 --- a/src/pages/challenge-detail/review-section/styles.ts +++ b/src/pages/challenge-detail/review-section/styles.ts @@ -16,9 +16,9 @@ export const Text = styled.span<{ fontWeight?: string; color?: string }>` `; export const Wrapper = styled.div` + padding: 16px 16px; display: flex; flex-direction: column; - height: auto; `; export const RatingContainer = styled.div` diff --git a/src/pages/challenge-list/index.tsx b/src/pages/challenge-list/index.tsx index 8d0da1c..38027ed 100644 --- a/src/pages/challenge-list/index.tsx +++ b/src/pages/challenge-list/index.tsx @@ -20,7 +20,13 @@ type Challenge = { }; const ChallengeList = () => { - const [activeTab, setActiveTab] = useState(0); + sessionStorage.setItem('challengeDetailActiveTab', '0'); // 챌린지 디테일의 탭을 초기화 + + const [activeTab, setActiveTab] = useState(() => { + // 세션 스토리지에 저장된 값 | 기본값 0 + const savedTab = sessionStorage.getItem('challengeListActiveTab'); + return savedTab ? Number(savedTab) : 0; + }); const [allData, setAllData] = useState([]); const [page, setPage] = useState(0); @@ -48,6 +54,7 @@ const ChallengeList = () => { ); if (tabIndex !== -1) { setActiveTab(tabIndex); + // sessionStorage.setItem('challengeListActiveTab', String(tabIndex)); // 다른 페이지 갔다가 돌아올 때 } } }, [categoryList]); @@ -62,7 +69,7 @@ const ChallengeList = () => { const handleSelectedTab = (value: number) => { setActiveTab(value); - sessionStorage.setItem('activeTab', String(value)); + sessionStorage.setItem('challengeListActiveTab', String(value)); }; const filteredData = allData.filter( diff --git a/src/pages/challenge-record/index.tsx b/src/pages/challenge-record/index.tsx index 59bd32e..9643f4d 100644 --- a/src/pages/challenge-record/index.tsx +++ b/src/pages/challenge-record/index.tsx @@ -1,4 +1,5 @@ import { useState } from 'react'; +import { useSearchParams } from 'react-router-dom'; import Records from './records'; import Verification from './verification'; @@ -6,12 +7,16 @@ import ChallengeTitle from '@/components/common/challenge-title'; import { Tab, Tabs } from '@/components/common/tabs'; import { TabPanel, TabPanels } from '@/components/common/tabs/tab-panels'; import TopBar, { HEADER_HEIGHT } from '@/components/features/layout/top-bar'; +import { formatCategory } from '@/utils/formatters'; import styled from '@emotion/styled'; -const SAMPLE_CATEGORY = '에코'; -const SAMPLE_TITLE = '환경 정화 활동'; - const ChallengeRecord = () => { + // ?id=:id&category=:category&title=:title + const [searchParams] = useSearchParams(); + const challengeId = searchParams.get('id') || ''; + const challengeCategory = searchParams.get('category') || ''; + const challengeTitle = searchParams.get('title') || ''; + const [activeTab, setActiveTab] = useState(() => { // 세션 스토리지에 저장된 값 | 기본값 0 const savedTab = sessionStorage.getItem('activeTab'); @@ -20,11 +25,11 @@ const ChallengeRecord = () => { const tabsList = [ { label: '인증 기록', - panel: , + panel: , }, { label: '인증하기', - panel: , + panel: , }, ]; @@ -37,7 +42,10 @@ const ChallengeRecord = () => { <> - + {tabsList.map((t, index) => ( diff --git a/src/pages/challenge-record/records/index.tsx b/src/pages/challenge-record/records/index.tsx index 734f1f7..01ee353 100644 --- a/src/pages/challenge-record/records/index.tsx +++ b/src/pages/challenge-record/records/index.tsx @@ -1,6 +1,6 @@ import { useState, useEffect } from 'react'; -import { useParams } from 'react-router-dom'; +// import { useParams } from 'react-router-dom'; import Caution from '../components/caution'; import RecordItem from '../components/record-item'; import Stamp from '../components/stamp'; @@ -16,10 +16,9 @@ import { formatDate } from '@/utils/formatters'; import { Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; -const Records = () => { - const { id } = useParams(); - const challengeId = Number(id); +type RecordsProps = { challengeId: number }; +const Records = ({ challengeId }: RecordsProps) => { const [data, setData] = useState(); // api 응답 데이터 전체 const [recordIdList, setRecordIdList] = useState([]); const [recordDetails, setRecordDetails] = diff --git a/src/pages/challenge-record/verification/index.tsx b/src/pages/challenge-record/verification/index.tsx index 6710a8f..56bd084 100644 --- a/src/pages/challenge-record/verification/index.tsx +++ b/src/pages/challenge-record/verification/index.tsx @@ -1,7 +1,7 @@ import { useEffect, useRef, useState } from 'react'; import { MdDeleteForever } from 'react-icons/md'; -import { useParams } from 'react-router-dom'; +// import { useParams } from 'react-router-dom'; import Caution from '../components/caution'; import { postVerification } from '@/apis/challenge-record/challenge.record.api'; import CTA, { CTAContainer } from '@/components/common/cta'; @@ -11,10 +11,9 @@ import styled from '@emotion/styled'; const MIN_CONTENT_LENGTH = 20; -const Verification = () => { - const { id } = useParams(); - const challengeId = Number(id); +type VerificationProps = { challengeId: number }; +const Verification = ({ challengeId }: VerificationProps) => { const fileInput = useRef(null); const [content, setContent] = useState(''); const [isContentValid, setIsContentValid] = useState(true); diff --git a/src/pages/my-challenge-record/index.tsx b/src/pages/my-challenge-record/index.tsx index 661cd83..3061dae 100644 --- a/src/pages/my-challenge-record/index.tsx +++ b/src/pages/my-challenge-record/index.tsx @@ -43,8 +43,16 @@ const MyChallengeRecord = () => { return () => window.removeEventListener('scroll', handleScroll); }, [loadMoreChallenges]); - const handleNavigate = (id: number) => { - navigate(`/challenge/${id}/review`); + const handleChallengeClick = ( + challengeId: number, + title: string, + category?: string + ) => { + if (category) { + navigate( + `/challenge/write?id=${challengeId}&category=${category}&title=${title}` + ); + } else navigate(`/challenge/write?id=${challengeId}&title=${title}`); }; return ( @@ -67,7 +75,12 @@ const MyChallengeRecord = () => { challengeTitle={challenge.challengeTitle} userNickname={challenge.user.nickname} profileImageUrl={challenge.user.profileImageUrl} - onClick={() => handleNavigate(challenge.challengeId)} + onClick={() => + handleChallengeClick( + challenge.challengeId, + challenge.challengeTitle + ) + } /> )) ) : ( diff --git a/src/pages/my-challenge/components/challenge-list/index.tsx b/src/pages/my-challenge/components/challenge-list/index.tsx index b8cc385..8f65f49 100644 --- a/src/pages/my-challenge/components/challenge-list/index.tsx +++ b/src/pages/my-challenge/components/challenge-list/index.tsx @@ -3,8 +3,8 @@ import { Link } from 'react-router-dom'; import * as S from './styles'; import NotChallenge from '@/assets/UserImage.svg'; import FinishStamp from '@/assets/challenge/ZZAN-Black.png'; +import { ChallengeData } from '@/interface/apis/challenge'; import { RouterPath } from '@/routes/path'; -import { useChallengeStore } from '@/store/useChallengeStore'; import { Box, Image, Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; @@ -12,10 +12,7 @@ type ChallengeListProps = { BackgroundColor: string; color: string; BorderColor: string; - challenges: { - id: number; - title: string; - }[]; + challenges: ChallengeData[]; }; const ChallengeList = ({ @@ -24,12 +21,6 @@ const ChallengeList = ({ BorderColor, challenges, }: ChallengeListProps) => { - const { setChallengeTitle } = useChallengeStore(); - - const handleSaveTitle = (title: string) => { - setChallengeTitle(title); - }; - return ( <> {challenges.length === 0 ? ( @@ -81,9 +72,10 @@ const ChallengeList = ({ backgroundColor={BackgroundColor} borderColor={BorderColor} cursor='pointer' - onClick={() => handleSaveTitle(challenge.title)} > - + - 인증하기 + 인증 기록 diff --git a/src/pages/my-challenge/index.tsx b/src/pages/my-challenge/index.tsx index 540b3ec..094997f 100644 --- a/src/pages/my-challenge/index.tsx +++ b/src/pages/my-challenge/index.tsx @@ -8,6 +8,8 @@ import { Box, Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; const MyChallengePage = () => { + sessionStorage.setItem('activeTab', '0'); // 선택 탭 초기화 + const [listChallenges, setListChallenges] = useState([]); useEffect(() => { @@ -28,7 +30,7 @@ const MyChallengePage = () => { <> - + 참여 중인 챌린지 diff --git a/src/pages/review-write/index.tsx b/src/pages/review-write/index.tsx index 32c4628..401d663 100644 --- a/src/pages/review-write/index.tsx +++ b/src/pages/review-write/index.tsx @@ -1,5 +1,4 @@ import { useEffect, useState } from 'react'; -import { useParams } from 'react-router-dom'; import { postReview } from '@/apis/review/review.api'; import ChallengeTitle from '@/components/common/challenge-title'; @@ -7,7 +6,6 @@ import CTA, { CTAContainer } from '@/components/common/cta'; import Textarea from '@/components/common/form/textarea'; import { StarRating } from '@/components/common/star-rating'; import TopBar, { HEADER_HEIGHT } from '@/components/features/layout/top-bar'; -import { useChallengeStore } from '@/store/useChallengeStore'; import { formatRating, formatDifficulty, @@ -19,12 +17,11 @@ import styled from '@emotion/styled'; const MIN_CONTENT_LENGTH = 20; const ReviewWrite = () => { - const { id } = useParams(); - const challengeId = Number(id); - // const challengeGrouptitle = sessionStorage.getItem('challengeGroupTitle'); - const categoryLabel = sessionStorage.getItem('categoryLabel'); - const { challengeTitle } = useChallengeStore(); - // const challengeGroupTitle = sessionStorage.getItem('challengeGroupTitle'); + // 쿼리 파라미터 추출 + const searchParams = new URLSearchParams(location.search); + const challengeId = Number(searchParams.get('id')); + const category = searchParams.get('category') || ''; + const title = searchParams.get('title') || ''; const [rating, setRating] = useState(0); const difficultyList = [1, 2, 3]; @@ -103,9 +100,8 @@ const ReviewWrite = () => { <> - {categoryLabel && challengeTitle && ( - - )} + + diff --git a/src/pages/review/index.tsx b/src/pages/review/index.tsx index 38ea824..85366a1 100644 --- a/src/pages/review/index.tsx +++ b/src/pages/review/index.tsx @@ -1,6 +1,5 @@ import { useState, useEffect } from 'react'; import { useInView } from 'react-intersection-observer'; -import { useParams } from 'react-router-dom'; import ReviewItem from './components/review-item'; import ReviewRating from './components/review-rating'; @@ -9,12 +8,16 @@ import type { ReviewData } from '@/apis/review/review.response'; import ChallengeTitle from '@/components/common/challenge-title'; import TopBar from '@/components/features/layout/top-bar'; import * as Base from '@/styles/baseStyles'; +import { formatCategory } from '@/utils/formatters'; +// import { formatCategory } from '@/utils/formatters'; import styled from '@emotion/styled'; const Review = () => { - const { id } = useParams(); - const challengeGroupId = Number(id); - const challengeGrouptitle = sessionStorage.getItem('challengeGroupTitle'); + // 쿼리 파라미터 추출 + const searchParams = new URLSearchParams(location.search); + const challengeGroupId = Number(searchParams.get('id')); + const category = searchParams.get('category') || ''; + const title = searchParams.get('title') || ''; const DATA_SIZE = 10; // 한번에 가져올 리뷰 개수 const [reviewList, setReviewList] = useState([]); @@ -55,7 +58,7 @@ const Review = () => { <> - + {reviewList.length > 0 ? ( // 리뷰 있을 때 diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 5a66d33..37d2c62 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -36,7 +36,7 @@ const router = createBrowserRouter([ path: RouterPath.challenge, children: [ { - index: true, + path: RouterPath.myChallenge, element: ( @@ -103,7 +103,7 @@ const router = createBrowserRouter([ ), }, { - path: `:id/${RouterPath.review}`, + path: `${RouterPath.review}`, element: ( @@ -111,7 +111,7 @@ const router = createBrowserRouter([ ), }, { - path: `:id/${RouterPath.record}`, + path: `${RouterPath.record}`, element: ( @@ -119,7 +119,7 @@ const router = createBrowserRouter([ ), }, { - path: `:id/${RouterPath.write}`, + path: `${RouterPath.write}`, element: ( diff --git a/src/routes/path.ts b/src/routes/path.ts index b55e80a..1cfe8e8 100644 --- a/src/routes/path.ts +++ b/src/routes/path.ts @@ -3,9 +3,10 @@ export const RouterPath = { main: '/', notFound: '*', challenge: 'challenge', + myChallenge: 'myChallenge', + myRecord: 'myRecord', record: 'record', detail: 'detail', - myRecord: 'my-record', shorts: 'shorts', rank: 'rank', dashboard: 'dashboard',