import { useState, useEffect, useCallback, useRef } from "react"; import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer, AreaChart, Area, LineChart, Line, CartesianGrid, Cell, } from "recharts"; /* ── API ──────────────────────────────────────────────────────── */ const api = async (path) => { try { const r = await fetch(`/api${path}`); if (!r.ok) throw new Error(r.statusText); return await r.json(); } catch (e) { console.error(`API [${path}]:`, e); return null; } }; /* ── 유틸 ─────────────────────────────────────────────────────── */ const fmt = (n, d = 4) => (n != null ? Number(n).toFixed(d) : "—"); const fmtTime = (iso) => { if (!iso) return "—"; const d = new Date(iso); return `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`; }; const fmtDate = (s) => (s ? s.slice(5, 10).replace("-", "/") : "—"); const pnlColor = (v) => (v > 0 ? "#34d399" : v < 0 ? "#f87171" : "rgba(255,255,255,0.5)"); const pnlSign = (v) => (v > 0 ? `+${fmt(v)}` : fmt(v)); /* ── 스타일 변수 ──────────────────────────────────────────────── */ const S = { sans: "'Satoshi','DM Sans',system-ui,sans-serif", mono: "'JetBrains Mono','Fira Code',monospace", bg: "#08080f", surface: "rgba(255,255,255,0.015)", surface2: "rgba(255,255,255,0.03)", border: "rgba(255,255,255,0.06)", text3: "rgba(255,255,255,0.35)", text4: "rgba(255,255,255,0.2)", green: "#34d399", red: "#f87171", indigo: "#818cf8", amber: "#f59e0b", }; /* ── Badge ────────────────────────────────────────────────────── */ const Badge = ({ children, bg = "rgba(255,255,255,0.06)", color = "rgba(255,255,255,0.5)" }) => ( {children} ); /* ── StatCard ─────────────────────────────────────────────────── */ const StatCard = ({ icon, label, value, sub, accent }) => (