Skip to content

Commit

Permalink
Merge pull request #89 from codestates-seb/dev-client#70/profile
Browse files Browse the repository at this point in the history
[FE]테스트 전 구글로그인, 현금기능 재확인 및 기능 추가Dev client#70/profile
  • Loading branch information
sirloinbh authored Sep 12, 2023
2 parents 1804486 + 29f9245 commit a1c010e
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 42 deletions.
10 changes: 10 additions & 0 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"dependencies": {
"@hyunbinseo/holidays-kr": "^2.2024.4",
"@react-oauth/google": "^0.11.1",
"@reduxjs/toolkit": "^1.9.5",
"axios": "^1.5.0",
"boxicons": "^2.1.4",
Expand Down
47 changes: 47 additions & 0 deletions client/src/components/Logins/GoogleSignin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import { GoogleOAuthProvider, GoogleLogin, useGoogleOneTapLogin } from '@react-oauth/google';
import { useDispatch } from 'react-redux';
import { setLoginState } from '../../reducer/member/loginSlice';

const GoogleSignInComponent: React.FC = () => {

const dispatch = useDispatch(); // Redux의 dispatch 함수를 사용하기 위해 가져옵니다.

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const handleSuccess = (credentialResponse: any) => {
console.log(credentialResponse);

const token = credentialResponse.token; // 실제 응답에서 토큰의 경로가 어떤지 확인하고 수정해야 합니다.
localStorage.setItem('authToken', token); // 토큰을 localStorage에 저장

// 로그인 성공 시 전역 상태를 업데이트합니다.
dispatch(setLoginState({
memberId: credentialResponse.memberId, // memberId는 예시입니다. 실제 값에 맞게 수정해야 합니다.
isLoggedIn: 1,
}));
};

const handleError = () => {
console.log('Login Failed');
};

// One-tap 로그인 (선택적)
useGoogleOneTapLogin({
onSuccess: handleSuccess,
onError: handleError,
});

return (
<GoogleOAuthProvider clientId="
690344785644-2oj84rcukd2rhu3o56gbq6rahap16m37.apps.googleusercontent.com">
<GoogleLogin
onSuccess={handleSuccess}
onError={handleError}
useOneTap
/>
</GoogleOAuthProvider>
);
};

export default GoogleSignInComponent;

4 changes: 2 additions & 2 deletions client/src/components/Logins/OAuthLogin.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import styled from 'styled-components';

import GoogleLogin from './GoogleSignin.tsx'
import kakaoLogo from '../../asset/images/KakaoLogo.svg';
import axios from 'axios';

Expand Down Expand Up @@ -34,7 +34,7 @@ const OAuthLoginModal: React.FC<LoginModalProps> = ({ onClose, onEmailLoginClick
<ModalContainer>
<CloseButton onClick={onClose}>&times;</CloseButton>
<Title>{titleText}</Title>

<GoogleLogin/>
<KakaoButton onClick={handleKakaoLogin}>
<LogoImage src={kakaoLogo} alt="Kakao Logo" />
{kakaoLoginText}
Expand Down
1 change: 1 addition & 0 deletions client/src/components/MarketComponents/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const NewsListLink = {

const Market = styled.div`
text-align: center;
height: 600px;
`;
const News = styled.div`
display: flex;
Expand Down
33 changes: 20 additions & 13 deletions client/src/components/Profile/cashModal.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import React, { useState } from 'react';
import styled from 'styled-components';
import { useSelector, useDispatch } from 'react-redux';
import { useCreateCash, useGetCash, useUpdateCash } from '../../hooks/useCash';
import { useCreateCash, useGetCash, useResetCash } from '../../hooks/useCash';
import { RootState } from '../../store/config';
import { setCashId, setCashAmount } from '../../reducer/cash/cashSlice';

const CashModal: React.FC<CashModalProps> = ({ onClose }) => {

const titleText = "현금";
const cashCreationPlaceholder = "생성할 현금 입력";
const createCashButtonText = "현금 생성";
const cashInputPlaceholder = "현금 입력";
const resetButtonText = "리셋";

const dispatch = useDispatch();
const cashId = useSelector((state: RootState) => state.cash.cashId);
const cashAmount = useSelector((state: RootState) => state.cash.cashAmount) || 0;

const createCashMutation = useCreateCash();
const { data: cashData, isLoading } = useGetCash(cashId);
const updateCashMutation = useUpdateCash();
const updateCashMutation = useResetCash();

const [cashInput, setCashInput] = useState<string>('');
const [initialAmount, setInitialAmount] = useState<number>(0); // 현금 생성을 위한 상태 변수
Expand All @@ -31,36 +38,37 @@ const CashModal: React.FC<CashModalProps> = ({ onClose }) => {
dispatch(setCashAmount(cashData.data.cash));
}

// 현금 충전 및 충전된 현금량 전역 저장
const handleCashReceive = () => {
if (cashId && cashAmount !== null) {
// 현금을 입력한 금액으로 리셋하는 함수
const handleCashReset = () => {
if (cashId) {
const numericCashId = parseInt(cashId, 10); // cashId를 숫자로 변환
const numericCashAmount = Number(cashInput); // cashInput을 숫자로 변환
updateCashMutation.mutate({ cashId: numericCashId, cashAmount: numericCashAmount }, {
onSuccess: () => {
dispatch(setCashAmount((prevCash: number) => prevCash ? prevCash + numericCashAmount : numericCashAmount));
dispatch(setCashAmount(numericCashAmount)); // 현금 금액을 입력한 금액으로 리셋
}
});
} else {
console.error("cashId or cashAmount is null or not a valid number.");
console.error("cashId is null or not a valid number.");
}
};


return (
<ModalBackground>
<ModalContainer>
<CloseButton onClick={onClose}>&times;</CloseButton>
<Title>현금</Title>
<Title>{titleText}</Title>

{/* 현금 생성 입력창 및 버튼 추가 */}
<div>
<CashCreationInput
type="number"
value={initialAmount}
onChange={e => setInitialAmount(Number(e.target.value))}
placeholder="생성할 현금 입력"
placeholder={cashCreationPlaceholder}
/>
<CreateCashButton onClick={handleCreateCash}>현금 생성</CreateCashButton>
<CreateCashButton onClick={handleCreateCash}>{createCashButtonText}</CreateCashButton>
</div>

<p>현재 현금: {isLoading ? 'Loading...' : cashAmount.toLocaleString()}</p>
Expand All @@ -69,16 +77,15 @@ const CashModal: React.FC<CashModalProps> = ({ onClose }) => {
type="number"
value={cashInput}
onChange={e => setCashInput(e.target.value)}
placeholder="현금 입력"
placeholder={cashInputPlaceholder}
/>
<ReceiveButton onClick={handleCashReceive}>받기</ReceiveButton>
<ReceiveButton onClick={handleCashReset}>{resetButtonText}</ReceiveButton>
</div>
</ModalContainer>
</ModalBackground>
);
};


interface CashModalProps {
onClose: () => void;
cashId: string | null;
Expand Down
1 change: 1 addition & 0 deletions client/src/components/communityComponents/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ const TimeLine = styled.div`
flex-direction: column;
align-content: space-around;
flex-wrap: wrap;
max-height:600px;
`;
//게시글 삭제
const Delete = styled.div`
Expand Down
36 changes: 26 additions & 10 deletions client/src/components/watchlist/Holdings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ const Holdings: React.FC<HoldingsProps> = ({ currentListType, onChangeListType }
</SlideMenu>
)}
</Header>
<Divider />
<Divider1 />
<EvaluationProfit>평가 수익금: +5,000,000원</EvaluationProfit> {/* 임의의 평가 수익금 */}
<Divider />
<Divider2 />
{holdingsData.map(stock => (
<>
<StockItem key={stock.name}>
Expand Down Expand Up @@ -88,10 +88,11 @@ const getColorByChange = (change: string) => {
};

const HoldingsContainer = styled.div`
padding: 16px;
padding: 8px 0px;
`;

const Header = styled.div`
padding:0px 16px;
display: flex;
align-items: center;
position: relative;
Expand Down Expand Up @@ -186,17 +187,32 @@ const getColorByChange = (change: string) => {
cursor: pointer; // 마우스 포인터 변경 추가
`;

const Divider = styled.div`
height: 1px;
background-color: #aaa; // 회색으로 설정
margin: 8px 0; // 상하 여백 추가
const Divider1 = styled.div`
margin:0px;
padding:0px;
width: 100%;
height: 11px;
display: flex;
flex-direction: row;
border-bottom: 1px solid #2f4f4f;
`;


const Divider2 = styled.div`
margin:0px;
padding:0px;
width: 100%;
height: 4.5px;
display: flex;
flex-direction: row;
border-bottom: 1px solid #2f4f4f;
`;



const EvaluationProfit = styled.div`
font-size: 16px;
font-weight: bold;
margin: 10px 0;
margin: 8px 0;
text-align: center;
color: red; // 수익금이 플러스일 경우 초록색으로 표시
`;
Expand Down Expand Up @@ -238,7 +254,7 @@ const ColoredDetailData = styled.span.attrs<{ value: string }>(({ value }) => ({
`;

const ThickDivider = styled.div`
height: 2px;
height: 3px;
background-color: #aaa;
margin: 8px 0;
`;
Expand Down
29 changes: 21 additions & 8 deletions client/src/components/watchlist/WatchList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ const WatchList: React.FC<WatchListProps> = ({ currentListType, onChangeListType
</SlideMenu>
)}
</Header>
<Divider />
<Divider1 />
<AddStockButton onClick={() => { /* 종목 추가 로직 */ }}>종목 추가</AddStockButton>
<Divider />
<Divider2 />
{favoriteStocks.map(stock => (
<StockItem key={stock.name}>
<Logo src={stock.logo} alt="stock logo"/>
Expand Down Expand Up @@ -77,7 +77,7 @@ const getColorByChange = (change: string) => {
};

const WatchListContainer = styled.div`
padding: 16px;
padding: 8px 0px;
`;

const Header = styled.div`
Expand Down Expand Up @@ -175,14 +175,27 @@ const StockChange = styled.span.attrs<{ change: string }>(({ change }) => ({
cursor: pointer;
`;

const Divider = styled.div`
height: 1px;
background-color: #aaa;
margin: 8px 0;
const Divider1 = styled.div`
margin:0px;
padding:0px;
width: 100%;
height: 11px;
display: flex;
flex-direction: row;
border-bottom: 1px solid #2f4f4f;
`;
const Divider2 = styled.div`
margin:0px;
padding:0px;
width: 100%;
height: 4px;
display: flex;
flex-direction: row;
border-bottom: 1px solid #2f4f4f;
`;

const AddStockButton = styled.button`
padding: 10px 20px;
padding: 10px;
border: none;
background-color: transparent;
cursor: pointer;
Expand Down
4 changes: 2 additions & 2 deletions client/src/hooks/useCash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ export const useGetCash = (cashId: string | null) => {
}


export const useUpdateCash = () => {
return useMutation((data: { cashId: number, cashAmount: number }) => axios.post(`http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com/cash/${data.cashId}`, { cash: data.cashAmount }));
export const useResetCash = () => {
return useMutation((data: { cashId: number, cashAmount: number }) => axios.patch(`http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com/cash/${data.cashId}`, { cash: data.cashAmount }));
}
5 changes: 1 addition & 4 deletions client/src/page/MainPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,8 @@ import Holdings from "../components/watchlist/Holdings"; // Assuming you have a
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";

const MainPage = () => {
Expand Down Expand Up @@ -200,7 +197,7 @@ const MainPage = () => {
}}
/>
)}
{isProfileModalOpen && <ProfileModal onClose={() => setProfileModalOpen(false)} />} //프로필 모달 컴포넌트 렌더링
{isProfileModalOpen && <ProfileModal onClose={() => setProfileModalOpen(false)} />}

</Container>
);
Expand Down
6 changes: 3 additions & 3 deletions client/src/reducer/member/loginSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ const loginSlice = createSlice({
name: 'login',
initialState: {
memberId: null,
isLoggedOut: 1
isLoggedIn: 1
},
reducers: {
setLoginState: (state, action) => {
state.memberId = action.payload;
state.isLoggedOut = 0;
state.isLoggedIn = 1;
},
setLogoutState: (state) => {
state.memberId = null;
state.isLoggedOut = 1;
state.isLoggedIn = 0;
},
updateMemberId: (state, action) => {
state.memberId = action.payload;
Expand Down

0 comments on commit a1c010e

Please sign in to comment.