feat(ssa): Complete V11 UI development and frontend-backend integration - Pixel-perfect V11 UI, multi-task support, Word export, input overlay fix, code cleanup. MVP Phase 1 core 95% complete.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-02-20 14:46:45 +08:00
parent 49b5c37cb1
commit 8d496d1515
38 changed files with 7255 additions and 1074 deletions

View File

@@ -0,0 +1,137 @@
/**
* SSASidebar - V11 左侧抽屉栏
*
* 100% 还原 V11 原型图
* - 汉堡菜单切换展开/收起
* - Logo + 新建按钮
* - 历史记录列表(展开时显示)
*/
import React, { useState, useEffect } from 'react';
import {
Menu,
BarChart3,
Plus,
MessageSquare
} from 'lucide-react';
import { useSSAStore } from '../stores/ssaStore';
import apiClient from '@/common/api/axios';
import type { SSASession } from '../types';
interface HistoryItem {
id: string;
title: string;
status: 'active' | 'completed' | 'archived';
}
export const SSASidebar: React.FC = () => {
const {
sidebarExpanded,
setSidebarExpanded,
currentSession,
hydrateFromHistory,
reset
} = useSSAStore();
const [historyItems, setHistoryItems] = useState<HistoryItem[]>([]);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
if (sidebarExpanded) {
fetchHistory();
}
}, [sidebarExpanded]);
const fetchHistory = async () => {
setIsLoading(true);
try {
const response = await apiClient.get('/api/v1/ssa/sessions');
setHistoryItems(response.data.sessions || []);
} catch (error) {
console.error('Failed to fetch history:', error);
setHistoryItems([]);
} finally {
setIsLoading(false);
}
};
const handleToggleSidebar = () => {
setSidebarExpanded(!sidebarExpanded);
};
const handleNewAnalysis = () => {
reset();
};
const handleSelectSession = async (sessionId: string) => {
if (sessionId === currentSession?.id) return;
try {
const response = await apiClient.get(`/api/v1/ssa/sessions/${sessionId}`);
const session: SSASession = response.data;
hydrateFromHistory(session);
} catch (error) {
console.error('Failed to load session:', error);
}
};
return (
<aside className={`ssa-sidebar ${sidebarExpanded ? 'expanded' : ''}`}>
{/* 顶部:汉堡菜单与 Logo */}
<div className="sidebar-header">
<button
className="sidebar-toggle-btn"
onClick={handleToggleSidebar}
>
<Menu size={18} />
</button>
{sidebarExpanded && (
<div className="sidebar-logo fade-in">
<div className="logo-icon">
<BarChart3 size={14} />
</div>
<span className="logo-text">SSA-Pro</span>
</div>
)}
</div>
{/* 核心操作区 */}
<div className="sidebar-actions">
{/* 新建按钮 */}
<button
className={`sidebar-new-btn ${sidebarExpanded ? 'expanded' : ''}`}
onClick={handleNewAnalysis}
>
<Plus size={16} className="new-btn-icon" />
{sidebarExpanded && <span className="new-btn-text"></span>}
</button>
</div>
{/* 历史记录列表 (展开时显示) */}
{sidebarExpanded && (
<div className="sidebar-history fade-in">
<div className="history-label"></div>
<div className="history-list">
{isLoading ? (
<div className="history-loading">...</div>
) : historyItems.length === 0 ? (
<div className="history-empty"></div>
) : (
historyItems.map((item) => (
<button
key={item.id}
className={`history-item ${item.id === currentSession?.id ? 'active' : ''}`}
onClick={() => handleSelectSession(item.id)}
>
<MessageSquare size={14} className="history-item-icon" />
<span className="history-item-title">{item.title}</span>
</button>
))
)}
</div>
</div>
)}
</aside>
);
};
export default SSASidebar;