feat: Update admin dashboard to show registered user count and set default date range for NASA data download to current month

main
mula.liu 2025-11-30 23:25:56 +08:00
parent 539a5319e4
commit a10d0e49fe
3 changed files with 49 additions and 12 deletions

View File

@ -1,14 +1,14 @@
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from sqlalchemy import select
from sqlalchemy import select, func
from typing import List
from pydantic import BaseModel
from app.database import get_db
from app.models.db import User
from app.services.auth import hash_password
from app.services.auth_deps import get_current_user # To protect endpoints
from app.services.auth_deps import get_current_user, get_current_admin_user # To protect endpoints
router = APIRouter(prefix="/users", tags=["users"])
@ -105,3 +105,16 @@ async def reset_user_password(
await db.commit()
return {"message": f"Password for user {user.username} has been reset."}
@router.get("/count", response_model=dict)
async def get_user_count(
db: AsyncSession = Depends(get_db),
current_admin_user: User = Depends(get_current_admin_user) # Ensure only admin can access
):
"""
Get the total count of registered users.
"""
result = await db.execute(select(func.count(User.id)))
total_users = result.scalar_one()
return {"total_users": total_users}

View File

@ -1,10 +1,33 @@
/**
* Dashboard Page
*/
import { Card, Row, Col, Statistic } from 'antd';
import { DatabaseOutlined, GlobalOutlined, RocketOutlined } from '@ant-design/icons';
import { Card, Row, Col, Statistic, message } from 'antd';
import { GlobalOutlined, RocketOutlined, UserOutlined } from '@ant-design/icons';
import { useEffect, useState } from 'react';
import { request } from '../../utils/request';
export function Dashboard() {
const [totalUsers, setTotalUsers] = useState<number | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchUserCount = async () => {
try {
setLoading(true);
// Assuming '/users/count' is the new endpoint we just created in the backend
const response = await request.get('/users/count');
setTotalUsers(response.data.total_users);
} catch (error) {
console.error('Failed to fetch user count:', error);
message.error('无法获取用户总数');
setTotalUsers(0); // Set to 0 or handle error display
} finally {
setLoading(false);
}
};
fetchUserCount();
}, []); // Run once on mount
return (
<div>
<h1></h1>
@ -13,7 +36,7 @@ export function Dashboard() {
<Card>
<Statistic
title="天体总数"
value={18}
value={18} // Currently hardcoded
prefix={<GlobalOutlined />}
/>
</Card>
@ -22,7 +45,7 @@ export function Dashboard() {
<Card>
<Statistic
title="探测器"
value={7}
value={7} // Currently hardcoded
prefix={<RocketOutlined />}
/>
</Card>
@ -30,13 +53,14 @@ export function Dashboard() {
<Col span={8}>
<Card>
<Statistic
title="数据记录"
value={1245}
prefix={<DatabaseOutlined />}
title="注册用户数"
value={totalUsers !== null ? totalUsers : '-'}
loading={loading}
prefix={<UserOutlined />}
/>
</Card>
</Col>
</Row>
</div>
);
}
}

View File

@ -56,8 +56,8 @@ export function NASADownload() {
const [bodies, setBodies] = useState<GroupedBodies>({});
const [selectedBodies, setSelectedBodies] = useState<string[]>([]);
const [dateRange, setDateRange] = useState<[Dayjs, Dayjs]>([
dayjs().subtract(1, 'month').startOf('month'),
dayjs().subtract(1, 'month').endOf('month')
dayjs().startOf('month'),
dayjs().endOf('month')
]);
const [availableDates, setAvailableDates] = useState<Set<string>>(new Set());
const [loadingDates, setLoadingDates] = useState(false);