App.tsx 5.02 KB
import { useCallback, useEffect, useState } from 'react';
import { Toaster } from 'sonner';
import { Layout } from './components/layout/Layout';
import { Dashboard } from './components/dashboard/Dashboard';
import { PlaceholderView } from './components/PlaceholderView';

import { LabelsView } from './components/labels/LabelsView';
import { TrainingView } from './components/training/TrainingView';
import { AlertsView } from './components/alerts/AlertsView';
import { ProductsView } from './components/products/ProductsView';
import { PeopleView } from './components/people/PeopleView';
import { ReportsView } from './components/reports/ReportsView';
import { SystemMenuView } from './components/system-menu/SystemMenuView';
import { SupportView } from './components/support/SupportView';
import { AuthProvider, useAuth } from './components/auth/AuthProvider';
import { LoginView } from './components/auth/LoginView';

const LABEL_MODULE_VIEWS = new Set([
  'Labels',
  'Label Categories',
  'Label Types',
  'Label Templates',
  'Multiple Options',
]);

function AuthedApp() {
  const auth = useAuth();
  const [currentView, setCurrentView] = useState('Dashboard');
  /** 侧栏点「Location Manager」时打开 Account Management 并切到门店 Tab */
  const [pendingPeopleSubTab, setPendingPeopleSubTab] = useState<'Location Manager' | null>(null);
  /** Dashboard「New Label」:递增后由 LabelsList 消费以打开新增弹窗 */
  const [labelCreateOpenSeq, setLabelCreateOpenSeq] = useState(0);
  /** Dashboard「View Reports」:与 reportsTargetTab 配合,仅在意图跳转时递增 */
  const [reportsOpenKey, setReportsOpenKey] = useState(0);
  const [reportsTargetTab, setReportsTargetTab] = useState<'print-log' | 'label-report'>('print-log');

  const resolveView = (name: string) => {
    const s = (name ?? "").trim();
    if (!s) return "Dashboard";
    // 后端菜单可能会返回更偏“模块名”的英文,这里做一次别名兼容
    if (s === "System Management") return "System Menu";
    if (s === "Location Management") return "Location Manager";
    if (s === "Account Manager") return "Account Management";
    return s;
  };

  const resolvedView = resolveView(currentView);

  const navigateToView = useCallback((view: string) => {
    const v = resolveView(view);
    if (v === 'Location Manager') {
      setPendingPeopleSubTab('Location Manager');
      setCurrentView('Account Management');
      return;
    }
    setCurrentView(v);
  }, []);

  const consumeLabelCreateIntent = useCallback(() => {
    setLabelCreateOpenSeq(0);
  }, []);

  useEffect(() => {
    if (!LABEL_MODULE_VIEWS.has(resolvedView)) {
      setLabelCreateOpenSeq(0);
    }
    if (resolvedView !== 'Reports') {
      setReportsOpenKey(0);
    }
  }, [resolvedView]);

  if (!auth.token) {
    return <LoginView />;
  }

  const renderView = () => {
    const view = resolvedView;
    switch (view) {
      case 'Dashboard':
        return (
          <Dashboard
            onNewLabel={() => {
              setLabelCreateOpenSeq((n) => n + 1);
              setCurrentView('Labels');
            }}
            onViewReports={() => {
              setReportsTargetTab('label-report');
              setReportsOpenKey((k) => k + 1);
              setCurrentView('Reports');
            }}
            onViewAllRecentLabels={() => {
              setReportsTargetTab('print-log');
              setReportsOpenKey((k) => k + 1);
              setCurrentView('Reports');
            }}
          />
        );
      case 'Training':
        return <TrainingView />;
      case 'Alerts':
        return <AlertsView />;
      case 'Menu Management':
        // 还原:Menu Management 对应“商品管理/新增”页面
        return <ProductsView />;
      case 'System Menu':
        return <SystemMenuView />;
      case 'Account Management':
        return (
          <PeopleView
            initialSubTab={pendingPeopleSubTab}
            onInitialSubTabConsumed={() => setPendingPeopleSubTab(null)}
          />
        );
      case 'Reports':
        return (
          <ReportsView layoutReportsOpenKey={reportsOpenKey} layoutReportsTargetTab={reportsTargetTab} />
        );
      case 'Support':
        return <SupportView />;
      case 'Labels':
      case 'Label Categories':
      case 'Label Types':
      case 'Label Templates':
      case 'Multiple Options':
        return (
          <LabelsView
            currentView={view}
            onViewChange={setCurrentView}
            labelCreateOpenSeq={labelCreateOpenSeq}
            onLabelCreateIntentConsumed={consumeLabelCreateIntent}
          />
        );
      default:
        return <PlaceholderView title={view} />;
    }
  };

  return (
    <>
      <Layout currentView={resolvedView} setCurrentView={navigateToView} menus={auth.menus} onLogout={auth.logout}>
        {renderView()}
      </Layout>
    </>
  );
}

export default function App() {
  return (
    <>
      <AuthProvider>
        <AuthedApp />
      </AuthProvider>
      <Toaster position="top-center" richColors closeButton expand={false} />
    </>
  );
}