diff --git a/website/src/App.jsx b/website/src/App.jsx
index edd8438..dcb861d 100644
--- a/website/src/App.jsx
+++ b/website/src/App.jsx
@@ -35,6 +35,10 @@ import Tasks from './user/Tasks';
import TaskDetail from './user/TaskDetail';
import Enterprise from './platform/Enterprise';
import ParkCenter from './platform/ParkCenter';
+import MyBookings from './user/MyBookings';
+import MyTasks from './user/MyTasks';
+import MyPark from './user/MyPark';
+import MyCert from './user/MyCert';
/* 公开路由(无需登录) */
const PUBLIC_ROUTES = [
@@ -54,7 +58,11 @@ const PUBLIC_ROUTES = [
{ path: 'task-detail', Page: TaskDetail },
{ path: 'enterprise', Page: Enterprise },
{ path: 'park-center', Page: ParkCenter },
- { path: 'profile', Page: Profile }
+ { path: 'profile', Page: Profile },
+ { path: 'my-bookings', Page: MyBookings },
+ { path: 'my-tasks', Page: MyTasks },
+ { path: 'my-park', Page: MyPark },
+ { path: 'my-cert', Page: MyCert }
];
/* 内部路由(/pine,需登录) */
diff --git a/website/src/components/organisms/index.jsx b/website/src/components/organisms/index.jsx
index b16e06f..a1ae50b 100644
--- a/website/src/components/organisms/index.jsx
+++ b/website/src/components/organisms/index.jsx
@@ -1,24 +1,37 @@
import React from 'react';
import { Logo } from '../atoms';
import { NAV, PINE_NAV } from '../../data/site';
-import { logout, getUser } from '../../services/auth';
+import { logout, getUser, isAuthed } from '../../services/auth';
-/* ---------- 组织:Header(含移动端汉堡 + 菜单) ---------- */
+/* 用户下拉菜单项:个人中心 / 我的报名 / 我的任务 / 我的园区 / 认证中心 */
+const USER_MENU = [
+ ['个人中心', '#/profile'],
+ ['我的报名', '#/my-bookings'],
+ ['我的任务', '#/my-tasks'],
+ ['我的园区', '#/my-park'],
+ ['认证中心', '#/my-cert'],
+];
+
+/* ---------- 组织:Header(含移动端汉堡 + 菜单 + 用户下拉) ---------- */
export function Header({ active }) {
const [open, setOpen] = React.useState(false);
+ const [menuOpen, setMenuOpen] = React.useState(false);
+ const menuRef = React.useRef(null);
const pine = !!active && active.startsWith('pine');
const nav = pine ? PINE_NAV : NAV;
- const user = pine ? null : getUser(); // 公开端显示登录昵称(像素字)
+ const user = pine ? null : getUser(); // 公开端显示登录昵称
React.useEffect(() => {
- const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
+ const onKey = (e) => { if (e.key === 'Escape') { setOpen(false); setMenuOpen(false); } };
const onResize = () => { if (window.innerWidth > 720) setOpen(false); };
+ const onDown = (e) => { if (menuRef.current && !menuRef.current.contains(e.target)) setMenuOpen(false); };
window.addEventListener('keydown', onKey);
window.addEventListener('resize', onResize);
- return () => { window.removeEventListener('keydown', onKey); window.removeEventListener('resize', onResize); };
+ window.addEventListener('mousedown', onDown);
+ return () => { window.removeEventListener('keydown', onKey); window.removeEventListener('resize', onResize); window.removeEventListener('mousedown', onDown); };
}, []);
- const doLogout = () => { setOpen(false); logout(); window.location.hash = '#/'; };
+ const doLogout = () => { setOpen(false); setMenuOpen(false); logout(); window.location.hash = '#/'; };
return (
<>
@@ -33,13 +46,32 @@ export function Header({ active }) {
{pine ? (
+ ) : isAuthed() ? (
+
+
+ {menuOpen && (
+
+ )}
+
) : (
- <>
- {user && user.role === 'service' &&
企业中心}
- {user && user.role === 'carrier' &&
园区管理}
- {user &&
{user.name}}
-
个人中心
- >
+
登录 / 注册
)}