-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #187 from 100-hours-a-week/feature/veronica
Feat : 년도별 게임 화면
- Loading branch information
Showing
23 changed files
with
980 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import info from "../../img/GameButton/infoImg.png"; | ||
import trade from "../../img/GameButton/tradeImg.png"; | ||
import pass from "../../img/GameButton/passImg.png"; | ||
import "./GameButtonsStyle.css"; | ||
import { useNavigate, useParams } from "react-router-dom"; | ||
|
||
interface GameButtonsProps { | ||
openTradeModal: () => void; | ||
} | ||
|
||
const GameButtons = ({ openTradeModal }: GameButtonsProps) => { | ||
const nav = useNavigate(); | ||
const { year } = useParams<{ year: string }>(); | ||
|
||
// 정보 거래소로 이동 | ||
const goToInfoPage = () => { | ||
if (year) { | ||
nav(`/game/info/${year}`); | ||
} | ||
}; | ||
|
||
return ( | ||
<div className="GameButtonsWrapper"> | ||
<div className="GameButton" onClick={goToInfoPage}> | ||
<img src={info}></img> | ||
<span>정보거래소</span> | ||
</div> | ||
<div className="GameButton" onClick={openTradeModal}> | ||
<img src={trade}></img> | ||
<span>거래하기</span> | ||
</div> | ||
<div className="GameButton"> | ||
<img src={pass}></img> | ||
<span>넘어가기</span> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default GameButtons; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
.GameButtonsWrapper { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
gap: 30px; | ||
margin-top: 30px; | ||
} | ||
|
||
.GameButton { | ||
width: 75px; | ||
height: 80px; | ||
background-color: #615efc; | ||
display: flex; | ||
flex-direction: column; | ||
border-radius: 20px; | ||
border: 4px solid rgb(255, 255, 255); | ||
align-items: center; | ||
justify-content: center; | ||
position: relative; | ||
transition: box-shadow 0.3s ease; | ||
transform: 1s ease; | ||
box-shadow: 0px 10px 20px rgba(0, 0, 0, 0.6); | ||
cursor: pointer; | ||
} | ||
|
||
.GameButton img { | ||
width: 30px; | ||
margin-top: -20px; | ||
} | ||
|
||
.GameButton span { | ||
position: absolute; | ||
bottom: 7px; | ||
color: white; | ||
font-size: 12px; | ||
} | ||
|
||
.GameButton:active { | ||
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.4); /* 눌렀을 때 그림자가 작아짐 */ | ||
transform: translateY(4px); /* 버튼이 살짝 눌리는 효과 */ | ||
} | ||
|
||
/* 클릭 후 원래 크기로 돌아오는 애니메이션 */ | ||
.GameButton { | ||
transition: transform 0.2s ease, box-shadow 0.2s ease; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import styled from "styled-components"; | ||
|
||
const GameMoneyContainer = styled.div` | ||
width: 85%; | ||
height: 150px; | ||
border-radius: 20px; | ||
box-shadow: 3px 3px 3px rgb(213, 213, 213); | ||
padding: 20px 40px; | ||
position: relative; | ||
margin-top: 20px; | ||
margin-bottom: 20px; | ||
`; | ||
|
||
const GameMoneyTitle = styled.div` | ||
margin-bottom: 30px; | ||
`; | ||
|
||
const GameMoneyBalance = styled.div` | ||
display: flex; | ||
margin: 15px 0; | ||
flex-direction: row; | ||
`; | ||
|
||
const BalanceDetailButton = styled.div` | ||
position: absolute; | ||
bottom: 20px; | ||
right: 20px; | ||
`; | ||
|
||
const BalanceTitle = styled.div` | ||
color: #6c6c6c; | ||
width: 110px; | ||
`; | ||
|
||
const Button = styled.button` | ||
width: 78px; | ||
height: 46px; | ||
border-radius: 50px; | ||
border: none; | ||
background-color: #f1f1f1; | ||
cursor: pointer; | ||
`; | ||
|
||
const GameMoney = () => { | ||
return ( | ||
<GameMoneyContainer> | ||
<GameMoneyTitle> | ||
<strong>루시는왜안돼요</strong> 님의 계좌잔고 💰 | ||
</GameMoneyTitle> | ||
<GameMoneyBalance> | ||
<BalanceTitle>총 평가금액</BalanceTitle> | ||
<div className="BalanceValue">0</div> | ||
</GameMoneyBalance> | ||
<GameMoneyBalance> | ||
<BalanceTitle>작년 대비</BalanceTitle> | ||
<div className="BalanceValue">0 (0%)</div> | ||
</GameMoneyBalance> | ||
<BalanceDetailButton> | ||
<Button>더보기</Button> | ||
</BalanceDetailButton> | ||
</GameMoneyContainer> | ||
); | ||
}; | ||
|
||
export default GameMoney; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
Oops, something went wrong.