"use client"; import { useState, useEffect, useRef } from "react"; import Image from "next/image"; import { Button } from "@heroui/react"; import { useApp } from "@/contexts/AppContext"; import { useQuery } from "@tanstack/react-query"; import { useChainId } from "wagmi"; import * as echarts from "echarts"; import { fetchLendingAPYHistory } from "@/lib/api/lending"; type Period = "1W" | "1M" | "1Y"; export default function SupplyContent() { const { t } = useApp(); const chainId = useChainId(); const [selectedPeriod, setSelectedPeriod] = useState("1W"); const chartRef = useRef(null); const chartInstance = useRef(null); const { data: apyData, isLoading } = useQuery({ queryKey: ["lending-apy-history", selectedPeriod, chainId], queryFn: () => fetchLendingAPYHistory(selectedPeriod, chainId), staleTime: 5 * 60 * 1000, }); const chartData = apyData?.history.map((p) => p.supply_apy) ?? []; const xLabels = apyData?.history.map((p) => { const d = new Date(p.time); if (selectedPeriod === "1W") return `${d.getMonth() + 1}/${d.getDate()} ${String(d.getHours()).padStart(2, "0")}:00`; if (selectedPeriod === "1M") return `${d.getMonth() + 1}/${d.getDate()}`; return `${d.getFullYear()}/${d.getMonth() + 1}/${d.getDate()}`; }) ?? []; const currentAPY = apyData?.current_supply_apy ?? 0; const apyChange = apyData?.apy_change ?? 0; // 初始化 & 销毁(只在 mount/unmount 执行) useEffect(() => { if (!chartRef.current) return; chartInstance.current = echarts.init(chartRef.current); const observer = new ResizeObserver(() => chartInstance.current?.resize()); observer.observe(chartRef.current); return () => { observer.disconnect(); chartInstance.current?.dispose(); chartInstance.current = null; }; }, []); // 更新图表数据(period/data 变化时) useEffect(() => { if (!chartInstance.current) return; chartInstance.current.setOption({ grid: { left: 0, right: 0, top: 10, bottom: 0 }, tooltip: { trigger: "axis", show: true, confine: true, backgroundColor: "rgba(17, 24, 39, 0.9)", borderColor: "#374151", textStyle: { color: "#f9fafb", fontSize: 12, fontWeight: 500 }, formatter: (params: any) => { const d = params[0]; return `
${d.axisValueLabel}
${Number(d.value).toFixed(4)}%
`; }, }, xAxis: { type: "category", data: xLabels, axisLine: { show: false }, axisTick: { show: false }, axisLabel: { show: xLabels.length > 0 && xLabels.length <= 24, color: "#9ca3af", fontSize: 10, fontWeight: 500, interval: Math.max(0, Math.floor(xLabels.length / 7) - 1), }, }, yAxis: { type: "value", axisLine: { show: false }, axisTick: { show: false }, axisLabel: { show: false }, splitLine: { show: false }, }, series: [ { data: chartData, type: "line", smooth: true, symbol: chartData.length <= 30 ? "circle" : "none", symbolSize: 4, lineStyle: { color: "#10b981", width: 2 }, itemStyle: { color: "#10b981" }, areaStyle: { color: { type: "linear", x: 0, y: 0, x2: 0, y2: 1, colorStops: [ { offset: 0, color: "rgba(16, 185, 129, 0.3)" }, { offset: 1, color: "rgba(16, 185, 129, 0)" }, ], }, }, }, ], }, true); }, [chartData, xLabels]); return (
{/* Header */}
USDC

{t("supply.usdcLendPool")}

{/* Historical APY Section */}
{/* Left - APY Display */}
{t("supply.historicalApy")}
{isLoading ? "--" : currentAPY > 0 ? `${currentAPY.toFixed(4)}%` : "--"} {!isLoading && apyData && apyData.history.length > 1 && (
= 0 ? "bg-[#e1f8ec] dark:bg-green-900/30" : "bg-red-50 dark:bg-red-900/30"}`}> = 0 ? "text-[#10b981] dark:text-green-400" : "text-red-500 dark:text-red-400"}`}> {apyChange >= 0 ? "+" : ""}{apyChange.toFixed(4)}%
)}
{/* Right - Period Selector */}
{(["1W", "1M", "1Y"] as Period[]).map((p) => ( ))}
{/* Chart Section — 始终渲染 div,避免 echarts 实例因 DOM 销毁而失效 */}
{/* Loading 遮罩 */} {isLoading && (
{t("common.loading")}
)}
); }