Files
track/frontend/src/pages/ProfilePage.tsx

106 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/** 我的 — 与 uni-app pages/profile/index.vue 完全同步 */
import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useAuth } from "../contexts/AuthContext";
import { useToast } from "../components/ui/Toast";
import { LogOut } from "lucide-react";
export default function ProfilePage() {
const { user, logout } = useAuth();
const { toast } = useToast();
const navigate = useNavigate();
const [showAbout, setShowAbout] = useState(false);
// ---- 从 AuthContext 派生真实数据 ----
const displayName = user?.display_name || user?.username || "未知用户";
const avatarChar = displayName.charAt(0);
function handleLogout() {
logout();
navigate("/admin/login", { replace: true });
}
function handleMenuClick(item: string) {
switch (item) {
case "关于":
setShowAbout(true);
break;
case "帮助与反馈":
toast("反馈通道搭建中,敬请期待...", "info");
break;
// 工作统计、设置 暂不处理
}
}
return (
<div className="flex min-h-full flex-col px-4 pt-safe pb-20">
{/* 用户卡片 */}
<div className="mt-4 flex items-center gap-3 rounded-xl bg-white p-4 shadow-[0_1px_3px_rgba(0,0,0,0.06)]">
<div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-blue-100 text-xl font-bold text-blue-600">
{avatarChar}
</div>
<div className="flex-1">
<span className="block text-base font-bold text-gray-800">
{displayName}
</span>
</div>
<span className="text-xl text-gray-300">›</span>
</div>
{/* 菜单列表 */}
<div className="mt-4 overflow-hidden rounded-xl bg-white shadow-[0_1px_3px_rgba(0,0,0,0.06)]">
{["工作统计", "设置", "帮助与反馈", "关于"].map((item, i) => (
<div
key={item}
onClick={() => handleMenuClick(item)}
className={`flex cursor-pointer items-center justify-between px-4 py-3.5 transition-colors hover:bg-gray-50 ${
i < 3 ? "border-b border-gray-50" : ""
}`}
>
<span className="text-sm text-gray-700">{item}</span>
<span className="text-xl text-gray-300">›</span>
</div>
))}
{/* 退出登录 */}
<button
onClick={handleLogout}
className="flex w-full items-center justify-between border-t border-gray-50 px-4 py-3.5 transition-colors hover:bg-red-50"
>
<span className="flex items-center gap-2 text-sm text-red-500">
<LogOut size={16} strokeWidth={2} />
退出登录
</span>
<span className="text-xl text-red-300">›</span>
</button>
</div>
<p className="mt-8 text-center text-xs text-gray-300">生产流转 T1.0.3</p>
{/* 关于弹窗 */}
{showAbout && (
<div className="fixed inset-0 z-50 flex items-center justify-center">
<div
className="absolute inset-0 bg-black/40"
onClick={() => setShowAbout(false)}
/>
<div className="relative z-10 mx-4 w-full max-w-sm rounded-xl bg-white p-6 shadow-2xl">
<h3 className="mb-4 text-center text-lg font-bold text-gray-800">
关于 Track
</h3>
<div className="mb-6 whitespace-pre-line text-center text-sm leading-relaxed text-gray-600">
Track 生产流转管理系统{"\n"}当前版本:T1.0.3{"\n"}核心架构:FastAPI + React + Tailwind
</div>
<button
onClick={() => setShowAbout(false)}
className="w-full rounded-lg bg-blue-600 py-2.5 text-sm font-medium text-white hover:bg-blue-700"
>
知道了
</button>
</div>
</div>
)}
</div>
);
}