Skip to content

Commit

Permalink
Feat : 게임 handler 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
yzooop committed Sep 7, 2024
1 parent 9f226c5 commit 0496622
Show file tree
Hide file tree
Showing 10 changed files with 512 additions and 47 deletions.
9 changes: 7 additions & 2 deletions src/Component/Game/GameButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ import pass from "../../img/GameButton/passImg.png";
import "./GameButtonsStyle.css";
import { useNavigate, useParams } from "react-router-dom";

const GameButtons = () => {
interface GameButtonsProps {
openTradeModal: () => void;
}

const GameButtons = ({ openTradeModal }: GameButtonsProps) => {
const nav = useNavigate();
const { year } = useParams<{ year: string }>();

// 정보 거래소로 이동
const goToInfoPage = () => {
if (year) {
nav(`/game/info/${year}`);
Expand All @@ -20,7 +25,7 @@ const GameButtons = () => {
<img src={info}></img>
<span>정보거래소</span>
</div>
<div className="GameButton">
<div className="GameButton" onClick={openTradeModal}>
<img src={trade}></img>
<span>거래하기</span>
</div>
Expand Down
13 changes: 7 additions & 6 deletions src/Component/Game/GameButtonsStyle.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
}

.GameButton {
width: 100px;
height: 120px;
width: 75px;
height: 80px;
background-color: #615efc;
display: flex;
flex-direction: column;
border-radius: 20px;
border: 5px solid rgb(255, 255, 255);
border: 4px solid rgb(255, 255, 255);
align-items: center;
justify-content: center;
position: relative;
Expand All @@ -24,14 +24,15 @@
}

.GameButton img {
width: 50px;
margin-top: -30px;
width: 30px;
margin-top: -20px;
}

.GameButton span {
position: absolute;
bottom: 10px;
bottom: 7px;
color: white;
font-size: 12px;
}

.GameButton:active {
Expand Down
22 changes: 11 additions & 11 deletions src/Component/Game/GameHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ import { Colors } from "../../Styles/Colors";
import { GameHeaderProp } from "../../constants/interface";

const Container = styled.div`
width: 100%;
height: 60px;
background-color: ${Colors.main};
color: white;
font-family: "SCDream6";
font-size: x-large;
text-align: center;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
padding-top: 15px;
width: 100%;
height: 60px;
background-color: ${Colors.main};
color: white;
font-family: "SCDream6";
font-size: x-large;
text-align: center;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
padding-top: 15px;
`;

const GameHeader: React.FC<GameHeaderProp> = ({ text }) => {
return <Container>{text}</Container>;
return <Container>{text}</Container>;
};

export default GameHeader;
165 changes: 165 additions & 0 deletions src/Component/Game/GameTradeSwipe.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import { useEffect, useState } from "react";
import "./GameTradeSwipeStyle.css";
import TradeChoice from "./TradeChoice";
import TradeConfirmModal from "./TradeConfirmModal"; // 모달 컴포넌트 불러오기
import axios from "axios";
import swal from "sweetalert";

interface GameTradeSwipeProps {
onClose: () => void;
isVisible: boolean;
year: string;
}

const GameTradeSwipe = ({ onClose, isVisible, year }: GameTradeSwipeProps) => {
const [show, setShow] = useState(isVisible);
const [selectedStock, setSelectedStock] = useState("A뷰티");
const [quantity, setQuantity] = useState(0);
const [acting, setActing] = useState<"BUY" | "SELL">();
const [isModalOpen, setIsModalOpen] = useState(false); // 모달 상태 추가

const stockOptions = ["A뷰티", "B전기", "C전자", "D건설"];

useEffect(() => {
setShow(isVisible);
}, [isVisible]);

// 종목 선택 핸들러
const handleStockChange = (direction: "left" | "right") => {
const currentIndex = stockOptions.indexOf(selectedStock);

if (direction === "left") {
const newIndex =
(currentIndex - 1 + stockOptions.length) % stockOptions.length;
setSelectedStock(stockOptions[newIndex]);
} else {
const newIndex = (currentIndex + 1) % stockOptions.length;
setSelectedStock(stockOptions[newIndex]);
}
};

// 수량 선택 핸들러
const handleQuantityChange = (direction: "left" | "right") => {
if (direction === "left" && quantity > 0) {
setQuantity(quantity - 1);
} else if (direction === "right") {
setQuantity(quantity + 1);
}
};

// 모달에서 확인 버튼 클릭 시 거래 처리
const handleTradeConfirm = () => {
// 데이터 전송하기
const handleTrade = async () => {
const data = {
year: year,
gameId: 0,
stockId: 0, // stockId로 stock 전달해야함. 수정 필요
stock: selectedStock,
quantity: quantity,
acting: acting, // 팔기 : SELL, 사기 : BUY
};

// 서버로 데이터 전송
// try {
// const res = await axios.post(
// `${process.env.REACT_APP_API_URL}/v1/game/stock`,
// {
// withCredentials: true,
// }
// );
// console.log(res);

// if (res.status === 200) {
// swal({
// title: "거래 성공",
// icon: "success",
// }).then(() => {
// window.location.reload();
// });
// }
// } catch (error: any) {
// console.error(error);
// }
swal({
title: "거래 성공",
icon: "success",
}).then(() => {
handleClose();
});

console.log("선택한 년도 : ", year);
console.log("선택한 종목 : ", selectedStock);
console.log("선택한 수량 : ", quantity);
console.log("선택한 acting : ", acting);
};
handleTrade();
setIsModalOpen(false); // 모달 닫기
};

// 모달 열기
const openTradeConfirmModal = (action: "BUY" | "SELL") => {
setActing(action); // 거래 종류 설정 (구매 or 판매)
setIsModalOpen(true); // 모달 열기
};

// 모달 닫기 핸들러
const handleClose = () => {
setShow(false);
setTimeout(() => {
onClose();
}, 700);
};

return (
<div className="GameTradeSwipe">
<div
className={`swipeModal ${show ? "open" : "closed"}`}
style={{ width: "90%", position: "absolute", bottom: "0" }}
>
<div className="swipeContainer">
<div style={{ display: "flex", justifyContent: "center" }}>
<button onClick={handleClose}></button>
</div>
<span>주식 거래하기</span>
<TradeChoice
title="종목"
choiceLeft="←"
choiceRight="→"
selectedOption={selectedStock}
onLeftClick={() => handleStockChange("left")}
onRightClick={() => handleStockChange("right")}
/>
<TradeChoice
title="수량"
choiceLeft="-"
choiceRight="+"
selectedOption={quantity.toString()}
onLeftClick={() => handleQuantityChange("left")}
onRightClick={() => handleQuantityChange("right")}
/>
<div className="trade-button">
<button onClick={() => openTradeConfirmModal("SELL")}>
팔기
</button>
<button onClick={() => openTradeConfirmModal("BUY")}>
사기
</button>
</div>
</div>
</div>

{/* 거래 확인 모달 */}
<TradeConfirmModal
isOpen={isModalOpen}
onConfirm={handleTradeConfirm}
onRequestClose={() => setIsModalOpen(false)}
stock={selectedStock}
quantity={quantity}
acting={acting!} // acting 값 전달 (BUY or SELL)
/>
</div>
);
};

export default GameTradeSwipe;
71 changes: 71 additions & 0 deletions src/Component/Game/GameTradeSwipeStyle.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
.swipeModal {
width: 90%;
position: fixed;
left: 50%;
bottom: -100%; /* 화면 아래에서 시작 */
max-height: 0; /* 높이 0으로 시작 */
height: 80vh;
max-width: 440px;
box-shadow: 0px -2px 10px rgba(0, 0, 0, 0.1);
transition: bottom 0.7s ease, max-height 0.7s ease; /* bottom을 애니메이션에 추가 */
z-index: 1;
overflow: hidden; /* 내부 컨텐츠가 넘치지 않게 */
border-top-left-radius: 20px;
border-top-right-radius: 20px;
transform: translateX(-50%);
}

.swipeContainer {
padding: 20px;
background-color: #f7f7f7;
overflow-y: auto;
height: 100%;
display: flex;
flex-direction: column;
}

/* 모달이 열릴 때 */
.swipeModal.open {
bottom: 0; /* 화면 하단에 위치 */
max-height: 80vh; /* 최대 높이 설정 */
}

/* 모달이 닫힐 때 */
.swipeModal.closed {
bottom: -100%; /* 화면 아래로 이동 */
max-height: 0; /* 높이를 0으로 줄임 */
}

.swipeContainer button {
width: 100px;
height: 10px;
border-radius: 10px;
border: none;
background-color: #dfdfdf;
cursor: pointer;
}

.swipeContainer span {
font-size: 28px;
font-weight: 700;
color: #615efc;
margin-top: 30px;
}

.trade-button {
display: flex;
justify-content: center;
align-items: center;
gap: 50px;
margin: 20px 0;
}

.trade-button button {
width: 100px;
height: 40px;
border-radius: 15px;
background: radial-gradient(circle, #4834d4 0%, #686de0 100%);
color: #fff;
border: none;
font-size: 14px;
}
Loading

0 comments on commit 0496622

Please sign in to comment.