变更图标和title提示完善账户总览页面

This commit is contained in:
Eamon-meng
2025-06-05 16:41:30 +08:00
parent 39975e4349
commit c17c17724f
18 changed files with 434 additions and 137 deletions

View File

@@ -1,26 +1,24 @@
import Page from '@/components/page'
import Image from 'next/image'
import {Card, CardContent, CardHeader, CardTitle} from '@/components/ui/card'
import {Tabs, TabsContent, TabsList, TabsTrigger} from '@/components/ui/tabs'
import {getProfile} from '@/actions/auth'
import {format} from 'date-fns'
import {CheckCircleIcon, CircleAlertIcon} from 'lucide-react'
import {Button, buttonVariants} from '@/components/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { getProfile } from '@/actions/auth'
import { format } from 'date-fns'
import { CheckCircleIcon, CircleAlertIcon } from 'lucide-react'
import { Button, buttonVariants } from '@/components/ui/button'
import RechargeModal from '@/components/composites/recharge'
import {merge} from '@/lib/utils'
import { merge } from '@/lib/utils'
import banner from './_assets/banner.webp'
import soon from './_assets/coming-soon.svg'
import actionBill from './_assets/action-bill.webp'
import actionBuy from './_assets/action-buy.webp'
import actionLogout from './_assets/action-logout.webp'
import Link from 'next/link'
import {listAnnouncements} from '@/actions/announcement'
import DashboardChart from './_client/chart'
import { listAnnouncements } from '@/actions/announcement'
import Charts from './_client/charts'
import Pins from './_client/pins'
export type DashboardPageProps = {}
export default async function DashboardPage(props: DashboardPageProps) {
export default function DashboardPage(props: DashboardPageProps) {
return (
<Page className={merge(
`flex-auto grid`,
@@ -29,7 +27,7 @@ export default async function DashboardPage(props: DashboardPageProps) {
)}>
{/* banner */}
<section className={`col-start-1 row-start-1 col-span-3 relative rounded-lg overflow-hidden`}>
<Image src={banner} alt={`banner image`} className={`w-full h-full inset-0 absolute object-cover`}/>
<Image src={banner} alt={`banner image`} className={`w-full h-full inset-0 absolute object-cover`} />
<div className={`flex flex-col absolute inset-0 justify-center px-8 gap-1`}>
<h3 className={`text-2xl text-primary font-medium`}>IP资源</h3>
<p className={`text-primary font-medium`}>//IP代理</p>
@@ -37,103 +35,21 @@ export default async function DashboardPage(props: DashboardPageProps) {
</section>
{/* 磁贴集 */}
<Pins/>
<Pins />
{/* 图表 */}
<Charts/>
<Charts />
{/* 信息 */}
<UserCenter/>
<UserCenter />
{/* 通知 */}
<Announcements/>
<Announcements />
</Page>
)
}
async function Pins() {
return <>
{/* 短效 */}
<Card className={`col-start-1 row-start-2 py-4`}>
<CardHeader>
<CardTitle></CardTitle>
</CardHeader>
<CardContent className={`flex-auto flex flex-col gap-2`}>
<div className={`flex-1 flex items-center justify-between`}>
<h4></h4>
<p className={`flex flex-col items-end`}>
<span className={`text-sm text-weak`}></span>
<span className={`text-lg`}>todo</span>
</p>
</div>
<div className={`border-b`}></div>
<div className={`flex-1 flex items-center justify-between`}>
<h4></h4>
<p className={`flex flex-col items-end`}>
<span className={`text-sm text-weak`}></span>
<span className={`text-lg`}>todo</span>
</p>
</div>
</CardContent>
</Card>
{/* 长效 */}
<Card className={`col-start-2 row-start-2`}>
<CardHeader>
<CardTitle></CardTitle>
</CardHeader>
<CardContent className={`flex-auto flex flex-col gap-2 items-center justify-center`}>
<Image alt={`coming soon`} src={soon}/>
<p></p>
</CardContent>
</Card>
{/* 固定 */}
<Card className={`col-start-3 row-start-2 py-4`}>
<CardHeader className={`px-4`}>
<CardTitle>IP套餐</CardTitle>
</CardHeader>
<CardContent className={`flex-auto flex flex-col gap-2 items-center justify-center`}>
<Image alt={`coming soon`} src={soon}/>
<p></p>
</CardContent>
</Card>
</>
}
async function Charts() {
const data = [
{time: `2023-10-01`, count: 100},
{time: `2023-10-02`, count: 50},
{time: `2023-10-03`, count: 80},
{time: `2023-10-04`, count: 200},
{time: `2023-10-05`, count: 150},
]
return (
<Card className={`col-start-1 row-start-3 col-span-3 row-span-2`}>
<CardContent className={`overflow-hidden`}>
<Tabs defaultValue={`dynamic`} className="h-full gap-4">
<TabsList>
<TabsTrigger value={`dynamic`} className={`data-[state=active]:text-primary`}> IP </TabsTrigger>
<TabsTrigger value={`static`} className={`data-[state=active]:text-primary`}> IP </TabsTrigger>
</TabsList>
<TabsContent value={`dynamic`} className={`overflow-hidden`}>
<DashboardChart/>
</TabsContent>
<TabsContent value={`static`} className={`flex flex-col items-center justify-center gap-2`}>
<Image alt={`coming soon`} src={soon}/>
<p></p>
</TabsContent>
</Tabs>
</CardContent>
</Card>
)
}
async function UserCenter() {
const resp = await getProfile()
@@ -160,7 +76,7 @@ async function UserCenter() {
{profile.id_token
? <>
<div className={`flex gap-2 items-center`}>
<CheckCircleIcon size={20} className={`text-done`}/>
<CheckCircleIcon size={20} className={`text-done`} />
<span></span>
</div>
<div className={`flex flex-col items-end`}>
@@ -170,7 +86,7 @@ async function UserCenter() {
</>
: <>
<span className={`flex gap-2 items-center`}>
<CircleAlertIcon className={`text-warn`}/>
<CircleAlertIcon className={`text-warn`} />
<span></span>
</span>
<Button className={`h-9`}></Button>
@@ -181,22 +97,22 @@ async function UserCenter() {
<h4 className={`text-sm text-weak`}></h4>
<div className={`flex justify-between items-baseline`}>
<p className={`text-xl text-accent`}>{profile.balance}</p>
<RechargeModal/>
<RechargeModal />
</div>
</div>
<div className={`flex flex-col gap-3`}>
<h4 className={`text-sm text-weak`}></h4>
<div className={`flex justify-around gap-2`}>
<Link href="/admin/bills" className={merge(buttonVariants({variant: `ghost`}), `flex flex-col gap-2 py-2 px-3 h-auto`)}>
<Image alt={`bill icon`} src={actionBill} height={48}/>
<Link href="/admin/bills" className={merge(buttonVariants({ variant: `ghost` }), `flex flex-col gap-2 py-2 px-3 h-auto`)}>
<Image alt={`bill icon`} src={actionBill} height={48} />
<span className={`text-sm text-weak`}></span>
</Link>
<Link href="/admin/purchase" className={merge(buttonVariants({variant: `ghost`}), `flex flex-col gap-2 py-2 px-3 h-auto`)}>
<Image alt={`buy icon`} src={actionBuy} height={48}/>
<Link href="/admin/purchase" className={merge(buttonVariants({ variant: `ghost` }), `flex flex-col gap-2 py-2 px-3 h-auto`)}>
<Image alt={`buy icon`} src={actionBuy} height={48} />
<span className={`text-sm text-weak`}></span>
</Link>
<Link href="/admin/profile" className={merge(buttonVariants({variant: `ghost`}), `flex flex-col gap-2 py-2 px-3 h-auto`)}>
<Image alt={`logout icon`} src={actionLogout} height={48}/>
<Link href="/admin/profile" className={merge(buttonVariants({ variant: `ghost` }), `flex flex-col gap-2 py-2 px-3 h-auto`)}>
<Image alt={`logout icon`} src={actionLogout} height={48} />
<span className={`text-sm text-weak`}></span>
</Link>
</div>
@@ -225,14 +141,17 @@ async function Announcements() {
return (
<Card className={`col-start-4 row-start-3 row-span-2`}>
<CardHeader>
<CardTitle></CardTitle>
<div className={`flex justify-between gap-2`}>
<CardTitle></CardTitle>
<span className={`text-sm text-weak`}></span>
</div>
</CardHeader>
<CardContent className={`flex-auto p-0`}>
{announcements.length === 0
? (
<div className={`flex flex-col items-center justify-center gap-2 h-full`}>
<Image alt={`coming soon`} src={soon}/>
<p></p>
{/* <Image alt={`coming soon`} src={soon} />
<p>暂无公告</p> */}
</div>
)
: announcements.map(item => (