import React, { useEffect, useMemo, useState } from 'react'; import { AnimatePresence, motion } from 'framer-motion'; const buildPath = (points, width, height) => { if (!points.length) { return ''; } const values = points.map((point) => point.value); const min = Math.min(...values); const max = Math.max(...values); const range = max - min || 1; return points .map((point, index) => { const x = (index / Math.max(points.length - 1, 1)) * width; const y = height - ((point.value - min) / range) * height; return `${index === 0 ? 'M' : 'L'} ${x.toFixed(2)} ${y.toFixed(2)}`; }) .join(' '); }; export const BalancePanel = ({ portfolio, history, lastDelta, trade }) => { const { value = 100000, cash = 100000, positions = {} } = portfolio || {}; const [displayValue, setDisplayValue] = useState(value); const direction = lastDelta > 0 ? 'up' : lastDelta < 0 ? 'down' : 'flat'; useEffect(() => { const start = displayValue; const end = value; let frameId; let startTime; const tick = (timestamp) => { if (!startTime) { startTime = timestamp; } const progress = Math.min((timestamp - startTime) / 500, 1); setDisplayValue(start + (end - start) * progress); if (progress < 1) { frameId = window.requestAnimationFrame(tick); } }; frameId = window.requestAnimationFrame(tick); return () => window.cancelAnimationFrame(frameId); }, [value]); const path = useMemo(() => buildPath(history || [], 260, 86), [history]); const invested = Math.max(value - cash, 0); const exposure = value > 0 ? (invested / value) * 100 : 0; return (