diff --git a/package.json b/package.json index 7aafade..6388f82 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "onlyBuiltDependencies": [ "canvas", "sharp" - ], + ], "overrides": { "react-is": "19.0.0-rc.1" } diff --git a/src/app/(auth)/login/layout.tsx b/src/app/(auth)/login/layout.tsx new file mode 100644 index 0000000..30c3605 --- /dev/null +++ b/src/app/(auth)/login/layout.tsx @@ -0,0 +1,17 @@ + +import { ReactNode } from 'react' +import { Metadata } from 'next' + +export async function generateMetadata(): Promise { + return { + title: '登录 - 蓝狐代理', + } +} + +export type LoginLayoutProps = { + children: ReactNode +} + +export default async function LoginLayout(props: LoginLayoutProps) { + return props.children +} \ No newline at end of file diff --git a/src/app/(home)/page.tsx b/src/app/(home)/page.tsx index 2abf5d3..fe1ce3f 100644 --- a/src/app/(home)/page.tsx +++ b/src/app/(home)/page.tsx @@ -72,24 +72,24 @@ export default function Home() { ].join(' ')}> + {icon: `s1-check`, text: `IP时效3-30分钟(可定制)`}, + {icon: `s1-check`, text: `支持高并发提取`}, + ]}/> + {icon: `s1-check`, text: `IP覆盖全国各地`}, + {icon: `s1-check`, text: `平均响应时长:0.03s`}, + ]}/> + {icon: `s1-check`, text: `稳定长输不掉线`}, + {icon: `s1-check`, text: `全国热门静态IP线路`}, + ]}/> + {icon: `s1-check`, text: `可视化监控设计`}, + {icon: `s1-check`, text: `技术团队现场支持`}, + ]}/> diff --git a/src/app/admin/(dashboard)/_assets/Mask group.webp b/src/app/admin/(dashboard)/_assets/Mask group.webp new file mode 100644 index 0000000..f7b1e25 Binary files /dev/null and b/src/app/admin/(dashboard)/_assets/Mask group.webp differ diff --git a/src/app/admin/(dashboard)/_client/charts.tsx b/src/app/admin/(dashboard)/_client/charts.tsx new file mode 100644 index 0000000..4b36cbb --- /dev/null +++ b/src/app/admin/(dashboard)/_client/charts.tsx @@ -0,0 +1,121 @@ +'use client' +import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs" +import DashboardChart from "./chart" +import Image from 'next/image' +import soon from '../_assets/coming-soon.svg' +import DatePicker from "@/components/date-picker" +import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card" +import { Form, FormField } from "@/components/ui/form" +import { Input } from "@/components/ui/input" +import { zodResolver } from "@hookform/resolvers/zod" +import { useForm } from "react-hook-form" +import zod from 'zod' +import {merge} from '@/lib/utils' +import mask from '../_assets/Mask group.webp' +import {Button} from '@/components/ui/button' + + + + + + + +export default 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 }, + ] + const formSchema = zod.object({ + name: zod.string(), + age: zod.string(), + }) + + type FormValues = zod.infer + + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: { + name: '', + age: '', + }, + }) + + return ( + + + + + + {/* {`Mask */} + 动态 IP 套餐 + 静态 IP 套餐 + +
+ 套餐编号} + className={`grid grid-cols-[70px_1fr] grid-rows-[auto_auto] `} + classNames={{ + message: `col-start-2`, + }} + > + {({ field }) => ( + + )} + +
+ 时间范围筛选} + className={`grid grid-cols-[100px_1fr] `} + classNames={{ + message: `col-start-2`, + }} + > + {({ field }) => ( + + )} + + - + + {({ field }) => ( + + )} + + +
+
+ + + + + {`coming +

敬请期待

+
+
+
+
+ ) +} \ No newline at end of file diff --git a/src/app/admin/(dashboard)/_client/pins.tsx b/src/app/admin/(dashboard)/_client/pins.tsx new file mode 100644 index 0000000..d890735 --- /dev/null +++ b/src/app/admin/(dashboard)/_client/pins.tsx @@ -0,0 +1,76 @@ +'use client' +import Image from 'next/image' +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' +import soon from '../_assets/coming-soon.svg' +import mask from '../_assets/Mask group.webp' + + + +export default function Pins() { + + + return <> + + {/* 短效 */} + + + {`Mask 短效动态套餐 + + +
+

包时

+

+ 当日可提取数量 + todo +

+
+
+
+

包量

+

+ 剩余可提取数量 + todo +

+
+
+
+ + {/* 长效 */} + + + {`Mask 长效动态套餐 + + + {/* {`coming +

敬请期待

*/} +
+

包时

+

+ 当日可提取数量 + todo +

+
+
+
+

包量

+

+ 剩余可提取数量 + todo +

+
+
+
+ + {/* 固定 */} + + + 固定IP套餐 + + + {`coming +

敬请期待

+
+
+ +} + diff --git a/src/app/admin/(dashboard)/layout.tsx b/src/app/admin/(dashboard)/layout.tsx new file mode 100644 index 0000000..77b4d0d --- /dev/null +++ b/src/app/admin/(dashboard)/layout.tsx @@ -0,0 +1,17 @@ + +import { ReactNode } from 'react' +import { Metadata } from 'next' + +export async function generateMetadata(): Promise { + return { + title: '账户总览 - 蓝狐代理', + } +} + +export type BillsLayoutProps = { + children: ReactNode +} + +export default async function BillsLayout(props: BillsLayoutProps) { + return props.children +} \ No newline at end of file diff --git a/src/app/admin/(dashboard)/page.tsx b/src/app/admin/(dashboard)/page.tsx index c0a8a10..418e951 100644 --- a/src/app/admin/(dashboard)/page.tsx +++ b/src/app/admin/(dashboard)/page.tsx @@ -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 ( {/* banner */}
- {`banner + {`banner

代理IP资源,先测后买

短效/长效/固定IP代理,一站式服务

@@ -37,103 +35,21 @@ export default async function DashboardPage(props: DashboardPageProps) {
{/* 磁贴集 */} - + {/* 图表 */} - + {/* 信息 */} - + {/* 通知 */} - +
) } -async function Pins() { - return <> - {/* 短效 */} - - - 短效动态套餐 - - -
-

包时

-

- 当日可提取数量 - todo -

-
-
-
-

包量

-

- 剩余可提取数量 - todo -

-
-
-
- - {/* 长效 */} - - - 长效动态套餐 - - - {`coming -

敬请期待

-
-
- - {/* 固定 */} - - - 固定IP套餐 - - - {`coming -

敬请期待

-
-
- -} - -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 ( - - - - - 动态 IP 套餐 - 静态 IP 套餐 - - - - - - - {`coming -

敬请期待

-
-
-
-
- ) -} - async function UserCenter() { const resp = await getProfile() @@ -160,7 +76,7 @@ async function UserCenter() { {profile.id_token ? <>
- + 已实名
@@ -170,7 +86,7 @@ async function UserCenter() { : <> - + 未实名 @@ -181,22 +97,22 @@ async function UserCenter() {

账户余额

¥{profile.balance}

- +

快捷入口

- - {`bill + + {`bill 我的帐单 - - {`buy + + {`buy 购买产品 - - {`logout + + {`logout 个人中心
@@ -225,14 +141,17 @@ async function Announcements() { return ( - 公告 +
+ 公告 + 查看更多 +
{announcements.length === 0 ? (
- {`coming -

暂无公告

+ {/* {`coming +

暂无公告

*/}
) : announcements.map(item => ( diff --git a/src/app/admin/_client/navbar.tsx b/src/app/admin/_client/navbar.tsx index c65cf27..f9411a2 100644 --- a/src/app/admin/_client/navbar.tsx +++ b/src/app/admin/_client/navbar.tsx @@ -7,9 +7,22 @@ import Image from 'next/image' import logoAvatar from '../_assets/logo-avatar.svg' import logoText from '../_assets/logo-text.svg' import {Tooltip, TooltipContent, TooltipProvider, TooltipTrigger} from '@/components/ui/tooltip' +import { UserRound } from 'lucide-react' +import { UserRoundPen } from 'lucide-react' +import { IdCard } from 'lucide-react' +import { LockKeyhole } from 'lucide-react' +import { Wallet } from 'lucide-react' +import { ShoppingCart } from 'lucide-react' +import { Package } from 'lucide-react' +import { HardDriveUpload } from 'lucide-react' +import { Eye } from 'lucide-react' +import { Archive } from 'lucide-react' +import { ArchiveRestore } from 'lucide-react' + export type NavbarProps = {} + export default function Navbar(props: NavbarProps) { const navbar = useLayoutStore(store => store.navbar) @@ -43,20 +56,20 @@ export default function Navbar(props: NavbarProps) { `group-data-[expand=true]:px-4 group-data-[expand=false]:px-3`, )}> - + } label={`账户总览`} expand={navbar}/> - - - - + } label={`个人中心`} expand={navbar}/> + } label={`实名认证`} expand={navbar}/> + } label={`白名单`} expand={navbar}/> + } label={`我的账单`} expand={navbar}/> - - + } label={`购买套餐`} expand={navbar}/> + } label={`套餐管理`} expand={navbar}/> - - - - + } label={`提取 IP`} expand={navbar}/> + } label={`IP 管理`} expand={navbar}/> + } label={`提取记录`} expand={navbar}/> + } label={`使用记录`} expand={navbar}/> diff --git a/src/app/admin/bills/layout.tsx b/src/app/admin/bills/layout.tsx new file mode 100644 index 0000000..ba3137b --- /dev/null +++ b/src/app/admin/bills/layout.tsx @@ -0,0 +1,17 @@ + +import { ReactNode } from 'react' +import { Metadata } from 'next' + +export async function generateMetadata(): Promise { + return { + title: '我的账单 - 蓝狐代理', + } +} + +export type BillsLayoutProps = { + children: ReactNode +} + +export default async function BillsLayout(props: BillsLayoutProps) { + return props.children +} \ No newline at end of file diff --git a/src/app/admin/channels/layout.tsx b/src/app/admin/channels/layout.tsx new file mode 100644 index 0000000..42e6efe --- /dev/null +++ b/src/app/admin/channels/layout.tsx @@ -0,0 +1,17 @@ + +import { ReactNode } from 'react' +import { Metadata } from 'next' + +export async function generateMetadata(): Promise { + return { + title: 'IP管理 - 蓝狐代理', + } +} + +export type ChannelsLayoutProps = { + children: ReactNode +} + +export default async function ChannelsLayout(props: ChannelsLayoutProps) { + return props.children +} \ No newline at end of file diff --git a/src/app/admin/extract/layout.tsx b/src/app/admin/extract/layout.tsx new file mode 100644 index 0000000..e7012a1 --- /dev/null +++ b/src/app/admin/extract/layout.tsx @@ -0,0 +1,17 @@ + +import { ReactNode } from 'react' +import { Metadata } from 'next' + +export async function generateMetadata(): Promise { + return { + title: '提取IP - 蓝狐代理', + } +} + +export type ExtractLayoutProps = { + children: ReactNode +} + +export default async function ExtractLayout(props: ExtractLayoutProps) { + return props.children +} \ No newline at end of file diff --git a/src/app/admin/identify/layout.tsx b/src/app/admin/identify/layout.tsx new file mode 100644 index 0000000..8a45e8a --- /dev/null +++ b/src/app/admin/identify/layout.tsx @@ -0,0 +1,16 @@ +import { ReactNode } from 'react' +import { Metadata } from 'next' + +export async function generateMetadata(): Promise { + return { + title: '实名认证 - 蓝狐代理', + } +} + +export type IdentifyLayoutProps = { + children: ReactNode +} + +export default async function IdentifyLayout(props: IdentifyLayoutProps) { + return props.children +} \ No newline at end of file diff --git a/src/app/admin/profile/layout.tsx b/src/app/admin/profile/layout.tsx new file mode 100644 index 0000000..7f365db --- /dev/null +++ b/src/app/admin/profile/layout.tsx @@ -0,0 +1,17 @@ + +import { ReactNode } from 'react' +import { Metadata } from 'next' + +export async function generateMetadata(): Promise { + return { + title: '个人中心 - 蓝狐代理', + } +} + +export type ProfileLayoutProps = { + children: ReactNode +} + +export default async function ProfileLayout(props: ProfileLayoutProps) { + return props.children +} \ No newline at end of file diff --git a/src/app/admin/purchase/layout.tsx b/src/app/admin/purchase/layout.tsx new file mode 100644 index 0000000..19fc988 --- /dev/null +++ b/src/app/admin/purchase/layout.tsx @@ -0,0 +1,17 @@ + +import { ReactNode } from 'react' +import { Metadata } from 'next' + +export async function generateMetadata(): Promise { + return { + title: '购买套餐 - 蓝狐代理', + } +} + +export type PurchaseLayoutProps = { + children: ReactNode +} + +export default async function PurchaseLayout(props: PurchaseLayoutProps) { + return props.children +} \ No newline at end of file diff --git a/src/app/admin/resources/layout.tsx b/src/app/admin/resources/layout.tsx new file mode 100644 index 0000000..4f29620 --- /dev/null +++ b/src/app/admin/resources/layout.tsx @@ -0,0 +1,17 @@ + +import { ReactNode } from 'react' +import { Metadata } from 'next' + +export async function generateMetadata(): Promise { + return { + title: '套餐管理 - 蓝狐代理', + } +} + +export type ResourcesLayoutProps = { + children: ReactNode +} + +export default async function ResourcesLayout(props: ResourcesLayoutProps) { + return props.children +} \ No newline at end of file diff --git a/src/app/admin/whitelist/layout.tsx b/src/app/admin/whitelist/layout.tsx new file mode 100644 index 0000000..e0a8593 --- /dev/null +++ b/src/app/admin/whitelist/layout.tsx @@ -0,0 +1,17 @@ + +import { ReactNode } from 'react' +import { Metadata } from 'next' + +export async function generateMetadata(): Promise { + return { + title: '白名单 - 蓝狐代理', + } +} + +export type WhitelistLayoutProps = { + children: ReactNode +} + +export default async function WhitelistLayout(props: WhitelistLayoutProps) { + return props.children +} \ No newline at end of file diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 82d3df1..2057b75 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -13,8 +13,7 @@ const font = localFont({ export async function generateMetadata(): Promise { return { - title: 'Create Next App', - description: 'Generated by create next app', + title: '蓝狐代理', } }