"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 (
);
}
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 */}
{t("assetOverview.currentPrice")}
1 {product.tokenSymbol} =
{currentPriceDisplay}
);
}