import React, { useState, useEffect, useMemo } from 'react'; import { TrendingUp, TrendingDown, Wallet, Activity, Briefcase, PieChart, Database, Zap, Timer, Trash2, Globe, ArrowUpRight, ArrowDownRight, ChevronRight } from 'lucide-react'; import { StockItem, TradeOrder, MarketType, WatchlistGroup, OrderType, AutoTradeConfig, ReservedOrder } from '../types'; import { DbService, HoldingItem } from '../services/dbService'; import StockDetailModal from '../components/StockDetailModal'; import TradeModal from '../components/TradeModal'; import { StatCard } from '../components/CommonUI'; import { StockRow } from '../components/StockRow'; interface DashboardProps { marketMode: MarketType; watchlistGroups: WatchlistGroup[]; stocks: StockItem[]; orders: TradeOrder[]; reservedOrders: ReservedOrder[]; autoTrades: AutoTradeConfig[]; onManualOrder: (order: Omit) => Promise; onAddReservedOrder: (order: Omit) => Promise; onDeleteReservedOrder: (id: string) => Promise; onRefreshHoldings: () => void; } const IndexBar = () => { const indices = [ { name: '코스피', value: '2,561.32', change: '+12.45', percent: '0.49%', isUp: true }, { name: '코스닥', value: '842.11', change: '-3.21', percent: '0.38%', isUp: false }, { name: '나스닥', value: '15,628.95', change: '+215.12', percent: '1.40%', isUp: true }, { name: 'S&P 500', value: '4,850.12', change: '+45.23', percent: '0.94%', isUp: true }, { name: 'USD/KRW', value: '1,324.50', change: '+2.10', percent: '0.16%', isUp: true }, ]; return (
{indices.map((idx, i) => (
{idx.name} {idx.value}
{idx.isUp ? : } {idx.percent} {idx.change}
))}
); }; const Dashboard: React.FC = ({ marketMode, watchlistGroups, stocks, reservedOrders, onAddReservedOrder, onDeleteReservedOrder, onRefreshHoldings, orders }) => { const [holdings, setHoldings] = useState([]); const [summary, setSummary] = useState({ totalAssets: 0, buyingPower: 0 }); const [activeGroupId, setActiveGroupId] = useState(null); const [detailStock, setDetailStock] = useState(null); const [tradeContext, setTradeContext] = useState<{ stock: StockItem, type: OrderType } | null>(null); const dbService = useMemo(() => new DbService(), []); useEffect(() => { loadData(); }, [orders, marketMode, reservedOrders]); const activeMarketGroups = useMemo(() => { return watchlistGroups.filter(group => group.market === marketMode); }, [watchlistGroups, marketMode]); useEffect(() => { if (activeMarketGroups.length > 0) { if (!activeGroupId || !activeMarketGroups.find(g => g.id === activeGroupId)) { setActiveGroupId(activeMarketGroups[0].id); } } else { setActiveGroupId(null); } }, [marketMode, activeMarketGroups, activeGroupId]); const loadData = async () => { const allHoldings = await dbService.getHoldings(); const filteredHoldings = allHoldings.filter(h => h.market === marketMode); const accSummary = await dbService.getAccountSummary(); setHoldings(filteredHoldings); setSummary(accSummary); }; const calculatePL = (holding: HoldingItem) => { const currentStock = stocks.find(s => s.code === holding.code); const currentPrice = currentStock ? currentStock.price : holding.avgPrice; const pl = (currentPrice - holding.avgPrice) * holding.quantity; const plPercent = ((currentPrice - holding.avgPrice) / holding.avgPrice) * 100; const value = currentPrice * holding.quantity; return { pl, plPercent, currentPrice, value, stock: currentStock }; }; const totalLiquidationSummary = holdings.reduce((acc, h) => { const plData = calculatePL(h); return { totalValue: acc.totalValue + plData.value, totalPL: acc.totalPL + plData.pl, totalCost: acc.totalCost + (h.avgPrice * h.quantity) }; }, { totalValue: 0, totalPL: 0, totalCost: 0 }); const aggregatePLPercent = totalLiquidationSummary.totalCost > 0 ? (totalLiquidationSummary.totalPL / totalLiquidationSummary.totalCost) * 100 : 0; const selectedGroup = activeMarketGroups.find(g => g.id === activeGroupId) || activeMarketGroups[0]; return (
{/* 1. 지수 및 환율 바 */}

관심 그룹

{activeMarketGroups.map(group => ( ))}
{selectedGroup?.codes.map(code => stocks.find(s => s.code === code)).filter(s => s?.market === marketMode).map(stock => { if (!stock) return null; return ( setTradeContext({ stock, type })} onClick={() => setDetailStock(stock)} /> ); })}

보유 포트폴리오

{holdings.map(holding => { const { pl, plPercent, stock } = calculatePL(holding); if (!stock) return null; return ( setTradeContext({ stock, type })} onClick={() => setDetailStock(stock)} /> ); })}
종목 현재가 수익금 (%) 주문

실시간 감시 목록

{reservedOrders.filter(o => o.market === marketMode).map(order => (

{order.stockName}

))}
{detailStock && setDetailStock(null)} />} {tradeContext && setTradeContext(null)} onExecute={onAddReservedOrder} />}
); }; export default Dashboard;