diff --git a/client/src/components/Profile/cashModal.tsx b/client/src/components/Profile/cashModal.tsx index 7032295b..866ff083 100644 --- a/client/src/components/Profile/cashModal.tsx +++ b/client/src/components/Profile/cashModal.tsx @@ -1,49 +1,69 @@ -import React, { useState, useEffect } from 'react'; -import styled from 'styled-components'; -import axios from 'axios'; +import React, { useState } from 'react'; +import styled from 'styled-components'; +import { useSelector, useDispatch } from 'react-redux'; +import { useCreateCash, useGetCash, useUpdateCash } from '../../hooks/useCash'; +import { RootState } from '../../store/config'; +import { setCashId, setCashAmount } from '../../reducer/cash/cashSlice'; -const CashModal: React.FC = ({ onClose, memberId }) => { - const [cash, setCash] = useState(null); - const [cashInput, setCashInput] = useState(''); +const CashModal: React.FC = ({ onClose }) => { + 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(); - useEffect(() => { - axios.get(`http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com/cash/${memberId}`) - .then(response => { - if (response.status === 200) { - setCash(response.data.cash); - } else if (response.status === 204) { - // Handle the "No Content" scenario. This could be setting cash to 0 or displaying a message. - setCash(0); // Or handle it in a way that suits your needs - } - }) - .catch(error => { - console.error("Error fetching cash:", error); - }); - }, [memberId]); + const [cashInput, setCashInput] = useState(''); + const [initialAmount, setInitialAmount] = useState(0); // 현금 생성을 위한 상태 변수 - const handleCashReceive = () => { - axios.post(`http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com/cash/${memberId}`, { - cash: cashInput - }) - .then(response => { - if (response.status === 201) { - // Update the cash display with the new value - setCash(prevCash => prevCash ? prevCash + Number(cashInput) : Number(cashInput)); - } else { - console.warn("Unexpected status code:", response.status); + // 현금 생성 및 cashId 전역 저장 + const handleCreateCash = () => { + createCashMutation.mutate(initialAmount, { + onSuccess: (data) => { + dispatch(setCashId(data.data.cashId)); } - }) - .catch(error => { - console.error("Error updating cash:", error); }); }; + // 보유 현금량 조회 및 전역 저장 + if (cashData && cashAmount !== cashData.data.cash) { + dispatch(setCashAmount(cashData.data.cash)); + } + + // 현금 충전 및 충전된 현금량 전역 저장 + const handleCashReceive = () => { + if (cashId && cashAmount !== null) { + 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)); + } + }); + } else { + console.error("cashId or cashAmount is null or not a valid number."); + } + }; + return ( × 현금 -

현재 현금: {cash ? cash.toLocaleString() : 'Loading...'}

+ + {/* 현금 생성 입력창 및 버튼 추가 */} +
+ setInitialAmount(Number(e.target.value))} + placeholder="생성할 현금 입력" + /> + 현금 생성 +
+ +

현재 현금: {isLoading ? 'Loading...' : cashAmount.toLocaleString()}

= ({ onClose, memberId }) => { ); }; + interface CashModalProps { onClose: () => void; - memberId: string; + cashId: string | null; } // Styled Components Definitions: @@ -119,5 +140,20 @@ const ReceiveButton = styled.button` border-radius: 5px; cursor: pointer; `; +const CashCreationInput = styled.input` + padding: 10px; + border: 1px solid lightgray; + border-radius: 5px; + margin-right: 10px; +`; + +const CreateCashButton = styled.button` + padding: 10px 15px; + background-color: blue; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; +`; export default CashModal; diff --git a/client/src/components/Profile/profileModal.tsx b/client/src/components/Profile/profileModal.tsx index c8754d2a..97601a83 100644 --- a/client/src/components/Profile/profileModal.tsx +++ b/client/src/components/Profile/profileModal.tsx @@ -1,10 +1,14 @@ 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 = ({ onClose }) => { const [selectedTab, setSelectedTab] = useState(1); + const cashId = useSelector((state: RootState) => state.cash.cashId); // Get cashId from Redux store const handleTabChange = (tabNumber: number) => { setSelectedTab(tabNumber); @@ -21,7 +25,7 @@ const ProfileModal: React.FC = ({ onClose }) => { {selectedTab === 1 && } - {selectedTab === 2 &&
현금 Content
} + {selectedTab === 3 && } {/* 회원탈퇴 모달 추가 */}
diff --git a/client/src/hooks/useCash.ts b/client/src/hooks/useCash.ts new file mode 100644 index 00000000..ade93b0b --- /dev/null +++ b/client/src/hooks/useCash.ts @@ -0,0 +1,34 @@ +// hooks/useCash.ts +import { useQuery, useMutation } from 'react-query'; +import axios from 'axios'; + +export const useCreateCash = () => { + return useMutation((initialAmount: number) => axios.post('http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com/cash', { cash: initialAmount })); +} + +export const useGetCash = (cashId: string | null) => { + const queryFn = () => { + if (!cashId) { + throw new Error("Cash ID is not provided."); + } + return axios.get(`http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com/cash/${cashId}`); + }; + + const queryResult = useQuery(['cash', cashId], queryFn, { + enabled: !!cashId, + }); + + if (!cashId) { + return { + ...queryResult, + data: null + }; + } + + return queryResult; +} + + +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 })); +} \ No newline at end of file diff --git a/client/src/reducer/cash/cashSlice.ts b/client/src/reducer/cash/cashSlice.ts new file mode 100644 index 00000000..f141e507 --- /dev/null +++ b/client/src/reducer/cash/cashSlice.ts @@ -0,0 +1,21 @@ +// store/cashSlice.ts +import { createSlice } from '@reduxjs/toolkit'; + +const cashSlice = createSlice({ + name: 'cash', + initialState: { + cashId: null, + cashAmount: null, + }, + reducers: { + setCashId: (state, action) => { + state.cashId = action.payload; + }, + setCashAmount: (state, action) => { + state.cashAmount = action.payload; + }, + }, +}); + +export const { setCashId, setCashAmount } = cashSlice.actions; +export default cashSlice.reducer; \ No newline at end of file diff --git a/client/src/store/config.ts b/client/src/store/config.ts index becb5721..f5c218f8 100644 --- a/client/src/store/config.ts +++ b/client/src/store/config.ts @@ -7,6 +7,7 @@ import { stockOrderSetReducer } from "../reducer/StockOrderSet-Reducer"; import { companyIdReducer } from "../reducer/CompanyId-Reducer"; import memberInfoReducer from '../reducer/member/memberInfoSlice'; import loginReducer from '../reducer/member/loginSlice'; +import cashSlice from '../reducer/cash/cashSlice'; const store = configureStore({ @@ -19,6 +20,7 @@ const store = configureStore({ companyId: companyIdReducer, memberInfo: memberInfoReducer, login: loginReducer, + cash: cashSlice, }, });