diff --git a/app/dashboard/mypage/page.tsx b/app/dashboard/mypage/page.tsx index 44c1938..b9e1b61 100644 --- a/app/dashboard/mypage/page.tsx +++ b/app/dashboard/mypage/page.tsx @@ -3,34 +3,32 @@ import Link from "next/link" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" -import { TrendingUp, TrendingDown, ChevronRight, Menu } from "lucide-react" +import { TrendingUp, TrendingDown, ChevronRight, Menu, PieChart, BarChart3, Wallet,DollarSign } from "lucide-react" import Image from "next/image"; -import { useRouter } from "next/navigation" +import { useRouter } from "next/navigation" import { useEffect, useState } from "react" import ProfileModal from "@/components/common/ProfileModal" -import { useGetProfileQuery,useGetWalletQuery, getStockPortfolio, getTradeHistory, getFavoriteStocks, getMyStocks } from "@/lib/api" -import { useGetOverallPortfolioQuery } from "@/lib/api"; +import { useGetProfileQuery, useGetWalletQuery, getStockPortfolio, getTradeHistory, getFavoriteStocks, getMyStocks } from "@/lib/api" +import { useGetOverallPortfolioQuery } from "@/lib/api"; import ProfileHandler from "@/components/common/ProfileHandler"; import LogoutButton from "@/components/common/LogoutButton" export default function MyPage() { - const holdings = [{ name: "테슬라", purchasePrice: 300, currentPrice: 344, Quantity: 2 , gain: 44, returnRate: 14.67 }] + const holdings = [{ name: "테슬라", purchasePrice: 300, currentPrice: 344, Quantity: 2, gain: 44, returnRate: 14.67 }] const router = useRouter() const [nickname, setNickname] = useState(null) - + const handleAvatarClick = () => { - const url = new URL(window.location.href) - url.searchParams.set("modal", "edit") - router.push(url.toString()) + const url = new URL(window.location.href) + url.searchParams.set("modal", "edit") + router.push(url.toString()) } - - const [isLoggedIn, setIsLoggedIn] = useState(true); - const { data: walletData, isLoading, isError,refetch: refetchWallet } = useGetWalletQuery(); - const { data, isLoading: Loading, isError:error,refetch: refetchPortfolio } = useGetOverallPortfolioQuery(); + // const { data: walletData, isLoading, isError,refetch: refetchWallet } = useGetWalletQuery(); + // const { data, isLoading: Loading, isError:error,refetch: refetchPortfolio } = useGetOverallPortfolioQuery(); const [stockPortfolio, setStockPortfolio] = useState([]); const [isLoadingPortfolio, setIsLoadingPortfolio] = useState(true); const [tradeHistory, setTradeHistory] = useState([]); @@ -40,6 +38,13 @@ export default function MyPage() { const [isLoadingFavorites, setIsLoadingFavorites] = useState(true); const [isLoadingMyStocks, setIsLoadingMyStocks] = useState(true); + + const { data: walletData, isLoading, isError, refetch: refetchWallet } = useGetWalletQuery(undefined, { + skip: !isLoggedIn, // 로그인하지 않은 경우 쿼리 실행하지 않음 + }); + const { data, isLoading: Loading, isError: error, refetch: refetchPortfolio } = useGetOverallPortfolioQuery(undefined, { + skip: !isLoggedIn, // 로그인하지 않은 경우 쿼리 실행하지 않음 + }); useEffect(() => { const fetchStockPortfolio = async () => { try { @@ -103,34 +108,41 @@ export default function MyPage() { fetchMyStocks(); }, []); + // 로그인 상태가 변경될 때마다 데이터 새로고침 + useEffect(() => { + if (isLoggedIn) { + refetchPortfolio(); + refetchWallet(); + } + }, [isLoggedIn, refetchPortfolio, refetchWallet]); if (isLoading) return
로딩 중...
; - if (error || !data?.data) return
에러 발생
; - - //포트폴리오 데이터 + if (error || !data?.data) return
잠시만 기다려주세요
; + + //포트폴리오 데이터 const portfolioData = { totalAssets: data.data.totalAsset, //총자산 investmentAmount: data.data.investedAmount, //투자금액 profitLoss: data.data.evalGain, //평가손익 - returnRate: data.data.returnRate * 100, // %로 보기 좋게 + returnRate: data.data.returnRate * 10, // %로 보기 좋게 investRatio: data.data.investRatio * 100, // 총 투자비율 cash: data.data.cash,// 현금자산 }; return ( - +
- Mars 로고 + Mars 로고 {/* Mars */}
@@ -140,26 +152,28 @@ export default function MyPage() { {nickname ? `${nickname}님 환영합니다` : "mars 모투에 오신걸 환영합니다"} + onNicknameUpdate={setNickname} + onLoginStatusUpdate={setIsLoggedIn} + /> - + 로그아웃
- +
{/* Left Column - Hidden on mobile, visible on lg screens */}
{/* Interest Stocks Section */} -
- 관심 종목 + {/*
*/} + {/*
*/} +
+ 관심 종목
- +
{isLoadingFavorites ? ( @@ -206,407 +220,471 @@ export default function MyPage() { )}
- - - {/* Purchased Stocks Section */} -
- 내가 구매한 종목 -
-
-
- {isLoadingMyStocks ? ( -
로딩 중...
- ) : myStocks.length === 0 ? ( -
내가 구매한 종목이 없습니다.
- ) : ( - myStocks.map((stock, index) => ( -
-
-
- {stock.symbol} { - const target = e.target as HTMLImageElement; - target.style.display = "none"; - const parent = target.parentElement; - if (parent) { - const fallback = document.createElement("div"); - fallback.className = "w-8 h-8 bg-gray-200 rounded-full flex items-center justify-center"; - fallback.innerHTML = `${stock.symbol.slice(0, 2)}`; - parent.appendChild(fallback); - } - }} - /> -
-
-
{stock.symbol}
-
{stock.name}
-
-
-
-
${stock.currentPrice.toFixed(2)}
-
= 0 ? "text-[#41c3a9]" : "text-red-500"}`}> - {stock.priceDelta >= 0 ? "+" : ""}{stock.priceDelta.toFixed(2)}% -
-
-
- )) - )} -
-
-
- - {/* Main Content */} - {/*
*/} -
- -
- - {`${nickname}님 자산현황 입니다.`} -
- {/* Integrated Portfolio Overview Block */} - - - 포트폴리오 현황 - - -
- {/* 총자산 */} - -
-
-
총자산
-
-
- ${" "} - {portfolioData.totalAssets.toLocaleString("en-US", { - minimumFractionDigits: 2, - maximumFractionDigits: 2, - })} -
-
Total Assets
-
- - - {/* 투자금액 */} - -
-
-
투자금액
-
-
- ${" "} - {portfolioData.investmentAmount.toLocaleString("en-US", { - minimumFractionDigits: 2, - maximumFractionDigits: 2, - })} -
-
Investment Amount
-
- - - {/* 평가손익 */} - -
-
-
평가손익
-
-
= 0 - ? "text-[#41c3a9] group-hover:text-[#c0392b]" - : "text-[#e74c3c] group-hover:text-[#2c80b4]"} - `} - > - {portfolioData.profitLoss >= 0 ? "+$" : "-$"} - {Math.abs(portfolioData.profitLoss).toLocaleString("en-US", { - minimumFractionDigits: 2, - maximumFractionDigits: 2, - })} -
-
Profit & Loss
-
- - - {/* 수익률 */} - -
-
-
수익률
-
-
= 0 - ? "text-[#41c3a9] group-hover:text-[#4caf50]" - : "text-[#e74c3c] group-hover:text-[#a73d2a]"} - `}//#41c3a9 - > - {portfolioData.returnRate >= 0 ? ( - - ) : ( - - )} - {portfolioData.returnRate >= 0 ? "+" : "-"} - {Math.abs(portfolioData.returnRate).toFixed(2)}% -
+ {/* Purchased Stocks Section */} + {/*
*/} +
+ 내가 구매한 종목 +
-
Return Rate
-
- - - {/* 제공시드머니 */} - -
-
-
제공시드머니
-
-
- {isLoading ? "Loading..." : isError || !walletData?.data ? ( - "$0.00" - ) : ( - `$ ${walletData.data.cyberDollar.toLocaleString("en-US", { - minimumFractionDigits: 2, - maximumFractionDigits: 2, - })}` - )} -
-
Provided Seed Money
+
+
+ {isLoadingMyStocks ? ( +
로딩 중...
+ ) : myStocks.length === 0 ? ( +
내가 구매한 종목이 없습니다.
+ ) : ( + myStocks.map((stock, index) => ( +
+
+
+ {stock.symbol} { + const target = e.target as HTMLImageElement; + target.style.display = "none"; + const parent = target.parentElement; + if (parent) { + const fallback = document.createElement("div"); + fallback.className = "w-8 h-8 bg-gray-200 rounded-full flex items-center justify-center"; + fallback.innerHTML = `${stock.symbol.slice(0, 2)}`; + parent.appendChild(fallback); + } + }} + /> +
+
+
{stock.symbol}
+
{stock.name}
+
+
+
+
${stock.currentPrice.toFixed(2)}
+
= 0 ? "text-[#41c3a9]" : "text-red-500"}`}> + {stock.priceDelta >= 0 ? "+" : ""}{stock.priceDelta.toFixed(2)}% +
+
+
+ )) + )}
- +
+
- {/* 시드머니 문의 */} - -
-
-
시드머니 문의
-
-
- 챗봇에게 문의하기 -
-
Seed Money Inquiry
-
- + {/* Main Content */} + {/*
*/} +
+ +
+ + {`${nickname}님 자산현황 입니다.`}
- {/* Summary Bar */} -
-
-
-
-
총 투자 비율
-
- {(portfolioData.investRatio).toFixed(1)}% -
-
- -
-
현금 자산
-
+
+ {/* Integrated Portfolio Overview Block */} + + + + + 포트폴리오 현황 + +

실시간 투자 성과 분석

+
+ +
+ {/* 총자산 */} + +
+
+
+
+
총자산
+ +
+
${" "} - {portfolioData.cash.toLocaleString("en-US", { + {portfolioData.totalAssets.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2, })}
+
Total Assets
-
- -
-
- - - - {/* Holdings Table */} - - - 보유종목/상품현황 - - -
- - - - - - - - - - - - - {isLoadingPortfolio ? ( - - - - ) : stockPortfolio.length === 0 ? ( - - - - ) : ( - stockPortfolio.map((stock, index) => ( - - - - - - - - - )) - )} - -
상품/종목명매수금액보유수량평가금액평가손익수익률
로딩 중...
보유 중인 종목이 없습니다.
-
-
- {stock.symbol} { - const target = e.target as HTMLImageElement; - target.style.display = "none"; - const parent = target.parentElement; - if (parent) { - const fallback = document.createElement("div"); - fallback.className = "w-8 h-8 bg-[#f99f01] rounded-full flex items-center justify-center text-white text-sm font-bold"; - fallback.innerHTML = `${stock.symbol.charAt(0)}`; - parent.appendChild(fallback); - } - }} - /> -
- {stock.name} -
-
- ${stock.avgBuyPrice.toLocaleString("en-US", { - minimumFractionDigits: 2, - maximumFractionDigits: 2, - })} - {stock.quantity} - ${stock.evalAmount.toLocaleString("en-US", { + + + + {/* 투자금액 */} + +
+
+
+
+
투자금액
+ +
+
+ ${" "} + {portfolioData.investmentAmount.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2, })} -
= 0 ? 'text-[#63c89b]' : 'text-[#e74c3c]'}`}> - {stock.evalGain >= 0 ? '+' : ''}${stock.evalGain.toLocaleString("en-US", { + +
Investment Amount
+ + + + {/* 평가손익 */} + +
= 0 + ? "bg-gradient-to-br from-emerald-50 to-teal-100 border-emerald-200/50" + : "bg-gradient-to-br from-red-50 to-rose-100 border-red-200/50" + }`} + > +
= 0 + ? "bg-gradient-to-br from-emerald-400/20 to-teal-500/20" + : "bg-gradient-to-br from-red-400/20 to-rose-500/20" + }`} + >
+
+
+
= 0 ? "text-emerald-700" : "text-red-700"}`} + > + 평가손익 +
+ {portfolioData.profitLoss >= 0 ? ( + + ) : ( + + )} +
+
= 0 ? "text-emerald-800" : "text-red-800" + }`} + > + {portfolioData.profitLoss >= 0 ? "+$" : "-$"} + {Math.abs(portfolioData.profitLoss).toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2, })} -
= 0 ? 'text-[#63c89b]' : 'text-[#e74c3c]'}`}> - {stock.returnRate >= 0 ? '+' : ''}{(stock.returnRate * 100).toFixed(2)}% -
-
-
-
- - {/* Stock Performance Table */} - - - 주식 거래내역 - - -
-
- - - - - - - - - - - - {isLoadingHistory ? ( - - - - ) : tradeHistory.length === 0 ? ( - - - - ) : ( - tradeHistory.map((trade, index) => ( - - - - - - + + + + + + + + + {/* Holdings Table */} + + + + 보유종목/상품현황 +

현재 보유 중인 주식

+
+ +
+
일자상품/종목명거래단가체결수량수익률
로딩 중...
거래 내역이 없습니다.
- {(() => { - try { - const date = new Date(trade.date); - if (isNaN(date.getTime())) { - console.error('Invalid date:', trade.date); - return '날짜 정보 없음'; - } - return date.toLocaleDateString('ko-KR', { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit' - }); - } catch (error) { - console.error('Date parsing error:', error); - return '날짜 정보 없음'; - } - })()} - -
-
- {trade.symbol} { - const target = e.target as HTMLImageElement; - target.style.display = "none"; - const parent = target.parentElement; - if (parent) { - const fallback = document.createElement("div"); - fallback.className = "w-8 h-8 bg-[#f99f01] rounded-full flex items-center justify-center text-white text-sm font-bold"; - fallback.innerHTML = `${trade.symbol.charAt(0)}`; - parent.appendChild(fallback); - } - }} - /> -
- {trade.name} -
-
- ${trade.currentPrice.toLocaleString("en-US", { + +
= 0 ? "text-emerald-600" : "text-red-600"}`} + > + Profit & Loss +
+ + + + {/* 수익률 */} + +
= 0 + ? "bg-gradient-to-br from-green-50 to-emerald-100 border-green-200/50" + : "bg-gradient-to-br from-orange-50 to-red-100 border-orange-200/50" + }`} + > +
= 0 + ? "bg-gradient-to-br from-green-400/20 to-emerald-500/20" + : "bg-gradient-to-br from-orange-400/20 to-red-500/20" + }`} + >
+
+
+
= 0 ? "text-green-700" : "text-orange-700"}`} + > + 수익률 +
+ {portfolioData.returnRate >= 0 ? ( + + ) : ( + + )} +
+
= 0 ? "text-green-800" : "text-orange-800" + }`} + > + {portfolioData.returnRate >= 0 ? "+" : "-"} + {Math.abs(portfolioData.returnRate * 100).toFixed(2)}% +
+
= 0 ? "text-green-600" : "text-orange-600"}`} + > + Return Rate +
+
+
+ + + {/* 제공시드머니 */} + +
+
+
+
+
제공시드머니
+ +
+
+ {isLoading ? "Loading..." : isError || !walletData?.data ? ( + "$0.00" + ) : ( + `$ ${walletData.data.cyberDollar.toLocaleString("en-US", { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })}` + )} +
+
Provided Seed Money
+
+
+ + + {/* 시드머니 문의 */} + +
alert("준비중입니다. 곧 제공될 예정입니다.")}> +
+
+
+
시드머니 문의
+ +
+
+ 챗봇에게 문의하기 +
+
Seed Money Inquiry
+
+
+ + + + {/* Summary Bar */} +
+
+
+
+
총 투자 비율
+
+ {(portfolioData.investRatio).toFixed(1)}% +
+
+ +
+
현금 자산
+
+ ${" "} + {portfolioData.cash.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2, })} -
{trade.quantity}= 0 ? 'text-[#63c89b]' : 'text-[#e74c3c]'}`}> - {trade.returnRate >= 0 ? '+' : ''}{(trade.returnRate * 100).toFixed(2)}% -
+ + + + + + + + - )) - )} - -
상품/종목명매수금액보유수량평가금액평가손익수익률
-
+ + + {isLoadingPortfolio ? ( + + 로딩 중... + + ) : stockPortfolio.length === 0 ? ( + + 보유 중인 종목이 없습니다. + + ) : ( + stockPortfolio.map((stock, index) => ( + + +
+
+ {stock.symbol} { + const target = e.target as HTMLImageElement; + target.style.display = "none"; + const parent = target.parentElement; + if (parent) { + const fallback = document.createElement("div"); + fallback.className = "w-8 h-8 bg-[#f99f01] rounded-full flex items-center justify-center text-white text-sm font-bold"; + fallback.innerHTML = `${stock.symbol.charAt(0)}`; + parent.appendChild(fallback); + } + }} + /> +
+ {stock.name} +
+ + + ${stock.avgBuyPrice.toLocaleString("en-US", { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })} + + {stock.quantity} + + ${stock.evalAmount.toLocaleString("en-US", { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })} + + = 0 ? 'text-[#63c89b]' : 'text-[#e74c3c]'}`}> + {stock.evalGain >= 0 ? '+' : ''}${stock.evalGain.toLocaleString("en-US", { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })} + + = 0 ? 'text-[#63c89b]' : 'text-[#e74c3c]'}`}> + {stock.returnRate >= 0 ? '+' : ''}{(stock.returnRate * 100).toFixed(2)}% + + + )) + )} + + +
+
+
+ + {/* Stock Performance Table */} + + + + 주식 거래내역 +

최근 주식 거래 기록

+
+ +
+
+ + + + + + + + + + + + {isLoadingHistory ? ( + + + + ) : tradeHistory.length === 0 ? ( + + + + ) : ( + tradeHistory.map((trade, index) => ( + + + + + + + + )) + )} + +
일자상품/종목명거래단가체결수량수익률
로딩 중...
거래 내역이 없습니다.
+ {(() => { + try { + const date = new Date(trade.date); + if (isNaN(date.getTime())) { + console.error('Invalid date:', trade.date); + return '날짜 정보 없음'; + } + return date.toLocaleDateString('ko-KR', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit' + }); + } catch (error) { + console.error('Date parsing error:', error); + return '날짜 정보 없음'; + } + })()} + +
+
+ {trade.symbol} { + const target = e.target as HTMLImageElement; + target.style.display = "none"; + const parent = target.parentElement; + if (parent) { + const fallback = document.createElement("div"); + fallback.className = "w-8 h-8 bg-[#f99f01] rounded-full flex items-center justify-center text-white text-sm font-bold"; + fallback.innerHTML = `${trade.symbol.charAt(0)}`; + parent.appendChild(fallback); + } + }} + /> +
+ {trade.name} +
+
+ ${trade.currentPrice.toLocaleString("en-US", { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })} + {trade.quantity}= 0 ? 'text-[#63c89b]' : 'text-[#e74c3c]'}`}> + {trade.returnRate >= 0 ? '+' : ''}{(trade.returnRate * 100).toFixed(2)}% +
+
+
+
+
- - +
+
+
-
- -
-) + ) } - diff --git a/app/dashboard/page.tsx b/app/dashboard/page.tsx index db15668..2433d24 100644 --- a/app/dashboard/page.tsx +++ b/app/dashboard/page.tsx @@ -16,7 +16,6 @@ import Link from "next/link"; import { Button } from "@/components/ui/button"; import ProfileModal from "@/components/common/ProfileModal"; import { Heart } from "lucide-react"; -import mockPortfolio from "@/lib/mock/mockportfolio"; import ProfileHandler from "@/components/common/ProfileHandler"; import useSWR from "swr"; @@ -316,12 +315,12 @@ export default function Dashboard() { isLoading: isPortfolioLoading, isError: isPortfolioError, } = useGetOverallPortfolioQuery(); - const cyberDollars = walletData?.data?.cyberDollar ?? 0; + const cyberDollar = walletData?.data?.cyberDollar ?? 0; const portfolioData = { totalAssets: overallData?.data?.totalAsset ?? 0, investmentAmount: overallData?.data?.investedAmount ?? 0, profitLoss: overallData?.data?.evalGain ?? 0, - returnRate: (overallData?.data?.returnRate ?? 0) * 100, + returnRate: (overallData?.data?.returnRate ?? 0) * 10, }; // 컴포넌트 마운트 시 실시간 데이터 가져오기 @@ -396,7 +395,7 @@ export default function Dashboard() { 내계좌 - + 로그아웃 @@ -414,7 +413,7 @@ export default function Dashboard() {
oo님 mars 모투에 오신걸 환영합니다
- - + { @@ -464,7 +469,8 @@ export default function FinanceDashboard() { {/* Left Column - Hidden on mobile, visible on lg screens */}
{/* 오늘의 핫 종목 목록 */} -
+ {/*
*/} +
오늘의 핫 종목
diff --git a/components/BuyPanel.tsx b/components/BuyPanel.tsx index e0eeb9e..9bb73a0 100644 --- a/components/BuyPanel.tsx +++ b/components/BuyPanel.tsx @@ -105,33 +105,33 @@ export default function BuyPanel({ open, onClose, symbol, name, totalAssets, pri
수익률
$ - {returnRate.toFixed(2)}% + {(returnRate * 100).toFixed(2)}%
시드머니
- $ - {cyberDollar.toFixed(2)} + $ + {cyberDollar.toFixed(2)}
투자금액
- $ - {investmentAmount.toFixed(2)} + $ + {investmentAmount.toFixed(2)}
평가손익
= 0 ? "text-[#e74c3c]" : "text-[#3498db]"}`} + className={`text-xs mr-1 ${profitLoss >= 0 ? "text-[#439a86]" : "text-[#e74c3c]"}`} > $ = 0 ? "text-[#e74c3c]" : "text-[#3498db]"}`} + className={`text-xl font-bold ${profitLoss >= 0 ? "text-[#439a86]" : "text-[#e74c3c]"}`} > {profitLoss >= 0 ? "+" : "-"} {Math.abs(profitLoss).toFixed(2)} diff --git a/components/SearchBar.tsx b/components/SearchBar.tsx index 06e0a0c..4df394a 100644 --- a/components/SearchBar.tsx +++ b/components/SearchBar.tsx @@ -70,8 +70,9 @@ export default function SearchBar({ onSelectStock }: SearchBarProps) { return (
-
- + {/*
*/} +
+ setShowResults(true)} - className="flex-1 bg-transparent border-0 focus:outline-none text-base text-gray-700 placeholder-gray-500" + className="flex-1 bg-transparent border-0 focus:outline-none text-base text-white placeholder-white" />
diff --git a/components/SellPanel.tsx b/components/SellPanel.tsx index 96d3a88..4b6cd1f 100644 --- a/components/SellPanel.tsx +++ b/components/SellPanel.tsx @@ -103,33 +103,33 @@ export default function SellPanel({ open, onClose, symbol, name, price, totalAss
수익률
$ - {returnRate.toFixed(2)}% + {(returnRate * 100).toFixed(2)}%
시드머니
- $ - {cyberDollar.toFixed(2)} + $ + {cyberDollar.toFixed(2)}
투자금액
- $ - {investmentAmount.toFixed(2)} + $ + {investmentAmount.toFixed(2)}
평가손익
= 0 ? "text-[#e74c3c]" : "text-[#3498db]"}`} + className={`text-xs mr-1 ${profitLoss >= 0 ? "text-[#439a86]" : "text-[#e74c3c]"}`} > $ = 0 ? "text-[#e74c3c]" : "text-[#3498db]"}`} + className={`text-xl font-bold ${profitLoss >= 0 ? "text-[#439a86]" : "text-[#e74c3c]"}`} > {profitLoss >= 0 ? "+" : "-"} {Math.abs(profitLoss).toFixed(2)} diff --git a/components/StockDetails.tsx b/components/StockDetails.tsx index f4c4bc3..ecd37fa 100644 --- a/components/StockDetails.tsx +++ b/components/StockDetails.tsx @@ -7,8 +7,8 @@ import type { StockDetails, NewsItem, Stock, RiskLevel, PreferredStrategy, Prefe import { Check, ChevronDown, ChevronLeft, Heart } from 'lucide-react'; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; -import mockPortfolio from "@/lib/mock/mockportfolio"; import { TrendingUp, TrendingDown } from "lucide-react" +import { useGetOverallPortfolioQuery, useGetWalletQuery } from "@/lib/api"; import { mutate } from 'swr'; // 주식 상세 정보를 보여주는 컴포넌트(종목정보 상세, 내 계좌, AI 추천 탭) @@ -31,7 +31,10 @@ export default function StockDetails({ symbol, activeTab, onTabChange, favoriteS const [showReasonDetail, setShowReasonDetail] = useState(false); const [aiSubmitted, setAiSubmitted] = useState(false); const [isHeartFilled, setIsHeartFilled] = useState(false); - const [portfolioData, setPortfolioData] = useState(mockPortfolio); + + const { data: portfolioData, isLoading: isPortfolioLoading } = useGetOverallPortfolioQuery(); + const { data: walletData, isLoading: isWalletLoading } = useGetWalletQuery(); + const [selectedRiskLevel, setSelectedRiskLevel] = useState(null); const [selectedStrategies, setSelectedStrategies] = useState([]); const [selectedSectors, setSelectedSectors] = useState([]); @@ -429,85 +432,91 @@ export default function StockDetails({ symbol, activeTab, onTabChange, favoriteS {activeTab === '내 계좌' ? ( isLoggedIn ? (
- {/* Financial Information */} -
- {/* Total Assets */} -
- 총자산 -
- $ - {portfolioData.totalAssets.toLocaleString("en-US", { - minimumFractionDigits: 2, - maximumFractionDigits: 2, - })} -
+ {isPortfolioLoading || isWalletLoading ? ( +
+
데이터 로딩 중...
- {/* 시드머니 */} -
- 시드머니 -
+ ) : ( +
+ {/* Total Assets */} +
+ 총자산 +
+ $ + {portfolioData?.data?.totalAsset?.toLocaleString("en-US", { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }) ?? '-'} +
+
+ {/* 시드머니 */} +
+ 시드머니 +
+ $ + {walletData?.data?.cyberDollar?.toLocaleString("en-US", { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }) ?? '-'} +
+
+ {/* Investment Amount */} +
+ 투자금액 +
$ - {portfolioData.seedMoney.toLocaleString("en-US", { - minimumFractionDigits: 2, - maximumFractionDigits: 2, - })} + + {portfolioData?.data?.investedAmount?.toLocaleString("en-US", { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }) ?? '-'} +
-
- {/* Investment Amount */} -
- 투자금액 -
- $ - - {portfolioData.investmentAmount.toLocaleString("en-US", { +
+ {/* Unrealized P&L */} +
+ 평가손익 +
= 0 + ? "text-[#41c3a9] group-hover:text-[#4caf50]" + : "text-[#e74c3c] group-hover:text-[#a73d2a]"} + `} + > + $ + + {(portfolioData?.data?.evalGain ?? 0) >= 0 ? "+" : "-"} + {Math.abs(portfolioData?.data?.evalGain ?? 0).toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2, })}
-
- {/* Unrealized P&L */} -
- 평가손익 -
= 0 - ? "text-[#e74c3c] group-hover:text-[#c0392b]" - : "text-[#3498db] group-hover:text-[#2c80b4]"} +
+ {/* Return Rate */} +
+ 수익률 + +
= 0 + ? "text-[#41c3a9] group-hover:text-[#4caf50]" + : "text-[#e74c3c] group-hover:text-[#a73d2a]"} `} - > - $ - - {portfolioData.profitLoss >= 0 ? "+" : "-"} - {Math.abs(portfolioData.profitLoss).toLocaleString("en-US", { - minimumFractionDigits: 2, - maximumFractionDigits: 2, - })} - -
-
- {/* Return Rate */} -
- 수익률 - -
= 0 - ? "text-[#e74c3c] group-hover:text-[#4caf50]" - : "text-[#3498db] group-hover:text-[#a73d2a]"} - `} - > - {portfolioData.returnRate >= 0 ? ( - - ) : ( - - )} - {portfolioData.returnRate >= 0 ? "+" : "-"} - {Math.abs(portfolioData.returnRate).toFixed(2)}% + > + {(portfolioData?.data?.returnRate ?? 0) >= 0 ? ( + + ) : ( + + )} + {(portfolioData?.data?.returnRate ?? 0) >= 0 ? "+" : "-"} + {Math.abs((portfolioData?.data?.returnRate ?? 0)*1000).toFixed(2)}% + +
+
-
-
+ )}
) : (
@@ -835,7 +844,7 @@ export default function StockDetails({ symbol, activeTab, onTabChange, favoriteS
ROE - {details.roe !== undefined ? `${details.roe.toFixed(2)}%` : '-'} + {details.roe !== undefined ? `${(details.roe*100).toFixed(2)}%` : '-'}
EPS @@ -859,7 +868,7 @@ export default function StockDetails({ symbol, activeTab, onTabChange, favoriteS
부채비율 - {details.debtRatio !== undefined ? `${details.debtRatio.toFixed(2)}%` : '-'} + {details.debtRatio !== undefined ? `${(details.debtRatio * 100).toFixed(2)}%` : '-'}
diff --git a/components/common/LoginModal.tsx b/components/common/LoginModal.tsx index 8f3b865..fbff98d 100644 --- a/components/common/LoginModal.tsx +++ b/components/common/LoginModal.tsx @@ -94,10 +94,13 @@ export default function LoginModal({ open, onOpenChange }: LoginModalProps) { className="relative w-full max-w-md rounded-lg bg-white dark:bg-gray-800 p-8 shadow-lg" >
+
+ M +
+

로그인

MARS 모의투자에 오신걸 환영합니다 !!!

-

로그인

@@ -108,7 +111,6 @@ export default function LoginModal({ open, onOpenChange }: LoginModalProps) { type="email" value={email} onChange={(e) => setEmail(e.target.value)} - placeholder="test@gmail.com" className="border-none bg-[#bfdbfe] dark:bg-gray-700 placeholder:text-[#3c3c43]/70 dark:placeholder:text-gray-400" required /> @@ -136,7 +138,7 @@ export default function LoginModal({ open, onOpenChange }: LoginModalProps) {
{/* test */} -
+
이미 계정이 있으신가요?{" "}