Skip to content

Commit

Permalink
[Feat] 매수/매도 버튼 클릭 시 렌더링 되는 모달창 구현
Browse files Browse the repository at this point in the history
- 매수/매도 관련 경우의 수 고려하여 렌더링 되는 모달창 구분
- 매수/매도 관련 종목/거래가/거래량/총 거래가 정보 기입하여 구매 확인의사 확인하는 모달창까지 모두 구현

Issues #17
  • Loading branch information
novice1993 committed Sep 11, 2023
1 parent 9ed9429 commit ed77549
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 26 deletions.
2 changes: 1 addition & 1 deletion client/src/components/CentralChart/StockChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const StockChart = () => {

companyList.forEach((company: CompanyProps) => {
if (company.korName === searchWord) {
searchResult = "ExistCompany";
searchResult = "existCompany";
dispatch(changeCompanyId(company.companyId));
}
});
Expand Down
12 changes: 8 additions & 4 deletions client/src/components/StockOrderSection/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,17 @@ import dummyLogo from "../../asset/CentralSectionMenu-dummyImg.png";
import { useState } from "react";

const StockOrderSection = () => {
// 🔴 로그인 구현될 때까지 임시
const [login, setLogin] = useState(true);

const dispatch = useDispatch();
const companyId = useSelector((state: StateProps) => state.companyId);
const stockOrderSet = useSelector((state: StateProps) => state.stockOrderSet);

// 🔴 로그인 구현될 때까지 임시
const [login, setLogin] = useState(true);
if (companyId === 10000000) {
setLogin(true);
}
//

const { stockInfo, stockInfoLoading, stockInfoError } = useGetStockInfo(companyId);
const { stockPrice, stockPriceLoading, stockPriceError } = useGetStockData(companyId);

Expand Down Expand Up @@ -78,7 +82,7 @@ const StockOrderSection = () => {
</div>
</div>
</StockName>
<StockOrder />
<StockOrder corpName={corpName} />
<OrderResult />
</>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { styled } from "styled-components";
import { StateProps } from "../../models/stateProps";
import { OrderTypeProps } from "../../models/orderTypeProps";
import { setStockOrderVolume } from "../../reducer/StockOrderVolume-Reducer";
import { openDecisionWindow } from "../../reducer/setDecisionWindow-Reducer";
import { openDecisionWindow } from "../../reducer/SetDecisionWindow-Reducer";

const availableMoneyText01: string = "최대";
const availableMoneyText02: string = "원";
Expand Down
166 changes: 157 additions & 9 deletions client/src/components/StockOrderSection/StockOrder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,33 @@ import { StateProps } from "../../models/stateProps";
import StockPriceList from "./StockPriceList";
import StockOrderSetting from "./StockOrderSetting";

// dummyData
import dummyImg from "../../asset/CentralSectionMenu-dummyImg.png";

const orderFailureMessage01: string = "주문 실패";
const orderFailureMessage02: string = "주문 수량이 없습니다";
const orderFailureMessage03: string = "입력하신 가격이 올바르지 않습니다";
const orderFailureButtonText: string = "확인";

const StockOrder = () => {
const orderPriceText: string = "주문단가";
const orderVolumeText: string = "주문수량";
const totalOrderAmountText: string = "총 주문금액";
const priceUnit: string = "원";
const volumeUnit: string = "주";
const cancelButtonText: string = "취소";
const confirmButtonText: string = "확인";

const StockOrder = ({ corpName }: { corpName: string }) => {
const dispatch = useDispatch();
const decisionWindow = useSelector((state: StateProps) => state.decisionWindow);
const orderType = useSelector((state: StateProps) => state.stockOrderType);
const orderVolume = useSelector((state: StateProps) => state.stockOrderVolume);
const orderPrice = useSelector((state: StateProps) => state.stockOrderPrice);
const decisionWindow = useSelector((state: StateProps) => state.decisionWindow);

const orderTypeText: string = !orderType ? "매수" : "매도";
const price = orderPrice.toLocaleString();
const volume = orderVolume.toLocaleString();
const totalPrice = (orderPrice * orderVolume).toLocaleString();

const handleCloseDecisionWindow = () => {
dispatch(closeDecisionWindow());
Expand All @@ -29,17 +48,51 @@ const StockOrder = () => {

{/* 주문 버튼 클릭 했을 때 */}
{decisionWindow ? (
orderVolume === 0 ? (
orderVolume === 0 || orderPrice === 0 ? (
<OrderFailed>
<div className="Container">
<div className="message01">{orderFailureMessage01}</div>
<div className="message02">{orderFailureMessage02}</div>
<div className="message02">{orderPrice !== 0 ? `${orderFailureMessage02}` : `${orderFailureMessage03}`}</div>
<button onClick={handleCloseDecisionWindow}>{orderFailureButtonText}</button>
</div>
</OrderFailed>
) : (
<OrderConfirm>
<button onClick={handleCloseDecisionWindow}>임시버튼</button>
<OrderConfirm orderType={orderType}>
<div className="Container">
<img className="CorpLogo" src={dummyImg} />
<div className="OrderOverview">
<span className="CorpName">{corpName}</span>
<span className="OrderType">{orderTypeText}</span>
</div>
<div className="OrderContent">
<div className="Price">
<span className="text">{orderPriceText}</span>
<span>
{price} {priceUnit}
</span>
</div>
<div className="Volume">
<span className="text">{orderVolumeText}</span>
<span>
{volume} {volumeUnit}
</span>
</div>
<div className="TotalOrderAmout">
<span className="text">{totalOrderAmountText}</span>
<span>
{totalPrice} {priceUnit}
</span>
</div>
<div className="ButtonContainer">
<button className="cancel" onClick={handleCloseDecisionWindow}>
{cancelButtonText}
</button>
<button className="confirm" onClick={handleCloseDecisionWindow}>
{confirmButtonText}
</button>
</div>
</div>
</div>
</OrderConfirm>
)
) : (
Expand Down Expand Up @@ -84,26 +137,29 @@ const OrderFailed = styled.div`
border-radius: 0.5rem;
.message01 {
font-size: 20px;
font-size: 18.5px;
font-weight: 500;
}
.message02 {
font-size: 18px;
font-size: 16.5px;
font-weight: 400;
}
& button {
width: 100%;
height: 36px;
border: none;
border-radius: 0.5rem;
font-size: 14.5px;
color: white;
background-color: #2f4f4f;
margin-top: 12px;
}
}
`;

const OrderConfirm = styled.div`
const OrderConfirm = styled.div<{ orderType: boolean }>`
position: fixed;
top: 0;
left: 0;
Expand All @@ -114,4 +170,96 @@ const OrderConfirm = styled.div`
display: flex;
justify-content: center;
align-items: center;
.Container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 328px;
height: 345px;
background-color: white;
border: none;
border-radius: 0.5rem;
padding-left: 20px;
padding-right: 20px;
padding-top: 24px;
.CorpLogo {
width: 40px;
height: 40px;
border-radius: 50%;
}
.OrderOverview {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 6px;
font-size: 18px;
font-weight: 500;
padding-top: 18px;
padding-bottom: 28px;
.OrderType {
color: ${(props) => (props.orderType ? "#2679ed" : "#e22926")};
}
}
.OrderContent {
width: 100%;
font-size: 15px;
& div {
height: 24px;
display: flex;
flex-direction: row;
justify-content: space-between;
padding-bottom: 40px;
}
.text {
color: #292828;
}
.Volume {
border-bottom: 0.1px solid #d3cece99;
}
.TotalOrderAmout {
padding-top: 20px;
padding-bottom: 45px;
}
}
.ButtonContainer {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
padding-top: 20px;
gap: 12px;
& button {
width: 50%;
height: 32px;
border: none;
border-radius: 0.25rem;
}
.cancel {
color: ${(props) => (!props.orderType ? "#e22926" : "#2679ed")};
background-color: ${(props) => (!props.orderType ? "#fcdddb" : "#dce9fc")};
}
.confirm {
color: white;
background-color: ${(props) => (!props.orderType ? "#e22926" : "#2679ed")};
}
}
}
`;
18 changes: 9 additions & 9 deletions client/src/components/StockOrderSection/StockPriceList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,17 @@ const StockPriceList = () => {
*/
const existSellingPrice = sellingPrice.filter((selling) => selling.price !== 0);
const existBuyingPrice = buyingPrice.filter((buyingPrice) => buyingPrice.price !== 0);
const priceInterval: number = existSellingPrice[existSellingPrice.length - 1].price - existBuyingPrice[0].price;
// const priceInterval: number = existSellingPrice[existSellingPrice.length - 1].price - existBuyingPrice[0].price;

for (let i = 0; existSellingPrice.length < 10; i++) {
const dummySellingData = { price: existSellingPrice[0].price + priceInterval, volume: 0 };
existSellingPrice.unshift(dummySellingData);
}
// for (let i = 0; existSellingPrice.length < 10; i++) {
// const dummySellingData = { price: existSellingPrice[0].price + priceInterval, volume: 0 };
// existSellingPrice.unshift(dummySellingData);
// }

for (let i = 0; existBuyingPrice.length < 10; i++) {
const dummyBuyingData = { price: existBuyingPrice[existBuyingPrice.length - 1].price - priceInterval, volume: 0 };
existBuyingPrice.push(dummyBuyingData);
}
// for (let i = 0; existBuyingPrice.length < 10; i++) {
// const dummyBuyingData = { price: existBuyingPrice[existBuyingPrice.length - 1].price - priceInterval, volume: 0 };
// existBuyingPrice.push(dummyBuyingData);
// }

// 1) 매도/매수호가 종합 2) 매수/매도호가 거래량 종합
const sellingAndBuyingPrice = [...existSellingPrice, ...existBuyingPrice];
Expand Down
2 changes: 1 addition & 1 deletion client/src/hooks/useGetKospiChart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const useGetKospiChart = () => {
export default useGetKospiChart;

// kospi 차트 데이터 fetch 로직
const getKospiData = async () => {
export const getKospiData = async () => {
const res = await axios.get("http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com/kospi");
const chartData = res.data.output2;
const kospiData = chartData.reverse();
Expand Down
2 changes: 1 addition & 1 deletion client/src/store/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { stockOrderSetReducer } from "../reducer/StockOrderSet-Reducer";
import { companyIdReducer } from "../reducer/CompanyId-Reducer";
import memberInfoReducer from "../reducer/member/memberInfoSlice";
import { stockOrderVolumeReducer } from "../reducer/StockOrderVolume-Reducer";
import { setDecisionWindowReducer } from "../reducer/setDecisionWindow-Reducer";
import { setDecisionWindowReducer } from "../reducer/SetDecisionWindow-Reducer";

const store = configureStore({
reducer: {
Expand Down

0 comments on commit ed77549

Please sign in to comment.