fix: improve analytics dark mode
This commit is contained in:
parent
0d67e2935c
commit
6c83826e1d
@ -1969,7 +1969,7 @@ export function AdminSettingsClient() {
|
||||
value: formatAnalyticsNumber(analyticsData?.overview.totalUsers),
|
||||
note: "参与生成的用户数",
|
||||
icon: Users,
|
||||
tone: "from-emerald-500/15 via-emerald-500/5 to-transparent text-emerald-700",
|
||||
tone: "from-emerald-500/15 via-emerald-500/5 to-transparent text-emerald-700 dark:text-emerald-200",
|
||||
},
|
||||
{
|
||||
key: "today-images",
|
||||
@ -1977,7 +1977,7 @@ export function AdminSettingsClient() {
|
||||
value: formatAnalyticsNumber(analyticsData?.overview.todayImages),
|
||||
note: `${formatAnalyticsNumber(analyticsData?.overview.todayUsers)} 位用户`,
|
||||
icon: TrendingUp,
|
||||
tone: "from-amber-500/20 via-amber-500/5 to-transparent text-amber-700",
|
||||
tone: "from-amber-500/20 via-amber-500/5 to-transparent text-amber-700 dark:text-amber-200",
|
||||
},
|
||||
{
|
||||
key: "month-images",
|
||||
@ -1985,7 +1985,7 @@ export function AdminSettingsClient() {
|
||||
value: formatAnalyticsNumber(analyticsData?.overview.monthImages),
|
||||
note: `${formatAnalyticsNumber(analyticsData?.overview.monthUsers)} 位用户`,
|
||||
icon: Calendar,
|
||||
tone: "from-lime-400/25 via-lime-300/10 to-transparent text-lime-700",
|
||||
tone: "from-lime-400/25 via-lime-300/10 to-transparent text-lime-700 dark:text-lime-200",
|
||||
},
|
||||
];
|
||||
}, [analyticsData?.overview, selectedMonth]);
|
||||
@ -9389,26 +9389,26 @@ export function AdminSettingsClient() {
|
||||
|
||||
{/* 🆕 数据分析 */}
|
||||
<TabsContent className="mt-6 space-y-4" value="analytics">
|
||||
<Card className="overflow-hidden border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.28)]">
|
||||
<CardHeader className="border-b border-zinc-200/70 bg-gradient-to-r from-zinc-50 via-white to-lime-50/40">
|
||||
<Card className="overflow-hidden border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.28)] dark:border-zinc-800/80 dark:bg-zinc-950/70 dark:shadow-none">
|
||||
<CardHeader className="border-b border-zinc-200/70 bg-gradient-to-r from-zinc-50 via-white to-lime-50/40 dark:border-zinc-800/80 dark:from-zinc-950 dark:via-zinc-950 dark:to-lime-950/20">
|
||||
<div className="space-y-3">
|
||||
<div className="text-[11px] uppercase tracking-[0.24em] text-muted-foreground">
|
||||
analytics overview
|
||||
</div>
|
||||
<div className="flex flex-col gap-3 lg:flex-row lg:items-end lg:justify-between">
|
||||
<div className="space-y-1">
|
||||
<CardTitle className="text-xl text-zinc-950">
|
||||
<CardTitle className="text-xl text-zinc-950 dark:text-zinc-50">
|
||||
生成与运营总览
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
统一展示生成规模、活跃用户、趋势波动、模型分布和分辨率结构。
|
||||
</CardDescription>
|
||||
</div>
|
||||
<div className="inline-flex items-center gap-2 rounded-full border border-zinc-200 bg-white/85 px-3 py-1.5 text-xs text-zinc-600 shadow-sm">
|
||||
<div className="inline-flex items-center gap-2 rounded-full border border-zinc-200 bg-white/85 px-3 py-1.5 text-xs text-zinc-600 shadow-sm dark:border-zinc-800 dark:bg-zinc-900/80 dark:text-zinc-300">
|
||||
<Database className="h-3.5 w-3.5" />
|
||||
<span>{formatAnalyticsMonthLabel(selectedMonth)}</span>
|
||||
{selectedDate ? (
|
||||
<span className="rounded-full bg-orange-100 px-2 py-0.5 text-orange-700">
|
||||
<span className="rounded-full bg-orange-100 px-2 py-0.5 text-orange-700 dark:bg-orange-500/15 dark:text-orange-200">
|
||||
{selectedDate}
|
||||
</span>
|
||||
) : null}
|
||||
@ -9423,7 +9423,7 @@ export function AdminSettingsClient() {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"rounded-2xl border border-zinc-200/70 bg-gradient-to-br p-4 shadow-[0_10px_25px_-18px_rgba(15,23,42,0.25)]",
|
||||
"rounded-2xl border border-zinc-200/70 bg-gradient-to-br p-4 shadow-[0_10px_25px_-18px_rgba(15,23,42,0.25)] dark:border-zinc-800 dark:bg-zinc-900/70 dark:shadow-none",
|
||||
item.tone
|
||||
)}
|
||||
key={item.key}
|
||||
@ -9437,7 +9437,7 @@ export function AdminSettingsClient() {
|
||||
{item.value}
|
||||
</div>
|
||||
</div>
|
||||
<div className="rounded-2xl border border-current/10 bg-white/70 p-2 text-current shadow-sm">
|
||||
<div className="rounded-2xl border border-current/10 bg-white/70 p-2 text-current shadow-sm dark:bg-white/10">
|
||||
<Icon className="h-4 w-4" />
|
||||
</div>
|
||||
</div>
|
||||
@ -9451,7 +9451,7 @@ export function AdminSettingsClient() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)]">
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)] dark:border-zinc-800/80 dark:bg-zinc-950/70 dark:shadow-none">
|
||||
<CardHeader className="pb-4">
|
||||
<div className="text-[11px] uppercase tracking-[0.24em] text-muted-foreground">
|
||||
filters & pulse
|
||||
@ -9463,12 +9463,12 @@ export function AdminSettingsClient() {
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
|
||||
<div className="rounded-2xl border border-zinc-200/70 bg-zinc-50/80 p-4">
|
||||
<div className="rounded-2xl border border-zinc-200/70 bg-zinc-50/80 p-4 dark:border-zinc-800 dark:bg-zinc-900/60">
|
||||
<Label className="text-[11px] uppercase tracking-[0.18em] text-muted-foreground">
|
||||
统计月份
|
||||
</Label>
|
||||
<Input
|
||||
className="mt-3 h-10 border-zinc-200 bg-white"
|
||||
className="mt-3 h-10 border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-950"
|
||||
onChange={(e) => setSelectedMonth(e.target.value)}
|
||||
type="month"
|
||||
value={selectedMonth}
|
||||
@ -9485,8 +9485,8 @@ export function AdminSettingsClient() {
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div className="rounded-2xl border border-zinc-200/70 bg-white p-4">
|
||||
<div className="flex items-center gap-2 text-zinc-900 text-sm">
|
||||
<div className="rounded-2xl border border-zinc-200/70 bg-white p-4 dark:border-zinc-800 dark:bg-zinc-900/60">
|
||||
<div className="flex items-center gap-2 text-zinc-900 text-sm dark:text-zinc-100">
|
||||
<Clock className="h-4 w-4" />
|
||||
高峰时段
|
||||
</div>
|
||||
@ -9502,7 +9502,7 @@ export function AdminSettingsClient() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-2xl border border-zinc-200/70 bg-zinc-950 p-4 text-white">
|
||||
<div className="rounded-2xl border border-zinc-900 bg-zinc-950 p-4 text-white dark:border-zinc-800 dark:bg-zinc-900">
|
||||
<div className="flex items-center gap-2 text-sm text-zinc-200">
|
||||
<Bot className="h-4 w-4" />
|
||||
领先模型
|
||||
@ -9525,20 +9525,20 @@ export function AdminSettingsClient() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-2xl border border-zinc-200/70 bg-white p-4">
|
||||
<div className="rounded-2xl border border-zinc-200/70 bg-white p-4 dark:border-zinc-800 dark:bg-zinc-900/60">
|
||||
<div className="text-[11px] uppercase tracking-[0.2em] text-muted-foreground">
|
||||
recent months
|
||||
</div>
|
||||
<div className="mt-3 grid grid-cols-3 gap-2 text-center">
|
||||
{analyticsRecentMonths.slice(-3).map((stat) => (
|
||||
<div
|
||||
className="rounded-xl border border-zinc-200/70 bg-zinc-50/80 px-2 py-2"
|
||||
className="rounded-xl border border-zinc-200/70 bg-zinc-50/80 px-2 py-2 dark:border-zinc-800 dark:bg-zinc-950/70"
|
||||
key={stat.month}
|
||||
>
|
||||
<div className="text-[11px] text-muted-foreground">
|
||||
{stat.month.slice(5)}
|
||||
</div>
|
||||
<div className="mt-1 font-semibold text-sm text-zinc-950">
|
||||
<div className="mt-1 font-semibold text-sm text-zinc-950 dark:text-zinc-50">
|
||||
{formatAnalyticsNumber(stat.count)}
|
||||
</div>
|
||||
</div>
|
||||
@ -9549,7 +9549,7 @@ export function AdminSettingsClient() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)]">
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)] dark:border-zinc-800/80 dark:bg-zinc-950/70 dark:shadow-none">
|
||||
<CardHeader className="pb-4">
|
||||
<div className="text-[11px] uppercase tracking-[0.24em] text-muted-foreground">
|
||||
throughput
|
||||
@ -9564,7 +9564,7 @@ export function AdminSettingsClient() {
|
||||
<span>近 30 天生成量</span>
|
||||
<span>点击柱体联动小时分布</span>
|
||||
</div>
|
||||
<div className="relative flex h-[240px] items-end gap-1 rounded-2xl border border-zinc-200/70 bg-zinc-50/80 px-3 py-4">
|
||||
<div className="relative flex h-[240px] items-end gap-1 rounded-2xl border border-zinc-200/70 bg-zinc-50/80 px-3 py-4 dark:border-zinc-800 dark:bg-zinc-900/60">
|
||||
{analyticsData?.dailyStats?.map((stat, index) => {
|
||||
const maxCount = Math.max(
|
||||
...(analyticsData.dailyStats?.map((s) => s.count) || [1])
|
||||
@ -9579,10 +9579,10 @@ export function AdminSettingsClient() {
|
||||
className={cn(
|
||||
"relative flex-1 cursor-pointer rounded-full transition-all",
|
||||
isSelected
|
||||
? "bg-zinc-950"
|
||||
? "bg-zinc-950 dark:bg-zinc-100"
|
||||
: isHovered
|
||||
? "bg-lime-400"
|
||||
: "bg-zinc-300 hover:bg-zinc-400"
|
||||
: "bg-zinc-300 hover:bg-zinc-400 dark:bg-zinc-700 dark:hover:bg-zinc-600"
|
||||
)}
|
||||
key={stat.date}
|
||||
onClick={() =>
|
||||
@ -9602,7 +9602,7 @@ export function AdminSettingsClient() {
|
||||
style={{ height: `${Math.max(height, 5)}%` }}
|
||||
>
|
||||
{isHovered ? (
|
||||
<div className="-translate-x-1/2 absolute bottom-full left-1/2 z-10 mb-2 whitespace-nowrap rounded-xl bg-zinc-950 px-3 py-2 text-white text-xs shadow-lg">
|
||||
<div className="-translate-x-1/2 absolute bottom-full left-1/2 z-10 mb-2 whitespace-nowrap rounded-xl bg-zinc-950 px-3 py-2 text-white text-xs shadow-lg dark:bg-zinc-100 dark:text-zinc-950">
|
||||
{stat.date} · {formatAnalyticsNumber(stat.count)} 次
|
||||
</div>
|
||||
) : null}
|
||||
@ -9617,7 +9617,7 @@ export function AdminSettingsClient() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)]">
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)] dark:border-zinc-800/80 dark:bg-zinc-950/70 dark:shadow-none">
|
||||
<CardHeader className="pb-4">
|
||||
<div className="text-[11px] uppercase tracking-[0.24em] text-muted-foreground">
|
||||
hourly load
|
||||
@ -9634,7 +9634,7 @@ export function AdminSettingsClient() {
|
||||
<span>小时分布</span>
|
||||
<span>{selectedDate || "默认最近样本"}</span>
|
||||
</div>
|
||||
<div className="flex h-[240px] items-end gap-1 rounded-2xl border border-zinc-200/70 bg-white px-3 py-4">
|
||||
<div className="flex h-[240px] items-end gap-1 rounded-2xl border border-zinc-200/70 bg-white px-3 py-4 dark:border-zinc-800 dark:bg-zinc-900/60">
|
||||
{Array.from({ length: 24 }, (_, hour) => {
|
||||
const stat = analyticsData?.hourlyStats?.find(
|
||||
(item) => item.hour === hour
|
||||
@ -9655,10 +9655,10 @@ export function AdminSettingsClient() {
|
||||
selectedDate
|
||||
? isHovered
|
||||
? "bg-orange-500"
|
||||
: "bg-orange-300"
|
||||
: "bg-orange-300 dark:bg-orange-500/60"
|
||||
: isHovered
|
||||
? "bg-lime-500"
|
||||
: "bg-zinc-300"
|
||||
: "bg-zinc-300 dark:bg-zinc-700"
|
||||
)}
|
||||
key={hour}
|
||||
onMouseEnter={() =>
|
||||
@ -9673,7 +9673,7 @@ export function AdminSettingsClient() {
|
||||
style={{ height: `${Math.max(height, 4)}%` }}
|
||||
>
|
||||
{isHovered ? (
|
||||
<div className="-translate-x-1/2 absolute bottom-full left-1/2 z-10 mb-2 whitespace-nowrap rounded-xl bg-zinc-950 px-3 py-2 text-white text-xs shadow-lg">
|
||||
<div className="-translate-x-1/2 absolute bottom-full left-1/2 z-10 mb-2 whitespace-nowrap rounded-xl bg-zinc-950 px-3 py-2 text-white text-xs shadow-lg dark:bg-zinc-100 dark:text-zinc-950">
|
||||
{String(hour).padStart(2, "0")}:00 ·{" "}
|
||||
{formatAnalyticsNumber(count)} 次
|
||||
</div>
|
||||
@ -9690,7 +9690,7 @@ export function AdminSettingsClient() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)]">
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)] dark:border-zinc-800/80 dark:bg-zinc-950/70 dark:shadow-none">
|
||||
<CardHeader className="pb-4">
|
||||
<div className="text-[11px] uppercase tracking-[0.24em] text-muted-foreground">
|
||||
top users
|
||||
@ -9702,7 +9702,7 @@ export function AdminSettingsClient() {
|
||||
<div className="space-y-3">
|
||||
{analyticsData?.userStats?.slice(0, 10).map((user, index) => (
|
||||
<div
|
||||
className="flex items-center justify-between rounded-2xl border border-zinc-200/70 bg-zinc-50/80 px-4 py-3"
|
||||
className="flex items-center justify-between rounded-2xl border border-zinc-200/70 bg-zinc-50/80 px-4 py-3 dark:border-zinc-800 dark:bg-zinc-900/60"
|
||||
key={user.userId}
|
||||
>
|
||||
<div className="flex min-w-0 items-center gap-3">
|
||||
@ -9712,14 +9712,14 @@ export function AdminSettingsClient() {
|
||||
index === 0
|
||||
? "bg-zinc-950 text-white"
|
||||
: index < 3
|
||||
? "bg-lime-100 text-lime-700"
|
||||
: "bg-white text-zinc-600"
|
||||
? "bg-lime-100 text-lime-700 dark:bg-lime-500/15 dark:text-lime-200"
|
||||
: "bg-white text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300"
|
||||
)}
|
||||
>
|
||||
{index + 1}
|
||||
</div>
|
||||
<div className="min-w-0">
|
||||
<div className="truncate font-medium text-sm text-zinc-950">
|
||||
<div className="truncate font-medium text-sm text-zinc-950 dark:text-zinc-50">
|
||||
{user.userName || user.userEmail?.split("@")[0]}
|
||||
</div>
|
||||
<div className="truncate text-muted-foreground text-xs">
|
||||
@ -9728,7 +9728,7 @@ export function AdminSettingsClient() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="font-semibold text-zinc-950">
|
||||
<div className="font-semibold text-zinc-950 dark:text-zinc-50">
|
||||
{formatAnalyticsNumber(user.imageCount)}
|
||||
</div>
|
||||
<div className="text-[11px] text-muted-foreground">
|
||||
@ -9738,7 +9738,7 @@ export function AdminSettingsClient() {
|
||||
</div>
|
||||
))}
|
||||
{(!analyticsData?.userStats || analyticsData.userStats.length === 0) && (
|
||||
<div className="rounded-2xl border border-dashed border-zinc-200 py-10 text-center text-muted-foreground text-sm">
|
||||
<div className="rounded-2xl border border-dashed border-zinc-200 py-10 text-center text-muted-foreground text-sm dark:border-zinc-800">
|
||||
暂无用户排行数据
|
||||
</div>
|
||||
)}
|
||||
@ -9746,7 +9746,7 @@ export function AdminSettingsClient() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)]">
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)] dark:border-zinc-800/80 dark:bg-zinc-950/70 dark:shadow-none">
|
||||
<CardHeader className="pb-4">
|
||||
<div className="text-[11px] uppercase tracking-[0.24em] text-muted-foreground">
|
||||
output sizes
|
||||
@ -9765,19 +9765,19 @@ export function AdminSettingsClient() {
|
||||
);
|
||||
return (
|
||||
<div
|
||||
className="rounded-2xl border border-zinc-200/70 bg-white p-4"
|
||||
className="rounded-2xl border border-zinc-200/70 bg-white p-4 dark:border-zinc-800 dark:bg-zinc-900/60"
|
||||
key={stat.imageSize || "unknown"}
|
||||
>
|
||||
<div className="text-[11px] uppercase tracking-[0.2em] text-muted-foreground">
|
||||
{stat.imageSize}
|
||||
</div>
|
||||
<div className="mt-3 font-semibold text-3xl tracking-tight text-zinc-950">
|
||||
<div className="mt-3 font-semibold text-3xl tracking-tight text-zinc-950 dark:text-zinc-50">
|
||||
{formatAnalyticsNumber(stat.count)}
|
||||
</div>
|
||||
<div className="mt-1 text-muted-foreground text-xs">
|
||||
占比 {percentage}
|
||||
</div>
|
||||
<div className="mt-4 h-2 overflow-hidden rounded-full bg-zinc-100">
|
||||
<div className="mt-4 h-2 overflow-hidden rounded-full bg-zinc-100 dark:bg-zinc-800">
|
||||
<div
|
||||
className="h-full rounded-full bg-gradient-to-r from-zinc-950 to-lime-400"
|
||||
style={{ width: percentage }}
|
||||
@ -9790,8 +9790,8 @@ export function AdminSettingsClient() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)]">
|
||||
<CardHeader className="border-b border-zinc-200/70 pb-4">
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)] dark:border-zinc-800/80 dark:bg-zinc-950/70 dark:shadow-none">
|
||||
<CardHeader className="border-b border-zinc-200/70 pb-4 dark:border-zinc-800/80">
|
||||
<div className="text-[11px] uppercase tracking-[0.24em] text-muted-foreground">
|
||||
model usage
|
||||
</div>
|
||||
@ -9812,7 +9812,7 @@ export function AdminSettingsClient() {
|
||||
);
|
||||
return (
|
||||
<div
|
||||
className="rounded-2xl border border-zinc-200/70 bg-zinc-50/80 p-4"
|
||||
className="rounded-2xl border border-zinc-200/70 bg-zinc-50/80 p-4 dark:border-zinc-800 dark:bg-zinc-900/60"
|
||||
key={`${stat.modelId || "unknown"}-${index}`}
|
||||
>
|
||||
<div className="flex flex-wrap items-start justify-between gap-3">
|
||||
@ -9822,11 +9822,11 @@ export function AdminSettingsClient() {
|
||||
{index + 1}
|
||||
</span>
|
||||
<div className="min-w-0">
|
||||
<div className="truncate font-medium text-base text-zinc-950">
|
||||
<div className="truncate font-medium text-base text-zinc-950 dark:text-zinc-50">
|
||||
{modelLabel}
|
||||
</div>
|
||||
<div className="mt-1 flex flex-wrap items-center gap-2 text-xs text-muted-foreground">
|
||||
<span className="rounded-full bg-white px-2 py-1">
|
||||
<span className="rounded-full bg-white px-2 py-1 dark:bg-zinc-800 dark:text-zinc-300">
|
||||
{resolved.providerName || "未知提供商"}
|
||||
</span>
|
||||
<span>{formatAnalyticsNumber(stat.userCount)} 位用户</span>
|
||||
@ -9835,7 +9835,7 @@ export function AdminSettingsClient() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="font-semibold text-3xl tracking-tight text-zinc-950">
|
||||
<div className="font-semibold text-3xl tracking-tight text-zinc-950 dark:text-zinc-50">
|
||||
{formatAnalyticsNumber(stat.count)}
|
||||
</div>
|
||||
<div className="text-[11px] text-muted-foreground">
|
||||
@ -9843,17 +9843,17 @@ export function AdminSettingsClient() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 h-2 overflow-hidden rounded-full bg-white">
|
||||
<div className="mt-4 h-2 overflow-hidden rounded-full bg-white dark:bg-zinc-800">
|
||||
<div
|
||||
className={cn(
|
||||
"h-full rounded-full",
|
||||
index === 0
|
||||
? "bg-zinc-950"
|
||||
? "bg-zinc-950 dark:bg-zinc-100"
|
||||
: index === 1
|
||||
? "bg-lime-500"
|
||||
: index === 2
|
||||
? "bg-amber-500"
|
||||
: "bg-zinc-300"
|
||||
: "bg-zinc-300 dark:bg-zinc-600"
|
||||
)}
|
||||
style={{
|
||||
width: formatAnalyticsRatio(
|
||||
@ -9868,14 +9868,14 @@ export function AdminSettingsClient() {
|
||||
})}
|
||||
{(!analyticsData?.modelDetailStats ||
|
||||
analyticsData.modelDetailStats.length === 0) && (
|
||||
<div className="rounded-2xl border border-dashed border-zinc-200 py-10 text-center text-muted-foreground text-sm">
|
||||
<div className="rounded-2xl border border-dashed border-zinc-200 py-10 text-center text-muted-foreground text-sm dark:border-zinc-800">
|
||||
暂无模型使用数据
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)]">
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)] dark:border-zinc-800/80 dark:bg-zinc-950/70 dark:shadow-none">
|
||||
<CardHeader className="pb-4">
|
||||
<div className="text-[11px] uppercase tracking-[0.24em] text-muted-foreground">
|
||||
provider distribution
|
||||
@ -9893,18 +9893,18 @@ export function AdminSettingsClient() {
|
||||
const width = formatAnalyticsRatio(stat.count, total);
|
||||
return (
|
||||
<div
|
||||
className="rounded-2xl border border-zinc-200/70 bg-white p-4"
|
||||
className="rounded-2xl border border-zinc-200/70 bg-white p-4 dark:border-zinc-800 dark:bg-zinc-900/60"
|
||||
key={`${stat.providerType || "unknown"}-${index}`}
|
||||
>
|
||||
<div className="flex items-center justify-between gap-3 text-sm">
|
||||
<span className="truncate font-medium text-zinc-950">
|
||||
<span className="truncate font-medium text-zinc-950 dark:text-zinc-50">
|
||||
{stat.providerName || stat.providerType || "未知提供商"}
|
||||
</span>
|
||||
<span className="shrink-0 text-muted-foreground text-xs">
|
||||
{formatAnalyticsNumber(stat.count)} · {width}
|
||||
</span>
|
||||
</div>
|
||||
<div className="mt-3 h-2 overflow-hidden rounded-full bg-zinc-100">
|
||||
<div className="mt-3 h-2 overflow-hidden rounded-full bg-zinc-100 dark:bg-zinc-800">
|
||||
<div
|
||||
className="h-full rounded-full bg-gradient-to-r from-zinc-950 to-lime-400"
|
||||
style={{ width }}
|
||||
@ -9916,7 +9916,7 @@ export function AdminSettingsClient() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)]">
|
||||
<Card className="border-zinc-200/80 shadow-[0_18px_40px_-28px_rgba(15,23,42,0.24)] dark:border-zinc-800/80 dark:bg-zinc-950/70 dark:shadow-none">
|
||||
<CardHeader className="pb-4">
|
||||
<div className="text-[11px] uppercase tracking-[0.24em] text-muted-foreground">
|
||||
recent 7 days
|
||||
@ -9929,29 +9929,29 @@ export function AdminSettingsClient() {
|
||||
const topModels = day.models.slice(0, 3);
|
||||
return (
|
||||
<div
|
||||
className="rounded-2xl border border-zinc-200/70 bg-zinc-50/80 p-4"
|
||||
className="rounded-2xl border border-zinc-200/70 bg-zinc-50/80 p-4 dark:border-zinc-800 dark:bg-zinc-900/60"
|
||||
key={day.date}
|
||||
>
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<div className="font-medium text-sm text-zinc-950">
|
||||
<div className="font-medium text-sm text-zinc-950 dark:text-zinc-50">
|
||||
{day.date}
|
||||
</div>
|
||||
<div className="text-muted-foreground text-xs">
|
||||
当日共 {formatAnalyticsNumber(day.total)} 次生成
|
||||
</div>
|
||||
</div>
|
||||
<div className="rounded-full bg-white px-3 py-1 text-xs text-zinc-700">
|
||||
<div className="rounded-full bg-white px-3 py-1 text-xs text-zinc-700 dark:bg-zinc-800 dark:text-zinc-300">
|
||||
{formatAnalyticsNumber(day.models.length)} 个模型活跃
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3 flex flex-wrap gap-2">
|
||||
{topModels.map((stat) => (
|
||||
<div
|
||||
className="inline-flex items-center gap-2 rounded-full border border-zinc-200 bg-white px-3 py-1.5 text-xs"
|
||||
className="inline-flex items-center gap-2 rounded-full border border-zinc-200 bg-white px-3 py-1.5 text-xs dark:border-zinc-800 dark:bg-zinc-950/70"
|
||||
key={`${day.date}-${stat.modelId || stat.modelName}`}
|
||||
>
|
||||
<span className="max-w-[180px] truncate text-zinc-900">
|
||||
<span className="max-w-[180px] truncate text-zinc-900 dark:text-zinc-100">
|
||||
{formatAnalyticsModelLabel(
|
||||
{
|
||||
modelName: stat.modelName,
|
||||
@ -9971,7 +9971,7 @@ export function AdminSettingsClient() {
|
||||
);
|
||||
})}
|
||||
{analyticsTrendDays.length === 0 ? (
|
||||
<div className="rounded-2xl border border-dashed border-zinc-200 py-10 text-center text-muted-foreground text-sm">
|
||||
<div className="rounded-2xl border border-dashed border-zinc-200 py-10 text-center text-muted-foreground text-sm dark:border-zinc-800">
|
||||
暂无趋势数据
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user