arbitrage-engine/frontend/app/history/page.tsx

92 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useEffect, useState } from "react";
import { HistoryPoint } from "@/lib/api";
import {
LineChart, Line, XAxis, YAxis, Tooltip, Legend,
ResponsiveContainer, ReferenceLine
} from "recharts";
export default function HistoryPage() {
const [btc, setBtc] = useState<HistoryPoint[]>([]);
const [eth, setEth] = useState<HistoryPoint[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch("/api/history")
.then((r) => r.json())
.then((d) => { setBtc(d.BTC ?? []); setEth(d.ETH ?? []); setLoading(false); })
.catch(() => setLoading(false));
}, []);
const btcMap = new Map(btc.map((p) => [p.timestamp.slice(0, 13), p.fundingRate * 100]));
const ethMap = new Map(eth.map((p) => [p.timestamp.slice(0, 13), p.fundingRate * 100]));
const allTimes = Array.from(new Set([...btcMap.keys(), ...ethMap.keys()])).sort();
const chartData = allTimes.slice(-42).map((t) => ({
time: t.slice(5).replace("T", " "),
BTC: btcMap.get(t) ?? null,
ETH: ethMap.get(t) ?? null,
}));
const tableData = allTimes.slice().reverse().slice(0, 50).map((t) => ({
time: t.replace("T", " "),
btc: btcMap.get(t),
eth: ethMap.get(t),
}));
return (
<div className="space-y-6">
<div>
<h1 className="text-2xl font-bold text-slate-900"></h1>
<p className="text-slate-500 text-sm mt-1">7 BTC / ETH </p>
</div>
{loading ? (
<div className="text-slate-500">...</div>
) : (
<>
<div className="rounded-xl border border-slate-200 bg-white p-6">
<h2 className="text-slate-800 font-semibold mb-4">7</h2>
<ResponsiveContainer width="100%" height={260}>
<LineChart data={chartData} margin={{ top: 4, right: 8, bottom: 4, left: 8 }}>
<XAxis dataKey="time" tick={{ fill: "#64748b", fontSize: 10 }} tickLine={false} interval="preserveStartEnd" />
<YAxis tick={{ fill: "#64748b", fontSize: 10 }} tickLine={false} axisLine={false} tickFormatter={(v) => `${v.toFixed(3)}%`} width={60} />
<Tooltip formatter={(v) => [`${Number(v).toFixed(4)}%`]} contentStyle={{ background: "#1e293b", border: "1px solid #475569", borderRadius: 8 }} />
<Legend wrapperStyle={{ fontSize: 12, color: "#94a3b8" }} />
<ReferenceLine y={0} stroke="#475569" strokeDasharray="4 2" />
<Line type="monotone" dataKey="BTC" stroke="#06b6d4" strokeWidth={1.5} dot={false} connectNulls />
<Line type="monotone" dataKey="ETH" stroke="#8b5cf6" strokeWidth={1.5} dot={false} connectNulls />
</LineChart>
</ResponsiveContainer>
</div>
<div className="rounded-xl border border-slate-200 bg-white overflow-hidden">
<table className="w-full text-sm">
<thead>
<tr className="border-b border-slate-200 bg-slate-800">
<th className="text-left px-4 py-3 text-slate-500 font-medium"></th>
<th className="text-right px-4 py-3 text-blue-600 font-medium">BTC </th>
<th className="text-right px-4 py-3 text-violet-400 font-medium">ETH </th>
</tr>
</thead>
<tbody>
{tableData.map((row, i) => (
<tr key={i} className="border-b border-slate-200/50 hover:bg-slate-50">
<td className="px-4 py-2 text-slate-500 font-mono text-xs">{row.time}</td>
<td className={`px-4 py-2 text-right font-mono text-xs ${row.btc == null ? "text-slate-500" : row.btc >= 0 ? "text-emerald-400" : "text-red-400"}`}>
{row.btc != null ? `${row.btc.toFixed(4)}%` : "--"}
</td>
<td className={`px-4 py-2 text-right font-mono text-xs ${row.eth == null ? "text-slate-500" : row.eth >= 0 ? "text-emerald-400" : "text-red-400"}`}>
{row.eth != null ? `${row.eth.toFixed(4)}%` : "--"}
</td>
</tr>
))}
</tbody>
</table>
</div>
</>
)}
</div>
);
}