Files
OpenFlare/frontend/components/common/home/home-main.tsx
T
ryan 48d414e197 裁剪
swagger

移除 merchant

swagger

改造首页内容为通用后台管理系统定位

- 修改首页标题从 'LINUX DO Credit' 改为 'Modern Platform'
- 更新副标题为 '为二次开发而生'
- 更新首页描述为通用平台的特点
- 更新首页特性标签为 '开箱即用、高度可扩展、工业级基建'
- 修改展示卡片为技术栈和二次开发相关
- 更新开发者示例代码为通用的注册和 API Key 获取示例
- 更新页脚品牌名为 'Modern Platform'
- 调整页脚导航链接为通用平台相关内容

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

去除遗留

裁剪
移除 /api/v1/user/pay-key 相关代码

- 删除后端 UpdatePayKey 处理器函数和 UpdatePayKeyRequest 结构体
- 删除 User 模型中的 PayKey 字段
- 删除 User.VerifyPayKey 方法
- 删除 EncryptPayKeyFailed 错误常量
- 删除 /api/v1/user/pay-key PUT 路由
- 删除 OAuth 返回中的 IsPayKey 字段
- 删除前端 UserService.updatePayKey 方法
- 删除前端所有支付密钥 UI 和逻辑
- 更新相关的导出和注释

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

去除遗留

api 修正

系统配置

前端裁剪

后端裁剪

init
2026-06-08 20:34:28 +08:00

183 lines
6.6 KiB
TypeScript

"use client"
import * as React from "react"
import { motion } from "motion/react"
import { useUser } from "@/contexts/user-context"
import { formatDateTime } from "@/lib/utils"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import {
User,
Key,
ShieldCheck,
FileText,
Layers,
ArrowRight,
Shield,
HelpCircle,
Clock,
ExternalLink
} from "lucide-react"
import Link from "next/link"
export function HomeMain() {
const { user, getTrustLevelLabel } = useUser()
const quickLinks = [
{
title: "个人资料",
description: "管理您的个人账户信息及个性化配置",
icon: User,
url: "/settings/profile",
color: "text-blue-500",
bgColor: "bg-blue-500/10",
borderColor: "hover:border-blue-500/30",
},
{
title: "开发接口文档",
description: "查看开放平台的 RESTful 接口规格说明",
icon: FileText,
url: "/docs/api",
color: "text-emerald-500",
bgColor: "bg-emerald-500/10",
borderColor: "hover:border-emerald-500/30",
external: true,
},
{
title: "使用文档",
description: "学习如何集成 API 及日常操作帮助指南",
icon: HelpCircle,
url: "/docs/how-to-use",
color: "text-purple-500",
bgColor: "bg-purple-500/10",
borderColor: "hover:border-purple-500/30",
external: true,
},
]
const adminLinks = [
{
title: "全局系统配置",
description: "动态管理平台运行时核心配置参数",
icon: ShieldCheck,
url: "/admin/system",
color: "text-indigo-500",
bgColor: "bg-indigo-500/10",
borderColor: "hover:border-indigo-500/30",
},
{
title: "用户权限管理",
description: "集中查询并管理系统注册用户的启用状态",
icon: User,
url: "/admin/users",
color: "text-rose-500",
bgColor: "bg-rose-500/10",
borderColor: "hover:border-rose-500/30",
},
{
title: "后台任务调度",
description: "分发与观测系统异步定时任务的执行情况",
icon: Layers,
url: "/admin/tasks",
color: "text-teal-500",
bgColor: "bg-teal-500/10",
borderColor: "hover:border-teal-500/30",
},
]
return (
<div className="py-6 space-y-8 max-w-6xl mx-auto">
{/* 快捷导航 */}
<div className="space-y-4">
<h2 className="text-lg font-semibold tracking-tight">常用功能导航</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
{quickLinks.map((link, idx) => (
<motion.div
key={link.title}
initial={{ opacity: 0, y: 15 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.4, delay: idx * 0.05 }}
whileHover={{ y: -4 }}
className="h-full"
>
<Card className={`h-full border border-dashed flex flex-col justify-between hover:bg-muted/40 transition-all ${link.borderColor} duration-300 shadow-none`}>
<CardHeader className="p-5">
<div className={`size-10 rounded-lg flex items-center justify-center ${link.bgColor} ${link.color} mb-3`}>
<link.icon className="size-5" />
</div>
<CardTitle className="text-sm font-semibold mb-1 flex items-center gap-1">
{link.title}
{link.external && <ExternalLink className="size-3 text-muted-foreground" />}
</CardTitle>
<p className="text-xs text-muted-foreground leading-normal font-normal">
{link.description}
</p>
</CardHeader>
<div className="px-5 pb-5">
{link.external ? (
<Button variant="link" className="p-0 h-auto text-xs text-indigo-500 font-medium" asChild>
<Link href={link.url} target="_blank" rel="noopener noreferrer">
立即跳转 <ArrowRight className="size-3 ml-1" />
</Link>
</Button>
) : (
<Button variant="link" className="p-0 h-auto text-xs text-indigo-500 font-medium" asChild>
<Link href={link.url}>
立即进入 <ArrowRight className="size-3 ml-1" />
</Link>
</Button>
)}
</div>
</Card>
</motion.div>
))}
</div>
</div>
{/* 管理面板 (仅管理员可见) */}
{user?.is_admin && (
<div className="space-y-4 pt-2">
<h2 className="text-lg font-semibold tracking-tight text-rose-500 flex items-center gap-1.5">
<Shield className="size-5" />
后台管理控制台
</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{adminLinks.map((link, idx) => (
<motion.div
key={link.title}
initial={{ opacity: 0, y: 15 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.4, delay: (idx + 4) * 0.05 }}
whileHover={{ y: -4 }}
className="h-full"
>
<Card className={`h-full border border-dashed flex flex-col justify-between hover:bg-muted/40 transition-all ${link.borderColor} duration-300 shadow-none`}>
<CardHeader className="p-5">
<div className={`size-10 rounded-lg flex items-center justify-center ${link.bgColor} ${link.color} mb-3`}>
<link.icon className="size-5" />
</div>
<CardTitle className="text-sm font-semibold mb-1">
{link.title}
</CardTitle>
<p className="text-xs text-muted-foreground leading-normal font-normal">
{link.description}
</p>
</CardHeader>
<div className="px-5 pb-5">
<Button variant="link" className="p-0 h-auto text-xs text-indigo-500 font-medium" asChild>
<Link href={link.url}>
管理配置 <ArrowRight className="size-3 ml-1" />
</Link>
</Button>
</div>
</Card>
</motion.div>
))}
</div>
</div>
)}
</div>
)
}