tony.cheng
2026-02-11 6f344a5292739e21d0c8f06c346be44c31c38552
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import React, { useState } from 'react';
import { Spin } from 'antd';
import './App.css';
 
// Context
import { CaseDataProvider, useCaseData } from './contexts/CaseDataContext';
 
// 调解看板组件
import TopSection from './components/dashboard/TopSection';
import MediationProgress from './components/dashboard/MediationProgress';
import TabContainer from './components/dashboard/TabContainer';
import ToolsPanel from './components/dashboard/ToolsPanel';
import FloatingControlPanel from './components/dashboard/FloatingControlPanel';
 
// 弹窗组件
import ToolModal from './components/common/ToolModal';
import OutboundCallWidget from './components/common/OutboundCallWidget';
 
// 工具内容组件
import WageCalculatorContent from './components/tools/WageCalculatorContent';
import LawSearchContent from './components/tools/LawSearchContent';
import CaseSearchContent from './components/tools/CaseSearchContent';
import SimilarCaseContent from './components/tools/SimilarCaseContent';
 
function App() {
  return (
    <CaseDataProvider>
      <AppContent />
    </CaseDataProvider>
  );
}
 
function AppContent() {
  const [activeModal, setActiveModal] = useState(null);
  const { loading } = useCaseData();
 
  // 工具配置
  const toolConfig = {
    'wage-calculator': {
      title: '欠薪计算器',
      icon: 'fas fa-calculator',
      component: WageCalculatorContent,
    },
    'law-search': {
      title: '法律条文查询',
      icon: 'fas fa-gavel',
      component: LawSearchContent,
    },
    'case-search': {
      title: '典型案例查询',
      icon: 'fas fa-search',
      component: CaseSearchContent,
    },
    'similar-case': {
      title: '类案与法条推荐',
      icon: 'fas fa-balance-scale',
      component: SimilarCaseContent,
    },
  };
 
  const handleToolClick = (toolKey) => {
    setActiveModal(toolKey);
  };
 
  const handleCloseModal = () => {
    setActiveModal(null);
  };
 
  const renderModalContent = () => {
    if (!activeModal || !toolConfig[activeModal]) return null;
    const Component = toolConfig[activeModal].component;
    return <Component />;
  };
 
  return (
    <Spin spinning={loading} tip="加载案件数据中...">
      <div className="app">
        {/* Font Awesome CDN */}
        <link
          rel="stylesheet"
          href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
        />
 
        {/* 顶部区域 */}
        <TopSection />
 
        {/* 中间区域 */}
        <section className="middle-section">
          {/* A区域:左侧主要内容 */}
          <div className="area-a">
            {/* AI调解进度 */}
            <MediationProgress />
 
            {/* 选项卡容器 */}
            <TabContainer />
          </div>
 
          {/* B区域:右侧工具栏 */}
          <ToolsPanel onToolClick={handleToolClick} />
        </section>
 
        {/* 底部悬浮控制看板 */}
        <FloatingControlPanel />
 
        {/* 工具弹窗 */}
        {activeModal && toolConfig[activeModal] && (
          <ToolModal
            visible={true}
            title={toolConfig[activeModal].title}
            icon={toolConfig[activeModal].icon}
            onClose={handleCloseModal}
          >
            {renderModalContent()}
          </ToolModal>
        )}
 
        {/* 智能外呼通话显示组件 - 默认隐藏,可主动触发显示 */}
        <OutboundCallWidget />
      </div>
    </Spin>
  );
}
 
export default App;