初步实现仪表盘界面布局
This commit is contained in:
BIN
src/app/admin/(dashboard)/_assets/banner.webp
Normal file
BIN
src/app/admin/(dashboard)/_assets/banner.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 168 KiB |
@@ -1,43 +1,104 @@
|
||||
import Page from '@/components/page'
|
||||
import Image from 'next/image'
|
||||
import banner from './_assets/banner.webp'
|
||||
import {Card, CardContent, CardHeader, CardTitle} from '@/components/ui/card'
|
||||
import {Button} from '@/components/ui/button'
|
||||
import {getProfile} from '@/actions/auth/auth'
|
||||
import {redirect} from 'next/navigation'
|
||||
import {Tabs, TabsContent, TabsList, TabsTrigger} from '@/components/ui/tabs'
|
||||
|
||||
export type DashboardPageProps = {}
|
||||
|
||||
export default async function DashboardPage(props: DashboardPageProps) {
|
||||
|
||||
return (
|
||||
<Page mode={`blank`} className={`flex-auto grid grid-cols-4 grid-rows-4`}>
|
||||
{/* banner */}
|
||||
<section className={`col-start-1 row-start-1 col-span-3 bg-red-200`}>
|
||||
const profile = await getProfile()
|
||||
if (!profile) {
|
||||
return redirect('/login')
|
||||
}
|
||||
|
||||
return (
|
||||
<Page className={`flex-auto grid grid-cols-4 grid-rows-[150px_minmax(200px,1fr)_minmax(200px,1fr)_minmax(200px,1fr)]`}>
|
||||
{/* 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`}/>
|
||||
<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>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 短效 */}
|
||||
<section className={`col-start-1 row-start-2 bg-red-200`}>
|
||||
|
||||
</section>
|
||||
<Card className={`col-start-1 row-start-2 py-4`}>
|
||||
<CardHeader>
|
||||
<CardTitle>短效动态套餐</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className={`flex gap-4`}>
|
||||
<div className={`flex-1 flex flex-col items-stretch justify-center gap-2`}>
|
||||
<h4 className={`text-lg`}>包时</h4>
|
||||
<p className={`flex justify-between`}>
|
||||
<span>套餐数量</span>
|
||||
<span>todo</span>
|
||||
</p>
|
||||
<Button className={`h-9`}>去购买</Button>
|
||||
</div>
|
||||
<div className={`flex-1 flex flex-col items-stretch justify-center gap-2`}>
|
||||
<h4 className={`text-lg`}>包量</h4>
|
||||
<p className={`flex justify-between`}>
|
||||
<span>套餐数量</span>
|
||||
<span>todo</span>
|
||||
</p>
|
||||
<Button className={`h-9`}>去购买</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
{/* 长效 */}
|
||||
<section className={`col-start-2 row-start-2 bg-red-200`}>
|
||||
|
||||
</section>
|
||||
<Card className={`col-start-2 row-start-2`}>
|
||||
<CardHeader>
|
||||
<CardTitle>长效动态套餐</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
todo
|
||||
</CardContent>
|
||||
</Card>
|
||||
{/* 固定 */}
|
||||
<section className={`col-start-3 row-start-2 bg-red-200`}>
|
||||
|
||||
</section>
|
||||
<Card className={`col-start-3 row-start-2 py-4`}>
|
||||
<CardHeader className={`px-4`}>
|
||||
<CardTitle>固定IP套餐</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className={`flex px-4 gap-4`}>
|
||||
todo
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* 图表 */}
|
||||
<section className={`col-start-1 row-start-3 col-span-3 row-span-2 bg-red-200`}>
|
||||
|
||||
<section className={`col-start-1 row-start-3 col-span-3 row-span-2`}>
|
||||
<Tabs defaultValue={`dynamic`}>
|
||||
<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`}>
|
||||
dynamic
|
||||
</TabsContent>
|
||||
<TabsContent value={`static`}>
|
||||
static
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</section>
|
||||
|
||||
{/* 信息 */}
|
||||
<section className={`col-start-4 row-start-1 row-span-2 bg-red-200`}>
|
||||
|
||||
</section>
|
||||
<Card className={`col-start-4 row-start-1 row-span-2`}>
|
||||
<CardHeader>
|
||||
<CardTitle>个人中心</CardTitle>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
|
||||
{/* 通知 */}
|
||||
<section className={`col-start-4 row-start-3 row-span-2 bg-red-200`}>
|
||||
|
||||
</section>
|
||||
<Card className={`col-start-4 row-start-3 row-span-2`}>
|
||||
<CardHeader>
|
||||
<CardTitle>待办事项</CardTitle>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,13 +3,15 @@
|
||||
@plugin "tailwindcss-animate";
|
||||
|
||||
:root {
|
||||
--background: oklch(1 0 0);
|
||||
--foreground: oklch(0.25 0 0);
|
||||
--weak: oklch(0.5 0 0);
|
||||
--idle: oklch(1 0 0);
|
||||
--idle-muted: oklch(0.965 0 0);
|
||||
--idle-text: oklch(0.25 0 0);
|
||||
--idle-desc: oklch(0.5 0 0);
|
||||
|
||||
--primary: oklch(0.65 0.16 265);
|
||||
--primary-muted: oklch(0.965 0.024 265);
|
||||
--primary-text: oklch(1 0 0);
|
||||
--primary-weak: oklch(0.5 0 0);
|
||||
--primary-desc: oklch(0.5 0 0);
|
||||
|
||||
--secondary: oklch(0.965 0 0);
|
||||
--secondary-text: oklch(0.25 0 0);
|
||||
@@ -29,9 +31,6 @@
|
||||
--card: oklch(0.985 0 0);
|
||||
--card-text: oklch(0.25 0 0);
|
||||
|
||||
--muted: oklch(0.965 0 0);
|
||||
--muted-text: oklch(0.25 0 0);
|
||||
|
||||
--popover: oklch(1 0 0);
|
||||
--popover-foreground: oklch(0.25 0 0);
|
||||
--border: oklch(0.928 0.006 264.531);
|
||||
@@ -53,13 +52,16 @@
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--color-weak: var(--weak);
|
||||
--color-background: var(--idle);
|
||||
--color-foreground: var(--idle-text);
|
||||
--color-weak: var(--idle-desc);
|
||||
--color-muted: var(--idle-muted);
|
||||
--color-muted-foreground: var(--idle-text);
|
||||
|
||||
--color-primary: var(--primary);
|
||||
--color-primary-muted: var(--primary-muted);
|
||||
--color-primary-foreground: var(--primary-text);
|
||||
--color-primary-weak: var(--primary-weak);
|
||||
--color-primary-weak: var(--primary-desc);
|
||||
|
||||
--color-secondary: var(--secondary);
|
||||
--color-secondary-foreground: var(--secondary-text);
|
||||
@@ -80,8 +82,6 @@
|
||||
--color-card-foreground: var(--card-text);
|
||||
--color-popover: var(--popover);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-muted-foreground: var(--muted-text);
|
||||
--color-destructive: var(--fail);
|
||||
--color-border: var(--border);
|
||||
--color-input: var(--input);
|
||||
|
||||
Reference in New Issue
Block a user