import { type ReactNode } from 'react'; import { TrendingUp, TrendingDown } from 'lucide-react'; import i18n from '@/i18n'; // 云厂商中文标签(主组件 + 弹窗共享) // Logan.Li export const providerLabels: Record = { aliyun: i18n.t('cloud.aliyun'), tencent: i18n.t('cloud.tencent'), aws: 'AWS', huawei: i18n.t('cloud.huawei'), azure: 'Azure', }; // 云厂商品牌色(跨主题固定,用 hex 避免 Tailwind 硬编码) // Logan.Li export const providerHex: Record = { aliyun: '#FF6A00', tencent: '#006EFF', aws: '#FF9900', huawei: '#CF0A2C', azure: '#0078D4', }; /** @deprecated 请改用 providerHex + style */ export const providerColors: Record = { aliyun: 'bg-orange-500', tencent: 'bg-blue-500', aws: 'bg-amber-500', huawei: 'bg-red-500', azure: 'bg-sky-500', }; export function ProviderDot({ provider, className = 'w-2 h-2' }: { provider: string; className?: string }) { return ( ); } export function formatCurrency(n: number) { return `¥${n.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; } export function StatCard({ icon, label, value, trend, trendLabel, alert }: { icon: ReactNode; label: string; value: string; trend?: number; trendLabel?: string; alert?: boolean; }) { return (
{label} {icon}
{value}
{trendLabel && (
{trend !== undefined && trend > 0 && } {trend !== undefined && trend < 0 && } {trendLabel}
)}
); } export function TrendChart({ data }: { data: { date: string; cost: number }[] }) { if (data.length === 0) { return

{i18n.t('aiops.assistantNoData')}

; } const max = Math.max(...data.map((d) => d.cost), 1); const recent = data.slice(-30); return (
{recent.map((d, i) => { const h = Math.max((d.cost / max) * 100, 2); return (
{d.date}: {formatCurrency(d.cost)}
); })}
{recent[0]?.date} {recent[recent.length - 1]?.date}
); }