refactor: 重构项目主页布局样式,采用侧边栏风格

This commit is contained in:
xiamuceer-j
2026-01-14 14:33:00 +08:00
parent e412e809eb
commit aeb78fddd2
3 changed files with 928 additions and 1065 deletions
+5 -30
View File
@@ -1,5 +1,4 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { import {
Card, Card,
Button, Button,
@@ -27,7 +26,6 @@ import {
ThunderboltOutlined, ThunderboltOutlined,
InfoCircleOutlined, InfoCircleOutlined,
ToolOutlined, ToolOutlined,
ArrowLeftOutlined,
ApiOutlined, ApiOutlined,
QuestionCircleOutlined, QuestionCircleOutlined,
WarningOutlined, WarningOutlined,
@@ -39,7 +37,6 @@ const { Paragraph, Text, Title } = Typography;
const { TextArea } = Input; const { TextArea } = Input;
export default function MCPPluginsPage() { export default function MCPPluginsPage() {
const navigate = useNavigate();
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const [form] = Form.useForm(); const [form] = Form.useForm();
const [modal, contextHolder] = Modal.useModal(); const [modal, contextHolder] = Modal.useModal();
@@ -592,11 +589,12 @@ export default function MCPPluginsPage() {
<> <>
{contextHolder} {contextHolder}
<div style={{ <div style={{
minHeight: '100vh', minHeight: '90vh',
background: 'linear-gradient(180deg, var(--color-bg-base) 0%, #EEF2F3 100%)', background: 'linear-gradient(180deg, var(--color-bg-base) 0%, #EEF2F3 100%)',
padding: isMobile ? '20px 16px' : '40px 24px', padding: isMobile ? '20px 16px' : '24px 24px',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
marginBottom: '55px',
}}> }}>
<div style={{ <div style={{
maxWidth: 1400, maxWidth: 1400,
@@ -640,29 +638,6 @@ export default function MCPPluginsPage() {
</Col> </Col>
<Col xs={24} sm={12}> <Col xs={24} sm={12}>
<Space size={12} style={{ display: 'flex', justifyContent: isMobile ? 'flex-start' : 'flex-end', width: '100%' }}> <Space size={12} style={{ display: 'flex', justifyContent: isMobile ? 'flex-start' : 'flex-end', width: '100%' }}>
<Button
icon={<ArrowLeftOutlined />}
onClick={() => navigate('/')}
style={{
borderRadius: 12,
background: 'rgba(255, 255, 255, 0.15)',
border: '1px solid rgba(255, 255, 255, 0.3)',
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
color: '#fff',
backdropFilter: 'blur(10px)',
transition: 'all 0.3s ease'
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'rgba(255, 255, 255, 0.25)';
e.currentTarget.style.transform = 'translateY(-1px)';
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'rgba(255, 255, 255, 0.15)';
e.currentTarget.style.transform = 'none';
}}
>
</Button>
<Button <Button
type="primary" type="primary"
icon={<PlusOutlined />} icon={<PlusOutlined />}
@@ -693,7 +668,7 @@ export default function MCPPluginsPage() {
backdropFilter: 'blur(10px)', backdropFilter: 'blur(10px)',
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.03)' boxShadow: '0 4px 12px rgba(0, 0, 0, 0.03)'
}} }}
bodyStyle={{ padding: 20 }} styles={{ body: { padding: 20 } }}
> >
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<Space align="start"> <Space align="start">
@@ -744,7 +719,7 @@ export default function MCPPluginsPage() {
backdropFilter: 'blur(10px)', backdropFilter: 'blur(10px)',
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.03)' boxShadow: '0 4px 12px rgba(0, 0, 0, 0.03)'
}} }}
bodyStyle={{ padding: 20 }} styles={{ body: { padding: 20 } }}
> >
<Space align="start"> <Space align="start">
<InfoCircleOutlined style={{ fontSize: 20, color: 'var(--color-primary)', marginTop: 4 }} /> <InfoCircleOutlined style={{ fontSize: 20, color: 'var(--color-primary)', marginTop: 4 }} />
File diff suppressed because it is too large Load Diff
+22 -41
View File
@@ -1,5 +1,4 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { import {
Card, Card,
Tabs, Tabs,
@@ -25,7 +24,6 @@ import {
UploadOutlined, UploadOutlined,
CheckCircleOutlined, CheckCircleOutlined,
FileSearchOutlined, FileSearchOutlined,
ArrowLeftOutlined,
InfoCircleOutlined InfoCircleOutlined
} from '@ant-design/icons'; } from '@ant-design/icons';
import axios from 'axios'; import axios from 'axios';
@@ -56,7 +54,6 @@ interface CategoryGroup {
} }
export default function PromptTemplates() { export default function PromptTemplates() {
const navigate = useNavigate();
const [modal, contextHolder] = Modal.useModal(); const [modal, contextHolder] = Modal.useModal();
const [categories, setCategories] = useState<CategoryGroup[]>([]); const [categories, setCategories] = useState<CategoryGroup[]>([]);
const [selectedCategory, setSelectedCategory] = useState<string>('0'); const [selectedCategory, setSelectedCategory] = useState<string>('0');
@@ -72,8 +69,9 @@ export default function PromptTemplates() {
setLoading(true); setLoading(true);
const response = await axios.get<CategoryGroup[]>('/api/prompt-templates/categories'); const response = await axios.get<CategoryGroup[]>('/api/prompt-templates/categories');
setCategories(response.data); setCategories(response.data);
} catch (error: any) { } catch (error: unknown) {
message.error(error.response?.data?.detail || '加载失败'); const err = error as { response?: { data?: { detail?: string } } };
message.error(err.response?.data?.detail || '加载失败');
} finally { } finally {
setLoading(false); setLoading(false);
} }
@@ -116,8 +114,9 @@ export default function PromptTemplates() {
message.success('保存成功'); message.success('保存成功');
setEditorVisible(false); setEditorVisible(false);
loadTemplates(); loadTemplates();
} catch (error: any) { } catch (error: unknown) {
message.error(error.response?.data?.detail || '保存失败'); const err = error as { response?: { data?: { detail?: string } } };
message.error(err.response?.data?.detail || '保存失败');
} finally { } finally {
setLoading(false); setLoading(false);
} }
@@ -137,8 +136,9 @@ export default function PromptTemplates() {
await axios.post(`/api/prompt-templates/${templateKey}/reset`); await axios.post(`/api/prompt-templates/${templateKey}/reset`);
message.success('已重置为系统默认'); message.success('已重置为系统默认');
loadTemplates(); loadTemplates();
} catch (error: any) { } catch (error: unknown) {
message.error(error.response?.data?.detail || '重置失败'); const err = error as { response?: { data?: { detail?: string } } };
message.error(err.response?.data?.detail || '重置失败');
} finally { } finally {
setLoading(false); setLoading(false);
} }
@@ -153,8 +153,9 @@ export default function PromptTemplates() {
is_active: checked is_active: checked
}); });
loadTemplates(); loadTemplates();
} catch (error: any) { } catch (error: unknown) {
message.error(error.response?.data?.detail || '操作失败'); const err = error as { response?: { data?: { detail?: string } } };
message.error(err.response?.data?.detail || '操作失败');
} }
}; };
@@ -180,8 +181,9 @@ export default function PromptTemplates() {
} else { } else {
message.success('导出成功'); message.success('导出成功');
} }
} catch (error: any) { } catch (error: unknown) {
message.error(error.response?.data?.detail || '导出失败'); const err = error as { response?: { data?: { detail?: string } } };
message.error(err.response?.data?.detail || '导出失败');
} }
}; };
@@ -219,7 +221,7 @@ export default function PromptTemplates() {
<div> <div>
<p style={{ fontWeight: 'bold', marginBottom: 8 }}></p> <p style={{ fontWeight: 'bold', marginBottom: 8 }}></p>
<ul style={{ marginLeft: 20 }}> <ul style={{ marginLeft: 20 }}>
{result.converted_templates.map((t: any) => ( {result.converted_templates.map((t: { template_key: string; template_name: string }) => (
<li key={t.template_key}> <li key={t.template_key}>
{t.template_name} ({t.template_key}) {t.template_name} ({t.template_key})
</li> </li>
@@ -236,8 +238,9 @@ export default function PromptTemplates() {
} }
loadTemplates(); loadTemplates();
} catch (error: any) { } catch (error: unknown) {
message.error(error.response?.data?.detail || '导入失败'); const err = error as { response?: { data?: { detail?: string } } };
message.error(err.response?.data?.detail || '导入失败');
} }
return false; // 阻止默认上传行为 return false; // 阻止默认上传行为
}; };
@@ -248,11 +251,12 @@ export default function PromptTemplates() {
<> <>
{contextHolder} {contextHolder}
<div style={{ <div style={{
minHeight: '100vh', minHeight: '90vh',
background: 'linear-gradient(180deg, var(--color-bg-base) 0%, #EEF2F3 100%)', background: 'linear-gradient(180deg, var(--color-bg-base) 0%, #EEF2F3 100%)',
padding: isMobile ? '20px 16px' : '40px 24px', padding: isMobile ? '20px 16px' : '24px 24px',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
marginBottom: '55px',
}}> }}>
<div style={{ <div style={{
maxWidth: 1400, maxWidth: 1400,
@@ -294,29 +298,6 @@ export default function PromptTemplates() {
</Col> </Col>
<Col xs={24} sm={12} md={10}> <Col xs={24} sm={12} md={10}>
<Space wrap style={{ justifyContent: isMobile ? 'flex-start' : 'flex-end', width: '100%' }}> <Space wrap style={{ justifyContent: isMobile ? 'flex-start' : 'flex-end', width: '100%' }}>
<Button
icon={<ArrowLeftOutlined />}
onClick={() => navigate('/projects')}
style={{
borderRadius: 12,
background: 'rgba(255, 255, 255, 0.15)',
border: '1px solid rgba(255, 255, 255, 0.3)',
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
color: '#fff',
backdropFilter: 'blur(10px)',
transition: 'all 0.3s ease'
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'rgba(255, 255, 255, 0.25)';
e.currentTarget.style.transform = 'translateY(-1px)';
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'rgba(255, 255, 255, 0.15)';
e.currentTarget.style.transform = 'none';
}}
>
</Button>
<Button <Button
icon={<DownloadOutlined />} icon={<DownloadOutlined />}
onClick={handleExport} onClick={handleExport}