import * as React from "react" import { Area, AreaChart, XAxis } from "recharts" import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart" import { CountingNumber } from '@/components/animate-ui/primitives/texts/counting-number' import { Skeleton } from "@/components/ui/skeleton" import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip" import { Info } from "lucide-react" import { useUser } from "@/contexts/user-context" import { DashboardService } from "@/lib/services" import type { DailyStatsItem } from "@/lib/services" const chartConfig = { total: { label: "总额", color: "hsl(217, 91%, 60%)", }, income: { label: "收入", color: "#10b981", }, expense: { label: "支出", color: "#f43f5e", }, } satisfies ChartConfig function ResponsiveInfoTip({ children }: { children: React.ReactNode }) { const triggerClassName = "shrink-0 items-center justify-center text-muted-foreground transition-colors hover:text-foreground" return ( <> {children} {children} > ) } /** * 数据面板组件 * 展示用户数据和积分余额 * @returns {React.ReactNode} 数据面板组件 */ export function DataPanel() { const { user, loading: userLoading } = useUser() const [dailyStats, setDailyStats] = React.useState([]) const [loading, setLoading] = React.useState(true) const availableBalance = parseFloat(user?.available_balance || '0') const pendingBalance = parseFloat(user?.pending_balance || '0') const remainQuota = parseFloat(user?.remain_quota || '0') /* 获取每日统计数据 */ React.useEffect(() => { const fetchDailyStats = async () => { setLoading(true) const data = await DashboardService.getDailyStats(7) setDailyStats(data) setLoading(false) } if (!userLoading && user) { fetchDailyStats() } }, [userLoading, user]) /* 根据当前余额和每日收支反推历史积分总额 */ const chartData = React.useMemo(() => { if (!dailyStats.length || userLoading) return [] const sortedStats = [...dailyStats].sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime() ) let currentBalance = availableBalance const balanceHistory: Array<{ date: string; total: number; income: number; expense: number }> = [] for (let i = 0; i < sortedStats.length; i++) { const stat = sortedStats[i] const income = parseFloat(stat.income || '0') const expense = parseFloat(stat.expense || '0') balanceHistory.unshift({ date: new Date(stat.date).toLocaleDateString('zh-CN', { month: 'numeric', day: 'numeric' }), total: Math.max(0, currentBalance), income, expense }) currentBalance = currentBalance - income + expense } return balanceHistory }, [dailyStats, availableBalance, userLoading]) return ( 积分趋势 {loading || userLoading ? ( ) : chartData.length > 0 ? ( } /> ) : ( 暂无统计数据 )} 可用LDC 可用 LINUX DO Credits 当前可立即使用的积分,不包含延迟到账中的未来积分。 {userLoading ? '-' : } 未来LDC 未来 LINUX DO Credits 流转后延迟到账的积分,到期后自动转入可用积分。 {userLoading ? '-' : } 今日剩余额度 每日积分消耗额度限制,每日 0 点自动重置 {userLoading ? '-' : remainQuota < 0 ? "无限制" : } ) }
{children}
暂无统计数据