init: 初始化 AssetX 项目仓库
包含 webapp(Next.js 用户端)、webapp-back(Go 后端)、 antdesign(管理后台)、landingpage(营销落地页)、 数据库 SQL 和配置文件。
This commit is contained in:
102
webapp/components/lending/repay/RepayHeader.tsx
Normal file
102
webapp/components/lending/repay/RepayHeader.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import Image from "next/image";
|
||||
import { useApp } from "@/contexts/AppContext";
|
||||
import { useYTPrice } from "@/hooks/useCollateral";
|
||||
import { fetchLendingStats } from "@/lib/api/lending";
|
||||
import { useTokenBySymbol } from "@/hooks/useTokenBySymbol";
|
||||
|
||||
const GRADIENT_COLORS: Record<string, string> = {
|
||||
'YT-A': 'linear-gradient(135deg, #FF8904 0%, #F54900 100%)',
|
||||
'YT-B': 'linear-gradient(135deg, #00BBA7 0%, #007A55 100%)',
|
||||
'YT-C': 'linear-gradient(135deg, #667EEA 0%, #764BA2 100%)',
|
||||
};
|
||||
const DEFAULT_GRADIENT = 'linear-gradient(135deg, #6B7280 0%, #374151 100%)';
|
||||
|
||||
interface RepayHeaderProps {
|
||||
tokenType: string;
|
||||
}
|
||||
|
||||
export default function RepayHeader({ tokenType }: RepayHeaderProps) {
|
||||
const { t } = useApp();
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const [availableUsd, setAvailableUsd] = useState<string | null>(null);
|
||||
|
||||
const ytToken = useTokenBySymbol(tokenType);
|
||||
const { formattedPrice, isLoading: isPriceLoading } = useYTPrice(ytToken);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
fetchLendingStats().then((stats) => {
|
||||
if (stats) {
|
||||
const available = stats.totalSuppliedUsd - stats.totalBorrowedUsd;
|
||||
setAvailableUsd(available > 0 ? available.toLocaleString('en-US', { maximumFractionDigits: 0 }) : '0');
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
const displayPrice = !mounted || isPriceLoading ? '--' : `$${parseFloat(formattedPrice).toFixed(4)}`;
|
||||
const displayAvailable = availableUsd !== null ? `$${availableUsd}` : '--';
|
||||
|
||||
return (
|
||||
<div className="bg-bg-surface dark:bg-gray-800 rounded-3xl border border-border-gray dark:border-gray-700 px-4 md:px-6 py-4 md:py-8 flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
||||
{/* Left Section - Token Icons and Title */}
|
||||
<div className="flex items-center gap-2">
|
||||
{/* Overlapping Token Icons */}
|
||||
<div className="flex items-center relative">
|
||||
<div
|
||||
className="w-[52px] h-[52px] rounded-full flex items-center justify-center text-white text-xs font-bold shadow-md relative z-10 overflow-hidden"
|
||||
style={{ background: GRADIENT_COLORS[tokenType] ?? DEFAULT_GRADIENT }}
|
||||
>
|
||||
{ytToken?.iconUrl ? (
|
||||
<Image src={ytToken.iconUrl} alt={tokenType} width={52} height={52} className="w-full h-full object-cover" />
|
||||
) : (
|
||||
tokenType.replace('YT-', '')
|
||||
)}
|
||||
</div>
|
||||
<Image
|
||||
src="/assets/tokens/usd-coin-usdc-logo-10.svg"
|
||||
alt="USDC"
|
||||
width={52}
|
||||
height={52}
|
||||
className="relative -ml-3"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Title and Subtitle */}
|
||||
<div className="flex flex-col gap-1 ml-2">
|
||||
<h1 className="text-heading-h2 font-bold text-text-primary dark:text-white leading-[130%] tracking-[-0.01em]">
|
||||
{tokenType} / USDC
|
||||
</h1>
|
||||
<p className="text-body-small font-regular text-text-tertiary dark:text-gray-400 leading-[150%]">
|
||||
{t("repay.supplyToBorrow")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right Section - Stats */}
|
||||
<div className="flex items-center justify-between md:w-[262px]">
|
||||
{/* Price */}
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="text-caption-tiny font-bold text-text-tertiary dark:text-gray-400 leading-[150%] tracking-[0.01em]">
|
||||
{t("repay.price")}
|
||||
</span>
|
||||
<span className="text-heading-h3 font-bold text-[#10b981] dark:text-green-400 leading-[130%] tracking-[-0.005em]">
|
||||
{displayPrice}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Available */}
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="text-caption-tiny font-bold text-text-tertiary dark:text-gray-400 leading-[150%] tracking-[0.01em]">
|
||||
{t("repay.available")}
|
||||
</span>
|
||||
<span className="text-heading-h3 font-bold text-text-primary dark:text-white leading-[130%] tracking-[-0.005em]">
|
||||
{displayAvailable}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user