arbitrage-engine/frontend/components/RateCard.tsx

67 lines
2.6 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 { RateData } from "@/lib/api";
interface Props {
asset: "BTC" | "ETH";
data: RateData | null;
}
const ASSET_EMOJI: Record<string, string> = { BTC: "₿", ETH: "Ξ" };
export default function RateCard({ asset, data }: Props) {
const rate = data?.lastFundingRate ?? null;
const positive = rate !== null && rate >= 0;
const rateColor = rate === null ? "text-slate-400" : positive ? "text-emerald-600" : "text-red-500";
const badgeColor = rate === null
? "bg-slate-100 text-slate-500"
: positive
? "bg-emerald-50 text-emerald-700 border border-emerald-200"
: "bg-red-50 text-red-600 border border-red-200";
const nextTime = (() => {
if (!data?.nextFundingTime) return "--";
// 转北京时间UTC+8
const ts = data.nextFundingTime;
const bjt = new Date(ts + 8 * 3600 * 1000);
const now = new Date(Date.now() + 8 * 3600 * 1000);
const isToday = bjt.getUTCDate() === now.getUTCDate() && bjt.getUTCMonth() === now.getUTCMonth();
const hhmm = `${String(bjt.getUTCHours()).padStart(2,"0")}:${String(bjt.getUTCMinutes()).padStart(2,"0")}`;
return isToday ? hhmm : `明天 ${hhmm}`;
})();
return (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm p-6 space-y-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<span className="text-2xl font-bold text-slate-700">{ASSET_EMOJI[asset]}</span>
<span className="text-lg font-semibold text-slate-800">{asset}/USDT</span>
</div>
<span className={`text-xs px-2 py-1 rounded-full font-medium ${badgeColor}`}>
{rate === null ? "加载中" : positive ? "正费率 收款" : "负费率 付款"}
</span>
</div>
<div>
<p className="text-slate-400 text-xs mb-1"></p>
<p className={`text-3xl font-mono font-bold ${rateColor}`}>
{rate === null ? "--" : `${(rate * 100).toFixed(4)}%`}
</p>
</div>
<div className="grid grid-cols-2 gap-3 pt-2 border-t border-slate-100">
<div>
<p className="text-slate-400 text-xs"></p>
<p className="text-slate-700 font-mono text-sm mt-0.5">
${data ? Number(data.markPrice).toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : "--"}
</p>
</div>
<div>
<p className="text-slate-400 text-xs"></p>
<p className="text-blue-600 font-mono text-sm mt-0.5">{nextTime}</p>
</div>
</div>
</div>
);
}