From 4beb91c0492af303b5001f9fa0c8250817857478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=91=ED=98=84?= Date: Thu, 14 Sep 2023 02:23:20 +0900 Subject: [PATCH 1/6] =?UTF-8?q?[Feat]=EA=B5=AC=EA=B8=80=20=EC=B9=B4?= =?UTF-8?q?=EC=B9=B4=EC=98=A4=20=EB=B2=84=ED=8A=BC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/Logins/GoogleLoginButton.tsx | 36 +++++++++++++++++++ .../components/Logins/KakaoLoginButton.tsx | 35 ++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 client/src/components/Logins/GoogleLoginButton.tsx create mode 100644 client/src/components/Logins/KakaoLoginButton.tsx diff --git a/client/src/components/Logins/GoogleLoginButton.tsx b/client/src/components/Logins/GoogleLoginButton.tsx new file mode 100644 index 00000000..ecec8fec --- /dev/null +++ b/client/src/components/Logins/GoogleLoginButton.tsx @@ -0,0 +1,36 @@ +// GoogleLoginButton.tsx + +import React from 'react'; + +interface Props { + backendURL: string; +} + +const GoogleLoginButton: React.FC = ({ backendURL }) => { + const handleLoginClick = () => { + window.location.href = `${backendURL}/oauth2/authorization/google`; + }; + + return ( + + ); +} + +export default GoogleLoginButton; + + +// 토큰 저장 로직 + +// const authToken = response.headers["authorization"]; +// console.log(authToken); + +// const refreshToken = response.headers["refresh"]; + +// // 로그인 상태로 만들기 +// dispatch(setLoginState()); + +// // 토큰들을 로컬 스토리지에 저장 +// if (authToken) localStorage.setItem("authToken", authToken); +// if (refreshToken) localStorage.setItem("refreshToken", refreshToken); \ No newline at end of file diff --git a/client/src/components/Logins/KakaoLoginButton.tsx b/client/src/components/Logins/KakaoLoginButton.tsx new file mode 100644 index 00000000..1d28d6fd --- /dev/null +++ b/client/src/components/Logins/KakaoLoginButton.tsx @@ -0,0 +1,35 @@ +// KakaoLoginButton.tsx + +import React from 'react'; + +interface Props { + backendURL: string; +} + +const KakaoLoginButton: React.FC = ({ backendURL }) => { + const handleLoginClick = () => { + window.location.href = `${backendURL}/oauth2/authorization/kakao`; + }; + + return ( + + ); +} + +export default KakaoLoginButton; + +// 토큰 저장 로직 + +// const authToken = response.headers["authorization"]; +// console.log(authToken); + +// const refreshToken = response.headers["refresh"]; + +// // 로그인 상태로 만들기 +// dispatch(setLoginState()); + +// // 토큰들을 로컬 스토리지에 저장 +// if (authToken) localStorage.setItem("authToken", authToken); +// if (refreshToken) localStorage.setItem("refreshToken", refreshToken); \ No newline at end of file From 283c2d7411ab3b03319aece67c82d6bce1879ee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=91=ED=98=84?= Date: Thu, 14 Sep 2023 02:56:13 +0900 Subject: [PATCH 2/6] =?UTF-8?q?[Feat]OAuth=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=82=BD=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/Logins/OAuthLogin.tsx | 94 ++++++++++----------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/client/src/components/Logins/OAuthLogin.tsx b/client/src/components/Logins/OAuthLogin.tsx index 9298f856..4470ad56 100644 --- a/client/src/components/Logins/OAuthLogin.tsx +++ b/client/src/components/Logins/OAuthLogin.tsx @@ -1,54 +1,53 @@ import React from 'react'; import styled from 'styled-components'; -import kakaoLogo from '../../asset/images/KakaoLogo.svg'; -import axios from 'axios'; -// import { GoogleOAuthProvider, GoogleLogin, googleLogout } from '@react-oauth/google'; +// import kakaoLogo from '../../asset/images/KakaoLogo.svg'; +// import axios from 'axios'; +import GoogleLoginButton from './GoogleLoginButton' +import KakaoLoginButton from './KakaoLoginButton'; + + + const OAuthLoginModal: React.FC = ({ onClose, onEmailLoginClick, onEmailSignupClick }) => { const titleText = "로그인"; - const kakaoLoginText = "카카오로 로그인"; + // const kakaoLoginText = "카카오로 로그인"; const orText = "또는"; const emailLoginText = "이메일로 로그인"; const emailSignupText = "이메일로 회원가입"; + // const handleGoogleLogout = async () => { // googleLogout(); // } - const handleKakaoLogin = async () => { - try { - const response = await axios.get('/oauth2/authorization/kakao'); - if (response.status === 200) { - const redirectUri = response.data.uri; - window.location.href = redirectUri; - } else { - console.error("Error logging in with Kakao, unexpected status code:", response.status); - } - } catch (error) { - console.error("Error logging in with Kakao:", error); - } - }; + //임시로 비활성화 + + // const handleKakaoLogin = async () => { + // try { + // const response = await axios.get('/oauth2/authorization/kakao'); + // if (response.status === 200) { + // const redirectUri = response.data.uri; + // window.location.href = redirectUri; + // } else { + // console.error("Error logging in with Kakao, unexpected status code:", response.status); + // } + // } catch (error) { + // console.error("Error logging in with Kakao:", error); + // } + // }; return ( × {titleText} - {/* - { - console.log(credentialResponse); - }} - onError={() => { - console.log('Login Failed'); - }} - />; - ; */} - + + + {/*임시로 비활성화 {kakaoLoginText} - + */} {orText} {emailLoginText} @@ -113,24 +112,25 @@ const OrText = styled.span` -const KakaoButton = styled.button` - margin: 10px 0; - padding: 10px 20px; - background-color: #FFFFFF; - border: 1px solid lightgray; - border-radius: 5px; - cursor: pointer; - width: 300px; - display: flex; - align-items: center; - justify-content: center; -`; - -const LogoImage = styled.img` - margin-right: 30px; - width: 60px; - height: auto; -`; +// 임시로 비활성화 +// const KakaoButton = styled.button` +// margin: 10px 0; +// padding: 10px 20px; +// background-color: #FFFFFF; +// border: 1px solid lightgray; +// border-radius: 5px; +// cursor: pointer; +// width: 300px; +// display: flex; +// align-items: center; +// justify-content: center; +// `; + +// const LogoImage = styled.img` +// margin-right: 30px; +// width: 60px; +// height: auto; +// `; const EmailButtonsContainer = styled.div` display: flex; From 685968c434df2a921fa01fa11443826cd7061efc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=91=ED=98=84?= Date: Thu, 14 Sep 2023 14:22:45 +0900 Subject: [PATCH 3/6] =?UTF-8?q?[Feat]=EA=B5=AC=EA=B8=80=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=20=EB=A1=A4=EB=B0=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/Logins/GoogleLoginButton.tsx | 3 +-- client/src/components/Logins/KakaoLoginButton.tsx | 2 +- client/src/components/Logins/Login.html | 13 +++++++++++++ client/src/components/Logins/OAuthLogin.tsx | 4 ++-- 4 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 client/src/components/Logins/Login.html diff --git a/client/src/components/Logins/GoogleLoginButton.tsx b/client/src/components/Logins/GoogleLoginButton.tsx index ecec8fec..66afa158 100644 --- a/client/src/components/Logins/GoogleLoginButton.tsx +++ b/client/src/components/Logins/GoogleLoginButton.tsx @@ -8,7 +8,7 @@ interface Props { const GoogleLoginButton: React.FC = ({ backendURL }) => { const handleLoginClick = () => { - window.location.href = `${backendURL}/oauth2/authorization/google`; + window.location.href = `${backendURL}`; }; return ( @@ -21,7 +21,6 @@ const GoogleLoginButton: React.FC = ({ backendURL }) => { export default GoogleLoginButton; -// 토큰 저장 로직 // const authToken = response.headers["authorization"]; // console.log(authToken); diff --git a/client/src/components/Logins/KakaoLoginButton.tsx b/client/src/components/Logins/KakaoLoginButton.tsx index 1d28d6fd..4b0c8faa 100644 --- a/client/src/components/Logins/KakaoLoginButton.tsx +++ b/client/src/components/Logins/KakaoLoginButton.tsx @@ -8,7 +8,7 @@ interface Props { const KakaoLoginButton: React.FC = ({ backendURL }) => { const handleLoginClick = () => { - window.location.href = `${backendURL}/oauth2/authorization/kakao`; + window.location.href = `${backendURL}`; }; return ( diff --git a/client/src/components/Logins/Login.html b/client/src/components/Logins/Login.html new file mode 100644 index 00000000..afe16d2b --- /dev/null +++ b/client/src/components/Logins/Login.html @@ -0,0 +1,13 @@ + + + + + + Google Login + + + + + \ No newline at end of file diff --git a/client/src/components/Logins/OAuthLogin.tsx b/client/src/components/Logins/OAuthLogin.tsx index 4470ad56..97a3da0c 100644 --- a/client/src/components/Logins/OAuthLogin.tsx +++ b/client/src/components/Logins/OAuthLogin.tsx @@ -42,8 +42,8 @@ const OAuthLoginModal: React.FC = ({ onClose, onEmailLoginClick × {titleText} - - + + {/*임시로 비활성화 {kakaoLoginText} From d11ce54c198fc566b9510f2c34960a135e6b0350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=91=ED=98=84?= Date: Fri, 15 Sep 2023 15:42:31 +0900 Subject: [PATCH 4/6] =?UTF-8?q?[Feat]=EC=86=8C=EC=85=9C=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=ED=9B=84=20=ED=86=A0=ED=81=B0=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=20=EB=A1=9C=EC=A7=81=20=EB=AF=B8=EC=99=84=EC=84=B1=20?= =?UTF-8?q?Issues=20#99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/Logins/OAuthLogin.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/client/src/components/Logins/OAuthLogin.tsx b/client/src/components/Logins/OAuthLogin.tsx index 97a3da0c..c34570e0 100644 --- a/client/src/components/Logins/OAuthLogin.tsx +++ b/client/src/components/Logins/OAuthLogin.tsx @@ -16,6 +16,20 @@ const OAuthLoginModal: React.FC = ({ onClose, onEmailLoginClick const emailLoginText = "이메일로 로그인"; const emailSignupText = "이메일로 회원가입"; + // URL에서 엑세스 토큰과 리프레시 토큰을 추출합니다. + const urlParams = new URLSearchParams(window.location.search); + const accessToken = urlParams.get("access_token"); + const refreshToken = urlParams.get("refresh_token"); + + if (accessToken && refreshToken) { + // 엑세스 토큰을 로컬 스토리지에 저장합니다. + localStorage.setItem("Authorization", `Bearer ${accessToken}`); + + // 리프레시 토큰을 로컬 스토리지에 저장합니다. + localStorage.setItem("Refresh-token", refreshToken); + } + + // const handleGoogleLogout = async () => { // googleLogout(); From f5729dc38a37827cb063899b5265883f60cab957 Mon Sep 17 00:00:00 2001 From: novice1993 Date: Fri, 15 Sep 2023 15:56:02 +0900 Subject: [PATCH 5/6] =?UTF-8?q?[Fix]=20=EB=B2=88=EB=93=A4=EB=A7=81=20?= =?UTF-8?q?=EC=8B=9C=20=EC=98=A4=EB=A5=98=20=EB=B0=9C=EC=83=9D=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - S3 서버 업로드 위한 빌드 작업 중 오류 발생하는 코드 수정 Issues #110 --- .../StockOrderSection/OrderResult.tsx | 4 +-- .../StockOrderSection/StockOrder.tsx | 12 ++++---- .../communityComponents/Comments.tsx | 19 ++++--------- .../components/communityComponents/index.tsx | 28 ++++--------------- 4 files changed, 19 insertions(+), 44 deletions(-) diff --git a/client/src/components/StockOrderSection/OrderResult.tsx b/client/src/components/StockOrderSection/OrderResult.tsx index a74dd639..be93ca67 100644 --- a/client/src/components/StockOrderSection/OrderResult.tsx +++ b/client/src/components/StockOrderSection/OrderResult.tsx @@ -26,8 +26,8 @@ const OrderResult = () => { const orderCompleteList = orderRecordData.filter((order: OrderRecordProps) => order.orderStates === "ORDER_COMPLETE"); // 최근 주문이 상단에 노출되도록 배열 순서 변경 - orderWaitList.reverse(); - orderCompleteList.reverse(); + // orderWaitList.reverse(); + // orderCompleteList.reverse(); const orderList = recordType ? orderCompleteList : orderWaitList; const orderListNum = orderList.length; diff --git a/client/src/components/StockOrderSection/StockOrder.tsx b/client/src/components/StockOrderSection/StockOrder.tsx index c6f76476..6976fcf3 100644 --- a/client/src/components/StockOrderSection/StockOrder.tsx +++ b/client/src/components/StockOrderSection/StockOrder.tsx @@ -90,12 +90,12 @@ const StockOrder = ({ corpName }: { corpName: string }) => { const today = new Date(); const nonBusinessDay = isHoliday(today, { include: { saturday: true, sunday: true } }); // 토요일, 일요일, 공휴일 (임시 공휴일 포함) - // 2) 개장시간 여부 체크 - const currentHour = today.getHours(); - const currentMinute = today.getMinutes(); - const isBefore9AM = currentHour < 9; - const isAfter330PM = currentHour > 15 || (currentHour === 15 && currentMinute >= 30); - const closingTime = isBefore9AM || isAfter330PM; + // 🟢 2) 개장시간 여부 체크 + // const currentHour = today.getHours(); + // const currentMinute = today.getMinutes(); + // const isBefore9AM = currentHour < 9; + // const isAfter330PM = currentHour > 15 || (currentHour === 15 && currentMinute >= 30); + // const closingTime = isBefore9AM || isAfter330PM; // 주문 실패 케이스 1) 개장시간 2) 가격/거래량 설정 // 🔴 3시 30분 이후 작업 위해 closingTime 조건 해제 diff --git a/client/src/components/communityComponents/Comments.tsx b/client/src/components/communityComponents/Comments.tsx index 1e290ba1..cba07333 100644 --- a/client/src/components/communityComponents/Comments.tsx +++ b/client/src/components/communityComponents/Comments.tsx @@ -1,14 +1,14 @@ import { useState } from "react"; import styled from "styled-components"; -const Comments = ({ postId }: { postId: number }) => { +const Comments = ({ boardId }: { boardId: number }) => { interface CommentData { id: number; comments: string; } const [commentData, setCommentData] = useState(() => { // 게시물별로 로컬 스토리지에서 댓글 데이터를 가져옵니다. - const storedData = localStorage.getItem(`commentData_${postId}`); + const storedData = localStorage.getItem(`commentData_${boardId}`); return storedData ? JSON.parse(storedData) : []; }); @@ -30,10 +30,7 @@ const Comments = ({ postId }: { postId: number }) => { setCommentData((prevCommentData) => [...prevCommentData, newCommentData]); // 게시물 ID에 따라 로컬 스토리지에 댓글 데이터를 저장합니다. - localStorage.setItem( - `commentData_${postId}`, - JSON.stringify([...commentData, newCommentData]) - ); + localStorage.setItem(`commentData_${boardId}`, JSON.stringify([...commentData, newCommentData])); // 댓글 입력창 초기화 setCommentsValue(""); @@ -51,14 +48,8 @@ const Comments = ({ postId }: { postId: number }) => { return (
- - handleClickSubmit()}> - {CommentText.write} - + + handleClickSubmit()}>{CommentText.write} {CommentText.replyCount} {commentData.length} diff --git a/client/src/components/communityComponents/index.tsx b/client/src/components/communityComponents/index.tsx index 14b69416..2f86d3e3 100644 --- a/client/src/components/communityComponents/index.tsx +++ b/client/src/components/communityComponents/index.tsx @@ -4,8 +4,7 @@ import Comments from "./Comments"; import { DotIcon } from "./IconComponent/Icon"; import axios from "axios"; import { useNavigate } from "react-router-dom"; -const serverUrl = - "http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com:8080/api/boards"; +const serverUrl = "http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com:8080/api/boards"; const TimeLineComponent = () => { const navigate = useNavigate(); @@ -101,9 +100,7 @@ const TimeLineComponent = () => { // 삭제 성공 처리 alert("삭제되었습니다"); // 삭제한 게시물을 클라이언트 데이터에서도 제거 - const updatedBoardData = boardData.filter( - (el) => el.boardId !== boardId - ); // boardId로 수정 + const updatedBoardData = boardData.filter((el) => el.boardId !== boardId); // boardId로 수정 setBoardData(updatedBoardData); } else { alert("삭제 실패"); @@ -123,21 +120,14 @@ const TimeLineComponent = () => { return ( - {openDropDown === false && ( - - )} + {openDropDown === false && } {openDropDown === true && ( <>

{timeLineText.close}

- + Submit @@ -145,9 +135,7 @@ const TimeLineComponent = () => { {boardData.length === 0 ? ( - - {timeLineText.notYetWriting} - + {timeLineText.notYetWriting} ) : ( boardData .slice() @@ -158,11 +146,7 @@ const TimeLineComponent = () => {
handleDotOpen(el.boardId)}>
- {dotMenuOpenMap[el.boardId] && ( - handleDeleteClick(el.boardId)}> - {timeLineText.delete} - - )} + {dotMenuOpenMap[el.boardId] && handleDeleteClick(el.boardId)}>{timeLineText.delete}} {el.member} From c250994674e1b988d6debca54fa91203635b7219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=91=ED=98=84?= Date: Sat, 16 Sep 2023 00:35:04 +0900 Subject: [PATCH 6/6] =?UTF-8?q?[Feat][Fix]=EC=86=8C=EC=85=9C=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=99=84=EB=B2=BD=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EC=86=8C=EC=85=9C=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=84=B1?= =?UTF-8?q?=EA=B3=B5=20=EC=8B=9C=20=EB=A1=9C=EC=BB=AC=20=EC=8A=A4=ED=86=A0?= =?UTF-8?q?=EB=A6=AC=EC=A7=80=EC=97=90=20=EC=97=91=EC=84=B8=EC=8A=A4?= =?UTF-8?q?=ED=86=A0=ED=81=B0,=20=EB=A6=AC=ED=94=84=EB=A0=88=EC=8B=9C=20?= =?UTF-8?q?=ED=86=A0=ED=81=B0=20=EC=A0=80=EC=9E=A5=20=EB=8B=A4=EC=8B=9C=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EB=B2=84=ED=8A=BC=EC=9D=84=20?= =?UTF-8?q?=EB=88=84=EB=A5=BC=20=EC=8B=9C=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=EB=B3=80=ED=99=94=20=EB=B0=8F=20=EC=9B=90?= =?UTF-8?q?=EB=9E=98=20=ED=8E=98=EC=9D=B4=EC=A7=80=EB=A1=9C=20=EB=A0=8C?= =?UTF-8?q?=EB=8D=94=EB=A7=81=20=EB=A1=9C=EA=B7=B8=EC=9D=B8,=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=95=84=EC=9B=83=20=EC=83=81=ED=83=9C=EB=A5=BC=20?= =?UTF-8?q?=EC=A0=84=EC=97=AD=EB=B3=80=EC=88=98=EC=97=90=EC=84=9C=EB=A7=8C?= =?UTF-8?q?=20=EA=B4=80=EB=A6=AC=ED=95=98=EB=8F=84=EB=A1=9D=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20Issues=20#99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/Headers/LoginHeader.tsx | 18 ++-- .../Logins/LoginConfirmatationModal.tsx | 4 - client/src/components/Logins/OAuthLogin.tsx | 83 ++++--------------- client/src/components/Logins/TokenHandler.tsx | 28 +++++++ client/src/page/MainPage.tsx | 36 ++++---- 5 files changed, 75 insertions(+), 94 deletions(-) create mode 100644 client/src/components/Logins/TokenHandler.tsx diff --git a/client/src/components/Headers/LoginHeader.tsx b/client/src/components/Headers/LoginHeader.tsx index 1e5ca928..585dfbee 100644 --- a/client/src/components/Headers/LoginHeader.tsx +++ b/client/src/components/Headers/LoginHeader.tsx @@ -7,16 +7,17 @@ import { useNavigate } from "react-router-dom"; import AlarmImage from "../../asset/images/alarm.png"; import ProfileModal from "../Profile/profileModal"; import StockSearchComponent from './stockSearchComponent'; +import { setLogoutState } from '../../reducer/member/loginSlice'; +import { useDispatch } from 'react-redux'; // 로그인 상태일 때의 헤더 컴포넌트 -const LoginHeader: React.FC = ({ onLogoutClick }) => { +const LoginHeader: React.FC = () => { const [isProfileModalOpen, setProfileModalOpen] = useState(false); // 프로필 모달 상태 const navigate = useNavigate(); // 페이지 이동 함수 - - - const logoutText = "로그아웃"; + const dispatch = useDispatch(); // 👈 useDispatch hook 추가 + // 프로필 모달 열기 함수 const handleProfileOpen = () => { setProfileModalOpen(true); @@ -32,6 +33,12 @@ const LoginHeader: React.FC = ({ onLogoutClick }) => { navigate("/"); // 메인 페이지로 이동 }; + const handleLogout = () => { + dispatch(setLogoutState()); // 전역변수에서 로그아웃 상태로 설정 + localStorage.removeItem("Authorization"); // 엑세스 토큰 제거 + localStorage.removeItem("Refresh-token"); // 리프레시 토큰 제거 +}; + return ( @@ -47,7 +54,7 @@ const LoginHeader: React.FC = ({ onLogoutClick }) => { {isProfileModalOpen && } - {logoutText} + {logoutText} ); @@ -57,7 +64,6 @@ export default LoginHeader; // 로그아웃 클릭 이벤트 타입 정의 interface LoginHeaderProps { - onLogoutClick: () => void; onProfileClick: () => void; } diff --git a/client/src/components/Logins/LoginConfirmatationModal.tsx b/client/src/components/Logins/LoginConfirmatationModal.tsx index 28192757..93ef659b 100644 --- a/client/src/components/Logins/LoginConfirmatationModal.tsx +++ b/client/src/components/Logins/LoginConfirmatationModal.tsx @@ -6,14 +6,10 @@ const LoginConfirmationModal: React.FC = ({ onClose }) = const messageText = "로그인이 성공적으로 완료되었습니다!"; const confirmText = "확인" - - return ( - {messageText} - {confirmText} diff --git a/client/src/components/Logins/OAuthLogin.tsx b/client/src/components/Logins/OAuthLogin.tsx index c34570e0..0cc9e247 100644 --- a/client/src/components/Logins/OAuthLogin.tsx +++ b/client/src/components/Logins/OAuthLogin.tsx @@ -1,71 +1,40 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import styled from 'styled-components'; -// import kakaoLogo from '../../asset/images/KakaoLogo.svg'; -// import axios from 'axios'; -import GoogleLoginButton from './GoogleLoginButton' +import GoogleLoginButton from './GoogleLoginButton'; import KakaoLoginButton from './KakaoLoginButton'; - - - +import { useSelector } from 'react-redux'; +import { RootState } from '../../store/config'; +import TokenHandler from './TokenHandler'; const OAuthLoginModal: React.FC = ({ onClose, onEmailLoginClick, onEmailSignupClick }) => { const titleText = "로그인"; - - // const kakaoLoginText = "카카오로 로그인"; const orText = "또는"; const emailLoginText = "이메일로 로그인"; const emailSignupText = "이메일로 회원가입"; - // URL에서 엑세스 토큰과 리프레시 토큰을 추출합니다. - const urlParams = new URLSearchParams(window.location.search); - const accessToken = urlParams.get("access_token"); - const refreshToken = urlParams.get("refresh_token"); - - if (accessToken && refreshToken) { - // 엑세스 토큰을 로컬 스토리지에 저장합니다. - localStorage.setItem("Authorization", `Bearer ${accessToken}`); - - // 리프레시 토큰을 로컬 스토리지에 저장합니다. - localStorage.setItem("Refresh-token", refreshToken); - } - + const loginState = useSelector((state: RootState) => state.login); + console.log("Login State:", loginState); + - // const handleGoogleLogout = async () => { - // googleLogout(); - // } - - //임시로 비활성화 - - // const handleKakaoLogin = async () => { - // try { - // const response = await axios.get('/oauth2/authorization/kakao'); - // if (response.status === 200) { - // const redirectUri = response.data.uri; - // window.location.href = redirectUri; - // } else { - // console.error("Error logging in with Kakao, unexpected status code:", response.status); - // } - // } catch (error) { - // console.error("Error logging in with Kakao:", error); - // } - // }; + useEffect(() => { + if (loginState === 1) { + onClose(); + } + }, [loginState, onClose]); return ( + × {titleText} - {/*임시로 비활성화 - - {kakaoLoginText} - */} {orText} {emailLoginText} - {emailSignupText} + {emailSignupText} @@ -124,28 +93,6 @@ const OrText = styled.span` color: grey; `; - - -// 임시로 비활성화 -// const KakaoButton = styled.button` -// margin: 10px 0; -// padding: 10px 20px; -// background-color: #FFFFFF; -// border: 1px solid lightgray; -// border-radius: 5px; -// cursor: pointer; -// width: 300px; -// display: flex; -// align-items: center; -// justify-content: center; -// `; - -// const LogoImage = styled.img` -// margin-right: 30px; -// width: 60px; -// height: auto; -// `; - const EmailButtonsContainer = styled.div` display: flex; justify-content: space-around; diff --git a/client/src/components/Logins/TokenHandler.tsx b/client/src/components/Logins/TokenHandler.tsx new file mode 100644 index 00000000..19e1da86 --- /dev/null +++ b/client/src/components/Logins/TokenHandler.tsx @@ -0,0 +1,28 @@ +// TokenHandler.tsx + +import React, { useEffect } from 'react'; +import { useDispatch } from "react-redux"; +import { useNavigate } from 'react-router-dom'; +import { setLoginState } from "../../reducer/member/loginSlice"; + +const TokenHandler: React.FC = () => { + const dispatch = useDispatch(); + const navigate = useNavigate(); + + useEffect(() => { + const urlParams = new URLSearchParams(window.location.search); + const accessToken = urlParams.get("access_token"); + const refreshToken = urlParams.get("refresh_token"); + + if (accessToken && refreshToken) { + localStorage.setItem("Authorization", `Bearer ${accessToken}`); + localStorage.setItem("Refresh-token", refreshToken); + dispatch(setLoginState()); + navigate('/'); + } + }, [dispatch, navigate]); + + return null; // 이 컴포넌트는 UI를 렌더링하지 않습니다. +}; + +export default TokenHandler; diff --git a/client/src/page/MainPage.tsx b/client/src/page/MainPage.tsx index b5b141fd..fbb0dbfb 100644 --- a/client/src/page/MainPage.tsx +++ b/client/src/page/MainPage.tsx @@ -10,18 +10,18 @@ import EmailSignupModal from "../components/Signups/EmailSignup"; import EmailVerificationModal from "../components/Signups/EmailCertify"; import PasswordSettingModal from "../components/Signups/Password"; import CentralChart from "../components/CentralChart/Index"; -import WatchList from "../components/watchlist/WatchList"; -import Holdings from "../components/watchlist/Holdings"; // Assuming you have a Holdings component +import WatchList from "../components/WatchList/WatchList"; +import Holdings from "../components/WatchList/Holdings";// Assuming you have a Holdings component import CompareChartSection from "../components/CompareChartSection/Index"; import StockOrderSection from "../components/StockOrderSection/Index"; import Welcome from "../components/Signups/Welcome"; import ProfileModal from "../components/Profile/profileModal"; import { StateProps } from "../models/stateProps"; import { TabContainerPage } from "./TabPages/TabContainerPage"; +import { RootState } from "../store/config"; // 🔴 로그아웃 관련 action 함수 -import { setLogoutState } from "../reducer/member/loginSlice"; -import { setLoginState } from "../reducer/member/loginSlice"; +import { setLoginState } from "../reducer/member/loginSlice" const MainPage = () => { const expandScreen = useSelector((state: StateProps) => state.expandScreen); @@ -33,6 +33,8 @@ const MainPage = () => { const [isWelcomeModalOpen, setWelcomeModalOpen] = useState(false); const [isProfileModalOpen, setProfileModalOpen] = useState(false); //프로필 모달 보이기/숨기기 + + const openOAuthModal = useCallback(() => { setOAuthModalOpen(true); }, []); @@ -92,23 +94,16 @@ const MainPage = () => { setWelcomeModalOpen(false); }, []); - // 🔴 로그인 지역 상태 제거 → 전역 상태로 대체 (지역 상태 관련된 코드 싹 다 지워야함... -> 전역 상태 만들었으니 전역 상태로 활용) const dispatch = useDispatch(); - const isLogin = useSelector((state: StateProps) => state.login); + const isLogin = useSelector((state: RootState) => state.login); // 🔴 페이지 로드 시 로컬 스토리지의 토큰을 기반으로 로그인 상태를 확인합니다. useEffect(() => { - const authToken = localStorage.getItem("authToken"); + const authToken = localStorage.getItem("Authorization"); if (authToken !== null) { dispatch(setLoginState()); } - }); - - // 🔴 로그아웃 시 로컬스토리지에 있는 Auth 토큰 제거 - const handleLogout = () => { - dispatch(setLogoutState()); - localStorage.removeItem("authToken"); - }; + }, [dispatch]); //프로필 모달 열고닫는 매커니즘 const openProfileModal = useCallback(() => { @@ -123,6 +118,12 @@ const MainPage = () => { dispatch(setLoginState()); }; + // // 🔴 로그아웃 시 로컬스토리지에 있는 Auth 토큰 제거 + // const handleLogout = () => { + // dispatch(setLogoutState()); + // localStorage.removeItem("Authorization"); + // }; + const handleLoginConfirmationClose = () => { setLoginConfirmationModalOpen(false); }; @@ -135,8 +136,11 @@ const MainPage = () => { return ( - {isLogin === 1 ? : } - + {isLogin === 1 ? ( + + ) : ( + + )}
{!expandScreen.left && (