/**
* # 路由 /my-account 账户页(Tailwind + shadcn/ui 实现)
* 未登录:登录 / 注册两个 Tab 表单;已登录:资料卡 + 订单列表 + 退出登录。
*/
import { createFileRoute, Link, useRouter } from "@tanstack/react-router";
import { useState } from "react";
import { getCurrentUser, loginFn, registerFn, logoutFn } from "~/server/auth";
import { useT } from "~/i18n";
import { getMyOrders } from "~/server/commerce";
import { getLayoutData, Layout } from "~/components/website/Layout";
import { Badge } from "~/components/ui/badge";
import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input";
import { Label } from "~/components/ui/label";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
export const Route = createFileRoute("/my-account")({
loader: async () => {
const user = await getCurrentUser();
const [layout, orders] = await Promise.all([getLayoutData(), user ? getMyOrders() : Promise.resolve([])]);
return { layout, user, orders };
},
head: () => ({ meta: [{ title: "My Account - DusunIoT" }] }),
component: MyAccountPage,
});
/** # 函数 组件 账户页面(外壳:公共布局) */
function MyAccountPage() {
const { layout } = Route.useLoaderData();
return (
);
}
/** # 函数 组件 账户内容区 */
function AccountInner() {
const t = useT();
const { user, orders } = Route.useLoaderData();
const router = useRouter();
/** # 函数 退出登录 */
async function handleLogout() {
await logoutFn();
router.invalidate();
}
if (!user) {
return (
My Account
{t("acct_login")}
{t("acct_register")}
router.invalidate()} />
router.invalidate()} />
);
}
return (
My Account
Profile
{user.displayName || user.email} ({user.email}) — role: {user.role}
{t("acct_recent_orders")}
{orders.length === 0 ? (
{t("acct_no_orders")}
) : (
{(["acct_th_order", "acct_th_date", "acct_th_items", "acct_th_total", "acct_th_status", "acct_th_payment"] as const).map((k) => (
|
{t(k)}
|
))}
{orders.map((o) => (
|
{o.orderNumber}
|
{o.createdAt ? new Date(o.createdAt).toLocaleDateString("en-US") : "-"} |
{Number(o.itemCount)} |
${Number(o.total).toFixed(2)} |
{o.status}
|
{o.paymentStatus}
|
))}
)}
);
}
/** # 组件 登录表单 */
function LoginForm({ onDone }: { onDone: () => void }) {
const t = useT();
const [authError, setAuthError] = useState("");
/** # 函数 登录提交 */
async function handleLogin(e: React.FormEvent) {
e.preventDefault();
setAuthError("");
const fd = new FormData(e.currentTarget);
const res = await loginFn({ data: { email: String(fd.get("email") ?? ""), password: String(fd.get("password") ?? "") } });
if (!res.ok) return setAuthError(res.error);
onDone();
}
return (
);
}
/** # 组件 注册表单 */
function RegisterForm({ onDone }: { onDone: () => void }) {
const [authError, setAuthError] = useState("");
/** # 函数 注册提交 */
async function handleRegister(e: React.FormEvent) {
e.preventDefault();
setAuthError("");
const fd = new FormData(e.currentTarget);
const res = await registerFn({
data: {
email: String(fd.get("email") ?? ""),
password: String(fd.get("password") ?? ""),
displayName: String(fd.get("displayName") ?? "") || undefined,
},
});
if (!res.ok) return setAuthError(res.error);
onDone();
}
return (
);
}