import { useEffect, useState } from "react"; import type { BillingSummary, Product, Project } from "../types"; import type { Page } from "./route-config"; import { api } from "../api"; import { SkeletonRows } from "../components/loading"; import { money, stageMeta, statusPill } from "./stage-config"; import { Progress } from "../components/pipeline-stage"; import { IconKitSvg } from "../components/IconKitSvg"; export function Dashboard({ products, projects, productTotal, projectTotal, billing, userName, loading = false, navigate }: { products: Product[]; projects: Project[]; productTotal?: number; // 后端真实总数(分页 count),用于「N 个/SKU」展示 projectTotal?: number; billing: BillingSummary | null; userName?: string; loading?: boolean; navigate: (page: Page) => void; }) { const projCount = projectTotal ?? projects.length; const prodCount = productTotal ?? products.length; // 资产总数:走轻量 summary 接口(各 tab 计数之和),不再吃全局 assets 全量数组 const [assetCount, setAssetCount] = useState(null); useEffect(() => { let alive = true; api.assetSummary() .then((c) => { if (alive) setAssetCount(Object.values(c).reduce((a, b) => a + b, 0)); }) .catch(() => {}); return () => { alive = false; }; }, []); const completed = projects.filter((project) => project.status === "completed").length; const running = projects.filter((project) => !["completed", "failed"].includes(project.status)).length; const productTitle = (id: string) => products.find((product) => product.id === id)?.title || "商品"; return ( <>

欢迎回来{userName ? `,${userName.split("@")[0]}` : ""}

// {new Date().toLocaleDateString("zh-CN")}·你有 {running} 个项目 正在进行中
++

最近项目

{loading && projects.length === 0 ? : projects.slice(0, 6).map((project) => )}

快捷入口

[ /shortcuts ]
navigate("products")} /> navigate("library")} /> navigate("account")} /> navigate("projects")} />

提示

[ FAQ ]
扣费规则生成失败、超时、用户重跑 — 均不扣费。仅在你点 [ 确认通过 ] 时按 token 实际结算。
); } export function KpiStat({ label, badge, value, delta }: { label: string; badge: string; value: string | number; delta: string }) { return
{label} {badge}
{value}
{delta}
; } export function Shortcut({ name, title, desc, onClick }: { name: string; title: string; desc: string; onClick: () => void }) { return
{title}
{desc}
; }