From 31797682aab1459b1e958f47dd70c3740d8949dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=84=EC=A7=84=ED=98=B8?= Date: Tue, 27 Feb 2024 16:54:45 +0900 Subject: [PATCH 01/10] feat: add TopicStatus const --- src/interfaces/models/topic.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/interfaces/models/topic.ts diff --git a/src/interfaces/models/topic.ts b/src/interfaces/models/topic.ts new file mode 100644 index 0000000..e02f2bf --- /dev/null +++ b/src/interfaces/models/topic.ts @@ -0,0 +1,9 @@ +const TopicStatus = { + VOTING: 'VOTING', + CLOSED: 'CLOSED', +} as const; + +type TopicStatusType = keyof typeof TopicStatus; + +export { TopicStatus }; +export type { TopicStatusType }; From cbc802025400fbefbe828d307c9d1514085b6a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=84=EC=A7=84=ED=98=B8?= Date: Tue, 27 Feb 2024 16:55:07 +0900 Subject: [PATCH 02/10] feat: apply TopicStatus to BTopics --- src/components/B/TopicCard.styles.tsx | 21 ++++++ src/components/B/TopicCard.tsx | 103 ++++++++++++++++++++++++++ src/routes/B/BTopics.tsx | 15 ++-- 3 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 src/components/B/TopicCard.styles.tsx create mode 100644 src/components/B/TopicCard.tsx diff --git a/src/components/B/TopicCard.styles.tsx b/src/components/B/TopicCard.styles.tsx new file mode 100644 index 0000000..43f6347 --- /dev/null +++ b/src/components/B/TopicCard.styles.tsx @@ -0,0 +1,21 @@ +import { styled } from 'styled-components'; + +const CardContainer = styled.div` + display: flex; + flex-direction: column; + background-color: ${({ theme }) => theme.colors.navy2_60}; + backdrop-filter: blur(1.5px); + border-radius: 10px; +`; + +const CardFooter = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + padding: 9px 22px; + background-color: rgb(100 81 155 / 60%); + border-bottom-right-radius: 10px; + border-bottom-left-radius: 10px; +`; + +export { CardContainer, CardFooter }; diff --git a/src/components/B/TopicCard.tsx b/src/components/B/TopicCard.tsx new file mode 100644 index 0000000..bf012a5 --- /dev/null +++ b/src/components/B/TopicCard.tsx @@ -0,0 +1,103 @@ +import React from 'react'; +import { useNavigate } from 'react-router-dom'; + +import CommentChip from '@components/commons/Chip/CommentChip'; +import { Col, Row } from '@components/commons/Flex/Flex'; +import Text from '@components/commons/Text/Text'; +import { TopicResponse } from '@interfaces/api/topic'; + +import { colors } from '@styles/theme'; + +import { MeatballIcon } from '@icons/index'; + +import { getDateDiff } from '@utils/date'; + +import BTopicChoice from './BTopicChoice'; +import { CardContainer, CardFooter } from './TopicCard.styles'; + +interface VotingCardProps { + topic: TopicResponse; +} + +const VotingCard = ({ topic }: VotingCardProps) => { + const navigate = useNavigate(); + + const handleCardClick = () => { + navigate(`/topics/b/${topic.topicId}`, { state: { topic } }); + }; + + const handleOptionClick = () => {}; + + return ( + <> + + + + + + {topic.keyword?.keywordName} + + + {getDateDiff(topic.createdAt)} 전 + + + {topic.selectedOption && ( + + 선택완료 + + )} + + + + {topic.topicTitle} + + {/* TBD: 1차 스펙 아웃 */} + {/* */} + + + {topic.choices.map((choice) => { + return ( + + ); + })} + + + + + + 선택 + + + {topic.voteCount.toLocaleString()} 명 + + + + + + + ); +}; + +export default VotingCard; diff --git a/src/routes/B/BTopics.tsx b/src/routes/B/BTopics.tsx index 78cf7d5..941e754 100644 --- a/src/routes/B/BTopics.tsx +++ b/src/routes/B/BTopics.tsx @@ -1,5 +1,4 @@ import React, { ChangeEvent, useEffect, useLayoutEffect, useState } from 'react'; -import { Helmet } from 'react-helmet'; import { useSearchParams } from 'react-router-dom'; import useTopics from '@apis/topic/useTopics'; @@ -8,6 +7,7 @@ import { Row, Col } from '@components/commons/Flex/Flex'; import Layout from '@components/commons/Layout/Layout'; import Text from '@components/commons/Text/Text'; import ToggleSwitch from '@components/commons/ToggleSwitch/ToggleSwitch'; +import { TopicStatus, TopicStatusType } from '@interfaces/models/topic'; import { colors } from '@styles/theme'; @@ -17,7 +17,9 @@ import { Container } from './BTopics.styles'; const BTopics = () => { const [searchParams, setSearchParams] = useSearchParams(); - const [topicFilter, setTopicFilter] = useState(searchParams.get('status') || '진행중'); + const [topicFilter, setTopicFilter] = useState( + (searchParams.get('status') as TopicStatusType) || TopicStatus.VOTING + ); const [isMineOnly, setIsMineOnly] = useState( JSON.parse(searchParams.get('mine') || 'false') ); @@ -27,15 +29,16 @@ const BTopics = () => { const { data } = useTopics({ side: 'TOPIC_B', sort: 'createdAt,DESC', - status: topicFilter === '진행중' ? 'VOTING' : 'CLOSED', + status: topicFilter, }); const topics = data?.pages.flatMap((page) => page.data); const handleTopicStatusChange = (e: ChangeEvent) => { - setTopicFilter(e.target.value); + setTopicFilter(e.target.value as TopicStatusType); }; + // TODO: let's make this to custom hooks someday... useLayoutEffect(() => { const prevColor = document.body.style.backgroundColor; document.body.style.backgroundColor = '#0e0d16'; @@ -61,12 +64,12 @@ const BTopics = () => { HeaderLeft={} HeaderCenter={ - + 진행중 - + 종료된 From 306a0a7715bcf4892779c446bd1b8866023308c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=84=EC=A7=84=ED=98=B8?= Date: Tue, 27 Feb 2024 17:41:38 +0900 Subject: [PATCH 03/10] feat: show ResultSlide depend on topicStatus --- src/components/B/ResultSlide.tsx | 69 ++++++++++++++++++++++++ src/components/commons/Layout/Layout.tsx | 6 ++- src/routes/B/BTopics.tsx | 7 +-- 3 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 src/components/B/ResultSlide.tsx diff --git a/src/components/B/ResultSlide.tsx b/src/components/B/ResultSlide.tsx new file mode 100644 index 0000000..d411737 --- /dev/null +++ b/src/components/B/ResultSlide.tsx @@ -0,0 +1,69 @@ +import React from 'react'; + +import Text from '@components/commons/Text/Text'; +import { + AlphaSideContainer, + AlphaSizeUpButton, + BetaSideContainer, + BetaSizeUpButton, + SideImage, + TextContainer, +} from '@components/Home/ChoiceSlide/ChoiceSlide.styles'; +import { ChoiceContent, TopicResponse } from '@interfaces/api/topic'; + +import { colors } from '@styles/theme'; + +import { SizeUpIcon } from '@icons/index'; + +interface Props { + topicSide: TopicResponse['topicSide']; + choiceContent: ChoiceContent; +} + +const ResultSlide = ({ topicSide, choiceContent }: Props) => { + const SlideContainer = topicSide === 'TOPIC_A' ? AlphaSideContainer : BetaSideContainer; + const SizeUpButton = topicSide === 'TOPIC_A' ? AlphaSizeUpButton : BetaSizeUpButton; + + return ( + +
+ + {topicSide === 'TOPIC_A' ? 'A' : 'B'} + +
+ {choiceContent.imageUrl ? ( +
+ +
+ ) : ( + + = 21 ? 16 : 20} + weight={600} + align="center" + > + {choiceContent.text} + + + )} +
+ ); +}; + +export default ResultSlide; diff --git a/src/components/commons/Layout/Layout.tsx b/src/components/commons/Layout/Layout.tsx index ab82d98..8364d42 100644 --- a/src/components/commons/Layout/Layout.tsx +++ b/src/components/commons/Layout/Layout.tsx @@ -1,6 +1,8 @@ import React from 'react'; import { Helmet } from 'react-helmet'; +import { colors } from '@styles/theme'; + import BottomNavigation from '../BottomNavigation/BottomNavigation'; import { @@ -16,7 +18,7 @@ interface LayoutProps { HeaderCenter?: React.ReactNode; HeaderRight?: React.ReactNode; hasBottomNavigation?: boolean; - ThemeColor?: string; + themeColor?: string; children: React.ReactNode; } @@ -26,7 +28,7 @@ const Layout = (props: LayoutProps) => { return (
- +
{HeaderLeft} diff --git a/src/routes/B/BTopics.tsx b/src/routes/B/BTopics.tsx index 941e754..42ce962 100644 --- a/src/routes/B/BTopics.tsx +++ b/src/routes/B/BTopics.tsx @@ -38,7 +38,6 @@ const BTopics = () => { setTopicFilter(e.target.value as TopicStatusType); }; - // TODO: let's make this to custom hooks someday... useLayoutEffect(() => { const prevColor = document.body.style.backgroundColor; document.body.style.backgroundColor = '#0e0d16'; @@ -59,7 +58,7 @@ const BTopics = () => { return ( } HeaderCenter={ @@ -105,7 +104,9 @@ const BTopics = () => { - {topics?.map((topic) => )} + {topics?.map((topic) => ( + + ))} From 8e1226434c84263526d85d8c1a220dacb4e08152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=84=EC=A7=84=ED=98=B8?= Date: Tue, 27 Feb 2024 17:46:00 +0900 Subject: [PATCH 04/10] feat: update theme-color according to topic status --- src/routes/B/BTopic.tsx | 62 ++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/src/routes/B/BTopic.tsx b/src/routes/B/BTopic.tsx index 97b45f2..fa55bcd 100644 --- a/src/routes/B/BTopic.tsx +++ b/src/routes/B/BTopic.tsx @@ -1,10 +1,11 @@ -import React from 'react'; +import React, { useLayoutEffect } from 'react'; import { useLocation } from 'react-router-dom'; import { usePreviewComment } from '@apis/comment/useComment'; import useHideTopic from '@apis/topic/useHideTopic'; import useReportTopic from '@apis/topic/useReportTopic'; import useVoteTopic from '@apis/topic/useVoteTopic'; +import ResultSlide from '@components/B/ResultSlide'; import { Row } from '@components/commons/Flex/Flex'; import BackButton from '@components/commons/Header/BackButton/BackButton'; import Layout from '@components/commons/Layout/Layout'; @@ -22,10 +23,10 @@ import { TopicFooter, } from '@components/Home/TopicCard/TopicCard.styles'; import TopicComments from '@components/Home/TopicComments/TopicComments'; -import VoteCompletion from '@components/Home/VoteCompletion/VoteCompletion'; import useBottomSheet from '@hooks/useBottomSheet/useBottomSheet'; import useActionSheet from '@hooks/useModal/useActionSheet'; import { Choice, TopicResponse } from '@interfaces/api/topic'; +import { TopicStatusType } from '@interfaces/models/topic'; import { useAuthStore } from '@store/auth'; @@ -44,14 +45,16 @@ import { ResponseError } from '@apis/fetch'; interface BTopicProps { topic: TopicResponse; + topicStatus: TopicStatusType; } const BTopic = () => { const location = useLocation(); const { BottomSheet: CommentSheet, toggleSheet } = useBottomSheet({}); const memberId = useAuthStore((store) => store.memberId); - const { topic } = location.state as BTopicProps; + const { topic, topicStatus } = location.state as BTopicProps; const isMyTopic = topic.author.id === memberId; + const isVoting = topicStatus === 'VOTING'; const { data: previewComment } = usePreviewComment( topic.topicId, @@ -126,9 +129,24 @@ const BTopic = () => { ], }); + useLayoutEffect(() => { + if (!isVoting) { + const prevColor = document.body.style.backgroundColor; + document.body.style.backgroundColor = '#3D3060'; + + return () => { + document.body.style.backgroundColor = prevColor; + }; + } + }, []); + return ( - }> + } + > {topic.keyword?.keywordName} @@ -138,26 +156,26 @@ const BTopic = () => { {topic.topicTitle} - {topic.selectedOption !== null ? ( - + {isVoting ? ( + <> + + {topic.deadline && } + + + + 밀어서 선택하기 + + + + ) : ( - + <> + + )} - {topic.deadline && } - - - - 밀어서 선택하기 - - - From 6983e0263d18f6949fa68a9275a094a673e02bd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=84=EC=A7=84=ED=98=B8?= Date: Tue, 27 Feb 2024 17:46:17 +0900 Subject: [PATCH 05/10] feat: navigate to b detail page with topic status --- src/components/B/BTopicCard.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/B/BTopicCard.tsx b/src/components/B/BTopicCard.tsx index 465b58b..5db119a 100644 --- a/src/components/B/BTopicCard.tsx +++ b/src/components/B/BTopicCard.tsx @@ -5,6 +5,7 @@ import CommentChip from '@components/commons/Chip/CommentChip'; import { Col, Row } from '@components/commons/Flex/Flex'; import Text from '@components/commons/Text/Text'; import { TopicResponse } from '@interfaces/api/topic'; +import { TopicStatusType } from '@interfaces/models/topic'; import { colors } from '@styles/theme'; @@ -17,13 +18,14 @@ import BTopicChoice from './BTopicChoice'; interface BTopicCardProps { topic: TopicResponse; + topicStatus: TopicStatusType; } -const BTopicCard = ({ topic }: BTopicCardProps) => { +const BTopicCard = ({ topic, topicStatus }: BTopicCardProps) => { const navigate = useNavigate(); const handleCardClick = () => { - navigate(`/topics/b/${topic.topicId}`, { state: { topic } }); + navigate(`/topics/b/${topic.topicId}`, { state: { topic, topicStatus } }); }; const handleOptionClick = () => {}; From abe4ee9e1c54f3f2fc009c2597983490ca07cf0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=84=EC=A7=84=ED=98=B8?= Date: Mon, 4 Mar 2024 19:48:37 +0900 Subject: [PATCH 06/10] feat: add crown icon --- src/assets/icons/crown.svg | 28 ++++++++++++++++++++++++++++ src/assets/icons/index.ts | 2 ++ 2 files changed, 30 insertions(+) create mode 100644 src/assets/icons/crown.svg diff --git a/src/assets/icons/crown.svg b/src/assets/icons/crown.svg new file mode 100644 index 0000000..a1ea425 --- /dev/null +++ b/src/assets/icons/crown.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/icons/index.ts b/src/assets/icons/index.ts index f90f3e4..b7dcadb 100644 --- a/src/assets/icons/index.ts +++ b/src/assets/icons/index.ts @@ -17,6 +17,7 @@ import ClockIcon from './clock.svg?react'; import CloseIcon from './close.svg?react'; import CommentBoxIcon from './comment-box.svg?react'; import CommentIcon from './comment.svg?react'; +import CrownIcon from './crown.svg?react'; import DefaultProfileIcon from './default-profile.svg?react'; import DeleteIcon from './delete.svg?react'; import DownChevronIcon from './down-chevron.svg?react'; @@ -62,6 +63,7 @@ export { CheckIcon, ClockIcon, CloseIcon, + CrownIcon, CommentIcon, CommentBoxIcon, DefaultProfileIcon, From c64b8fc17f7bc319138fef082a9bc12e4b930397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=84=EC=A7=84=ED=98=B8?= Date: Wed, 6 Mar 2024 15:35:58 +0900 Subject: [PATCH 07/10] fix: make OAuthResponse's token to optional --- src/interfaces/api/oauth.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interfaces/api/oauth.ts b/src/interfaces/api/oauth.ts index 7bccf39..b37ebf2 100644 --- a/src/interfaces/api/oauth.ts +++ b/src/interfaces/api/oauth.ts @@ -33,6 +33,6 @@ export interface OAuthResponse { newMember: boolean; memberId: number; joinStatus: JoinStatus; - accessToken: string; - refreshToken: string; + accessToken?: string; + refreshToken?: string; } From 486c02a8b4fd6b27972265d599f4a2a820f22a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=84=EC=A7=84=ED=98=B8?= Date: Wed, 6 Mar 2024 16:31:45 +0900 Subject: [PATCH 08/10] fix: integrate props to choice --- src/components/B/ResultSlide.styles.tsx | 42 ++++++++++ src/components/B/ResultSlide.tsx | 102 +++++++++++++----------- src/routes/B/BTopic.tsx | 8 +- 3 files changed, 100 insertions(+), 52 deletions(-) create mode 100644 src/components/B/ResultSlide.styles.tsx diff --git a/src/components/B/ResultSlide.styles.tsx b/src/components/B/ResultSlide.styles.tsx new file mode 100644 index 0000000..d78e0c5 --- /dev/null +++ b/src/components/B/ResultSlide.styles.tsx @@ -0,0 +1,42 @@ +import { styled } from 'styled-components'; + +const SlideContainer = styled.div` + position: relative; + display: flex; + align-items: center; + width: 100%; + height: 148px; + overflow: hidden; +`; + +const ASideContainer = styled(SlideContainer)` + position: relative; + justify-content: flex-end; + background-color: #d04376; + border-top-right-radius: 74px; + border-bottom-right-radius: 74px; +`; + +const BSideContainer = styled(SlideContainer)` + position: relative; + justify-content: flex-start; + background-color: #1498aa; + border-top-left-radius: 74px; + border-bottom-left-radius: 74px; +`; + +const CrownContainer = styled.div` + position: absolute; + top: -26px; + left: 50%; + transform: translate(-50%, 0%); +`; + +const ResultSlideTextContainer = styled.div` + z-index: 10; + width: 100%; + padding: 0 20px; + text-align: center; +`; + +export { SlideContainer, ASideContainer, BSideContainer, CrownContainer, ResultSlideTextContainer }; diff --git a/src/components/B/ResultSlide.tsx b/src/components/B/ResultSlide.tsx index d411737..463ad1a 100644 --- a/src/components/B/ResultSlide.tsx +++ b/src/components/B/ResultSlide.tsx @@ -1,68 +1,74 @@ -import React from 'react'; - import Text from '@components/commons/Text/Text'; -import { - AlphaSideContainer, - AlphaSizeUpButton, - BetaSideContainer, - BetaSizeUpButton, - SideImage, - TextContainer, -} from '@components/Home/ChoiceSlide/ChoiceSlide.styles'; -import { ChoiceContent, TopicResponse } from '@interfaces/api/topic'; +import { SideImage } from '@components/Home/ChoiceSlide/ChoiceSlide.styles'; +import { Choice } from '@interfaces/api/topic'; import { colors } from '@styles/theme'; -import { SizeUpIcon } from '@icons/index'; +import { CrownIcon } from '@icons/index'; + +import { + ASideContainer, + BSideContainer, + CrownContainer, + ResultSlideTextContainer, +} from './ResultSlide.styles'; interface Props { - topicSide: TopicResponse['topicSide']; - choiceContent: ChoiceContent; + choice: Choice; } -const ResultSlide = ({ topicSide, choiceContent }: Props) => { - const SlideContainer = topicSide === 'TOPIC_A' ? AlphaSideContainer : BetaSideContainer; - const SizeUpButton = topicSide === 'TOPIC_A' ? AlphaSizeUpButton : BetaSizeUpButton; +const ResultSlide = ({ choice }: Props) => { + const SlideContainer = choice.choiceOption === 'CHOICE_A' ? ASideContainer : BSideContainer; return ( - -
- - {topicSide === 'TOPIC_A' ? 'A' : 'B'} - -
- {choiceContent.imageUrl ? ( +
+ + + +
- -
- ) : ( - = 21 ? 16 : 20} - weight={600} - align="center" + color={choice.choiceOption === 'CHOICE_A' ? '#e15ba1' : '#19b1be'} + size={200} + weight={900} > - {choiceContent.text} + {choice.choiceOption === 'CHOICE_A' ? 'A' : 'B'} - - )} -
+
+ + {choice.content.imageUrl ? ( +
+ +
+ ) : ( + + = 21 ? 16 : 20} + weight={600} + align="center" + > + {choice.content.text} + + + )} +
+ ); }; diff --git a/src/routes/B/BTopic.tsx b/src/routes/B/BTopic.tsx index fa55bcd..c50e9e4 100644 --- a/src/routes/B/BTopic.tsx +++ b/src/routes/B/BTopic.tsx @@ -53,8 +53,11 @@ const BTopic = () => { const { BottomSheet: CommentSheet, toggleSheet } = useBottomSheet({}); const memberId = useAuthStore((store) => store.memberId); const { topic, topicStatus } = location.state as BTopicProps; + const isMyTopic = topic.author.id === memberId; const isVoting = topicStatus === 'VOTING'; + const [choiceA, choiceB] = topic.choices; + const winChoice = choiceA.voteCount > choiceB.voteCount ? choiceA : choiceB; const { data: previewComment } = usePreviewComment( topic.topicId, @@ -170,10 +173,7 @@ const BTopic = () => { ) : ( <> - + )} From f4fdd63b8b1b2a1508b86426147c34c2b1921a8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=84=EC=A7=84=ED=98=B8?= Date: Wed, 6 Mar 2024 16:33:13 +0900 Subject: [PATCH 09/10] feat: add imageUrl to SideImage --- src/components/B/ResultSlide.tsx | 2 +- src/components/Home/ChoiceSlide/ChoiceSlide.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/B/ResultSlide.tsx b/src/components/B/ResultSlide.tsx index 463ad1a..be8ce3d 100644 --- a/src/components/B/ResultSlide.tsx +++ b/src/components/B/ResultSlide.tsx @@ -52,7 +52,7 @@ const ResultSlide = ({ choice }: Props) => { justifyContent: choice.choiceOption === 'CHOICE_A' ? 'flex-end' : 'flex-start', }} > - + ) : ( diff --git a/src/components/Home/ChoiceSlide/ChoiceSlide.tsx b/src/components/Home/ChoiceSlide/ChoiceSlide.tsx index a8db42e..5ac2648 100644 --- a/src/components/Home/ChoiceSlide/ChoiceSlide.tsx +++ b/src/components/Home/ChoiceSlide/ChoiceSlide.tsx @@ -62,7 +62,7 @@ const ChoiceSlide = ({ side, topicContent }: ChoiceSlideProps) => { justifyContent: side === 'A' ? 'flex-end' : 'flex-start', }} > - + From 00a71c902a086630cd8fd6989da62b165f7c9db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=84=EC=A7=84=ED=98=B8?= Date: Wed, 6 Mar 2024 19:44:09 +0900 Subject: [PATCH 10/10] fix: safely get tokens --- src/hooks/useOAuth/useOAuth.ts | 3 +++ src/store/auth.ts | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/hooks/useOAuth/useOAuth.ts b/src/hooks/useOAuth/useOAuth.ts index b3fa8fc..7fcdc98 100644 --- a/src/hooks/useOAuth/useOAuth.ts +++ b/src/hooks/useOAuth/useOAuth.ts @@ -34,6 +34,9 @@ export default function useOAuth({ type }: UseOAuthProps) { state: { memberId: response.memberId }, }); } else { + if (!response.accessToken || !response.refreshToken || !response.memberId) { + throw new Error('토큰이 올바르지 않습니다.'); + } login(response.accessToken, response.refreshToken, response.memberId); navigate('/'); } diff --git a/src/store/auth.ts b/src/store/auth.ts index a5872eb..0748c42 100644 --- a/src/store/auth.ts +++ b/src/store/auth.ts @@ -42,6 +42,10 @@ export const useAuthStore = create( }, }); const { refreshToken: newRefreshToken, memberId, accessToken } = response; + + if (!newRefreshToken || !memberId || !accessToken) { + throw new Error('토큰이 올바르지 않습니다.'); + } set({ refreshToken: newRefreshToken, isLoggedIn: true, memberId }); client.setAccessToken(accessToken); return get().isLoggedIn;