Skip to content

Commit

Permalink
[Add] 브랜치 병합
Browse files Browse the repository at this point in the history
- 로그인/로그아웃 관련 기능 구현으로 인한 브랜치 병합

Issues #17
  • Loading branch information
novice1993 committed Sep 15, 2023
2 parents 2ccaa78 + 67e86b3 commit 9d5ed6d
Show file tree
Hide file tree
Showing 11 changed files with 175 additions and 119 deletions.
18 changes: 12 additions & 6 deletions client/src/components/Headers/LoginHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<LoginHeaderProps> = ({ onLogoutClick }) => {
const LoginHeader: React.FC<LoginHeaderProps> = () => {
const [isProfileModalOpen, setProfileModalOpen] = useState(false); // 프로필 모달 상태
const navigate = useNavigate(); // 페이지 이동 함수



const logoutText = "로그아웃";
const dispatch = useDispatch(); // 👈 useDispatch hook 추가

// 프로필 모달 열기 함수
const handleProfileOpen = () => {
setProfileModalOpen(true);
Expand All @@ -32,6 +33,12 @@ const LoginHeader: React.FC<LoginHeaderProps> = ({ onLogoutClick }) => {
navigate("/"); // 메인 페이지로 이동
};

const handleLogout = () => {
dispatch(setLogoutState()); // 전역변수에서 로그아웃 상태로 설정
localStorage.removeItem("Authorization"); // 엑세스 토큰 제거
localStorage.removeItem("Refresh-token"); // 리프레시 토큰 제거
};

return (
<HeaderContainer>
<LogoButton onClick={handleLogoClick}>
Expand All @@ -47,7 +54,7 @@ const LoginHeader: React.FC<LoginHeaderProps> = ({ onLogoutClick }) => {
<ProfileImage src={SampleProfile} />
</ProfileButton>
{isProfileModalOpen && <ProfileModal onClose={handleProfileClose} />}
<LogoutButton onClick={onLogoutClick}>{logoutText}</LogoutButton>
<LogoutButton onClick={handleLogout}>{logoutText}</LogoutButton>
</UserActions>
</HeaderContainer>
);
Expand All @@ -57,7 +64,6 @@ export default LoginHeader;

// 로그아웃 클릭 이벤트 타입 정의
interface LoginHeaderProps {
onLogoutClick: () => void;
onProfileClick: () => void;
}

Expand Down
35 changes: 35 additions & 0 deletions client/src/components/Logins/GoogleLoginButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// GoogleLoginButton.tsx

import React from 'react';

interface Props {
backendURL: string;
}

const GoogleLoginButton: React.FC<Props> = ({ backendURL }) => {
const handleLoginClick = () => {
window.location.href = `${backendURL}`;
};

return (
<button onClick={handleLoginClick}>
Login with Google
</button>
);
}

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);
35 changes: 35 additions & 0 deletions client/src/components/Logins/KakaoLoginButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// KakaoLoginButton.tsx

import React from 'react';

interface Props {
backendURL: string;
}

const KakaoLoginButton: React.FC<Props> = ({ backendURL }) => {
const handleLoginClick = () => {
window.location.href = `${backendURL}`;
};

return (
<button onClick={handleLoginClick}>
Login with Kakao
</button>
);
}

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);
13 changes: 13 additions & 0 deletions client/src/components/Logins/Login.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Google Login</title>
</head>
<body>
<div>
<a href="/oauth2/authorization/google">Google 로그인</a>
</div>
</body>
</html>
4 changes: 0 additions & 4 deletions client/src/components/Logins/LoginConfirmatationModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,10 @@ const LoginConfirmationModal: React.FC<LoginConfirmationProps> = ({ onClose }) =
const messageText = "로그인이 성공적으로 완료되었습니다!";
const confirmText = "확인"



return (
<ModalBackground>
<ModalContainer>

<Message>{messageText}</Message>

<ConfirmButton onClick={onClose}>{confirmText}</ConfirmButton>
</ModalContainer>
</ModalBackground>
Expand Down
75 changes: 18 additions & 57 deletions client/src/components/Logins/OAuthLogin.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +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 { GoogleOAuthProvider, GoogleLogin, googleLogout } from '@react-oauth/google';
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<LoginModalProps> = ({ onClose, onEmailLoginClick, onEmailSignupClick }) => {
const titleText = "로그인";

const kakaoLoginText = "카카오로 로그인";
const orText = "또는";
const emailLoginText = "이메일로 로그인";
const emailSignupText = "이메일로 회원가입";

// const handleGoogleLogout = async () => {
// googleLogout();
// }
const loginState = useSelector((state: RootState) => state.login);
console.log("Login State:", loginState);



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 (
<ModalBackground>
<ModalContainer>
<TokenHandler />
<CloseButton onClick={onClose}>&times;</CloseButton>
<Title>{titleText}</Title>
{/* <GoogleOAuthProvider clientId="<your_client_id>">
<GoogleLogin
onSuccess={credentialResponse => {
console.log(credentialResponse);
}}
onError={() => {
console.log('Login Failed');
}}
/>;
</GoogleOAuthProvider>; */}
<KakaoButton onClick={handleKakaoLogin}>
<LogoImage src={kakaoLogo} alt="Kakao Logo" />
{kakaoLoginText}
</KakaoButton>
<GoogleLoginButton backendURL="http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com:8080/oauth2/authorization/google" />
<KakaoLoginButton backendURL="http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com:8080/oauth2/authorization/kakao" />
<OrText>{orText}</OrText>
<EmailButtonsContainer>
<EmailButton onClick={onEmailLoginClick}>{emailLoginText}</EmailButton>
<EmailButton onClick={onEmailSignupClick}>{emailSignupText}</EmailButton>
<EmailButton onClick={onEmailSignupClick}>{emailSignupText}</EmailButton>
</EmailButtonsContainer>
</ModalContainer>
</ModalBackground>
Expand Down Expand Up @@ -111,27 +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;
Expand Down
28 changes: 28 additions & 0 deletions client/src/components/Logins/TokenHandler.tsx
Original file line number Diff line number Diff line change
@@ -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;
3 changes: 3 additions & 0 deletions client/src/components/StockOrderSection/OrderResult.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ const OrderResult = () => {
const orderWaitList = orderRecordData.filter((order: OrderRecordProps) => order.orderStates === "ORDER_WAIT");
const orderCompleteList = orderRecordData.filter((order: OrderRecordProps) => order.orderStates === "ORDER_COMPLETE");

// 최근 주문이 상단에 노출되도록 배열 순서 변경
// orderWaitList.reverse();
// orderCompleteList.reverse();
const orderList = recordType ? orderCompleteList : orderWaitList;
const orderListNum = orderList.length;

Expand Down
19 changes: 5 additions & 14 deletions client/src/components/communityComponents/Comments.tsx
Original file line number Diff line number Diff line change
@@ -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<CommentData[]>(() => {
// 게시물별로 로컬 스토리지에서 댓글 데이터를 가져옵니다.
const storedData = localStorage.getItem(`commentData_${postId}`);
const storedData = localStorage.getItem(`commentData_${boardId}`);
return storedData ? JSON.parse(storedData) : [];
});

Expand All @@ -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("");
Expand All @@ -51,14 +48,8 @@ const Comments = ({ postId }: { postId: number }) => {
return (
<CommentContainer>
<div>
<CommentInput
type="text"
value={commentsValue}
onChange={handleOnChange}
/>
<CommentInputSubmit onClick={() => handleClickSubmit()}>
{CommentText.write}
</CommentInputSubmit>
<CommentInput type="text" value={commentsValue} onChange={handleOnChange} />
<CommentInputSubmit onClick={() => handleClickSubmit()}>{CommentText.write}</CommentInputSubmit>
<CommentCount onClick={handleShowMoreComments}>
{CommentText.replyCount}
{commentData.length}
Expand Down
Loading

0 comments on commit 9d5ed6d

Please sign in to comment.