"use client"; import Image from "next/image"; import { useApp } from "@/contexts/AppContext"; import { ProductDetail } from "@/lib/api/fundmarket"; interface OverviewItemProps { icon: string; label: string; value: string; } function OverviewItem({ icon, label, value }: OverviewItemProps) { return (
{label}
{label}
{value}
); } interface AssetOverviewCardProps { product: ProductDetail; vaultInfo?: any[]; isVaultLoading?: boolean; vaultTimedOut?: boolean; } export default function AssetOverviewCard({ product, vaultInfo, isVaultLoading, vaultTimedOut, }: AssetOverviewCardProps) { const { t } = useApp(); const hasContract = !!product.contractAddress; const vaultReady = !hasContract || vaultInfo !== undefined || vaultTimedOut; const loading = hasContract && isVaultLoading && !vaultTimedOut; // nextRedemptionTime: getVaultInfo[8] const nextRedemptionTime = vaultInfo ? Number(vaultInfo[8]) : 0; const maturityDisplay = (() => { if (loading) return '...'; if (!nextRedemptionTime) return '--'; return new Date(nextRedemptionTime * 1000).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric', }); })(); // ytPrice: getVaultInfo[7], 30 decimals const ytPriceRaw: bigint = vaultInfo ? (vaultInfo[7] as bigint) ?? 0n : 0n; const currentPriceDisplay = (() => { if (loading) return '...'; if (!ytPriceRaw || ytPriceRaw <= 0n) return '--'; const divisor = 10n ** 30n; const intPart = ytPriceRaw / divisor; const fracScaled = ((ytPriceRaw % divisor) * 1_000_000n) / divisor; return `$${intPart}.${fracScaled.toString().padStart(6, '0')}`; })(); // Pool Capacity %: totalSupply[4] / hardCap[5] const totalSupplyRaw: bigint = vaultInfo ? (vaultInfo[4] as bigint) ?? 0n : 0n; const hardCapRaw: bigint = vaultInfo ? (vaultInfo[5] as bigint) ?? 0n : 0n; const livePoolCapPercent = (vaultReady && hardCapRaw > 0n) ? Math.min((Number(totalSupplyRaw) / Number(hardCapRaw)) * 100, 100) : null; const displayPoolCapPercent = livePoolCapPercent !== null ? livePoolCapPercent : vaultReady ? product.poolCapacityPercent : null; const poolCapDisplay = !vaultReady ? '...' : `${(displayPoolCapPercent ?? 0).toFixed(4)}%`; // Format USD values const formatUSD = (value: number) => { if (value >= 1000000) return `$${(value / 1000000).toFixed(1)}M`; if (value >= 1000) return `$${(value / 1000).toFixed(1)}K`; return `$${value.toFixed(2)}`; }; // Risk badge const getRiskColor = (riskLevel: number) => { switch (riskLevel) { case 1: return { bg: "#e1f8ec", border: "#b8ecd2", color: "#10b981" }; case 2: return { bg: "#fffbf5", border: "#ffedd5", color: "#ffb933" }; case 3: return { bg: "#fee2e2", border: "#fecaca", color: "#ef4444" }; default: return { bg: "#fffbf5", border: "#ffedd5", color: "#ffb933" }; } }; const riskColors = getRiskColor(product.riskLevel); const getRiskBars = () => { const bars = [ { height: 5, active: product.riskLevel >= 1 }, { height: 7, active: product.riskLevel >= 2 }, { height: 11, active: product.riskLevel >= 3 }, ]; return bars.map((bar, i) => (
)); }; return (
{/* Header */}

{t("assetOverview.title")}

{product.riskLabel}
{getRiskBars()}
{/* Overview Items - 2 per row */}
{/* Progress Bar - full width */}
{/* Divider */}
{/* Current Price */}
Price
{t("assetOverview.currentPrice")}
1 {product.tokenSymbol} = {currentPriceDisplay}
); }