feat: improve channel resilience and operations

This commit is contained in:
hectorzhao
2026-07-24 08:17:33 +08:00
parent 2f781ebb8a
commit afd3c96070
43 changed files with 1969 additions and 299 deletions
+19 -3
View File
@@ -12,7 +12,7 @@ import {
PanelLeftOpen,
X,
} from 'lucide-react';
import { NavLink, Outlet, useLocation, useNavigate } from 'react-router-dom';
import { Link, NavLink, Outlet, useLocation, useNavigate } from 'react-router-dom';
import { portalSessionApi } from '@/api/adminApi';
import {
clearSession,
@@ -337,13 +337,20 @@ export function AppShell({
const Icon = item.icon;
return (
<NavLink key={item.to} onClick={() => setMobileNavOpen(false)} to={item.to} end title={item.pending ? `${item.label}(待开发)` : item.label}>
<Link
aria-current={isShellNavItemActive(location.pathname, item.to) ? 'page' : undefined}
className={isShellNavItemActive(location.pathname, item.to) ? 'active' : undefined}
key={item.to}
onClick={() => setMobileNavOpen(false)}
to={item.to}
title={item.pending ? `${item.label}(待开发)` : item.label}
>
<Icon size={17} strokeWidth={2.1} />
<span className="side-nav-label">
<span className="side-nav-label-text">{item.label}</span>
{item.pending ? <span className="dev-status-badge side-nav-pending-badge"></span> : null}
</span>
</NavLink>
</Link>
);
})}
</div>
@@ -498,6 +505,15 @@ export function AppShell({
);
}
function isShellNavItemActive(pathname: string, itemPath: string) {
if (pathname === itemPath) return true;
if (itemPath === '/admin' || itemPath === '/client') return false;
if (pathname.startsWith(`${itemPath}/`)) return true;
if (itemPath === '/admin/enterprise-applications' && /^\/admin\/customers\/[^/]+\/sms-apps\//.test(pathname)) return true;
if (itemPath === '/admin/customer-enterprises' && /^\/admin\/customers\/[^/]+\/edit$/.test(pathname)) return true;
return false;
}
function formatCountdown(seconds: number) {
const minutes = Math.floor(seconds / 60);
return `${String(minutes).padStart(2, '0')}:${String(seconds % 60).padStart(2, '0')}`;