-
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.
- Loading branch information
Showing
10 changed files
with
512 additions
and
47 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
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
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; |
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,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; | ||
} |
Oops, something went wrong.