feat: complete login and user management flow
This commit is contained in:
@@ -24,15 +24,23 @@ import {
|
||||
Users,
|
||||
UserX,
|
||||
} from 'lucide-react';
|
||||
import { Navigate } from 'react-router-dom';
|
||||
import { readSession } from '@/api/session';
|
||||
import { AppShell } from '@/layouts/AppShell';
|
||||
|
||||
export function AdminLayout() {
|
||||
const session = readSession();
|
||||
if (session?.portal !== 'admin') {
|
||||
return <Navigate to="/admin/login" replace />;
|
||||
}
|
||||
|
||||
return (
|
||||
<AppShell
|
||||
title="CMPP 运营端"
|
||||
subtitle="平台运营管理中心"
|
||||
workspaceName="平台运营工作区"
|
||||
userName="运营"
|
||||
loginPath="/admin/login"
|
||||
userName={session.user.displayName}
|
||||
userRole="平台管理员"
|
||||
auditNotifications={[
|
||||
{ label: '企业认证审核', count: 3, to: '/admin/enterprise-audit' },
|
||||
|
||||
@@ -12,7 +12,8 @@ import {
|
||||
Search,
|
||||
Sparkles,
|
||||
} from 'lucide-react';
|
||||
import { NavLink, Outlet } from 'react-router-dom';
|
||||
import { NavLink, Outlet, useNavigate } from 'react-router-dom';
|
||||
import { clearSession } from '@/api/session';
|
||||
|
||||
export type ShellNavItem = {
|
||||
label: string;
|
||||
@@ -37,6 +38,7 @@ type AppShellProps = {
|
||||
title: string;
|
||||
subtitle: string;
|
||||
workspaceName: string;
|
||||
loginPath: string;
|
||||
userName: string;
|
||||
userRole: string;
|
||||
navSections: ShellNavSection[];
|
||||
@@ -47,6 +49,7 @@ export function AppShell({
|
||||
title,
|
||||
subtitle,
|
||||
workspaceName,
|
||||
loginPath,
|
||||
userName,
|
||||
userRole,
|
||||
navSections,
|
||||
@@ -56,6 +59,7 @@ export function AppShell({
|
||||
const [closedSections, setClosedSections] = useState<Record<string, boolean>>({});
|
||||
const [userMenuOpen, setUserMenuOpen] = useState(false);
|
||||
const [noticeOpen, setNoticeOpen] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
const ToggleIcon = collapsed ? PanelLeftOpen : PanelLeftClose;
|
||||
const auditTotal = useMemo(
|
||||
() => auditNotifications.reduce((sum, item) => sum + item.count, 0),
|
||||
@@ -205,7 +209,11 @@ export function AppShell({
|
||||
<KeyRound size={16} />
|
||||
修改密码
|
||||
</button>
|
||||
<button onClick={() => setUserMenuOpen(false)} role="menuitem" type="button">
|
||||
<button onClick={() => {
|
||||
clearSession();
|
||||
setUserMenuOpen(false);
|
||||
navigate(loginPath, { replace: true });
|
||||
}} role="menuitem" type="button">
|
||||
<LogOut size={16} />
|
||||
退出登录
|
||||
</button>
|
||||
|
||||
@@ -10,15 +10,23 @@ import {
|
||||
ShieldCheck,
|
||||
Users,
|
||||
} from 'lucide-react';
|
||||
import { Navigate } from 'react-router-dom';
|
||||
import { readSession } from '@/api/session';
|
||||
import { AppShell } from '@/layouts/AppShell';
|
||||
|
||||
export function ClientLayout() {
|
||||
const session = readSession();
|
||||
if (session?.portal !== 'client') {
|
||||
return <Navigate to="/client/login" replace />;
|
||||
}
|
||||
|
||||
return (
|
||||
<AppShell
|
||||
title="CMPP 客户端"
|
||||
subtitle="短信服务控制台"
|
||||
workspaceName="华东一区客户空间"
|
||||
userName="赵先生"
|
||||
workspaceName={session.user.tenantName ?? '企业客户空间'}
|
||||
loginPath="/client/login"
|
||||
userName={session.user.displayName}
|
||||
userRole="企业管理员"
|
||||
navSections={[
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user