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

106 lines
3.8 KiB
TypeScript
Raw Normal View History

/** 我的 — 与 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>
);
}