arbitrage-engine/frontend/app/history/page.tsx
2026-02-26 12:48:09 +00:00

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-100"></h1>
<p className="text-slate-400 text-sm mt-1">7 BTC / ETH </p>
</div>
{loading ? (
<div className="text-slate-400">...</div>
) : (
<>
<div className="rounded-xl border border-slate-700 bg-slate-800/50 p-6">
<h2 className="text-slate-200 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-700 bg-slate-800/50 overflow-hidden">
<table className="w-full text-sm">
<thead>
<tr className="border-b border-slate-700 bg-slate-800">
<th className="text-left px-4 py-3 text-slate-400 font-medium"></th>
<th className="text-right px-4 py-3 text-cyan-400 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-700/50 hover:bg-slate-700/30">
<td className="px-4 py-2 text-slate-400 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>
);
}