| | import React, { useRef, useState, useEffect } from 'react';
|
| | import { AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid } from 'recharts';
|
| | import Draggable from 'react-draggable';
|
| | import { FaPen, FaEraser, FaSave, FaTimes } from 'react-icons/fa';
|
| | import html2canvas from 'html2canvas';
|
| |
|
| | const Dashboard = ({ report, onClose }) => {
|
| | const [isDrawingMode, setIsDrawingMode] = useState(false);
|
| | const canvasRef = useRef(null);
|
| | const containerRef = useRef(null);
|
| | const [context, setContext] = useState(null);
|
| |
|
| |
|
| | const chartData = report.deals.map((deal, index) => ({
|
| | name: index,
|
| | balance: deal.balance,
|
| | profit: deal.profit
|
| | }));
|
| |
|
| |
|
| | useEffect(() => {
|
| | if (canvasRef.current) {
|
| | const canvas = canvasRef.current;
|
| | canvas.width = canvas.offsetWidth;
|
| | canvas.height = canvas.offsetHeight;
|
| | const ctx = canvas.getContext('2d');
|
| | ctx.strokeStyle = "yellow";
|
| | ctx.lineWidth = 3;
|
| | setContext(ctx);
|
| | }
|
| | }, [isDrawingMode]);
|
| |
|
| | const startDrawing = (e) => {
|
| | if (!isDrawingMode || !context) return;
|
| | context.beginPath();
|
| | context.moveTo(e.nativeEvent.offsetX, e.nativeEvent.offsetY);
|
| | };
|
| |
|
| | const draw = (e) => {
|
| | if (!isDrawingMode || !context || e.buttons !== 1) return;
|
| | context.lineTo(e.nativeEvent.offsetX, e.nativeEvent.offsetY);
|
| | context.stroke();
|
| | };
|
| |
|
| | const saveReport = () => {
|
| | if (containerRef.current) {
|
| | html2canvas(containerRef.current).then(canvas => {
|
| | const link = document.createElement('a');
|
| | link.download = `Remodeled_Report_${report.accountId}.png`;
|
| | link.href = canvas.toDataURL();
|
| | link.click();
|
| | });
|
| | }
|
| | };
|
| |
|
| | return (
|
| | <Draggable handle=".drag-handle">
|
| | <div
|
| | ref={containerRef}
|
| | className="bg-black border border-gray-700 rounded-xl overflow-hidden relative shadow-2xl min-h-[600px]"
|
| | >
|
| | {/* Header / Drag Handle */}
|
| | <div className="drag-handle bg-gray-900 p-3 cursor-grab flex justify-between items-center border-b border-gray-800">
|
| | <h3 className="font-bold text-white">Account: {report.accountId}</h3>
|
| | <div className="flex gap-2">
|
| | <button onClick={() => setIsDrawingMode(!isDrawingMode)} className={`p-2 rounded ${isDrawingMode ? 'bg-blue-600' : 'bg-gray-700'}`}><FaPen /></button>
|
| | <button onClick={saveReport} className="p-2 bg-green-600 rounded"><FaSave /></button>
|
| | <button onClick={onClose} className="p-2 bg-red-600 rounded"><FaTimes /></button>
|
| | </div>
|
| | </div>
|
| |
|
| | {/* Content */}
|
| | <div className="p-4 relative">
|
| |
|
| | {/* Canvas Overlay */}
|
| | <canvas
|
| | ref={canvasRef}
|
| | onMouseDown={startDrawing}
|
| | onMouseMove={draw}
|
| | className={`absolute inset-0 z-20 ${isDrawingMode ? 'cursor-crosshair pointer-events-auto' : 'pointer-events-none'}`}
|
| | style={{ width: '100%', height: '100%' }}
|
| | />
|
| |
|
| | {/* Grid Layout for Remodeled Report */}
|
| | <div className="grid grid-cols-3 gap-4 mb-6">
|
| | <div className="col-span-3 bg-gray-900/50 p-4 rounded-lg">
|
| | <h4 className="text-gray-400 mb-2">Equity & Balance Curve</h4>
|
| | <div className="h-64 w-full">
|
| | <ResponsiveContainer width="100%" height="100%">
|
| | <AreaChart data={chartData}>
|
| | <defs>
|
| | <linearGradient id="colorBal" x1="0" y1="0" x2="0" y2="1">
|
| | <stop offset="5%" stopColor="#8884d8" stopOpacity={0.8}/>
|
| | <stop offset="95%" stopColor="#8884d8" stopOpacity={0}/>
|
| | </linearGradient>
|
| | </defs>
|
| | <CartesianGrid strokeDasharray="3 3" stroke="#333" />
|
| | <XAxis dataKey="name" stroke="#666" />
|
| | <YAxis stroke="#666" domain={['auto', 'auto']} />
|
| | <Tooltip contentStyle={{backgroundColor: '#000', borderColor: '#333'}} />
|
| | <Area type="monotone" dataKey="balance" stroke="#8884d8" fillOpacity={1} fill="url(#colorBal)" />
|
| | </AreaChart>
|
| | </ResponsiveContainer>
|
| | </div>
|
| | </div>
|
| |
|
| | {/* Stat Cards */}
|
| | <div className="bg-gray-800 p-4 rounded text-center">
|
| | <p className="text-gray-400 text-xs">Total Deals</p>
|
| | <p className="text-2xl font-bold">{report.deals.length}</p>
|
| | </div>
|
| | <div className="bg-gray-800 p-4 rounded text-center">
|
| | <p className="text-gray-400 text-xs">Final Balance</p>
|
| | <p className="text-2xl font-bold text-green-400">
|
| | ${report.deals[report.deals.length - 1]?.balance.toFixed(2)}
|
| | </p>
|
| | </div>
|
| | <div className="bg-gray-800 p-4 rounded text-center">
|
| | <p className="text-gray-400 text-xs">Profit Factor</p>
|
| | <p className="text-2xl font-bold">1.5</p> {/* Placeholder calculation */}
|
| | </div>
|
| | </div>
|
| |
|
| | {/* Data Table */}
|
| | <div className="overflow-x-auto">
|
| | <table className="w-full text-left text-xs text-gray-400">
|
| | <thead className="bg-gray-900 text-gray-200">
|
| | <tr>
|
| | <th className="p-2">Time</th>
|
| | <th className="p-2">Symbol</th>
|
| | <th className="p-2">Type</th>
|
| | <th className="p-2">Profit</th>
|
| | </tr>
|
| | </thead>
|
| | <tbody>
|
| | {report.deals.slice(0, 10).map((d, i) => (
|
| | <tr key={i} className="border-b border-gray-800 hover:bg-gray-900">
|
| | <td className="p-2">{d.time}</td>
|
| | <td className="p-2 text-blue-400">{d.symbol}</td>
|
| | <td className="p-2">{d.type}</td>
|
| | <td className={`p-2 ${d.profit >= 0 ? 'text-green-500' : 'text-red-500'}`}>
|
| | {d.profit}
|
| | </td>
|
| | </tr>
|
| | ))}
|
| | </tbody>
|
| | </table>
|
| | </div>
|
| |
|
| | </div>
|
| | </div>
|
| | </Draggable>
|
| | );
|
| | };
|
| |
|
| | export default Dashboard; |