From 59e164114738ebea3d3b391432b09ecc74af89a0 Mon Sep 17 00:00:00 2001 From: "yeondu._" Date: Fri, 20 Sep 2024 16:20:32 +0900 Subject: [PATCH] =?UTF-8?q?Fix=20:=20=EC=9D=B4=EC=8A=88=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Game/Main/BentoBar/bentoBar.tsx | 76 +++++++++ src/Game/Main/BentoBar/bentoStyle.ts | 54 +++++++ src/Game/Main/gameStart.tsx | 63 ++++++-- src/Game/Main/gameStart2.tsx | 232 --------------------------- src/Game/Main/styleMain.ts | 1 + src/Game/Tutorial/ex.tsx | 8 +- src/Game/Tutorial/exStyle.scss | 69 ++++---- src/Pages/game/gameStocks.tsx | 4 +- src/Pages/game/playPage.tsx | 11 +- src/Pages/game/rank.tsx | 4 +- src/Pages/game/totalResult.tsx | 7 +- src/Pages/skrrrGame.tsx | 1 - 12 files changed, 242 insertions(+), 288 deletions(-) create mode 100644 src/Game/Main/BentoBar/bentoBar.tsx create mode 100644 src/Game/Main/BentoBar/bentoStyle.ts delete mode 100644 src/Game/Main/gameStart2.tsx diff --git a/src/Game/Main/BentoBar/bentoBar.tsx b/src/Game/Main/BentoBar/bentoBar.tsx new file mode 100644 index 0000000..b5f4a78 --- /dev/null +++ b/src/Game/Main/BentoBar/bentoBar.tsx @@ -0,0 +1,76 @@ +import { useEffect, useRef, useState } from "react"; +import { CgMenuGridO } from "react-icons/cg"; +import { useNavigate } from "react-router-dom"; +import { ListBox, Restart, IconDiv } from "./bentoStyle"; + +const BentoBar = () => { + const [isOpen, setIsOpen] = useState(false); + const outsideRef = useRef(null); + const iconRef = useRef(null); + const navigate = useNavigate(); + + const Nav = (location: string) => { + if (location === "game") { + navigate("/game"); + localStorage.removeItem("hasSeenTutorial"); + } else if (location === "rank") { + navigate("/game/rank"); + } else { + navigate("/home"); + } + }; + + // 슬라이드 토글 + const toggleSlide = () => { + setIsOpen((prev) => !prev); + }; + + // 외부 클릭 감지 및 메뉴 닫기 + useEffect(() => { + const handleClickOutside = (e: any) => { + if ( + outsideRef.current && + !outsideRef.current.contains(e.target as Node) && + iconRef.current && + !iconRef.current.contains(e.target as Node) + ) { + setIsOpen(false); + } + }; + + document.addEventListener("mousedown", handleClickOutside); + + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, [outsideRef]); + + return ( + <> + + + + {isOpen ? ( + + Nav("game")}>게임 재시작 + Nav("rank")}>랭킹 + Nav("home")}>홈 + + ) : ( + <> + )} + + + ); +}; + +export default BentoBar; diff --git a/src/Game/Main/BentoBar/bentoStyle.ts b/src/Game/Main/BentoBar/bentoStyle.ts new file mode 100644 index 0000000..3d78c95 --- /dev/null +++ b/src/Game/Main/BentoBar/bentoStyle.ts @@ -0,0 +1,54 @@ +import styled, { keyframes } from "styled-components"; +import { Colors } from "../../../Styles/Colors"; + +export const Restart = styled.div` + display: flex; + width: 90px; + height: 40px; + border: 1px solid #615efc; + border-radius: 20px; + font-size: 12px; + align-items: center; + justify-content: center; + margin-bottom: 0.5rem; + box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px; + background-color: white; + color: black; +`; + +const fadeIn = keyframes` + from{ + opacity:0; + transform: translateY(10px) + } + to{ + opacity:1; + transform: translateY(0) + } +`; + +export const ListBox = styled.div` + position: absolute; + bottom: 50px; + width: 100px; + height: 150px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + margin-top: 0.5rem; + animation: ${fadeIn} 0.5s ease-out forwards; + opacity: 0; +`; + +export const IconDiv = styled.div` + border-radius: 25px; + width: 50px; + height: 50px; + position: relative; + display: flex; + justify-content: center; + align-items: center; + color: ${Colors.main}; + box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px; +`; diff --git a/src/Game/Main/gameStart.tsx b/src/Game/Main/gameStart.tsx index 36b2dd7..cb137c4 100644 --- a/src/Game/Main/gameStart.tsx +++ b/src/Game/Main/gameStart.tsx @@ -18,6 +18,7 @@ const GameMain: React.FC = () => { const [nickname, setNickname] = useState(""); const navigate = useNavigate(); const [isValidQuantity, setIsValidQuantity] = useState(true); + const [isSkipped, setIsSkipped] = useState(false); const handleRank = () => { navigate("/game/rank"); @@ -68,35 +69,42 @@ const GameMain: React.FC = () => { setIsValidQuantity(true); }; + const handleSkip = () => { + setIsSkipped(true); + setIsLoadingFinished(false); + setIsFlying(false); + setIsGame(true); + }; + useEffect(() => { - // Wait for the loading animation to finish (2s + 2s duration of the loading animation) - const timer = setTimeout(() => { - setIsLoadingFinished(true); + if (!isSkipped) { + const timer = setTimeout(() => { + setIsLoadingFinished(true); - const flyTimer = setTimeout(() => { - setIsFlying(true); + const flyTimer = setTimeout(() => { + setIsFlying(true); - const gameTimer = setTimeout(() => { - setIsGame(true); - }, 2000); + const gameTimer = setTimeout(() => { + setIsGame(true); + }, 2000); - return () => clearTimeout(gameTimer); - }, 2000); + return () => clearTimeout(gameTimer); + }, 2000); - return () => clearTimeout(flyTimer); - }, 5000); + return () => clearTimeout(flyTimer); + }, 5000); - return () => clearTimeout(timer); // Clean up the timer - }, []); + return () => clearTimeout(timer); + } + }, [isSkipped]); return (
- {/* {isGame ?
스껄게임
: ""} */}
- {isLoadingFinished && ( + {isLoadingFinished && !isSkipped && ( {
+ {/* 스킵 버튼 */} + {!isGame && ( + + )} {isGame && ( <>
{ flexDirection: "column", }} > - Skrr 모의 투자 게임 + + Skrrr  모의 투자 게임 + { - const [isLoadingFinished, setIsLoadingFinished] = useState(false); - const [isFlying, setIsFlying] = useState(false); - const [isGame, setIsGame] = useState(false); - const [nickname, setNickname] = useState(""); - const navigate = useNavigate(); - const [isValidQuantity, setIsValidQuantity] = useState(true); - - const handleRank = () => { - navigate("/game/rank"); - }; - - const handleConfirm = () => { - if (!nickname || !nickname.trim()) { - setIsValidQuantity(false); - setNickname(""); - return; - } - axios - .get(`${process.env.REACT_APP_API_URL}/v1/game/start`, { - withCredentials: true, - params: { nickname }, - }) - .then((res) => { - if (res.status == 200) { - const stock2014 = res.data; - - localStorage.setItem( - "stock2014", - JSON.stringify(stock2014) - ); - navigate(`/game/play/2014`, { state: { nickname } }); - } else { - swal({ - icon: "error", - title: "닉네임을 입력해주세요!", - }); - setNickname(""); - } - }) - .catch((error) => { - console.error("서버 에러 : ", error); - setNickname(""); - }); - }; - - const handleChangeQuantity = (e: React.ChangeEvent) => { - const value = e.target.value; - // setNickname(value); - // 공백을 허용하지 않도록 필터링 - if (value.includes(" ")) { - swal({ - icon: "error", - title: "닉네임에 공백을 포함할 수 없습니다.", - }); - return; - } - setNickname(value); - setIsValidQuantity(true); - }; - - useEffect(() => { - // Wait for the loading animation to finish (2s + 2s duration of the loading animation) - const timer = setTimeout(() => { - setIsLoadingFinished(true); - - const flyTimer = setTimeout(() => { - setIsFlying(true); - - const gameTimer = setTimeout(() => { - setIsGame(true); - }, 2000); - - return () => clearTimeout(gameTimer); - }, 2000); - - return () => clearTimeout(flyTimer); - }, 5000); - - return () => clearTimeout(timer); // Clean up the timer - }, []); - - return ( -
- {/* {isGame ?
스껄게임
: ""} */} -
-
-
-
- {isLoadingFinished && ( - - )} - {isGame && ( -
-

- U'STOCK{" "} -

-

- 모의투자 -

-

- {" "} - 게임해볼래? -

-
- )} -
-
-
-
-
-
-
    -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
-
    -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
-
-
-
-
- {isGame && ( - <> -
- Skrr 모의 투자 게임 - - - -
- -
-
- - )} -
- ); -}; - -export default GameMain2; - -// state로 넘긴 값 사용하는 방법 -// useLocation을 사용해서 불러온 다음 , const {stockData, nickname} = location.state || {}; 널처리는 꼭 해줘야함 ~~ 이렇게 하면 사용가능! diff --git a/src/Game/Main/styleMain.ts b/src/Game/Main/styleMain.ts index 8f1588d..4075f42 100644 --- a/src/Game/Main/styleMain.ts +++ b/src/Game/Main/styleMain.ts @@ -12,4 +12,5 @@ export const GameTitle = styled.p` justify-content: center; font-size: 25px; font-weight: 900; + margin-bottom: 1rem; `; diff --git a/src/Game/Tutorial/ex.tsx b/src/Game/Tutorial/ex.tsx index 687932b..addfc47 100644 --- a/src/Game/Tutorial/ex.tsx +++ b/src/Game/Tutorial/ex.tsx @@ -127,10 +127,11 @@ const ExSAm: React.FC = ({
{/* // 강조할 부분 (뚫릴 부분) */}
-

+

2014년부터 게임이 시작되고,
게임 한 회당 1년단위로 진행됩니다!

+ {/* */}
@@ -146,6 +147,7 @@ const ExSAm: React.FC = ({ {/* // 강조할 부분 (뚫릴 부분) */}

게임 시작 시 50만원을 지급받습니다!

+ {/* */}
@@ -173,6 +175,7 @@ const ExSAm: React.FC = ({ 알 수 있습니다 😉

+ {/* */} @@ -212,6 +215,7 @@ const ExSAm: React.FC = ({

+ {/* */} )} @@ -238,6 +242,7 @@ const ExSAm: React.FC = ({ {" "} 확인할 수 있습니다!

+ {/* */} @@ -252,6 +257,7 @@ const ExSAm: React.FC = ({ {/* // 강조할 부분 (뚫릴 부분) */}

원하는 종목을 구매할 수 있습니다.

+ {/* */}
diff --git a/src/Game/Tutorial/exStyle.scss b/src/Game/Tutorial/exStyle.scss index 66e76ff..92146bc 100644 --- a/src/Game/Tutorial/exStyle.scss +++ b/src/Game/Tutorial/exStyle.scss @@ -1,6 +1,7 @@ #tutorial { & #page { width: 100%; + /* // 뚫린 배경 */ & .background { box-sizing: border-box; @@ -10,44 +11,50 @@ width: 100%; height: 100vh; position: fixed; - top: -0px; + top: 0px; z-index: 1000; - @media (max-width: 1366px) { - width: 100%; - padding: 64px calc((100% - 757px) / 2) 20px; - left: -1px; - } - @media (max-width: 800px) { - min-width: 400px; - padding: 64px 23px 20px 20px; - left: 0px; - } - @media screen and (max-width: 768px) { + // position: absolute; + @media (max-width: 768px) { width: 100%; - padding: 64px calc((100% - 757px) / 2) 20px; + display: flex; } + // 년도 & .rowBox { - display: flex; - position: relative; - width: 100%; + display: flex-start; + gap: 10px; + position: absolute; + left: 755px; + // width: 100%; height: 100vh; margin-top: -35px; + @media (max-width: 430px) { + display: flex-start; + position: absolute; + left: 210px; + height: 100vh; + margin-top: -35px; + } & .mainIcon { background-color: rgb(255 255 255); - position: absolute; - left: 50%; + // position: absolute; + // left: 50%; transform: translateX(-50%); width: 85px; height: 44px; border-radius: 12px; } - & p { + & .text { color: rgb(255 255 255); font-size: 16px; - position: absolute; - left: 54%; + width: 250px; + // position: absolute; + left: 55%; margin-top: 0.2rem; + @media (max-width: 430px) { + left: -40px; + position: absolute; + } } } } @@ -60,12 +67,19 @@ width: 100%; height: 100vh; // flex-direction: column; + @media (max-width: 430px) { + display: flex-start; + position: absolute; + left: 210px; + height: 100vh; + margin-top: -35px; + } color: rgb(255 255 255 / 80%); & .mainIcon2 { background-color: rgb(255 255 255 / 90%); border-radius: 12px; position: absolute; - left: 45.2%; + left: 640px; top: 0; transform: translateX(-50%); width: 200px; @@ -75,7 +89,7 @@ color: rgb(255 255 255); font-size: 16px; position: absolute; - left: 53%; + left: 750px; top: 1.5%; } } @@ -83,7 +97,7 @@ & .rowBox3 { display: flex; align-items: center; - margin-top: 316px; + margin-top: 215px; flex-direction: column; position: relative; width: 100%; @@ -113,7 +127,6 @@ & .rowBox4 { display: flex; align-items: center; - margin-top: 180px; flex-direction: column; position: relative; width: 100%; @@ -123,7 +136,7 @@ background-color: rgb(255 255 255 / 90%); position: absolute; left: 50%; - top: 0; + top: 185px; transform: translateX(-50%); border-radius: 12px; width: 450px; @@ -132,10 +145,10 @@ & p { color: rgb(255 255 255); font-size: 16px; - text-align: left; + text-align: center; position: absolute; left: 40%; - top: -6%; + top: 135px; } } // 정보 거래소 diff --git a/src/Pages/game/gameStocks.tsx b/src/Pages/game/gameStocks.tsx index 1cf1b87..f29bfa6 100644 --- a/src/Pages/game/gameStocks.tsx +++ b/src/Pages/game/gameStocks.tsx @@ -3,6 +3,7 @@ import GameCarousel from "../../Component/GameCarousel/gameCarousel"; import { useEffect, useState } from "react"; import axios from "axios"; import { GameStockProps } from "../../constants/interface"; +import BentoBar from "../../Game/Main/BentoBar/bentoBar"; const GameStocks = () => { const [stocks, setStocks] = useState([]); @@ -27,13 +28,14 @@ const GameStocks = () => { }, []); return ( -
+
{stocks.length > 0 ? ( ) : (

데이터가 없습니다.

)} +
); }; diff --git a/src/Pages/game/playPage.tsx b/src/Pages/game/playPage.tsx index fbaec1a..7f7e350 100644 --- a/src/Pages/game/playPage.tsx +++ b/src/Pages/game/playPage.tsx @@ -21,6 +21,7 @@ const Container = styled.div` justify-content: center; align-items: center; text-align: center; + position: relative; `; const PlayPage = () => { @@ -86,12 +87,12 @@ const PlayPage = () => { } ); if (response.status === 200) { - const updatedStockList = response.data.stockList; - setStockData(updatedStockList); - - // 새해 모달을 먼저 보여줌 + // 새해 모달을 먼저 보여줌(7초동안 띄워야함) setIsHappyNewYearModal(true); - + if (yearValue === response.data.year) { + const updatedStockList = response.data.stockList; + setStockData(updatedStockList); + } // 4초 후 페이지를 이동 setTimeout(() => { const nextYear = (parseInt(yearValue, 10) + 1).toString(); diff --git a/src/Pages/game/rank.tsx b/src/Pages/game/rank.tsx index d0b10d3..9117cc1 100644 --- a/src/Pages/game/rank.tsx +++ b/src/Pages/game/rank.tsx @@ -3,6 +3,7 @@ import GameHeader from "../../Component/Game/GameHeader"; import { RankDataProps, RankListProps } from "../../constants/interface"; import axios from "axios"; import RankList from "../../Component/Game/Rank/rankList"; +import BentoBar from "../../Game/Main/BentoBar/bentoBar"; const Rank = () => { const [rankList, setRankList] = useState([]); @@ -25,9 +26,10 @@ const Rank = () => { }, []); return ( -
+
+
); }; diff --git a/src/Pages/game/totalResult.tsx b/src/Pages/game/totalResult.tsx index 2a8005f..c570108 100644 --- a/src/Pages/game/totalResult.tsx +++ b/src/Pages/game/totalResult.tsx @@ -8,11 +8,13 @@ import { useEffect, useState } from "react"; import { RankListProps, RankDataProps } from "../../constants/interface"; import RankList from "../../Component/Game/Rank/rankList"; import { useNavigate } from "react-router-dom"; +import BentoBar from "../../Game/Main/BentoBar/bentoBar"; const Container = styled.div` display: flex; flex-direction: column; align-items: center; + position: relative; `; const SkrrContainer = styled.div` @@ -78,12 +80,13 @@ const TotalResult = () => {