diff --git a/web/src/components/GroupPanelItem.tsx b/web/src/components/GroupPanelItem.tsx
new file mode 100644
index 00000000..786d89bb
--- /dev/null
+++ b/web/src/components/GroupPanelItem.tsx
@@ -0,0 +1,42 @@
+import { Badge, Typography } from 'antd';
+import clsx from 'clsx';
+import React from 'react';
+import { useLocation } from 'react-router';
+import { Link } from 'react-router-dom';
+
+export const GroupPanelItem: React.FC<{
+ name: string;
+ icon: React.ReactNode;
+ to: string;
+ badge?: boolean;
+}> = React.memo((props) => {
+ const { icon, name, to, badge } = props;
+ const location = useLocation();
+ const isActive = location.pathname.startsWith(to);
+
+ return (
+
+
+
{icon}
+
+
+ {name}
+
+
+ {badge === true ? (
+
+ ) : (
+
+ )}
+
+
+ );
+});
+GroupPanelItem.displayName = 'GroupPanelItem';
diff --git a/web/src/components/GroupSection.tsx b/web/src/components/GroupSection.tsx
new file mode 100644
index 00000000..50fc8104
--- /dev/null
+++ b/web/src/components/GroupSection.tsx
@@ -0,0 +1,37 @@
+import { Icon } from '@iconify/react';
+import React from 'react';
+import { useReducer } from 'react';
+
+export const GroupSection: React.FC<{
+ header: string;
+}> = React.memo((props) => {
+ const [isShow, switchShow] = useReducer((v) => !v, true);
+
+ return (
+
+
+
+ ref?.style.setProperty('--max-height', `${ref.scrollHeight}px`)
+ }
+ >
+ {props.children}
+
+
+ );
+});
+GroupSection.displayName = 'GroupSection';
diff --git a/web/src/routes/Main/Content/Group/Sidebar.tsx b/web/src/routes/Main/Content/Group/Sidebar.tsx
index 07690321..b60bc3ed 100644
--- a/web/src/routes/Main/Content/Group/Sidebar.tsx
+++ b/web/src/routes/Main/Content/Group/Sidebar.tsx
@@ -1,87 +1,14 @@
-import React, { useReducer } from 'react';
-import { Icon } from '@iconify/react';
+import React from 'react';
import { GroupPanelType, useGroupInfo } from 'tailchat-shared';
-import { useLocation, useParams } from 'react-router';
-import { Badge, Typography } from 'antd';
-import { Link } from 'react-router-dom';
-import clsx from 'clsx';
+import { useParams } from 'react-router';
import { GroupHeader } from './GroupHeader';
+import { GroupSection } from '@/components/GroupSection';
+import { GroupPanelItem } from '@/components/GroupPanelItem';
interface GroupParams {
groupId: string;
}
-const GroupSection: React.FC<{
- header: string;
-}> = React.memo((props) => {
- const [isShow, switchShow] = useReducer((v) => !v, true);
-
- return (
-
-
-
- ref?.style.setProperty('--max-height', `${ref.scrollHeight}px`)
- }
- >
- {props.children}
-
-
- );
-});
-GroupSection.displayName = 'GroupSection';
-
-const GroupPanelItem: React.FC<{
- name: string;
- icon: React.ReactNode;
- to: string;
- badge?: boolean;
-}> = React.memo((props) => {
- const { icon, name, to, badge } = props;
- const location = useLocation();
- const isActive = location.pathname.startsWith(to);
-
- return (
-
-
-
{icon}
-
-
- {name}
-
-
- {badge === true ? (
-
- ) : (
-
- )}
-
-
- );
-});
-GroupPanelItem.displayName = 'GroupPanelItem';
-
/**
* 个人面板侧边栏组件
*/