From 6217d314633aeafcf73c01c6fdf71cafa9fbecd2 Mon Sep 17 00:00:00 2001 From: lucy726j Date: Tue, 24 Sep 2024 17:51:15 +0900 Subject: [PATCH 01/18] pull --- src/Component/Game/Rank/rankBox.tsx | 4 +- src/util/gameUtil.ts | 66 ++++++++++++++--------------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/Component/Game/Rank/rankBox.tsx b/src/Component/Game/Rank/rankBox.tsx index 7c91040..644f466 100644 --- a/src/Component/Game/Rank/rankBox.tsx +++ b/src/Component/Game/Rank/rankBox.tsx @@ -3,7 +3,7 @@ import * as S from "./rankBoxStyle"; import gold from "../../../img/goldMedal.png"; import silver from "../../../img/silverMedal.png"; import bronze from "../../../img/bronzeMedal.png"; -import { formatPrice, formatRate } from "../../../util/util"; +import { formatPrice, formatChangeRateFrom } from "../../../util/gameUtil"; const RankBox: React.FC = ({ nickname, @@ -24,7 +24,7 @@ const RankBox: React.FC = ({ {nickname} {formatPrice(total)} - {formatRate(profitRate)} % + {profitRate} % ); diff --git a/src/util/gameUtil.ts b/src/util/gameUtil.ts index bf5af11..1405fc6 100644 --- a/src/util/gameUtil.ts +++ b/src/util/gameUtil.ts @@ -1,48 +1,48 @@ import React from "react"; export const formatPrice = (num: number): string => { - if (num === 0) { - return "-"; - } + if (num === 0) { + return "-"; + } - return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); + return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); }; export const formatChangeRate = (changeRate: number): string => { - if (changeRate === 0) { - return "-"; - } + if (changeRate === 0) { + return "-"; + } - const formattedRate = `${Math.abs(changeRate).toFixed()}%`; // 소수점 2자리까지 표시 - if (changeRate > 0) { - return `▲ + ${formattedRate}`; - } else if (changeRate < 0) { - return `▼ - ${formattedRate}`; - } else { - return formattedRate; - } + const formattedRate = `${Math.abs(changeRate).toFixed(1)}%`; // 소수점 2자리까지 표시 + if (changeRate > 0) { + return `▲ ${formattedRate}`; + } else if (changeRate < 0) { + return `▼ ${formattedRate}`; + } else { + return formattedRate; + } }; interface ChangeRateResult { - format: string; - color: string; + format: string; + color: string; } export const formatChangeRateFrom = (changeRate: number): ChangeRateResult => { - if (changeRate > 0) { - return { - format: `+ ${changeRate}%`, - color: "red", - }; - } else if (changeRate < 0) { - return { - format: `- ${changeRate}`, - color: "blue", - }; - } else { - return { - format: "-", - color: "black", - }; - } + if (changeRate > 0) { + return { + format: `+ ${changeRate}%`, + color: "red", + }; + } else if (changeRate < 0) { + return { + format: `- ${changeRate}`, + color: "blue", + }; + } else { + return { + format: "-", + color: "black", + }; + } }; From 6e766353234548ad6c28746e40dca6e16fc6b529 Mon Sep 17 00:00:00 2001 From: lucy726j Date: Thu, 26 Sep 2024 15:52:07 +0900 Subject: [PATCH 02/18] pull --- src/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/index.tsx b/src/index.tsx index d97ca1d..c7cbae3 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,4 +1,3 @@ -import React from "react"; import ReactDOM from "react-dom/client"; import "./index.css"; import App from "./App"; From b73e949209896394ce650c3233bf78536699fbf1 Mon Sep 17 00:00:00 2001 From: lucy726j Date: Fri, 27 Sep 2024 14:21:22 +0900 Subject: [PATCH 03/18] =?UTF-8?q?Fix=20:=20=EB=9E=AD=ED=82=B9=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20=EB=B2=84=ED=8A=BC=20nav=20=EC=82=AD=EC=A0=9C,=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=ED=99=95=EC=9D=B8=20=EB=AA=A8=EB=8B=AC=20?= =?UTF-8?q?=EB=9D=84=EC=9A=B0=EA=B8=B0=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Pages/game/totalResult.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Pages/game/totalResult.tsx b/src/Pages/game/totalResult.tsx index fb5be86..e0034ef 100644 --- a/src/Pages/game/totalResult.tsx +++ b/src/Pages/game/totalResult.tsx @@ -106,7 +106,13 @@ const TotalResult = () => { ) .then((res) => { if (res.status === 200) { - nav("/game/rank"); + { + swal({ + title: "랭킹 등록 완료!", + text: "랭킹이 등록되었습니다.", + icon: "success", + }); + } } else { { swal({ From 50b7a47f0e7bf9ab3c38ee22d40049adf22087b2 Mon Sep 17 00:00:00 2001 From: lucy726j Date: Fri, 27 Sep 2024 14:23:38 +0900 Subject: [PATCH 04/18] =?UTF-8?q?Fix=20:=20=EA=B2=8C=EC=9E=84=20=ED=97=A4?= =?UTF-8?q?=EB=8D=94=EC=97=90=20=EB=A3=B0=20=EC=84=A4=EB=AA=85=20=EB=8B=AC?= =?UTF-8?q?=EB=A6=AC=EB=8A=94=20=EA=B1=B0=20=EA=B2=8C=EC=9E=84=EC=A4=91?= =?UTF-8?q?=EC=97=90=EB=A7=8C=20=EB=8B=AC=EB=A6=AC=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Component/Game/GameHeader.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Component/Game/GameHeader.tsx b/src/Component/Game/GameHeader.tsx index 3dc22af..54add40 100644 --- a/src/Component/Game/GameHeader.tsx +++ b/src/Component/Game/GameHeader.tsx @@ -21,7 +21,7 @@ const GameHeader: React.FC = ({ text }) => { return ( <>{text} - + {text.length < 4 ? : <>} ); }; From b883d08b58efe93086dc67038cc9e1c85b9e5c70 Mon Sep 17 00:00:00 2001 From: lucy726j Date: Fri, 27 Sep 2024 14:40:55 +0900 Subject: [PATCH 05/18] =?UTF-8?q?Fix=20:=20=EB=9E=AD=ED=82=B9=20=EB=B0=95?= =?UTF-8?q?=EC=8A=A4=20=ED=95=AD=EB=AA=A9=20=EC=B6=94=EA=B0=80=20#222?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Pages/game/rank.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Pages/game/rank.tsx b/src/Pages/game/rank.tsx index 72c8eab..c57bb67 100644 --- a/src/Pages/game/rank.tsx +++ b/src/Pages/game/rank.tsx @@ -4,7 +4,15 @@ import { RankDataProps, RankListProps } from "../../constants/interface"; import axios from "axios"; import RankList from "../../Component/Game/Rank/rankList"; import BentoBar from "../../Game/Main/BentoBar/bentoBar"; -import swal from "sweetalert"; +import styled from "styled-components"; + +const TitleContainer = styled.div` + display: flex; + flex-direction: row; + margin-top: 1rem; + border-bottom: 1px solid black; + padding-bottom: 0.5rem; +`; const Rank = () => { const [rankList, setRankList] = useState([]); @@ -29,6 +37,12 @@ const Rank = () => { return (
+ +

순위

+

닉네임

+

수익금

+

수익률

+
From 0434ff922d4217710f5aac9056fb96ef8ee552a6 Mon Sep 17 00:00:00 2001 From: lucy726j Date: Fri, 27 Sep 2024 14:53:32 +0900 Subject: [PATCH 06/18] =?UTF-8?q?Style=20:=20=EC=B5=9C=EC=A2=85=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Pages/game/rank.tsx | 4 ++-- src/Pages/game/totalResult.tsx | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Pages/game/rank.tsx b/src/Pages/game/rank.tsx index c57bb67..e180aaf 100644 --- a/src/Pages/game/rank.tsx +++ b/src/Pages/game/rank.tsx @@ -39,8 +39,8 @@ const Rank = () => {

순위

-

닉네임

-

수익금

+

닉네임

+

수익금

수익률

diff --git a/src/Pages/game/totalResult.tsx b/src/Pages/game/totalResult.tsx index e0034ef..d0ca08b 100644 --- a/src/Pages/game/totalResult.tsx +++ b/src/Pages/game/totalResult.tsx @@ -22,6 +22,7 @@ const SkrrContainer = styled.div` display: flex; flex-direction: row; position: relative; + margin-top: 1.5rem; `; const ImgStyle = styled.img` @@ -38,9 +39,9 @@ const BtnBox = styled.div` flex-direction: row; align-items: center; gap: 1rem; - margin-top: 0.5rem; margin-left: auto; margin-right: 2.5rem; + margin-top: 1rem; `; const NickBox = styled.div` @@ -134,10 +135,7 @@ const TotalResult = () => { - -

{user}

-

의 점수를

-
+ {user} - - - {showTable && } - - ); + const nav = useNavigate(); + + const [nickname, setNickname] = useState(""); // 닉네임 + const [total, setTotal] = useState(0); // 총 평가금액 + const [changeFromLast, setChangeFromLast] = useState(0); // 작년 대비 금액 + const [changeFromStart, setChangeFromStart] = useState(0); // 전체 대비 금액 + const [changeRateFromLast, setChangeRateFromLast] = useState(0); // 작년 대비 변동률 + const [changeRateFromStart, setChangeRateFromStart] = useState(0); // 전체 대비 변동률 + const [holdingList, setHoldingList] = useState([]); // 20xx년 주식가격 + const [showTable, setShowTable] = useState(false); + + const check = usePortfolioStore((state) => state.check); + + // 페이지 유효성 검사 + const setCheckYear = useGameStore((state) => state.setCheckYear); + + useEffect(() => { + axios + .get(`${process.env.REACT_APP_API_URL}/v1/game/user`, { + withCredentials: true, + headers: { + "Content-Type": "application/json", + }, + }) + .then((res) => { + if (res.status === 200) { + setCheckYear(res.data.year); + setNickname(res.data.nickname); + setBudget(res.data.budget); + setTotal(res.data.total); + setChangeFromLast(res.data.changeFromLast); + setChangeFromStart(res.data.changeFromStart); + setChangeRateFromLast(res.data.changeRateFromLast); + setChangeRateFromStart(res.data.changeRateFromStart); + setHoldingList(res.data.holdingList); + } else if (res.status === 401) { + alert("401"); + } + }) + .catch((e) => { + nav("/error"); + }); + }, [check]); + + const handleShowTable = () => { + setShowTable((prev) => !prev); + }; + + return ( + + + {nickname} 님의 계좌잔고 💰 + + + 거래가능금액 +
{formatPrice(budget)} 원
+
+
+ + 총 평가금액 +
{formatPrice(total)} 원
+
+ + 작년 대비 +
0 + ? "red" + : changeRateFromLast < 0 + ? "blue" + : "black", + }} + > + {formatPrice(changeFromLast)} 원 ({changeRateFromLast}%) +
+
+ + 전체 대비 +
0 + ? "red" + : changeRateFromStart < 0 + ? "blue" + : "black", + }} + > + {formatPrice(changeFromStart)} 원 ({changeRateFromStart}%) +
+
+ + + + + {showTable && } +
+ ); }; const GameMoneyContainer = styled.div` - width: 85%; - height: auto; - border-radius: 20px; - box-shadow: 3px 3px 3px rgb(213, 213, 213); - padding: 20px 10px; - position: relative; - margin-top: 20px; - margin-bottom: 20px; + width: 85%; + height: auto; + border-radius: 20px; + box-shadow: 3px 3px 3px rgb(213, 213, 213); + padding: 20px 10px; + position: relative; + margin-top: 20px; + margin-bottom: 20px; `; const GameMoneyTitle = styled.div` - margin-bottom: 30px; + margin-bottom: 30px; `; const GameMoneyBalance = styled.div` - display: flex; - margin: 15px 0; - flex-direction: row; + display: flex; + margin: 15px 0; + flex-direction: row; `; const BalanceDetailButton = styled.div` - position: absolute; - top: 118px; - right: 20px; + position: absolute; + top: 118px; + right: 20px; `; const BalanceTitle = styled.div` - color: #6c6c6c; - width: 110px; + color: #6c6c6c; + width: 110px; `; const Button = styled.button` - width: 78px; - height: 40px; - border-radius: 50px; - border: none; - background-color: #f1f1f1; - cursor: pointer; - - &:hover { - background-color: #615efc; - color: white; - font-weight: 600; - } + width: 78px; + height: 40px; + border-radius: 50px; + border: none; + background-color: #f1f1f1; + cursor: pointer; + + &:hover { + background-color: #615efc; + color: white; + font-weight: 600; + } `; export default GameMoney; diff --git a/src/Pages/404/noUser.tsx b/src/Pages/404/noUser.tsx index 296e704..e323774 100644 --- a/src/Pages/404/noUser.tsx +++ b/src/Pages/404/noUser.tsx @@ -2,8 +2,6 @@ import { useNavigate } from "react-router-dom"; import styled from "styled-components"; import { GoAlert } from "react-icons/go"; import { Colors } from "../../Styles/Colors"; -import Header from "../../Component/Layout/Header/Header"; -import NavBar from "../../Component/Layout/NavBar/NavBar"; const Box = styled.div` height: 60vh; diff --git a/src/Pages/game/infoPage.tsx b/src/Pages/game/infoPage.tsx index 3ad2be0..a086451 100644 --- a/src/Pages/game/infoPage.tsx +++ b/src/Pages/game/infoPage.tsx @@ -1,14 +1,54 @@ -import { useParams } from "react-router-dom"; +import { useParams, useNavigate } from "react-router-dom"; import ExchangeStoreMain from "../../Game/Shop/exchangeStoreMain"; import GameHeader from "../../Component/Game/GameHeader"; +import { GoAlert } from "react-icons/go"; +import { Colors } from "../../Styles/Colors"; +import Button from "../../Component/Button/button"; +import { useGameStore } from "../../store/useGameStore"; const InfoPage = () => { const { year } = useParams<{ year: string }>(); + const yearValue = year || "2014"; + const yearNumber = parseInt(yearValue, 10); + const checkYear = useGameStore((state) => state.checkYear); + const nav = useNavigate(); + return ( -
- - -
+ <> + {yearNumber !== checkYear ? ( +
+ +

정상적인 접근 경로가 아닙니다

+
+ ) : ( +
+ + +
+ )} + ); }; diff --git a/src/Pages/game/playPage.tsx b/src/Pages/game/playPage.tsx index 9678c29..c904916 100644 --- a/src/Pages/game/playPage.tsx +++ b/src/Pages/game/playPage.tsx @@ -1,5 +1,4 @@ -import { useNavigate, useParams, useLocation } from "react-router-dom"; -import { useEffect } from "react"; +import { useNavigate, useParams } from "react-router-dom"; import GameButtons from "../../Component/Game/GameButtons"; import GameHeader from "../../Component/Game/GameHeader"; import GameMoney from "../../Component/Game/GameMoney"; @@ -13,7 +12,11 @@ import "./gameStyle.css"; import HappyNewYearModal from "./HappyNewYearModal"; import { useStock } from "../../store/stockContext"; import { usePortfolioStore } from "../../store/usePortfolioStore"; +import { useGameStore } from "../../store/useGameStore"; import ProgressBar from "../../Game/Loading/progressBar"; +import { GoAlert } from "react-icons/go"; +import { Colors } from "../../Styles/Colors"; +import Button from "../../Component/Button/button"; const Container = styled.div` display: flex; @@ -24,16 +27,19 @@ const Container = styled.div` `; const PlayPage = () => { - const { year } = useParams<{ year: string }>(); + const { year } = useParams<{ year?: string }>(); const { stockData, setStockData } = useStock(); const nav = useNavigate(); const yearValue = year || "2014"; + // 페이지 유효성 검사를 위한 변수 + const yearNumber = parseInt(yearValue, 10); const [isTradeModalVisible, setIsTradeModalVisible] = useState(false); const [isPassModalVisible, setIsPassModalVisible] = useState(false); const [isHappyNewYearModal, setIsHappyNewYearModal] = useState(false); const [budget, setBudget] = useState(0); const [loading, setLoading] = useState(false); + const checkYear = useGameStore((state) => state.checkYear); const check = usePortfolioStore((state) => state.check); const setCheck = usePortfolioStore((state) => state.setCheck); @@ -75,7 +81,6 @@ const PlayPage = () => { setIsPassModalVisible(false); if (year === "2023") { - console.log("게임 끝"); nav("/game/result/total"); } else { const response = await axios.get( @@ -116,20 +121,49 @@ const PlayPage = () => { }; return ( - - - -
- {/*
*/} - {/*

+ {yearNumber !== checkYear ? ( +

+ +

정상적인 접근 경로가 아닙니다

+
+ ) : ( + + + +
+ {/*
*/} + {/*

{ > 게임 진행도

*/} - {/*
*/} - -
- - - - - - -
+ {/*
*/} + +
+ + + + + + +
+ )} + ); }; diff --git a/src/store/useGameStore.ts b/src/store/useGameStore.ts new file mode 100644 index 0000000..5bd84a5 --- /dev/null +++ b/src/store/useGameStore.ts @@ -0,0 +1,15 @@ +import { create } from "zustand"; +import { PortfolioProps, StockProps } from "../constants/interface"; + +interface GameState { + checkYear: number; + setCheckYear: (checkYear: number) => void; +} + +export const useGameStore = create((set) => ({ + checkYear: 2014, + + setCheckYear(checkYear) { + set({ checkYear }); + }, +}));