Skip to content

Commit

Permalink
[Fix]현금 모달 정상화
Browse files Browse the repository at this point in the history
moneyId ->cashId, moneyAmount ->money 로 변수명 변경
useCash훅에서 전역변수를 도입하여 불러낸 데이터를 저장하도록 변경
cashModal 기능을 변경
Issues #70
  • Loading branch information
김병현 authored and 김병현 committed Sep 16, 2023
1 parent 467ad0e commit aa35233
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 77 deletions.
13 changes: 8 additions & 5 deletions client/src/components/EntireList/EntireList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import styled from 'styled-components';
import Header from './Header';
import StockItem from './StockItem';
import useCompanyData from '../../hooks/useCompanyData';
import { useGetCash } from '../../hooks/useCash'; // 훅 가져오기
import { useSelector } from 'react-redux';
import { RootState } from '../../store/config';

const EntireList: React.FC<EntireListProps> = ({ currentListType, onChangeListType }) => {
const [isMenuOpen, setMenuOpen] = useState(false);
Expand All @@ -16,9 +17,9 @@ const EntireList: React.FC<EntireListProps> = ({ currentListType, onChangeListTy
const companiesList = companies || [];

// 현금 보유량 가져오기
const moneyId = localStorage.getItem('moneyId');
const { data: cashData } = useGetCash(moneyId);
const holdingsAmount = cashData?.data?.money || "0";
// 현금 보유량 가져오기: Redux store에서 직접 가져옵니다.
const holdingsAmount = useSelector((state: RootState) => state.cash.money) || "0";


return (
<WatchListContainer>
Expand Down Expand Up @@ -51,6 +52,8 @@ const EntireList: React.FC<EntireListProps> = ({ currentListType, onChangeListTy
);
};

export default EntireList;

// Props와 상태에 대한 타입 정의
type EntireListProps = {
currentListType: '전체종목' | '관심종목' | '보유종목';
Expand Down Expand Up @@ -99,4 +102,4 @@ const StockList = styled.div`
overflow-y: auto; /* 세로 스크롤을 활성화합니다 */
`;

export default EntireList;

58 changes: 26 additions & 32 deletions client/src/components/Profile/cashModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,71 +3,66 @@ import styled from 'styled-components';
import { useSelector, useDispatch } from 'react-redux';
import { useCreateCash, useGetCash, useResetCash } from '../../hooks/useCash';
import { RootState } from '../../store/config';
import { setMoneyId, setMoneyAmount } from '../../reducer/cash/cashSlice';
import { setCashId, setMoney } from '../../reducer/cash/cashSlice';

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

// 상태 및 변수 초기화
const titleText = "현금";
const cashCreationPlaceholder = "생성할 현금 입력";
const createCashButtonText = "현금 생성";
const cashInputPlaceholder = "현금 입력";
const resetButtonText = "리셋";
const refreshButtonText ="새로고침"
const refreshButtonText ="새로고침";

const dispatch = useDispatch();
const moneyId = useSelector((state: RootState) => state.cash.moneyId);
const moneyAmount = useSelector((state: RootState) => state.cash.moneyAmount) || '0';
const cashId = useSelector((state: RootState) => state.cash.cashId);
const money = useSelector((state: RootState) => state.cash.money) || '0';

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

const [cashInput, setCashInput] = useState<string>('0');
const [initialAmount, setInitialAmount] = useState<string>('0'); // 현금 생성을 위한 상태 변수

// 현금 정보 재조회 함수
const refreshCashInfo = () => {
// 여기에 현금 정보를 다시 불러오는 로직을 추가합니다.
// 예: useGetCash() hook을 다시 호출한다던지, 특정 상태를 변경하여 리렌더링을 유발하는 등의 방법이 있습니다.
cashQuery.refetch(); // 현금 정보를 다시 가져옵니다.
};

// 현금 생성 및 cashId 전역 저장
// 현금 생성 및 cashId 전역 저장 함수
const handleCreateCash = () => {
createCashMutation.mutate(initialAmount, {
onSuccess: (data) => {
dispatch(setMoneyId(data.data.moneyId));
}
});
createCashMutation.mutate(initialAmount);
};

// 보유 현금량 조회 및 전역 저장
if (cashData && moneyAmount !== cashData.data.cash) {
dispatch(setMoneyAmount(cashData.data.cash));
// 보유 현금량 조회 및 전역 저장 함수
if (cashQuery.data && money !== cashQuery.data.data.cash) {
dispatch(setMoney(cashQuery.data.data.cash));
}

// 현금을 입력한 금액으로 리셋하는 함수
// 입력한 금액으로 현금 리셋 함수
const handleCashReset = () => {
if (moneyId) {
const numericCashId = parseInt(moneyId, 10); // cashId를 숫자로 변환
const numericCashAmount =cashInput; // cashInput을 숫자로 변환
updateCashMutation.mutate({ moneyId: numericCashId, money: numericCashAmount }, {
if (cashId) {
const numericCashAmount = cashInput; // cashInput을 숫자로 변환
updateCashMutation.mutate({ money: numericCashAmount }, {
onSuccess: () => {
dispatch(setMoneyAmount(numericCashAmount)); // 현금 금액을 입력한 금액으로 리셋
dispatch(setMoney(numericCashAmount)); // 현금 금액을 입력한 금액으로 리셋
dispatch(setCashId(cashId) );
}
});
} else {
console.error("moneyId 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>{titleText}</Title>

{/* 현금 생성 입력창 및 버튼 추가 */}
{/* 현금 생성 입력창 및 버튼 */}
<div>
<CashCreationInput
type="string"
Expand All @@ -79,7 +74,7 @@ const CashModal: React.FC<CashModalProps> = ({ onClose }) => {
</div>
<div>
<p style={{ display: 'inline-block', margin: '20px' }}>
현재 현금: {isLoading ? 'Loading...' : moneyAmount.toLocaleString()}
현재 현금: {cashQuery.isLoading ? 'Loading...' : money.toLocaleString()}
</p>
<RefreshButton onClick={refreshCashInfo}>{refreshButtonText}</RefreshButton>
</div>
Expand All @@ -99,10 +94,9 @@ const CashModal: React.FC<CashModalProps> = ({ onClose }) => {

export default CashModal;

interface CashModalProps {
onClose: () => void;
moneyId: number | null;
}
// interface CashModalProps {
// onClose: () => void;
// }

// Styled Components Definitions:

Expand Down
19 changes: 7 additions & 12 deletions client/src/components/Profile/profileModal.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,29 @@
import React, { useState } from 'react';
import styled from 'styled-components';
import { useSelector } from 'react-redux';
import MemberInfoModal from './memberInfoModal';
import MemberWithdrawalModal from './memberWithdrawalModal';
import CashModal from './cashModal';
import { RootState } from '../../store/config';

const ProfileModal: React.FC<ProfileModalProps> = ({ onClose }) => {

const memberInfoText = "회원정보";
const cashText = "현금";
const memberWithdrawText = "회원탈퇴";
const moneyId = useSelector((state: RootState) => state.cash.moneyId);

const [selectedTab, setSelectedTab] = useState(1); // 1: MemberInfo, 2: CashModal, 3: WithdrawalModal
const [selectedTab, setSelectedTab] = useState(1);

return (
<ModalBackground>
<ModalContainer>
<Tabs>
<TabButton isActive={selectedTab === 1} onClick={() => setSelectedTab(1)}>{memberInfoText}</TabButton>
<TabButton isActive={selectedTab === 2} onClick={() => setSelectedTab(2)}>{cashText}</TabButton>
<TabButton isActive={selectedTab === 3} onClick={() => setSelectedTab(3)}>{memberWithdrawText}</TabButton>
</Tabs>
<Tabs>
<TabButton isActive={selectedTab === 1} onClick={() => setSelectedTab(1)}>{memberInfoText}</TabButton>
<TabButton isActive={selectedTab === 2} onClick={() => setSelectedTab(2)}>{cashText}</TabButton>
<TabButton isActive={selectedTab === 3} onClick={() => setSelectedTab(3)}>{memberWithdrawText}</TabButton>
</Tabs>
<TabContent>
{selectedTab === 1 && <MemberInfoModal onClose={onClose} />}
{selectedTab === 2 && <CashModal onClose={onClose} moneyId={moneyId} />}
{selectedTab === 2 && <CashModal onClose={onClose} />}
{selectedTab === 3 && <MemberWithdrawalModal onClose={onClose} />}
</TabContent>
{/* <CloseButton onClick={onClose}>&times;</CloseButton> */}
</ModalContainer>
</ModalBackground>
);
Expand Down
100 changes: 81 additions & 19 deletions client/src/hooks/useCash.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { useQuery, useMutation } from 'react-query';
import axios from 'axios';
import axios, { AxiosError } from 'axios';
import { useDispatch } from 'react-redux';
import { setCashId, setMoney } from '../reducer/cash/cashSlice';
import { useSelector } from 'react-redux';
import { RootState } from '../store/config';

const BASE_URL = 'http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com:8080';

Expand All @@ -12,37 +16,95 @@ const getAuthHeader = () => {
};

export const useCreateCash = () => {
const dispatch = useDispatch();
return useMutation((initialAmount: string) => axios.post(`${BASE_URL}/cash`, { "money": initialAmount }, {
headers: getAuthHeader()
}));
}), {
onSuccess: (res) => {
// 200번 응답 처리
dispatch(setCashId(res.data.cashId));
dispatch(setMoney(res.data.money));
},
onError: (error) => {
const axiosError = error as AxiosError<ErrorResponse>;
if (axiosError?.response?.status === 400 || axiosError?.response?.status === 401) {
// 에러 메시지 출력
const errorMessage = axiosError?.response?.data?.message || 'Unknown error occurred.';
alert(errorMessage);
}
}
});
}

export const useGetCash = (moneyId: string | null) => {


export const useGetCash = () => {
const dispatch = useDispatch();
const queryFn = () => {
if (!moneyId) {
throw new Error("Cash ID is not provided.");
}
return axios.get(`${BASE_URL}/cash`, {
headers: getAuthHeader()
});
};

const queryResult = useQuery(['money', moneyId], queryFn, {
enabled: !!moneyId,
return useQuery('money', queryFn, {
onSuccess: (res) => {
// 200번 응답 처리
dispatch(setCashId(res.data.cashId));
dispatch(setMoney(res.data.money));
},
onError: (error) => {
const axiosError = error as AxiosError<ErrorResponse>;
switch (axiosError?.response?.status) {
case 400:
case 401:
case 404: {
// 중괄호 내에서 변수 선언
const errorMessage = axiosError?.response?.data?.message || 'Unknown error occurred.';
alert(errorMessage);
break;
}
default:
alert('Unknown error occurred.');
break;
}
},
refetchInterval: false, // 자동 재요청 비활성화
retry: false // 재시도 비활성화
});

if (!moneyId) {
return {
...queryResult,
data: null
};
}

return queryResult;
}


export const useResetCash = () => {
return useMutation((data: { moneyId: number, money: string }) => axios.patch(`${BASE_URL}/cash/${data.moneyId}`, { "money": data.money }, {
const cashId = useSelector((state: RootState) => state.cash.cashId); // cashId를 전역 상태에서 가져옵니다.
const dispatch = useDispatch();

return useMutation((data: { money: string }) => axios.patch(`${BASE_URL}/cash/${cashId}`, { "money": data.money }, {
headers: getAuthHeader()
}));
}), {
onSuccess: (data) => {
// 200번 응답 처리
dispatch(setCashId(data.data.cashId));
dispatch(setMoney(data.data.money));
},
onError: (error) => {
const axiosError = error as AxiosError<ErrorResponse>;
switch (axiosError?.response?.status) {
case 400:
case 401:
case 404: {
const errorMessage = axiosError?.response?.data?.message || 'Unknown error occurred.';
alert(errorMessage);
break;
}
default:
alert('Unknown error occurred.');
break;
}
}
});
}


interface ErrorResponse {
message: string;
}
17 changes: 8 additions & 9 deletions client/src/reducer/cash/cashSlice.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
// store/cashSlice.ts
import { createSlice } from "@reduxjs/toolkit";

const cashSlice = createSlice({
name: "cash",
initialState: {
moneyId: null,
moneyAmount: null,
cashId: null,
money: null,
},
reducers: {
setMoneyId: (state, action) => {
state.moneyId = action.payload;
setCashId: (state, action) => {
state.cashId = action.payload;
},
setMoneyAmount: (state, action) => {
state.moneyAmount = action.payload;
setMoney: (state, action) => {
state.money = action.payload;
},
},
});

export const { setMoneyId, setMoneyAmount } = cashSlice.actions;
export default cashSlice.reducer;
export const { setCashId, setMoney } = cashSlice.actions;
export default cashSlice.reducer;

0 comments on commit aa35233

Please sign in to comment.