88 lines
3.0 KiB
JavaScript
88 lines
3.0 KiB
JavaScript
/*
|
||
Copyright (C) 2025 QuantumNous
|
||
|
||
This program is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Affero General Public License as
|
||
published by the Free Software Foundation, either version 3 of the
|
||
License, or (at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Affero General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Affero General Public License
|
||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
||
For commercial licensing, please contact support@quantumnous.com
|
||
*/
|
||
|
||
import React, { useContext } from 'react';
|
||
import { UserContext } from '../../context/User';
|
||
import { useUserMessageUnreadCount } from '../../hooks/common/useUserMessageUnreadCount';
|
||
import { useDashboardData } from '../../hooks/dashboard/useDashboardData';
|
||
|
||
import TopBar from './TopBar';
|
||
import Hero from './Hero';
|
||
import BentoStats from './BentoStats';
|
||
import BentoTrend from './BentoTrend';
|
||
import MonthlyForecast from './MonthlyForecast';
|
||
import RecentActivity from './RecentActivity';
|
||
|
||
const Dashboard = () => {
|
||
const [userState] = useContext(UserContext);
|
||
const user = userState?.user;
|
||
|
||
const dashboard = useDashboardData(userState);
|
||
const { unreadCount } = useUserMessageUnreadCount(user);
|
||
|
||
return (
|
||
<div className='min-h-full bg-slate-50 pb-16 text-slate-900 dark:bg-neutral-950 dark:text-white'>
|
||
<div className='mx-auto w-full max-w-[1400px] px-4 sm:px-6 lg:px-10'>
|
||
<TopBar
|
||
onSearch={() => {}}
|
||
onRefresh={dashboard.refresh}
|
||
loading={dashboard.loading}
|
||
user={user}
|
||
unreadCount={unreadCount}
|
||
/>
|
||
|
||
<div className='space-y-6 pt-8 pb-8'>
|
||
<Hero user={user} />
|
||
|
||
{/* 第一行:5 个核心指标卡 */}
|
||
<div className='grid grid-cols-2 gap-5 md:grid-cols-3 xl:grid-cols-5'>
|
||
<BentoStats
|
||
metrics={dashboard.metrics}
|
||
monthDelta={dashboard.monthDelta}
|
||
/>
|
||
</div>
|
||
|
||
{/* 第二行:七日用量趋势 + 本月账单预测 */}
|
||
<div className='grid grid-cols-1 gap-5 md:grid-cols-4'>
|
||
<BentoTrend
|
||
dailyStats={dashboard.dailyStats}
|
||
topModels={dashboard.topModels}
|
||
className='md:col-span-2'
|
||
/>
|
||
<MonthlyForecast
|
||
forecast={dashboard.monthlyForecast}
|
||
className='md:col-span-2'
|
||
/>
|
||
</div>
|
||
|
||
{/* 第三行:最近调用 */}
|
||
<RecentActivity
|
||
logs={dashboard.recentLogs}
|
||
/>
|
||
</div>
|
||
|
||
<div className='flex items-center justify-center border-t border-slate-200 py-6 text-xs text-slate-400 dark:border-white/10 dark:text-white/30'>
|
||
<span>TokenFactory · 2026</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default Dashboard; |