@lobehub/lobehub 2.0.0-next.296 → 2.0.0-next.298

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/package.json +2 -2
  4. package/packages/types/package.json +1 -1
  5. package/packages/types/src/discover/assistants.ts +4 -0
  6. package/packages/types/src/discover/groupAgents.ts +196 -0
  7. package/packages/types/src/discover/index.ts +5 -1
  8. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/DetailProvider.tsx +19 -0
  9. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/Members/index.tsx +137 -0
  10. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/Nav.tsx +87 -0
  11. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/Overview/index.tsx +213 -0
  12. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/Related/index.tsx +89 -0
  13. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/SystemRole/TagList.tsx +20 -0
  14. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/SystemRole/index.tsx +71 -0
  15. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/Versions/index.tsx +119 -0
  16. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/index.tsx +51 -0
  17. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Header.tsx +253 -0
  18. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Sidebar/ActionButton/AddGroupAgent.tsx +222 -0
  19. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Sidebar/ActionButton/index.tsx +34 -0
  20. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Sidebar/Summary/index.tsx +42 -0
  21. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Sidebar/index.tsx +41 -0
  22. package/src/app/[variants]/(main)/community/(detail)/group_agent/features/StatusPage/index.tsx +104 -0
  23. package/src/app/[variants]/(main)/community/(detail)/group_agent/index.tsx +103 -0
  24. package/src/app/[variants]/(main)/community/(detail)/group_agent/loading.tsx +1 -0
  25. package/src/app/[variants]/(main)/community/(detail)/user/features/DetailProvider.tsx +7 -1
  26. package/src/app/[variants]/(main)/community/(detail)/user/features/UserContent.tsx +2 -0
  27. package/src/app/[variants]/(main)/community/(detail)/user/features/UserGroupCard.tsx +186 -0
  28. package/src/app/[variants]/(main)/community/(detail)/user/features/UserGroupList.tsx +59 -0
  29. package/src/app/[variants]/(main)/community/(detail)/user/index.tsx +3 -1
  30. package/src/app/[variants]/(main)/community/(list)/assistant/features/List/Item.tsx +26 -8
  31. package/src/app/[variants]/(main)/community/(list)/assistant/index.tsx +1 -0
  32. package/src/app/[variants]/(main)/group/profile/features/GroupProfile/index.tsx +2 -0
  33. package/src/app/[variants]/(main)/group/profile/features/Header/AgentPublishButton/PublishResultModal.tsx +2 -1
  34. package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/GroupForkConfirmModal.tsx +60 -0
  35. package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/GroupPublishResultModal.tsx +62 -0
  36. package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/PublishButton.tsx +122 -0
  37. package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/index.tsx +46 -0
  38. package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/types.ts +12 -0
  39. package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/useMarketGroupPublish.ts +211 -0
  40. package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/utils.ts +22 -0
  41. package/src/app/[variants]/(main)/home/_layout/HomeAgentIdSync.tsx +23 -0
  42. package/src/app/[variants]/(main)/home/_layout/index.tsx +2 -0
  43. package/src/app/[variants]/router/desktopRouter.config.tsx +7 -0
  44. package/src/locales/default/setting.ts +12 -0
  45. package/src/server/routers/lambda/market/agentGroup.ts +296 -0
  46. package/src/server/routers/lambda/market/index.ts +134 -4
  47. package/src/server/services/discover/index.ts +123 -7
  48. package/src/services/discover.ts +58 -1
  49. package/src/store/discover/slices/groupAgent/action.ts +80 -0
  50. package/src/store/discover/store.ts +3 -0
  51. package/src/store/tool/slices/lobehubSkillStore/action.ts +1 -2
@@ -0,0 +1,103 @@
1
+ 'use client';
2
+
3
+ import { Flexbox } from '@lobehub/ui';
4
+ import { memo } from 'react';
5
+ import { useParams } from 'react-router-dom';
6
+
7
+ import { useQuery } from '@/hooks/useQuery';
8
+ import { useDiscoverStore } from '@/store/discover';
9
+
10
+ import NotFound from '../components/NotFound';
11
+ import { TocProvider } from '../features/Toc/useToc';
12
+ import Details from './features/Details';
13
+ import { DetailProvider } from './features/DetailProvider';
14
+ import Header from './features/Header';
15
+ import StatusPage from './features/StatusPage';
16
+ import Loading from './loading';
17
+
18
+ interface GroupAgentDetailPageProps {
19
+ mobile?: boolean;
20
+ }
21
+
22
+ const GroupAgentDetailPage = memo<GroupAgentDetailPageProps>(({ mobile }) => {
23
+ const params = useParams<{ slug: string }>();
24
+ const identifier = decodeURIComponent(params.slug ?? '');
25
+ const { version } = useQuery() as { version?: string };
26
+
27
+ // Fetch group agent detail
28
+ const useGroupAgentDetail = useDiscoverStore((s) => s.useGroupAgentDetail);
29
+ const { data, isLoading } = useGroupAgentDetail({ identifier, version });
30
+
31
+ if (isLoading) return <Loading />;
32
+
33
+ if (!data) return <NotFound />;
34
+
35
+ // Check status and show appropriate page
36
+ const status = (data as any)?.group?.status || (data as any)?.status;
37
+ if (status === 'unpublished' || status === 'archived' || status === 'deprecated') {
38
+ return <StatusPage status={status} />;
39
+ }
40
+
41
+ // Transform API data to match DiscoverGroupAgentDetail type
42
+ const apiConfig = (data as any)?.currentVersion?.config || {};
43
+
44
+ const transformedData = {
45
+ // Top level fields
46
+ author: (data as any)?.author,
47
+ // From currentVersion
48
+ avatar: (data as any)?.currentVersion?.avatar,
49
+ backgroundColor: (data as any)?.currentVersion?.backgroundColor,
50
+ category: (data as any)?.currentVersion?.category,
51
+ commentCount: (data as any)?.group?.commentCount,
52
+
53
+ // From currentVersion.config - rename systemPrompt to systemRole for consistency
54
+ config: {
55
+ ...apiConfig,
56
+ allowDM: apiConfig.allowDM,
57
+ // Rename systemPrompt -> systemRole
58
+ openingMessage: apiConfig.openingMessage,
59
+ openingQuestions: apiConfig.openingQuestions,
60
+ revealDM: apiConfig.revealDM,
61
+ summary: apiConfig.summary,
62
+ systemRole: apiConfig.systemPrompt,
63
+ },
64
+
65
+ createdAt: (data as any)?.group?.createdAt,
66
+ // Version info
67
+ currentVersion: (data as any)?.currentVersion?.version,
68
+ currentVersionNumber: (data as any)?.currentVersion?.versionNumber,
69
+ description: (data as any)?.currentVersion?.description,
70
+ favoriteCount: (data as any)?.group?.favoriteCount,
71
+ homepage: (data as any)?.group?.homepage,
72
+ // From group
73
+ identifier: (data as any)?.group?.identifier,
74
+ installCount: (data as any)?.group?.installCount,
75
+ likeCount: (data as any)?.group?.likeCount,
76
+ locale: (data as any)?.locale,
77
+ memberAgents: (data as any)?.memberAgents || [],
78
+ status: (data as any)?.group?.status,
79
+ summary: (data as any)?.summary,
80
+ tags: (data as any)?.currentVersion?.tags,
81
+ title: (data as any)?.currentVersion?.name || (data as any)?.group?.name,
82
+ updatedAt: (data as any)?.group?.updatedAt,
83
+ userName: (data as any)?.author?.userName,
84
+ versions: (data as any)?.versions || [],
85
+ visibility: (data as any)?.group?.visibility,
86
+ };
87
+
88
+ return (
89
+ <TocProvider>
90
+ <DetailProvider config={transformedData}>
91
+ <Flexbox gap={16} width={'100%'}>
92
+ {/* Header Section */}
93
+ <Header mobile={mobile} />
94
+
95
+ {/* Details Section */}
96
+ <Details mobile={mobile} />
97
+ </Flexbox>
98
+ </DetailProvider>
99
+ </TocProvider>
100
+ );
101
+ });
102
+
103
+ export default GroupAgentDetailPage;
@@ -0,0 +1 @@
1
+ export { DetailsLoading as default } from '../../components/ListLoading';
@@ -3,11 +3,17 @@
3
3
  import { type ReactNode, createContext, memo, use } from 'react';
4
4
 
5
5
  import { type MarketUserProfile } from '@/layout/AuthProvider/MarketAuth/types';
6
- import { type DiscoverAssistantItem, type DiscoverUserInfo } from '@/types/discover';
6
+ import {
7
+ type DiscoverAssistantItem,
8
+ type DiscoverGroupAgentItem,
9
+ type DiscoverUserInfo,
10
+ } from '@/types/discover';
7
11
 
8
12
  export interface UserDetailContextConfig {
9
13
  agentCount: number;
14
+ agentGroups?: DiscoverGroupAgentItem[];
10
15
  agents: DiscoverAssistantItem[];
16
+ groupCount: number;
11
17
  isOwner: boolean;
12
18
  mobile?: boolean;
13
19
  onEditProfile?: (onSuccess?: (profile: MarketUserProfile) => void) => void;
@@ -6,11 +6,13 @@ import { memo } from 'react';
6
6
  import UserAgentList from './UserAgentList';
7
7
  import UserFavoriteAgents from './UserFavoriteAgents';
8
8
  import UserFavoritePlugins from './UserFavoritePlugins';
9
+ import UserGroupList from './UserGroupList';
9
10
 
10
11
  const UserContent = memo(() => {
11
12
  return (
12
13
  <Flexbox gap={32}>
13
14
  <UserAgentList />
15
+ <UserGroupList />
14
16
  <UserFavoriteAgents />
15
17
  <UserFavoritePlugins />
16
18
  </Flexbox>
@@ -0,0 +1,186 @@
1
+ 'use client';
2
+
3
+ import { Avatar, Block, Flexbox, Icon, Tag, Text, Tooltip, TooltipGroup } from '@lobehub/ui';
4
+ import { createStaticStyles } from 'antd-style';
5
+ import { ClockIcon, DownloadIcon, UsersIcon } from 'lucide-react';
6
+ import qs from 'query-string';
7
+ import { memo, useCallback } from 'react';
8
+ import { useTranslation } from 'react-i18next';
9
+ import { Link, useNavigate } from 'react-router-dom';
10
+ import urlJoin from 'url-join';
11
+
12
+ import PublishedTime from '@/components/PublishedTime';
13
+ import { type DiscoverGroupAgentItem } from '@/types/discover';
14
+ import { formatIntergerNumber } from '@/utils/format';
15
+
16
+ const styles = createStaticStyles(({ css, cssVar }) => {
17
+ return {
18
+ desc: css`
19
+ flex: 1;
20
+ margin: 0 !important;
21
+ color: ${cssVar.colorTextSecondary};
22
+ `,
23
+ footer: css`
24
+ margin-block-start: 16px;
25
+ border-block-start: 1px dashed ${cssVar.colorBorder};
26
+ background: ${cssVar.colorBgContainer};
27
+ `,
28
+ secondaryDesc: css`
29
+ font-size: 12px;
30
+ color: ${cssVar.colorTextDescription};
31
+ `,
32
+ statTag: css`
33
+ border-radius: 4px;
34
+
35
+ font-family: ${cssVar.fontFamilyCode};
36
+ font-size: 11px;
37
+ color: ${cssVar.colorTextSecondary};
38
+
39
+ background: ${cssVar.colorFillTertiary};
40
+ `,
41
+ title: css`
42
+ margin: 0 !important;
43
+ font-size: 16px !important;
44
+ font-weight: 500 !important;
45
+
46
+ &:hover {
47
+ color: ${cssVar.colorLink};
48
+ }
49
+ `,
50
+ };
51
+ });
52
+
53
+ type UserGroupCardProps = DiscoverGroupAgentItem;
54
+
55
+ const UserGroupCard = memo<UserGroupCardProps>(
56
+ ({ avatar, title, description, createdAt, category, installCount, identifier, memberCount }) => {
57
+ const { t } = useTranslation(['discover']);
58
+ const navigate = useNavigate();
59
+
60
+ const link = qs.stringifyUrl(
61
+ {
62
+ query: { source: 'new' },
63
+ url: urlJoin('/community/group_agent', identifier),
64
+ },
65
+ { skipNull: true },
66
+ );
67
+
68
+ const handleCardClick = useCallback(() => {
69
+ navigate(link);
70
+ }, [link, navigate]);
71
+
72
+ return (
73
+ <Block
74
+ clickable
75
+ height={'100%'}
76
+ onClick={handleCardClick}
77
+ style={{
78
+ cursor: 'pointer',
79
+ overflow: 'hidden',
80
+ position: 'relative',
81
+ }}
82
+ variant={'outlined'}
83
+ width={'100%'}
84
+ >
85
+ <Flexbox
86
+ align={'flex-start'}
87
+ gap={16}
88
+ horizontal
89
+ justify={'space-between'}
90
+ padding={16}
91
+ width={'100%'}
92
+ >
93
+ <Flexbox
94
+ gap={12}
95
+ horizontal
96
+ style={{
97
+ overflow: 'hidden',
98
+ }}
99
+ >
100
+ <Avatar avatar={avatar} shape={'square'} size={40} style={{ flex: 'none' }} />
101
+ <Flexbox
102
+ flex={1}
103
+ gap={2}
104
+ style={{
105
+ overflow: 'hidden',
106
+ }}
107
+ >
108
+ <Link
109
+ onClick={(e) => e.stopPropagation()}
110
+ style={{ color: 'inherit', flex: 1, overflow: 'hidden' }}
111
+ to={link}
112
+ >
113
+ <Text as={'h3'} className={styles.title} ellipsis style={{ flex: 1 }}>
114
+ {title}
115
+ </Text>
116
+ </Link>
117
+ </Flexbox>
118
+ </Flexbox>
119
+ </Flexbox>
120
+ <Flexbox flex={1} gap={12} paddingInline={16}>
121
+ <Text
122
+ as={'p'}
123
+ className={styles.desc}
124
+ ellipsis={{
125
+ rows: 3,
126
+ }}
127
+ >
128
+ {description}
129
+ </Text>
130
+ <TooltipGroup>
131
+ <Flexbox align={'center'} gap={4} horizontal>
132
+ {memberCount !== undefined && memberCount > 0 && (
133
+ <Tooltip
134
+ placement={'top'}
135
+ styles={{ root: { pointerEvents: 'none' } }}
136
+ title={t('groupAgents.memberCount', { defaultValue: 'Members' })}
137
+ >
138
+ <Tag className={styles.statTag} icon={<Icon icon={UsersIcon} />}>
139
+ {formatIntergerNumber(memberCount)}
140
+ </Tag>
141
+ </Tooltip>
142
+ )}
143
+ {installCount !== undefined && installCount > 0 && (
144
+ <Tooltip
145
+ placement={'top'}
146
+ styles={{ root: { pointerEvents: 'none' } }}
147
+ title={t('groupAgents.downloads', { defaultValue: 'Downloads' })}
148
+ >
149
+ <Tag className={styles.statTag} icon={<Icon icon={DownloadIcon} />}>
150
+ {formatIntergerNumber(installCount)}
151
+ </Tag>
152
+ </Tooltip>
153
+ )}
154
+ </Flexbox>
155
+ </TooltipGroup>
156
+ </Flexbox>
157
+ <Flexbox
158
+ align={'center'}
159
+ className={styles.footer}
160
+ horizontal
161
+ justify={'space-between'}
162
+ padding={16}
163
+ >
164
+ <Flexbox
165
+ align={'center'}
166
+ className={styles.secondaryDesc}
167
+ horizontal
168
+ justify={'space-between'}
169
+ >
170
+ <Flexbox align={'center'} gap={4} horizontal>
171
+ <Icon icon={ClockIcon} size={14} />
172
+ <PublishedTime
173
+ className={styles.secondaryDesc}
174
+ date={createdAt}
175
+ template={'MMM DD, YYYY'}
176
+ />
177
+ </Flexbox>
178
+ {category && t(`category.groupAgent.${category}` as any, { defaultValue: category })}
179
+ </Flexbox>
180
+ </Flexbox>
181
+ </Block>
182
+ );
183
+ },
184
+ );
185
+
186
+ export default UserGroupCard;
@@ -0,0 +1,59 @@
1
+ 'use client';
2
+
3
+ import { Flexbox, Grid, Tag, Text } from '@lobehub/ui';
4
+ import { Pagination } from 'antd';
5
+ import { memo, useMemo, useState } from 'react';
6
+ import { useTranslation } from 'react-i18next';
7
+
8
+ import { useUserDetailContext } from './DetailProvider';
9
+ import UserGroupCard from './UserGroupCard';
10
+
11
+ interface UserGroupListProps {
12
+ pageSize?: number;
13
+ rows?: number;
14
+ }
15
+
16
+ const UserGroupList = memo<UserGroupListProps>(({ rows = 4, pageSize = 10 }) => {
17
+ const { t } = useTranslation('discover');
18
+ const { agentGroups, groupCount } = useUserDetailContext();
19
+ const [currentPage, setCurrentPage] = useState(1);
20
+
21
+ const paginatedGroups = useMemo(() => {
22
+ if (!agentGroups) return [];
23
+ const startIndex = (currentPage - 1) * pageSize;
24
+ return agentGroups.slice(startIndex, startIndex + pageSize);
25
+ }, [agentGroups, currentPage, pageSize]);
26
+
27
+ if (!agentGroups || agentGroups.length === 0) return null;
28
+
29
+ const showPagination = agentGroups.length > pageSize;
30
+
31
+ return (
32
+ <Flexbox gap={16}>
33
+ <Flexbox align={'center'} gap={8} horizontal>
34
+ <Text fontSize={16} weight={500}>
35
+ {t('user.publishedGroups', { defaultValue: '创作的群组' })}
36
+ </Text>
37
+ {groupCount > 0 && <Tag>{groupCount}</Tag>}
38
+ </Flexbox>
39
+ <Grid rows={rows} width={'100%'}>
40
+ {paginatedGroups.map((item, index) => (
41
+ <UserGroupCard key={item.identifier || index} {...item} />
42
+ ))}
43
+ </Grid>
44
+ {showPagination && (
45
+ <Flexbox align={'center'} justify={'center'}>
46
+ <Pagination
47
+ current={currentPage}
48
+ onChange={(page) => setCurrentPage(page)}
49
+ pageSize={pageSize}
50
+ showSizeChanger={false}
51
+ total={agentGroups.length}
52
+ />
53
+ </Flexbox>
54
+ )}
55
+ </Flexbox>
56
+ );
57
+ });
58
+
59
+ export default UserGroupList;
@@ -58,11 +58,13 @@ const UserDetailPage = memo<UserDetailPageProps>(({ mobile }) => {
58
58
 
59
59
  const contextConfig = useMemo(() => {
60
60
  if (!data || !data.user) return null;
61
- const { user, agents } = data;
61
+ const { user, agents, agentGroups } = data;
62
62
  const totalInstalls = agents.reduce((sum, agent) => sum + (agent.installCount || 0), 0);
63
63
  return {
64
64
  agentCount: agents.length,
65
+ agentGroups: agentGroups || [],
65
66
  agents,
67
+ groupCount: agentGroups?.length || 0,
66
68
  isOwner,
67
69
  mobile,
68
70
  onEditProfile: handleEditProfile,
@@ -1,4 +1,4 @@
1
- import { Avatar, Block, Flexbox, Icon, Text } from '@lobehub/ui';
1
+ import { Avatar, Block, Flexbox, Icon, Tag, Text } from '@lobehub/ui';
2
2
  import { createStaticStyles } from 'antd-style';
3
3
  import { ClockIcon } from 'lucide-react';
4
4
  import qs from 'query-string';
@@ -9,8 +9,8 @@ import urlJoin from 'url-join';
9
9
 
10
10
  import PublishedTime from '@/components/PublishedTime';
11
11
  import { useQuery } from '@/hooks/useQuery';
12
- import { type AssistantMarketSource, type DiscoverAssistantItem } from '@/types/discover';
13
12
  import { discoverService } from '@/services/discover';
13
+ import { type AssistantMarketSource, type DiscoverAssistantItem } from '@/types/discover';
14
14
 
15
15
  import TokenTag from './TokenTag';
16
16
 
@@ -68,13 +68,16 @@ const AssistantItem = memo<DiscoverAssistantItem>(
68
68
  installCount,
69
69
  backgroundColor,
70
70
  userName,
71
+ type,
71
72
  }) => {
72
73
  const navigate = useNavigate();
73
74
  const { source } = useQuery() as { source?: AssistantMarketSource };
75
+ const isGroupAgent = type === 'agent-group';
76
+ const basePath = isGroupAgent ? '/community/group_agent' : '/community/assistant';
74
77
  const link = qs.stringifyUrl(
75
78
  {
76
79
  query: { source },
77
- url: urlJoin('/community/assistant', identifier),
80
+ url: urlJoin(basePath, identifier),
78
81
  },
79
82
  { skipNull: true },
80
83
  );
@@ -93,11 +96,13 @@ const AssistantItem = memo<DiscoverAssistantItem>(
93
96
  );
94
97
 
95
98
  const handleClick = useCallback(() => {
96
- discoverService.reportAgentEvent({
97
- event: 'click',
98
- identifier,
99
- source: location.pathname,
100
- }).catch(() => {});
99
+ discoverService
100
+ .reportAgentEvent({
101
+ event: 'click',
102
+ identifier,
103
+ source: location.pathname,
104
+ })
105
+ .catch(() => {});
101
106
 
102
107
  navigate(link);
103
108
  }, [identifier, link, navigate]);
@@ -115,6 +120,19 @@ const AssistantItem = memo<DiscoverAssistantItem>(
115
120
  variant={'outlined'}
116
121
  width={'100%'}
117
122
  >
123
+ {isGroupAgent && (
124
+ <Tag
125
+ color="info"
126
+ style={{
127
+ position: 'absolute',
128
+ right: 12,
129
+ top: 12,
130
+ zIndex: 1,
131
+ }}
132
+ >
133
+ {t('groupAgents.tag', { defaultValue: '群组' })}
134
+ </Tag>
135
+ )}
118
136
  <Flexbox
119
137
  align={'flex-start'}
120
138
  gap={16}
@@ -16,6 +16,7 @@ const AssistantPage = memo(() => {
16
16
  const useAssistantList = useDiscoverStore((s) => s.useAssistantList);
17
17
  const { data, isLoading } = useAssistantList({
18
18
  category,
19
+ includeAgentGroup: true,
19
20
  order,
20
21
  page,
21
22
  pageSize: 21,
@@ -14,6 +14,7 @@ import { agentGroupSelectors } from '@/store/agentGroup/selectors';
14
14
  import { useGroupProfileStore } from '@/store/groupProfile';
15
15
 
16
16
  import AutoSaveHint from '../Header/AutoSaveHint';
17
+ import GroupPublishButton from '../Header/GroupPublishButton';
17
18
  import GroupHeader from './GroupHeader';
18
19
 
19
20
  const GroupProfile = memo(() => {
@@ -75,6 +76,7 @@ const GroupProfile = memo(() => {
75
76
  >
76
77
  {t('startConversation')}
77
78
  </Button>
79
+ <GroupPublishButton />
78
80
  </Flexbox>
79
81
  </Flexbox>
80
82
  <Divider />
@@ -19,7 +19,8 @@ const PublishResultModal = memo<PublishResultModalProps>(({ identifier, onCancel
19
19
 
20
20
  const handleGoToMarket = () => {
21
21
  if (identifier) {
22
- navigate(`/community/assistant/${identifier}`);
22
+ console.log('identifier', identifier);
23
+ navigate(`/community/group_agent/${identifier}`);
23
24
  }
24
25
  onCancel();
25
26
  };
@@ -0,0 +1,60 @@
1
+ 'use client';
2
+
3
+ import { Avatar, Flexbox, Modal } from '@lobehub/ui';
4
+ import { memo } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+
7
+ import type { OriginalGroupInfo } from './types';
8
+
9
+ interface GroupForkConfirmModalProps {
10
+ loading?: boolean;
11
+ onCancel: () => void;
12
+ onConfirm: () => void;
13
+ open: boolean;
14
+ originalGroup: OriginalGroupInfo | null;
15
+ }
16
+
17
+ const GroupForkConfirmModal = memo<GroupForkConfirmModalProps>(
18
+ ({ open, onCancel, onConfirm, originalGroup, loading }) => {
19
+ const { t } = useTranslation('setting');
20
+
21
+ if (!originalGroup) return null;
22
+
23
+ const authorName = originalGroup.author?.name || originalGroup.author?.userName || 'Unknown';
24
+
25
+ return (
26
+ <Modal
27
+ cancelText={t('cancel', { ns: 'common' })}
28
+ centered
29
+ closable
30
+ confirmLoading={loading}
31
+ okText={t('marketPublish.forkConfirm.confirmGroup')}
32
+ onCancel={onCancel}
33
+ onOk={onConfirm}
34
+ open={open}
35
+ title={t('marketPublish.forkConfirm.titleGroup')}
36
+ width={480}
37
+ >
38
+ <Flexbox gap={16} style={{ marginTop: 16 }}>
39
+ <Flexbox align="center" gap={12} horizontal>
40
+ <Avatar avatar={originalGroup.avatar} size={48} style={{ flex: 'none' }} />
41
+ <Flexbox gap={4}>
42
+ <div style={{ fontWeight: 500 }}>{originalGroup.name}</div>
43
+ <div style={{ fontSize: 12, opacity: 0.6 }}>
44
+ {t('marketPublish.forkConfirm.by', { author: authorName })}
45
+ </div>
46
+ </Flexbox>
47
+ </Flexbox>
48
+
49
+ <p style={{ lineHeight: 1.6, margin: 0 }}>
50
+ {t('marketPublish.forkConfirm.descriptionGroup')}
51
+ </p>
52
+ </Flexbox>
53
+ </Modal>
54
+ );
55
+ },
56
+ );
57
+
58
+ GroupForkConfirmModal.displayName = 'GroupForkConfirmModal';
59
+
60
+ export default GroupForkConfirmModal;
@@ -0,0 +1,62 @@
1
+ 'use client';
2
+
3
+ import { FluentEmoji, Modal, Text } from '@lobehub/ui';
4
+ import { Result } from 'antd';
5
+ import { memo } from 'react';
6
+ import { useTranslation } from 'react-i18next';
7
+ import { useNavigate } from 'react-router-dom';
8
+
9
+ interface GroupPublishResultModalProps {
10
+ identifier?: string;
11
+ onCancel: () => void;
12
+ open: boolean;
13
+ }
14
+
15
+ const GroupPublishResultModal = memo<GroupPublishResultModalProps>(
16
+ ({ identifier, onCancel, open }) => {
17
+ const navigate = useNavigate();
18
+ const { t } = useTranslation('setting');
19
+ const { t: tCommon } = useTranslation('common');
20
+
21
+ const handleGoToMarket = () => {
22
+ if (identifier) {
23
+ navigate(`/community/group_agent/${identifier}`);
24
+ }
25
+ onCancel();
26
+ };
27
+
28
+ return (
29
+ <Modal
30
+ cancelText={tCommon('cancel')}
31
+ centered
32
+ okText={t('marketPublish.resultModal.view')}
33
+ onCancel={onCancel}
34
+ onOk={handleGoToMarket}
35
+ open={open}
36
+ title={null}
37
+ width={440}
38
+ >
39
+ <Result
40
+ icon={<FluentEmoji emoji={'🎉'} size={96} type={'anim'} />}
41
+ style={{
42
+ paddingBottom: 32,
43
+ paddingTop: 48,
44
+ width: '100%',
45
+ }}
46
+ subTitle={
47
+ <Text fontSize={14} type={'secondary'}>
48
+ {t('marketPublish.resultModal.messageGroup')}
49
+ </Text>
50
+ }
51
+ title={
52
+ <Text fontSize={28} weight={'bold'}>
53
+ {t('marketPublish.resultModal.title')}
54
+ </Text>
55
+ }
56
+ />
57
+ </Modal>
58
+ );
59
+ },
60
+ );
61
+
62
+ export default GroupPublishResultModal;