e.stopPropagation()}>
+
e.stopPropagation()} style={width ? { width } : undefined}>
{title}
@@ -15,10 +25,12 @@ function Modal({ visible, title, children, onConfirm, onCancel, confirmText = '
{children}
-
-
-
-
+ {showConfirm && (
+
+
+
+
+ )}
);
diff --git a/src/components/layout/AppHeader.jsx b/src/components/layout/AppHeader.jsx
new file mode 100644
index 0000000..fe1843c
--- /dev/null
+++ b/src/components/layout/AppHeader.jsx
@@ -0,0 +1,114 @@
+import { useState, useEffect, useRef } from 'react';
+import { useLocation, useNavigate, Link } from 'react-router-dom';
+import { FiSettings, FiCode, FiUsers, FiMenu, FiX } from 'react-icons/fi';
+import Modal from '../common/Modal.jsx';
+import UserDropdown from './UserDropdown.jsx';
+
+const PLATFORMS = [
+ { id: 'console', name: '工作台', path: '/console', icon: FiSettings },
+ { id: 'developer', name: '开发台', path: '/developer', icon: FiCode },
+ { id: 'admin', name: '管理台', path: '/admin', icon: FiUsers },
+];
+
+function AppHeader() {
+ const location = useLocation();
+ const navigate = useNavigate();
+ const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
+ const [confirmModal, setConfirmModal] = useState({ visible: false, platform: null });
+ const mobileMenuRef = useRef(null);
+
+ const currentPlatform = PLATFORMS.find(p => location.pathname.startsWith(p.path))?.id || null;
+
+ useEffect(() => {
+ function handleClickOutside(event) {
+ if (mobileMenuRef.current && !mobileMenuRef.current.contains(event.target)) {
+ setMobileMenuOpen(false);
+ }
+ }
+ document.addEventListener('mousedown', handleClickOutside);
+ return () => document.removeEventListener('mousedown', handleClickOutside);
+ }, []);
+
+ const handlePlatformClick = (platform) => {
+ if (platform.id === currentPlatform) return;
+ setConfirmModal({ visible: true, platform });
+ setMobileMenuOpen(false);
+ };
+
+ const handleConfirmSwitch = () => {
+ if (confirmModal.platform) {
+ navigate(confirmModal.platform.path);
+ }
+ setConfirmModal({ visible: false, platform: null });
+ };
+
+ return (
+
+ );
+}
+
+export default AppHeader;
diff --git a/src/components/layout/AppLayout.jsx b/src/components/layout/AppLayout.jsx
new file mode 100644
index 0000000..9ae1da7
--- /dev/null
+++ b/src/components/layout/AppLayout.jsx
@@ -0,0 +1,15 @@
+import { Outlet } from 'react-router-dom';
+import AppHeader from './AppHeader.jsx';
+
+function AppLayout() {
+ return (
+
+ );
+}
+
+export default AppLayout;
diff --git a/src/components/layout/SidebarBrand.jsx b/src/components/layout/SidebarBrand.jsx
deleted file mode 100644
index 7afba79..0000000
--- a/src/components/layout/SidebarBrand.jsx
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * SidebarBrand - 侧边栏品牌区域组件
- * 统一显示 GrandClaw 品牌标识和副标题
- *
- * @param {Object} props - 组件属性
- * @param {string} [props.subtitle] - 副标题文本(如"企业级AI平台"、"运营管理台"、"技能开发台")
- */
-function SidebarBrand({ subtitle = '企业级AI平台' }) {
- return (
-
-
-
-
-
-
-
GrandClaw
-
{subtitle}
-
-
- );
-}
-
-export default SidebarBrand;
diff --git a/src/components/layout/SidebarUser.jsx b/src/components/layout/SidebarUser.jsx
deleted file mode 100644
index 0b4a95a..0000000
--- a/src/components/layout/SidebarUser.jsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import { useUserContext } from '../../contexts/UserContext.jsx';
-
-/**
- * SidebarUser - 侧边栏用户信息组件
- * 从 UserContext 获取用户信息并显示
- *
- * @param {Object} props - 组件属性
- * @param {Function} [props.onClick] - 点击回调函数
- * @param {string} [props.wrapperClassName] - 包装器类名(如"chat-sidebar-user"、"admin-sidebar-user")
- * @param {string} [props.infoClassName] - 信息容器类名(如"chat-sidebar-user-info"、"admin-sidebar-user-info")
- * @param {string} [props.nameClassName] - 姓名容器类名(如"chat-sidebar-user-name"、"admin-sidebar-user-name")
- * @param {string} [props.roleClassName] - 角色容器类名(如"chat-sidebar-user-role"、"admin-sidebar-user-role")
- */
-function SidebarUser({
- onClick,
- wrapperClassName = 'chat-sidebar-user',
- infoClassName = 'chat-sidebar-user-info',
- nameClassName = 'chat-sidebar-user-name',
- roleClassName = 'chat-sidebar-user-role',
-}) {
- const { user } = useUserContext();
-
- return (
-
-
{user.avatar}
-
-
{user.name}
-
{user.role}
-
-
- );
-}
-
-export default SidebarUser;
diff --git a/src/components/layout/UserDropdown.jsx b/src/components/layout/UserDropdown.jsx
new file mode 100644
index 0000000..94f2c38
--- /dev/null
+++ b/src/components/layout/UserDropdown.jsx
@@ -0,0 +1,222 @@
+import { useState, useRef, useEffect } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { FiChevronDown, FiUser, FiLogOut } from 'react-icons/fi';
+import { useUserContext } from '../../contexts/UserContext.jsx';
+import Modal from '../common/Modal.jsx';
+import Toast from '../common/Toast.jsx';
+
+function UserDropdown() {
+ const navigate = useNavigate();
+ const { user } = useUserContext();
+ const [isOpen, setIsOpen] = useState(false);
+ const [showAccountModal, setShowAccountModal] = useState(false);
+ const [profileToast, setProfileToast] = useState(null);
+ const [passwordErrors, setPasswordErrors] = useState({});
+ const [passwordForm, setPasswordForm] = useState({
+ currentPassword: '',
+ newPassword: '',
+ confirmPassword: '',
+ });
+ const dropdownRef = useRef(null);
+
+ useEffect(() => {
+ function handleClickOutside(event) {
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
+ setIsOpen(false);
+ }
+ }
+ document.addEventListener('mousedown', handleClickOutside);
+ return () => document.removeEventListener('mousedown', handleClickOutside);
+ }, []);
+
+ const handleAccountClick = () => {
+ setIsOpen(false);
+ setShowAccountModal(true);
+ };
+
+ const handleLogout = () => {
+ setIsOpen(false);
+ navigate('/login');
+ };
+
+ const handleProfileSave = () => {
+ setProfileToast({ type: 'success', message: '保存成功' });
+ setTimeout(() => setProfileToast(null), 3000);
+ };
+
+ const handlePasswordChange = (field, value) => {
+ setPasswordForm(prev => ({ ...prev, [field]: value }));
+ setPasswordErrors(prev => ({ ...prev, [field]: '' }));
+ };
+
+ const handlePasswordSubmit = () => {
+ const errors = {};
+ if (!passwordForm.currentPassword) {
+ errors.currentPassword = '请输入当前密码';
+ }
+ if (!passwordForm.newPassword) {
+ errors.newPassword = '请输入新密码';
+ }
+ if (!passwordForm.confirmPassword) {
+ errors.confirmPassword = '请再次输入新密码';
+ } else if (passwordForm.newPassword !== passwordForm.confirmPassword) {
+ errors.confirmPassword = '两次输入的密码不一致';
+ }
+
+ if (Object.keys(errors).length === 0) {
+ setProfileToast({ type: 'success', message: '密码更新成功' });
+ setPasswordForm({ currentPassword: '', newPassword: '', confirmPassword: '' });
+ setTimeout(() => setProfileToast(null), 3000);
+ } else {
+ setPasswordErrors(errors);
+ }
+ };
+
+ return (
+ <>
+
+
setIsOpen(!isOpen)}>
+
{user.avatar}
+
{user.name}
+
+
+ {isOpen && (
+
+
+
+ 账户设置
+
+
+
+ 退出登录
+
+
+ )}
+
+
+
setShowAccountModal(false)}
+ showConfirm={false}
+ width="720px"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
修改密码
+
+
+
+
handlePasswordChange('currentPassword', e.target.value)}
+ />
+ {passwordErrors.currentPassword && (
+
{passwordErrors.currentPassword}
+ )}
+
+
+
+
+
handlePasswordChange('newPassword', e.target.value)}
+ />
+ {passwordErrors.newPassword && (
+
{passwordErrors.newPassword}
+ )}
+
+
+
+
+
handlePasswordChange('confirmPassword', e.target.value)}
+ />
+ {passwordErrors.confirmPassword && (
+
{passwordErrors.confirmPassword}
+ )}
+
+
+
+
+
+
+
+
+
+
setProfileToast(null)}
+ />
+ >
+ );
+}
+
+export default UserDropdown;
diff --git a/src/pages/AdminPage.jsx b/src/pages/AdminPage.jsx
index 6e0f0f0..d0bc7f0 100644
--- a/src/pages/AdminPage.jsx
+++ b/src/pages/AdminPage.jsx
@@ -2,8 +2,6 @@ import { useState, useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { FiHome, FiBarChart2, FiUsers, FiList, FiCheckCircle, FiActivity, FiSettings } from 'react-icons/fi';
import Layout from '../components/Layout.jsx';
-import SidebarBrand from '../components/layout/SidebarBrand.jsx';
-import SidebarUser from '../components/layout/SidebarUser.jsx';
import SidebarNavItem from '../components/layout/SidebarNavItem.jsx';
import usePageState from '../hooks/usePageState.js';
import { ADMIN_PAGES } from '../constants/pages.js';
@@ -20,7 +18,6 @@ import ConsoleReviewListPage from './console/ConsoleReviewListPage.jsx';
import ConsoleReviewDetailPage from './console/ConsoleReviewDetailPage.jsx';
import ModelConfigsPage from './admin/ModelConfigsPage.jsx';
import AddModelConfigPage from './admin/AddModelConfigPage.jsx';
-import AccountPage from '../components/account/AccountPage.jsx';
function AdminPage() {
const location = useLocation();
@@ -107,30 +104,13 @@ function AdminPage() {
onBack={() => navigateTo('modelConfigs')}
editData={editData}
/>;
- case 'account':
- return ;
default:
return Page not found
;
}
};
- const getPageTitle = () => {
- if (editData && (currentPage === 'addDepartment' || currentPage === 'addUser' || currentPage === 'addProject' || currentPage === 'addModelConfig')) {
- const prefix = '编辑';
- const nameMap = { addDepartment: '部门', addUser: '用户', addProject: '项目', addModelConfig: '配置' };
- return prefix + nameMap[currentPage];
- }
- if (currentPage === 'reviewDetail') {
- return reviewType === 'version' ? '版本审核' : '下架审核';
- }
- return ADMIN_PAGES[currentPage]?.title || '';
- };
-
const sidebar = (
<>
-
-
-
- navigateTo('account')}
- wrapperClassName="admin-sidebar-user"
- infoClassName="admin-sidebar-user-info"
- nameClassName="admin-sidebar-user-name"
- roleClassName="admin-sidebar-user-role"
- />
>
);
return (
{renderPage()}
diff --git a/src/pages/ConsolePage.jsx b/src/pages/ConsolePage.jsx
index be3aebc..ef664a4 100644
--- a/src/pages/ConsolePage.jsx
+++ b/src/pages/ConsolePage.jsx
@@ -3,8 +3,6 @@ import { useLocation, useNavigate } from 'react-router-dom';
import { FiPlus, FiClock, FiList, FiUsers, FiBox } from 'react-icons/fi';
import { FaPuzzlePiece } from 'react-icons/fa';
import Layout from '../components/Layout.jsx';
-import SidebarBrand from '../components/layout/SidebarBrand.jsx';
-import SidebarUser from '../components/layout/SidebarUser.jsx';
import SidebarNavItem from '../components/layout/SidebarNavItem.jsx';
import usePageState from '../hooks/usePageState.js';
import { CONSOLE_PAGES } from '../constants/pages.js';
@@ -18,7 +16,6 @@ import SkillConfigPage from './console/SkillConfigPage.jsx';
import LogsPage from './console/LogsPage.jsx';
import TasksPage from './console/TasksPage.jsx';
import TaskDetailPage from './console/TaskDetailPage.jsx';
-import AccountPage from '../components/account/AccountPage.jsx';
import ProjectsPage from './console/ProjectsPage.jsx';
import MemberConfigPage from './console/MemberConfigPage.jsx';
import AddMemberPage from './console/AddMemberPage.jsx';
@@ -120,8 +117,6 @@ function ConsolePage() {
taskId={currentTaskId}
onBack={() => switchPage('scheduledTasks')}
/>;
- case 'account':
- return ;
case 'projects':
return switchPage('addMember')} />;
case 'memberConfig':
@@ -149,8 +144,6 @@ function ConsolePage() {
const sidebar = (
<>
-
-
- switchPage('account')} />
>
);
return (
diff --git a/src/pages/DeveloperPage.jsx b/src/pages/DeveloperPage.jsx
index 21092a3..2c0ebfd 100644
--- a/src/pages/DeveloperPage.jsx
+++ b/src/pages/DeveloperPage.jsx
@@ -3,8 +3,6 @@ import { useLocation, useNavigate } from 'react-router-dom';
import { FiPlus, FiTerminal, FiHome } from 'react-icons/fi';
import { FaPuzzlePiece } from 'react-icons/fa';
import Layout from '../components/Layout.jsx';
-import SidebarBrand from '../components/layout/SidebarBrand.jsx';
-import SidebarUser from '../components/layout/SidebarUser.jsx';
import SidebarNavItem from '../components/layout/SidebarNavItem.jsx';
import usePageState from '../hooks/usePageState.js';
import { DEVELOPER_PAGES } from '../constants/pages.js';
@@ -15,7 +13,6 @@ import MySkillsPage from './developer/MySkillsPage.jsx';
import UploadSkillPage from './developer/UploadSkillPage.jsx';
import NewVersionPage from './developer/NewVersionPage.jsx';
import DevDocsPage from './developer/DevDocsPage.jsx';
-import AccountPage from '../components/account/AccountPage.jsx';
import SkillEditorPage from './developer/SkillEditorPage.jsx';
import UpdateSkillInfoPage from './developer/UpdateSkillInfoPage.jsx';
import UploadVersionPage from './developer/UploadVersionPage.jsx';
@@ -103,8 +100,6 @@ function DeveloperPage() {
return switchPage('mySkills')} />;
case 'devDocs':
return ;
- case 'devAccount':
- return ;
case 'skillEditor':
return {
- return DEVELOPER_PAGES[currentPage]?.title || '';
- };
-
const sidebar = (
<>
-
-
- switchPage('devAccount')} />
>
);
return (
{renderPage()}
diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx
index 12155c3..c82f71b 100644
--- a/src/pages/HomePage.jsx
+++ b/src/pages/HomePage.jsx
@@ -1,33 +1,10 @@
import { Link } from 'react-router-dom';
-import { FiSettings, FiCode, FiUsers, FiMonitor, FiList, FiLogIn } from 'react-icons/fi';
+import { FiMonitor, FiList } from 'react-icons/fi';
import { FaRobot, FaPuzzlePiece } from 'react-icons/fa';
function HomePage() {
return (
-
-
-
-
@@ -66,9 +43,6 @@ function HomePage() {
-
);
}
diff --git a/src/styles/components/_index.scss b/src/styles/components/_index.scss
index 793b025..fe95e64 100644
--- a/src/styles/components/_index.scss
+++ b/src/styles/components/_index.scss
@@ -16,6 +16,7 @@
@forward 'password-input';
@forward 'search-bar';
@forward 'stat-card';
+@forward 'header';
.page-back-btn {
display: inline-flex;
diff --git a/src/styles/components/header/_index.scss b/src/styles/components/header/_index.scss
new file mode 100644
index 0000000..d6935d4
--- /dev/null
+++ b/src/styles/components/header/_index.scss
@@ -0,0 +1,251 @@
+// AppHeader 组件样式
+
+@use '../../tokens' as *;
+
+// 全局布局容器
+.app-layout {
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ overflow: hidden;
+ background: var(--color-bg-1);
+}
+
+.app-layout__main {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ overflow-y: auto;
+ min-height: 0;
+}
+
+// 头部容器
+.app-header {
+ height: var(--header-height);
+ background: var(--color-bg-1);
+ border-bottom: 1px solid var(--color-border-2);
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0 24px;
+ position: sticky;
+ top: 0;
+ z-index: $z-index-header;
+ flex-shrink: 0;
+}
+
+// 左侧品牌区
+.app-header__left {
+ display: flex;
+ align-items: center;
+}
+
+.app-header__brand {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ text-decoration: none;
+ color: var(--color-text-1);
+ cursor: pointer;
+}
+
+.app-header__title {
+ font-size: 18px;
+ font-weight: 700;
+ letter-spacing: -0.3px;
+}
+
+// 右侧功能区
+.app-header__right {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+}
+
+// 导航区
+.app-header__nav {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+}
+
+.app-header__nav-item {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ padding: 8px 14px;
+ color: var(--color-text-2);
+ font-size: 14px;
+ font-weight: 600;
+ cursor: pointer;
+ border-radius: var(--radius-md);
+ transition: all 0.2s;
+
+ svg {
+ width: 18px;
+ height: 18px;
+ }
+
+ &:hover {
+ color: var(--color-text-1);
+ background: var(--color-bg-2);
+ }
+
+ &.active {
+ color: var(--color-primary);
+ background: var(--color-primary-light);
+ }
+}
+
+// 用户状态区
+.app-header__user {
+ position: relative;
+}
+
+.app-header__user-trigger {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 6px 10px;
+ cursor: pointer;
+ border-radius: var(--radius-md);
+ transition: background 0.2s;
+
+ &:hover {
+ background: var(--color-bg-2);
+ }
+}
+
+.app-header__user-name {
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--color-text-1);
+}
+
+.app-header__user-arrow {
+ width: 16px;
+ height: 16px;
+ color: var(--color-text-3);
+ transition: transform 0.2s;
+
+ &.open {
+ transform: rotate(180deg);
+ }
+}
+
+// 下拉菜单
+.app-header__dropdown {
+ position: absolute;
+ top: 100%;
+ right: 0;
+ margin-top: 4px;
+ min-width: 160px;
+ background: var(--color-bg-1);
+ border: 1px solid var(--color-border-2);
+ border-radius: var(--radius-md);
+ box-shadow: 0 4px 12px rgba(15, 23, 42, 0.1);
+ overflow: hidden;
+ z-index: $z-index-modal;
+}
+
+.app-header__dropdown-item {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 10px 14px;
+ font-size: 14px;
+ color: var(--color-text-2);
+ cursor: pointer;
+ transition: background 0.15s;
+
+ svg {
+ width: 16px;
+ height: 16px;
+ }
+
+ &:hover {
+ background: var(--color-bg-2);
+ color: var(--color-text-1);
+ }
+}
+
+// 移动端菜单
+.app-header__mobile {
+ display: none;
+}
+
+.app-header__mobile-btn {
+ width: 40px;
+ height: 40px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ border-radius: var(--radius-md);
+
+ svg {
+ width: 20px;
+ height: 20px;
+ color: var(--color-text-2);
+ }
+
+ &:hover {
+ background: var(--color-bg-2);
+ }
+}
+
+.app-header__mobile-menu {
+ position: absolute;
+ top: 100%;
+ right: 16px;
+ margin-top: 4px;
+ min-width: 160px;
+ background: var(--color-bg-1);
+ border: 1px solid var(--color-border-2);
+ border-radius: var(--radius-md);
+ box-shadow: 0 4px 12px rgba(15, 23, 42, 0.1);
+ overflow: hidden;
+ z-index: $z-index-modal;
+}
+
+.app-header__mobile-item {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 12px 14px;
+ font-size: 14px;
+ font-weight: 500;
+ color: var(--color-text-2);
+ cursor: pointer;
+ transition: background 0.15s;
+
+ svg {
+ width: 18px;
+ height: 18px;
+ }
+
+ &:hover {
+ background: var(--color-bg-2);
+ color: var(--color-text-1);
+ }
+
+ &.active {
+ color: var(--color-primary);
+ background: var(--color-primary-light);
+ }
+}
+
+// 响应式 - 移动端
+@include mobile {
+ .app-header__nav {
+ display: none;
+ }
+
+ .app-header__mobile {
+ display: block;
+ }
+
+ .app-header__user-name {
+ display: none;
+ }
+}
diff --git a/src/styles/layouts/_admin-layout.scss b/src/styles/layouts/_admin-layout.scss
index 176232e..d502cc0 100644
--- a/src/styles/layouts/_admin-layout.scss
+++ b/src/styles/layouts/_admin-layout.scss
@@ -19,11 +19,6 @@
height: 100%;
}
-.admin-sidebar-header {
- padding: 16px;
- border-bottom: 1px solid var(--color-border-2);
-}
-
.admin-sidebar-nav {
flex: 1;
overflow-y: auto;
@@ -68,41 +63,6 @@
flex: 1;
}
-// 管理台用户区域
-.admin-sidebar-user {
- display: flex;
- align-items: center;
- gap: 12px;
- padding: 16px;
- border-top: 1px solid var(--color-border-2);
- background: var(--color-bg-2);
- cursor: pointer;
- transition: background 0.2s;
-
- &:hover {
- background: var(--color-bg-3);
- }
-}
-
-.admin-sidebar-user-info {
- flex: 1;
- min-width: 0;
-}
-
-.admin-sidebar-user-name {
- font-size: 14px;
- font-weight: 600;
- color: var(--color-text-1);
- margin-bottom: 2px;
- @include text-truncate;
-}
-
-.admin-sidebar-user-role {
- font-size: 12px;
- color: var(--color-text-3);
- @include text-truncate;
-}
-
// 管理台内容区
.admin-layout__content {
flex: 1;
diff --git a/src/styles/layouts/_app-shell.scss b/src/styles/layouts/_app-shell.scss
index 57e221a..a240616 100644
--- a/src/styles/layouts/_app-shell.scss
+++ b/src/styles/layouts/_app-shell.scss
@@ -6,7 +6,7 @@
.app-shell,
.layout {
display: flex;
- height: 100vh;
+ height: 100%;
overflow: hidden;
}
@@ -16,7 +16,7 @@
background: var(--color-bg-1);
border-right: 1px solid var(--color-border-2);
position: fixed;
- height: 100vh;
+ height: 100%;
overflow-y: auto;
overflow-x: hidden;
z-index: $z-index-sidebar;
@@ -24,23 +24,6 @@
flex-direction: column;
}
-// 侧边栏头部
-.sidebar-header {
- height: var(--header-height);
- display: flex;
- align-items: center;
- padding: 0 20px;
- border-bottom: 1px solid var(--color-border-2);
- flex-shrink: 0;
-}
-
-// 品牌区
-.sidebar-brand {
- display: flex;
- align-items: center;
- gap: 10px;
-}
-
.sidebar-logo-icon {
width: 28px;
height: 28px;
@@ -87,20 +70,6 @@
}
}
-.sidebar-brand-text {
- display: flex;
- flex-direction: column;
- gap: 2px;
-}
-
-.sidebar-logo {
- font-size: 18px;
- font-weight: 700;
- color: var(--color-text-1);
- letter-spacing: -0.3px;
- line-height: 1.2;
-}
-
// 导航区
.sidebar__nav,
.sidebar-menu {
@@ -114,13 +83,6 @@
margin: 12px 0;
}
-.sidebar-subtitle {
- font-size: 13px;
- color: var(--color-text-3);
- font-weight: 600;
- line-height: 1.2;
-}
-
// 导航项 - 统一使用 .nav-item
.nav-item,
.menu-item {
@@ -178,34 +140,6 @@
overflow: hidden;
}
-// 顶部栏
-.app-shell__header,
-.header {
- height: var(--header-height);
- background: var(--color-bg-1);
- border-bottom: 1px solid var(--color-border-2);
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0 24px;
- position: sticky;
- top: 0;
- z-index: $z-index-header;
-}
-
-.header__left,
-.header-left {
- display: flex;
- align-items: center;
- gap: 16px;
-}
-
-.header-title {
- font-size: 15px;
- font-weight: 600;
- color: var(--color-text-1);
-}
-
// 用户头像
.user-avatar {
width: 34px;
@@ -290,10 +224,6 @@
padding: 16px;
}
- .header-title {
- display: none;
- }
-
.mobile-menu-btn {
display: flex !important;
}
diff --git a/src/styles/layouts/_chat-layout.scss b/src/styles/layouts/_chat-layout.scss
index b58338a..cfd7b4a 100644
--- a/src/styles/layouts/_chat-layout.scss
+++ b/src/styles/layouts/_chat-layout.scss
@@ -177,41 +177,6 @@
color: var(--color-text-3);
}
-// 侧边栏用户状态区域
-.chat-sidebar-user {
- display: flex;
- align-items: center;
- gap: 12px;
- padding: 16px;
- border-top: 1px solid var(--color-border-2);
- background: var(--color-bg-1);
- cursor: pointer;
- transition: background 0.2s;
-
- &:hover {
- background: var(--color-bg-2);
- }
-}
-
-.chat-sidebar-user-info {
- flex: 1;
- min-width: 0;
-}
-
-.chat-sidebar-user-name {
- font-size: 14px;
- font-weight: 600;
- color: var(--color-text-1);
- margin-bottom: 2px;
- @include text-truncate;
-}
-
-.chat-sidebar-user-role {
- font-size: 12px;
- color: var(--color-text-3);
- @include text-truncate;
-}
-
// 侧边栏项目切换区域
.chat-sidebar-project {
padding: 16px;
diff --git a/src/styles/pages/_home.scss b/src/styles/pages/_home.scss
index 12c0973..d0c92e0 100644
--- a/src/styles/pages/_home.scss
+++ b/src/styles/pages/_home.scss
@@ -3,7 +3,7 @@
@use '../tokens' as *;
.home-layout {
- min-height: 100vh;
+ flex: 1;
display: flex;
flex-direction: column;
background: linear-gradient(180deg, #F8FAFC 0%, #FFFFFF 100%);
@@ -33,116 +33,6 @@
}
}
-.home-header {
- padding: 0 48px;
- height: 68px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- position: relative;
- z-index: 1;
- border-bottom: 1px solid var(--color-border-2);
- background: rgba(255, 255, 255, 0.8);
- backdrop-filter: blur(12px);
-}
-
-.home-logo {
- font-size: 18px;
- font-weight: 800;
- color: var(--color-text-1);
- display: flex;
- align-items: center;
- gap: 10px;
- letter-spacing: -0.3px;
-
- .sidebar-logo-icon {
- width: 28px;
- height: 28px;
- background: linear-gradient(135deg, #3B82F6 0%, #8B5CF6 100%);
- border-radius: 6px;
- flex-shrink: 0;
- display: flex;
- align-items: center;
- justify-content: center;
- position: relative;
- overflow: hidden;
-
- &::before {
- content: '';
- position: absolute;
- width: 14px;
- height: 10px;
- background: rgba(255, 255, 255, 0.95);
- border-radius: 4px 4px 2px 2px;
- top: 5px;
- }
-
- &::after {
- content: '';
- position: absolute;
- width: 18px;
- height: 10px;
- background: rgba(255, 255, 255, 0.85);
- border-radius: 2px 2px 4px 4px;
- bottom: 4px;
- }
-
- span {
- position: absolute;
- width: 3px;
- height: 3px;
- background: rgba(59, 130, 246, 0.9);
- border-radius: 50%;
- top: 9px;
- z-index: 1;
-
- &:nth-child(1) { left: 9px; }
- &:nth-child(2) { right: 9px; }
- }
- }
-}
-
-.home-nav {
- display: flex;
- gap: 6px;
-
- a {
- color: var(--color-text-2);
- text-decoration: none;
- padding: 9px 16px;
- border-radius: 8px;
- font-weight: 600;
- font-size: 14px;
- transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
- display: flex;
- align-items: center;
- gap: 6px;
-
- &:hover {
- color: var(--color-text-1);
- background: var(--color-bg-2);
- }
-
- svg, .home-icon {
- width: 18px;
- height: 18px;
- display: flex;
- align-items: center;
- justify-content: center;
- }
-
- &.home-nav-login {
- color: #3B82F6;
- font-weight: 600;
-
- &:hover {
- color: #2563EB;
- background: #EFF6FF;
- }
- }
- }
-}
-
.home-main {
flex: 1;
display: flex;
@@ -300,22 +190,8 @@
line-height: 1.6;
}
-.home-footer {
- padding: 28px;
- text-align: center;
- color: var(--color-text-4);
- font-size: 13px;
- font-weight: 500;
- position: relative;
- z-index: 1;
-}
-
// Responsive
@include mobile {
- .home-header {
- padding: 0 16px;
- }
-
.home-title {
font-size: 36px;
}
@@ -338,8 +214,4 @@
.home-features {
grid-template-columns: 1fr;
}
-
- .home-nav {
- display: none;
- }
}