Files
neo-blog/web/src/components/console/dashboard/index.tsx
Snowykami 64b1c54911
All checks were successful
Push to Helm Chart Repository / build (push) Successful in 11s
feat: enhance post management with pagination, search, and order functionality
- Added search input for filtering posts by keywords.
- Implemented pagination controls for navigating through posts.
- Introduced order selector for sorting posts based on various criteria.
- Enhanced post item display with additional metrics (view count, like count, comment count).
- Added dropdown menu for post actions (edit, view, toggle privacy, delete).
- Integrated double confirmation for delete action.
- Updated user profile to support background image upload.
- Improved user security settings with better layout and validation.
- Refactored auth context to use useCallback for logout function.
- Added command palette component for improved command execution.
- Introduced popover component for better UI interactions.
- Implemented debounce hooks for optimized state updates.
- Updated localization files with new keys for improved internationalization.
- Added tailwind configuration for styling.
2025-09-25 00:51:29 +08:00

74 lines
2.0 KiB
TypeScript

"use client"
import { getDashboard, DashboardResp } from "@/api/admin"
import { Card, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Eye, MessageCircle, Newspaper, Users } from "lucide-react"
import { useEffect, useState } from "react"
import { toast } from "sonner"
import Link from "next/link"
import { IconType } from "@/types/icon"
import { consolePath } from "@/hooks/use-route"
export function Dashboard() {
return (
<div className="">
<DataOverview />
</div>
)
}
function DataOverview() {
const data: { key: keyof DashboardResp; label: string; icon: IconType; url: string }[] = [
{
key: "totalPosts",
label: "Total Posts",
icon: Newspaper,
url: consolePath.post
},
{
key: "totalUsers",
label: "Total Users",
icon: Users,
url: consolePath.user
},
{
key: "totalComments",
label: "Total Comments",
icon: MessageCircle,
url: consolePath.comment
},
{
key: "totalViews",
label: "Total Views",
icon: Eye,
url: consolePath.file
},
]
const [fetchData, setFetchData] = useState<DashboardResp | null>(null);
useEffect(() => {
getDashboard().then(res => {
setFetchData(res.data);
}).catch(err => {
toast.error(err.message || "Failed to fetch dashboard data");
});
}, [])
if (!fetchData) return <div>Loading...</div>
return <div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4">
{data.map(item => (
<Link key={item.key} href={item.url}>
<Card key={item.key} className="p-4">
<CardHeader className="pb-2 text-lg font-medium">
<CardDescription>{item.label}</CardDescription>
<CardTitle className="text-2xl font-semibold tabular-nums @[250px]/card:text-3xl text-primary">
<item.icon className="inline mr-2" />
{fetchData[item.key]}
</CardTitle>
</CardHeader>
</Card>
</Link>
))}
</div>
}