diff --git a/biome.json b/biome.json
index 41b3b95..4e5da7a 100644
--- a/biome.json
+++ b/biome.json
@@ -30,7 +30,7 @@
"assist": {
"actions": {
"source": {
- "organizeImports": "on"
+ "organizeImports": "off"
}
}
}
diff --git a/package.json b/package.json
index 783c7f0..e09ce5b 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"drizzle-orm": "1.0.0-rc.4",
"lucide-react": "^1.24.0",
"next": "16.2.10",
+ "nodemailer": "^9.0.3",
"pg": "^8.22.0",
"proxy-agent": "^8.0.2",
"react": "19.2.4",
@@ -32,6 +33,7 @@
"@tailwindcss/postcss": "^4",
"@types/ali-oss": "^6.23.3",
"@types/node": "^20",
+ "@types/nodemailer": "^8.0.1",
"@types/pg": "^8.20.0",
"@types/react": "^19",
"@types/react-dom": "^19",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8de2cae..d6bb6c7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -35,6 +35,9 @@ importers:
next:
specifier: 16.2.10
version: 16.2.10(@babel/core@7.29.7)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
+ nodemailer:
+ specifier: ^9.0.3
+ version: 9.0.3
pg:
specifier: ^8.22.0
version: 8.22.0
@@ -69,6 +72,9 @@ importers:
'@types/node':
specifier: ^20
version: 20.19.43
+ '@types/nodemailer':
+ specifier: ^8.0.1
+ version: 8.0.1
'@types/pg':
specifier: ^8.20.0
version: 8.20.0
@@ -1118,6 +1124,9 @@ packages:
'@types/node@20.19.43':
resolution: {integrity: sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==}
+ '@types/nodemailer@8.0.1':
+ resolution: {integrity: sha512-PxpaInm8V1JQDd4j0ds5HfvWQk8JupS1C0Picb96QJsrrRDjBH+DlK7L4ZdNSqNULhiZRQHc40nLVShaGxXAMw==}
+
'@types/pg@8.20.0':
resolution: {integrity: sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow==}
@@ -2339,6 +2348,10 @@ packages:
resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==}
engines: {node: '>=18'}
+ nodemailer@9.0.3:
+ resolution: {integrity: sha512-n+YP+NKwR5zRWa60k3GiQ6Q3B4KXCoAw40dAKeCtYn020iNN74aWK2liXIC3ZEATeGql7we3tE3t8QwhY0eskw==}
+ engines: {node: '>=6.0.0'}
+
npm-run-path@4.0.1:
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
engines: {node: '>=8'}
@@ -3786,6 +3799,10 @@ snapshots:
dependencies:
undici-types: 6.21.0
+ '@types/nodemailer@8.0.1':
+ dependencies:
+ '@types/node': 20.19.43
+
'@types/pg@8.20.0':
dependencies:
'@types/node': 20.19.43
@@ -4778,6 +4795,8 @@ snapshots:
node-releases@2.0.51: {}
+ nodemailer@9.0.3: {}
+
npm-run-path@4.0.1:
dependencies:
path-key: 3.1.1
diff --git a/src/app/(admin)/admin/page.tsx b/src/app/(admin)/admin/page.tsx
index 09d5b01..2d2480d 100644
--- a/src/app/(admin)/admin/page.tsx
+++ b/src/app/(admin)/admin/page.tsx
@@ -1,203 +1,5 @@
-import {
- Card,
- CardAction,
- CardContent,
- CardDescription,
- CardFooter,
- CardHeader,
- CardTitle,
-} from "@/components/ui/card";
-import { Button } from "@/components/ui/button";
-import { Badge } from "@/components/ui/badge";
-import {
- Activity,
- DollarSign,
- Users,
- TrendingUp,
- ArrowUpRight,
- ArrowDownRight,
-} from "lucide-react";
+import { redirect } from "next/navigation";
-const stats = [
- {
- title: "总收入",
- value: "¥ 128,430",
- change: "+12.5%",
- trend: "up" as const,
- icon: DollarSign,
- desc: "较上月",
- },
- {
- title: "活跃用户",
- value: "2,840",
- change: "+8.2%",
- trend: "up" as const,
- icon: Users,
- desc: "较上周",
- },
- {
- title: "转化率",
- value: "3.6%",
- change: "-0.4%",
- trend: "down" as const,
- icon: TrendingUp,
- desc: "较上月",
- },
- {
- title: "实时会话",
- value: "147",
- change: "+23",
- trend: "up" as const,
- icon: Activity,
- desc: "当前在线",
- },
-];
-
-const recentOrders = [
- {
- id: "ORD-7821",
- customer: "张三",
- email: "zhangsan@example.com",
- amount: "¥ 1,299",
- status: "已完成",
- },
- {
- id: "ORD-7820",
- customer: "李四",
- email: "lisi@example.com",
- amount: "¥ 899",
- status: "处理中",
- },
- {
- id: "ORD-7819",
- customer: "王五",
- email: "wangwu@example.com",
- amount: "¥ 2,499",
- status: "已完成",
- },
- {
- id: "ORD-7818",
- customer: "赵六",
- email: "zhaoliu@example.com",
- amount: "¥ 599",
- status: "已取消",
- },
-];
-
-function statusVariant(status: string) {
- if (status === "已完成") return "default" as const;
- if (status === "处理中") return "secondary" as const;
- return "destructive" as const;
-}
-
-export default function AdminDashboardPage() {
- return (
-
-
-
仪表盘
-
- 欢迎回来,这是你的管理后台概览。
-
-
-
-
- {stats.map((stat) => (
-
-
-
- {stat.title}
-
-
-
- {stat.value}
-
-
-
-
- {stat.trend === "up" ? (
-
- ) : (
-
- )}
- {stat.change}
-
- {stat.desc}
-
-
- ))}
-
-
-
-
-
- 最近订单
- 最近 5 笔订单记录
-
-
-
-
-
-
- {recentOrders.map((order) => (
-
-
-
- {order.customer}
-
-
- {order.email}
-
-
-
-
- {order.status}
-
-
- {order.amount}
-
-
-
- ))}
-
-
-
-
-
-
- 快捷操作
- 常用管理入口
-
-
-
-
-
-
-
-
-
-
- );
+export default function AdminIndexPage() {
+ redirect("/admin/uploads");
}
diff --git a/src/app/(admin)/admin/settings/page.tsx b/src/app/(admin)/admin/settings/page.tsx
deleted file mode 100644
index 7e4b70f..0000000
--- a/src/app/(admin)/admin/settings/page.tsx
+++ /dev/null
@@ -1,86 +0,0 @@
-import {
- Card,
- CardAction,
- CardContent,
- CardDescription,
- CardFooter,
- CardHeader,
- CardTitle,
-} from "@/components/ui/card";
-import { Button } from "@/components/ui/button";
-import { Input } from "@/components/ui/input";
-import { Label } from "@/components/ui/label";
-import { Separator } from "@/components/ui/separator";
-
-export default function SettingsPage() {
- return (
-
-
-
设置
-
- 管理系统偏好与账户信息。
-
-
-
-
-
- 站点信息
- 配置站点名称与基础信息。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 通知设置
- 配置邮件与系统通知偏好。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 危险操作
- 以下操作不可撤销,请谨慎处理。
-
-
-
-
-
-
- );
-}
diff --git a/src/app/(admin)/admin/users/page.tsx b/src/app/(admin)/admin/users/page.tsx
deleted file mode 100644
index 9439421..0000000
--- a/src/app/(admin)/admin/users/page.tsx
+++ /dev/null
@@ -1,163 +0,0 @@
-import { headers } from "next/headers";
-
-import { auth } from "@/lib/auth";
-import {
- Card,
- CardAction,
- CardContent,
- CardDescription,
- CardHeader,
- CardTitle,
-} from "@/components/ui/card";
-import { Button } from "@/components/ui/button";
-import { Input } from "@/components/ui/input";
-import { Badge } from "@/components/ui/badge";
-import {
- Table,
- TableBody,
- TableCell,
- TableHead,
- TableHeader,
- TableRow,
-} from "@/components/ui/table";
-import {
- Avatar,
- AvatarFallback,
- AvatarImage,
-} from "@/components/ui/avatar";
-import { UserActions } from "@/components/user-actions";
-import { Plus, Search, Filter } from "lucide-react";
-
-export default async function UsersPage() {
- const session = await auth.api.getSession({
- headers: await headers(),
- });
-
- const result = await auth.api.listUsers({
- headers: await headers(),
- query: {
- limit: 100,
- },
- });
-
- const users = result?.users ?? [];
- const total = result?.total ?? 0;
-
- return (
-
-
-
用户管理
-
- 管理系统中的用户、角色和权限。
-
-
-
-
-
- 用户列表
- 共 {total} 位用户
-
-
-
-
-
-
-
-
-
-
-
- 用户
- 邮箱
- 角色
- 状态
-
-
-
-
- {users.length === 0 ? (
-
-
- 暂无用户数据
-
-
- ) : (
- users.map((user) => (
-
-
-
-
-
-
- {user.name.charAt(0)}
-
-
-
- {user.name}
- {user.id === session?.user.id && (
-
- (你)
-
- )}
-
-
-
-
- {user.email}
-
-
-
- {user.role === "admin" ? "管理员" : "普通用户"}
-
-
-
- {user.banned ? (
- 已封禁
- ) : (
- 正常
- )}
-
-
-
-
-
- ))
- )}
-
-
-
-
-
-
- );
-}
diff --git a/src/app/(admin)/layout.tsx b/src/app/(admin)/layout.tsx
index ce632ee..988038b 100644
--- a/src/app/(admin)/layout.tsx
+++ b/src/app/(admin)/layout.tsx
@@ -1,11 +1,10 @@
-import { headers } from "next/headers";
-import { redirect } from "next/navigation";
-
-import { auth } from "@/lib/auth";
import { AppSidebar } from "@/components/app-sidebar";
import { SiteHeader } from "@/components/site-header";
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
import { TooltipProvider } from "@/components/ui/tooltip";
+import { auth } from "@/lib/auth";
+import { headers } from "next/headers";
+import { redirect } from "next/navigation";
export default async function AdminLayout({
children,
diff --git a/src/app/(auth)/login/page.tsx b/src/app/(auth)/login/page.tsx
index 6740357..c20cf0e 100644
--- a/src/app/(auth)/login/page.tsx
+++ b/src/app/(auth)/login/page.tsx
@@ -18,7 +18,6 @@ import { authClient } from "@/lib/auth-client";
export default function LoginPage() {
const [email, setEmail] = useState("");
- const [name, setName] = useState("");
const [loading, setLoading] = useState(false);
const [sent, setSent] = useState(false);
const [error, setError] = useState(null);
@@ -30,8 +29,7 @@ export default function LoginPage() {
const { error } = await authClient.signIn.magicLink({
email,
- name: name || undefined,
- callbackURL: "/admin",
+ callbackURL: "/admin/uploads",
});
setLoading(false);
@@ -70,7 +68,6 @@ export default function LoginPage() {
onClick={() => {
setSent(false);
setEmail("");
- setName("");
}}
>
@@ -96,17 +93,6 @@ export default function LoginPage() {