- Set up Next.js project structure - Added UI components and styling - Configured package dependencies - Added feature documentation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
59 lines
1.3 KiB
TypeScript
59 lines
1.3 KiB
TypeScript
"use client";
|
|
|
|
import { useMemo } from 'react';
|
|
import { StatsOverview } from '@/lib/types';
|
|
|
|
export interface StatsDataItem {
|
|
value: string;
|
|
label: string;
|
|
count: number;
|
|
}
|
|
|
|
export function useStatsData(stats: StatsOverview | null) {
|
|
const platforms = useMemo(() => {
|
|
if (!stats?.platformSummary) return [];
|
|
return Object.entries(stats.platformSummary).map(([platform, count]) => ({
|
|
value: platform,
|
|
label: platform,
|
|
count
|
|
}));
|
|
}, [stats?.platformSummary]);
|
|
|
|
const owners = useMemo(() => {
|
|
if (!stats?.ownerSummary) return [];
|
|
return Object.entries(stats.ownerSummary).map(([owner, count]) => ({
|
|
value: owner,
|
|
label: owner,
|
|
count
|
|
}));
|
|
}, [stats?.ownerSummary]);
|
|
|
|
const statuses = useMemo(() => {
|
|
if (!stats?.statusSummary) return [];
|
|
return Object.entries(stats.statusSummary).map(([status, count]) => ({
|
|
value: status,
|
|
label: getStatusLabel(status),
|
|
count
|
|
}));
|
|
}, [stats?.statusSummary]);
|
|
|
|
return {
|
|
platforms,
|
|
owners,
|
|
statuses,
|
|
hasData: Boolean(stats)
|
|
};
|
|
}
|
|
|
|
function getStatusLabel(status: string): string {
|
|
switch (status) {
|
|
case 'available':
|
|
return '可用';
|
|
case 'locked':
|
|
return '已锁定';
|
|
case 'banned':
|
|
return '已封禁';
|
|
default:
|
|
return status;
|
|
}
|
|
} |