From ced401bd6805518fcdbb50071d2abd9acec58c35 Mon Sep 17 00:00:00 2001 From: bill Date: Wed, 3 Dec 2025 14:07:45 +0800 Subject: [PATCH] Feat: Delete user profile page --- web/src/pages/profile-setting/components.tsx | 24 - web/src/pages/profile-setting/hooks.tsx | 20 - web/src/pages/profile-setting/index.tsx | 47 -- .../profile-setting/mcp/edit-mcp-dialog.tsx | 178 -------- .../profile-setting/mcp/edit-mcp-form.tsx | 171 -------- .../mcp/import-mcp-dialog/import-mcp-form.tsx | 72 --- .../mcp/import-mcp-dialog/index.tsx | 36 -- web/src/pages/profile-setting/mcp/index.tsx | 157 ------- .../pages/profile-setting/mcp/mcp-card.tsx | 74 ---- .../profile-setting/mcp/mcp-operation.tsx | 43 -- .../pages/profile-setting/mcp/tool-card.tsx | 16 - .../mcp/use-bulk-operate-mcp.tsx | 56 --- .../pages/profile-setting/mcp/use-edit-mcp.ts | 53 --- .../profile-setting/mcp/use-export-mcp.ts | 21 - .../profile-setting/mcp/use-import-mcp.ts | 73 ---- web/src/pages/profile-setting/model/index.tsx | 44 -- .../profile-setting/model/model-card.tsx | 136 ------ web/src/pages/profile-setting/plan/index.tsx | 121 ----- .../profile-setting/plan/pricing-card.tsx | 86 ---- .../profile/hooks/use-profile.ts | 151 ------- .../pages/profile-setting/profile/index.tsx | 412 ------------------ .../pages/profile-setting/prompt/index.tsx | 48 -- .../pages/profile-setting/sidebar/hooks.tsx | 24 - .../pages/profile-setting/sidebar/index.tsx | 113 ----- web/src/pages/profile-setting/team/index.tsx | 107 ----- web/src/routes.ts | 70 +-- 26 files changed, 35 insertions(+), 2318 deletions(-) delete mode 100644 web/src/pages/profile-setting/components.tsx delete mode 100644 web/src/pages/profile-setting/hooks.tsx delete mode 100644 web/src/pages/profile-setting/index.tsx delete mode 100644 web/src/pages/profile-setting/mcp/edit-mcp-dialog.tsx delete mode 100644 web/src/pages/profile-setting/mcp/edit-mcp-form.tsx delete mode 100644 web/src/pages/profile-setting/mcp/import-mcp-dialog/import-mcp-form.tsx delete mode 100644 web/src/pages/profile-setting/mcp/import-mcp-dialog/index.tsx delete mode 100644 web/src/pages/profile-setting/mcp/index.tsx delete mode 100644 web/src/pages/profile-setting/mcp/mcp-card.tsx delete mode 100644 web/src/pages/profile-setting/mcp/mcp-operation.tsx delete mode 100644 web/src/pages/profile-setting/mcp/tool-card.tsx delete mode 100644 web/src/pages/profile-setting/mcp/use-bulk-operate-mcp.tsx delete mode 100644 web/src/pages/profile-setting/mcp/use-edit-mcp.ts delete mode 100644 web/src/pages/profile-setting/mcp/use-export-mcp.ts delete mode 100644 web/src/pages/profile-setting/mcp/use-import-mcp.ts delete mode 100644 web/src/pages/profile-setting/model/index.tsx delete mode 100644 web/src/pages/profile-setting/model/model-card.tsx delete mode 100644 web/src/pages/profile-setting/plan/index.tsx delete mode 100644 web/src/pages/profile-setting/plan/pricing-card.tsx delete mode 100644 web/src/pages/profile-setting/profile/hooks/use-profile.ts delete mode 100644 web/src/pages/profile-setting/profile/index.tsx delete mode 100644 web/src/pages/profile-setting/prompt/index.tsx delete mode 100644 web/src/pages/profile-setting/sidebar/hooks.tsx delete mode 100644 web/src/pages/profile-setting/sidebar/index.tsx delete mode 100644 web/src/pages/profile-setting/team/index.tsx diff --git a/web/src/pages/profile-setting/components.tsx b/web/src/pages/profile-setting/components.tsx deleted file mode 100644 index a2ee73acd..000000000 --- a/web/src/pages/profile-setting/components.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { Card, CardContent, CardHeader } from '@/components/ui/card'; -import { PropsWithChildren } from 'react'; - -export function Title({ children }: PropsWithChildren) { - return {children}; -} - -type ProfileSettingWrapperCardProps = { - header: React.ReactNode; -} & PropsWithChildren; - -export function ProfileSettingWrapperCard({ - header, - children, -}: ProfileSettingWrapperCardProps) { - return ( - - - {header} - - {children} - - ); -} diff --git a/web/src/pages/profile-setting/hooks.tsx b/web/src/pages/profile-setting/hooks.tsx deleted file mode 100644 index 364cff2b0..000000000 --- a/web/src/pages/profile-setting/hooks.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { ProfileSettingRouteKey } from '@/constants/setting'; -import { useSecondPathName } from '@/hooks/route-hook'; - -export const useGetPageTitle = (): string => { - const pathName = useSecondPathName(); - - const LabelMap = { - [ProfileSettingRouteKey.Profile]: 'User profile', - [ProfileSettingRouteKey.Plan]: 'Plan & balance', - [ProfileSettingRouteKey.Model]: 'Model management', - [ProfileSettingRouteKey.System]: 'System', - [ProfileSettingRouteKey.Api]: 'Api', - [ProfileSettingRouteKey.Team]: 'Team management', - [ProfileSettingRouteKey.Prompt]: 'Prompt management', - [ProfileSettingRouteKey.Chunk]: 'Chunking method', - [ProfileSettingRouteKey.Logout]: 'Logout', - }; - - return LabelMap[pathName as ProfileSettingRouteKey]; -}; diff --git a/web/src/pages/profile-setting/index.tsx b/web/src/pages/profile-setting/index.tsx deleted file mode 100644 index 88be7acd9..000000000 --- a/web/src/pages/profile-setting/index.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { PageHeader } from '@/components/page-header'; -import { - Breadcrumb, - BreadcrumbItem, - BreadcrumbLink, - BreadcrumbList, - BreadcrumbPage, - BreadcrumbSeparator, -} from '@/components/ui/breadcrumb'; -import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks'; -import { House } from 'lucide-react'; -import { useTranslation } from 'react-i18next'; -import { Outlet } from 'umi'; -import { SideBar } from './sidebar'; - -export default function ProfileSetting() { - const { navigateToHome } = useNavigatePage(); - const { t } = useTranslation(); - - return ( -
- - - - - - - - - - - {t('setting.profile')} - - - - - -
- - -
- -
-
-
- ); -} diff --git a/web/src/pages/profile-setting/mcp/edit-mcp-dialog.tsx b/web/src/pages/profile-setting/mcp/edit-mcp-dialog.tsx deleted file mode 100644 index e62c1007e..000000000 --- a/web/src/pages/profile-setting/mcp/edit-mcp-dialog.tsx +++ /dev/null @@ -1,178 +0,0 @@ -import { Collapse } from '@/components/collapse'; -import { Button, ButtonLoading } from '@/components/ui/button'; -import { Card, CardContent } from '@/components/ui/card'; -import { - Dialog, - DialogClose, - DialogContent, - DialogFooter, - DialogHeader, - DialogTitle, -} from '@/components/ui/dialog'; -import { useGetMcpServer, useTestMcpServer } from '@/hooks/use-mcp-request'; -import { IModalProps } from '@/interfaces/common'; -import { IMCPTool, IMCPToolObject } from '@/interfaces/database/mcp'; -import { cn } from '@/lib/utils'; -import { zodResolver } from '@hookform/resolvers/zod'; -import { isEmpty, omit, pick } from 'lodash'; -import { RefreshCw } from 'lucide-react'; -import { - MouseEventHandler, - useCallback, - useEffect, - useMemo, - useState, -} from 'react'; -import { useForm } from 'react-hook-form'; -import { useTranslation } from 'react-i18next'; -import { z } from 'zod'; -import { - EditMcpForm, - FormId, - ServerType, - useBuildFormSchema, -} from './edit-mcp-form'; -import { McpToolCard } from './tool-card'; - -function transferToolToArray(tools: IMCPToolObject) { - return Object.entries(tools).reduce((pre, [name, tool]) => { - pre.push({ ...tool, name }); - return pre; - }, []); -} - -const DefaultValues = { - name: '', - server_type: ServerType.SSE, - url: '', -}; - -export function EditMcpDialog({ - hideModal, - loading, - onOk, - id, -}: IModalProps & { id: string }) { - const { t } = useTranslation(); - const { - testMcpServer, - data: testData, - loading: testLoading, - } = useTestMcpServer(); - const [isTriggeredBySaving, setIsTriggeredBySaving] = useState(false); - const FormSchema = useBuildFormSchema(); - const [collapseOpen, setCollapseOpen] = useState(true); - const { data } = useGetMcpServer(id); - const [fieldChanged, setFieldChanged] = useState(false); - - const tools = useMemo(() => { - return testData?.data || []; - }, [testData?.data]); - - const form = useForm>({ - resolver: zodResolver(FormSchema), - defaultValues: DefaultValues, - }); - - const handleTest: MouseEventHandler = useCallback((e) => { - e.stopPropagation(); - setIsTriggeredBySaving(false); - }, []); - - const handleSave: MouseEventHandler = useCallback(() => { - setIsTriggeredBySaving(true); - }, []); - - const handleOk = async (values: z.infer) => { - const nextValues = { - ...omit(values, 'authorization_token'), - variables: { authorization_token: values.authorization_token }, - headers: { Authorization: 'Bearer ${authorization_token}' }, - }; - if (isTriggeredBySaving) { - onOk?.(nextValues); - } else { - const ret = await testMcpServer(nextValues); - if (ret.code === 0) { - setFieldChanged(false); - } - } - }; - - useEffect(() => { - if (!isEmpty(data)) { - form.reset(pick(data, ['name', 'server_type', 'url'])); - } - }, [data, form]); - - const nextTools = useMemo(() => { - return isEmpty(tools) - ? transferToolToArray(data.variables?.tools || {}) - : tools; - }, [data.variables?.tools, tools]); - - const disabled = !!!tools?.length || testLoading || fieldChanged; - - return ( - - - - {id ? t('mcp.editMCP') : t('mcp.addMCP')} - - - - - - {nextTools?.length || 0} {t('mcp.toolsAvailable')} - - } - open={collapseOpen} - onOpenChange={setCollapseOpen} - rightContent={ - - } - > -
- {nextTools?.map((x) => ( - - ))} -
-
-
-
- - - - - - {t('common.save')} - - -
-
- ); -} diff --git a/web/src/pages/profile-setting/mcp/edit-mcp-form.tsx b/web/src/pages/profile-setting/mcp/edit-mcp-form.tsx deleted file mode 100644 index d6b49db11..000000000 --- a/web/src/pages/profile-setting/mcp/edit-mcp-form.tsx +++ /dev/null @@ -1,171 +0,0 @@ -'use client'; - -import { UseFormReturn } from 'react-hook-form'; -import { z } from 'zod'; - -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from '@/components/ui/form'; -import { Input } from '@/components/ui/input'; -import { RAGFlowSelect } from '@/components/ui/select'; -import { IModalProps } from '@/interfaces/common'; -import { buildOptions } from '@/utils/form'; -import { loader } from '@monaco-editor/react'; -import { Dispatch, SetStateAction } from 'react'; -import { useTranslation } from 'react-i18next'; - -loader.config({ paths: { vs: '/vs' } }); - -export const FormId = 'EditMcpForm'; - -export enum ServerType { - SSE = 'sse', - StreamableHttp = 'streamable-http', -} - -const ServerTypeOptions = buildOptions(ServerType); - -export function useBuildFormSchema() { - const { t } = useTranslation(); - - const FormSchema = z.object({ - name: z - .string() - .min(1, { - message: t('common.mcp.namePlaceholder'), - }) - .regex(/^[a-zA-Z0-9_-]{1,64}$/, { - message: t('common.mcp.nameRequired'), - }) - .trim(), - url: z - .string() - .url() - .min(1, { - message: t('common.mcp.urlPlaceholder'), - }) - .trim(), - server_type: z - .string() - .min(1, { - message: t('common.pleaseSelect'), - }) - .trim(), - authorization_token: z.string().optional(), - }); - - return FormSchema; -} - -export function EditMcpForm({ - form, - onOk, - setFieldChanged, -}: IModalProps & { - form: UseFormReturn; - setFieldChanged: Dispatch>; -}) { - const { t } = useTranslation(); - const FormSchema = useBuildFormSchema(); - - function onSubmit(data: z.infer) { - onOk?.(data); - } - - return ( -
- - ( - - {t('common.name')} - - - - - - )} - /> - ( - - {t('mcp.url')} - - { - field.onChange(e.target.value.trim()); - setFieldChanged(true); - }} - /> - - - - )} - /> - ( - - {t('mcp.serverType')} - - { - field.onChange(value); - setFieldChanged(true); - }} - /> - - - - )} - /> - ( - - Authorization Token - - { - field.onChange(e.target.value.trim()); - setFieldChanged(true); - }} - /> - - - - )} - /> - - - ); -} diff --git a/web/src/pages/profile-setting/mcp/import-mcp-dialog/import-mcp-form.tsx b/web/src/pages/profile-setting/mcp/import-mcp-dialog/import-mcp-form.tsx deleted file mode 100644 index 6408b9e18..000000000 --- a/web/src/pages/profile-setting/mcp/import-mcp-dialog/import-mcp-form.tsx +++ /dev/null @@ -1,72 +0,0 @@ -'use client'; - -import { zodResolver } from '@hookform/resolvers/zod'; -import { useForm } from 'react-hook-form'; -import { z } from 'zod'; - -import { FileUploader } from '@/components/file-uploader'; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from '@/components/ui/form'; -import { FileMimeType, Platform } from '@/constants/common'; -import { TagRenameId } from '@/constants/knowledge'; -import { IModalProps } from '@/interfaces/common'; -import { useTranslation } from 'react-i18next'; - -export function ImportMcpForm({ hideModal, onOk }: IModalProps) { - const { t } = useTranslation(); - const FormSchema = z.object({ - platform: z - .string() - .min(1, { - message: t('common.namePlaceholder'), - }) - .trim(), - fileList: z.array(z.instanceof(File)), - }); - - const form = useForm>({ - resolver: zodResolver(FormSchema), - defaultValues: { platform: Platform.RAGFlow }, - }); - - async function onSubmit(data: z.infer) { - const ret = await onOk?.(data); - if (ret) { - hideModal?.(); - } - } - - return ( -
- - ( - - {t('common.name')} - - - - - - )} - /> - - - ); -} diff --git a/web/src/pages/profile-setting/mcp/import-mcp-dialog/index.tsx b/web/src/pages/profile-setting/mcp/import-mcp-dialog/index.tsx deleted file mode 100644 index 1946523eb..000000000 --- a/web/src/pages/profile-setting/mcp/import-mcp-dialog/index.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { - Dialog, - DialogContent, - DialogFooter, - DialogHeader, - DialogTitle, -} from '@/components/ui/dialog'; -import { LoadingButton } from '@/components/ui/loading-button'; -import { TagRenameId } from '@/constants/knowledge'; -import { IModalProps } from '@/interfaces/common'; -import { useTranslation } from 'react-i18next'; -import { ImportMcpForm } from './import-mcp-form'; - -export function ImportMcpDialog({ - hideModal, - onOk, - loading, -}: IModalProps) { - const { t } = useTranslation(); - - return ( - - - - {t('mcp.import')} - - - - - {t('common.save')} - - - - - ); -} diff --git a/web/src/pages/profile-setting/mcp/index.tsx b/web/src/pages/profile-setting/mcp/index.tsx deleted file mode 100644 index d790ac6d3..000000000 --- a/web/src/pages/profile-setting/mcp/index.tsx +++ /dev/null @@ -1,157 +0,0 @@ -import { CardContainer } from '@/components/card-container'; -import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog'; -import Spotlight from '@/components/spotlight'; -import { Button } from '@/components/ui/button'; -import { Checkbox } from '@/components/ui/checkbox'; -import { SearchInput } from '@/components/ui/input'; -import { Label } from '@/components/ui/label'; -import { RAGFlowPagination } from '@/components/ui/ragflow-pagination'; -import { useListMcpServer } from '@/hooks/use-mcp-request'; -import { pick } from 'lodash'; -import { - Download, - LayoutList, - ListChecks, - Plus, - Trash2, - Upload, -} from 'lucide-react'; -import { useCallback, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { ProfileSettingWrapperCard } from '../components'; -import { EditMcpDialog } from './edit-mcp-dialog'; -import { ImportMcpDialog } from './import-mcp-dialog'; -import { McpCard } from './mcp-card'; -import { useBulkOperateMCP } from './use-bulk-operate-mcp'; -import { useEditMcp } from './use-edit-mcp'; -import { useImportMcp } from './use-import-mcp'; - -export default function McpServer() { - const { data, setPagination, searchString, handleInputChange, pagination } = - useListMcpServer(); - const { editVisible, showEditModal, hideEditModal, handleOk, id, loading } = - useEditMcp(); - const { - selectedList, - handleSelectChange, - handleDelete, - handleExportMcp, - handleSelectAll, - } = useBulkOperateMCP(data.mcp_servers); - const { t } = useTranslation(); - const { importVisible, showImportModal, hideImportModal, onImportOk } = - useImportMcp(); - - const [isSelectionMode, setSelectionMode] = useState(false); - - const handlePageChange = useCallback( - (page: number, pageSize?: number) => { - setPagination({ page, pageSize }); - }, - [setPagination], - ); - - const switchSelectionMode = useCallback(() => { - setSelectionMode((prev) => !prev); - }, []); - - return ( - -
- {t('mcp.mcpServers')} -
-
-
- {t('mcp.customizeTheListOfMcpServers')} -
-
- - - - -
-
- - } - > - {isSelectionMode && ( -
- - - - {t('mcp.selected')} {selectedList.length} - -
- - - - -
-
- )} - - {data.mcp_servers.map((item) => ( - - ))} - -
- -
- {editVisible && ( - - )} - {importVisible && ( - - )} - -
- ); -} diff --git a/web/src/pages/profile-setting/mcp/mcp-card.tsx b/web/src/pages/profile-setting/mcp/mcp-card.tsx deleted file mode 100644 index b0cfcd162..000000000 --- a/web/src/pages/profile-setting/mcp/mcp-card.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { Card, CardContent } from '@/components/ui/card'; -import { Checkbox } from '@/components/ui/checkbox'; -import { IMcpServer } from '@/interfaces/database/mcp'; -import { formatDate } from '@/utils/date'; -import { isPlainObject } from 'lodash'; -import { useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; -import { McpOperation } from './mcp-operation'; -import { UseBulkOperateMCPReturnType } from './use-bulk-operate-mcp'; -import { UseEditMcpReturnType } from './use-edit-mcp'; - -export type DatasetCardProps = { - data: IMcpServer; - isSelectionMode: boolean; -} & Pick & - Pick; - -export function McpCard({ - data, - selectedList, - handleSelectChange, - showEditModal, - isSelectionMode, -}: DatasetCardProps) { - const { t } = useTranslation(); - const toolLength = useMemo(() => { - const tools = data.variables?.tools; - if (isPlainObject(tools)) { - return Object.keys(tools || {}).length; - } - return 0; - }, [data.variables?.tools]); - const onCheckedChange = (checked: boolean) => { - if (typeof checked === 'boolean') { - handleSelectChange(data.id, checked); - } - }; - - return ( - - -
-

- {data.name} -

-
- {isSelectionMode ? ( - { - e.stopPropagation(); - }} - /> - ) : ( - - )} -
-
-
-
-
- {toolLength} {t('mcp.cachedTools')} -
-

{formatDate(data.update_date)}

-
-
-
-
- ); -} diff --git a/web/src/pages/profile-setting/mcp/mcp-operation.tsx b/web/src/pages/profile-setting/mcp/mcp-operation.tsx deleted file mode 100644 index 9bbd9e5c8..000000000 --- a/web/src/pages/profile-setting/mcp/mcp-operation.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog'; -import { RAGFlowTooltip } from '@/components/ui/tooltip'; -import { useDeleteMcpServer } from '@/hooks/use-mcp-request'; -import { PenLine, Trash2, Upload } from 'lucide-react'; -import { MouseEventHandler, useCallback } from 'react'; -import { useTranslation } from 'react-i18next'; -import { UseEditMcpReturnType } from './use-edit-mcp'; -import { useExportMcp } from './use-export-mcp'; - -export function McpOperation({ - mcpId, - showEditModal, -}: { mcpId: string } & Pick) { - const { t } = useTranslation(); - const { deleteMcpServer } = useDeleteMcpServer(); - const { handleExportMcpJson } = useExportMcp(); - - const handleDelete: MouseEventHandler = useCallback(() => { - deleteMcpServer([mcpId]); - }, [deleteMcpServer, mcpId]); - - return ( -
- - - - - - - - - - - -
- ); -} diff --git a/web/src/pages/profile-setting/mcp/tool-card.tsx b/web/src/pages/profile-setting/mcp/tool-card.tsx deleted file mode 100644 index 123b4a611..000000000 --- a/web/src/pages/profile-setting/mcp/tool-card.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { IMCPTool } from '@/interfaces/database/mcp'; - -export type McpToolCardProps = { - data: IMCPTool; -}; - -export function McpToolCard({ data }: McpToolCardProps) { - return ( -
-

{data.name}

-
- {data.description} -
-
- ); -} diff --git a/web/src/pages/profile-setting/mcp/use-bulk-operate-mcp.tsx b/web/src/pages/profile-setting/mcp/use-bulk-operate-mcp.tsx deleted file mode 100644 index 2afef8347..000000000 --- a/web/src/pages/profile-setting/mcp/use-bulk-operate-mcp.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { useDeleteMcpServer } from '@/hooks/use-mcp-request'; -import { IMcpServer } from '@/interfaces/database/mcp'; -import { Trash2, Upload } from 'lucide-react'; -import { useCallback, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { useExportMcp } from './use-export-mcp'; - -export function useBulkOperateMCP(mcpList: IMcpServer[]) { - const { t } = useTranslation(); - const [selectedList, setSelectedList] = useState>([]); - const { deleteMcpServer } = useDeleteMcpServer(); - const { handleExportMcpJson } = useExportMcp(); - - const handleDelete = useCallback(() => { - deleteMcpServer(selectedList); - }, [deleteMcpServer, selectedList]); - - const handleSelectChange = useCallback((id: string, checked: boolean) => { - setSelectedList((list) => { - return checked ? [...list, id] : list.filter((item) => item !== id); - }); - }, []); - - const handleSelectAll = useCallback( - (checked: boolean) => { - setSelectedList(() => (checked ? mcpList.map((item) => item.id) : [])); - }, - [mcpList], - ); - - const list = [ - { - id: 'export', - label: t('mcp.export'), - icon: , - onClick: handleExportMcpJson(selectedList), - }, - { - id: 'delete', - label: t('common.delete'), - icon: , - onClick: handleDelete, - }, - ]; - - return { - list, - selectedList, - handleSelectChange, - handleDelete, - handleExportMcp: handleExportMcpJson(selectedList), - handleSelectAll, - }; -} - -export type UseBulkOperateMCPReturnType = ReturnType; diff --git a/web/src/pages/profile-setting/mcp/use-edit-mcp.ts b/web/src/pages/profile-setting/mcp/use-edit-mcp.ts deleted file mode 100644 index 09fc83be5..000000000 --- a/web/src/pages/profile-setting/mcp/use-edit-mcp.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { useSetModalState } from '@/hooks/common-hooks'; -import { - useCreateMcpServer, - useUpdateMcpServer, -} from '@/hooks/use-mcp-request'; -import { useCallback, useState } from 'react'; - -export const useEditMcp = () => { - const { - visible: editVisible, - hideModal: hideEditModal, - showModal: showEditModal, - } = useSetModalState(); - const { createMcpServer, loading } = useCreateMcpServer(); - const [id, setId] = useState(''); - - const { updateMcpServer, loading: updateLoading } = useUpdateMcpServer(); - - const handleShowModal = useCallback( - (id: string) => () => { - setId(id); - showEditModal(); - }, - [setId, showEditModal], - ); - - const handleOk = useCallback( - async (values: any) => { - let code; - if (id) { - code = await updateMcpServer({ ...values, mcp_id: id }); - } else { - code = await createMcpServer(values); - } - if (code === 0) { - hideEditModal(); - } - }, - [createMcpServer, hideEditModal, id, updateMcpServer], - ); - - return { - editVisible, - hideEditModal, - showEditModal: handleShowModal, - loading: loading || updateLoading, - createMcpServer, - handleOk, - id, - }; -}; - -export type UseEditMcpReturnType = ReturnType; diff --git a/web/src/pages/profile-setting/mcp/use-export-mcp.ts b/web/src/pages/profile-setting/mcp/use-export-mcp.ts deleted file mode 100644 index 636290c91..000000000 --- a/web/src/pages/profile-setting/mcp/use-export-mcp.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { useExportMcpServer } from '@/hooks/use-mcp-request'; -import { downloadJsonFile } from '@/utils/file-util'; -import { useCallback } from 'react'; - -export function useExportMcp() { - const { exportMcpServer } = useExportMcpServer(); - - const handleExportMcpJson = useCallback( - (ids: string[]) => async () => { - const data = await exportMcpServer(ids); - if (data.code === 0) { - downloadJsonFile(data.data, `mcp.json`); - } - }, - [exportMcpServer], - ); - - return { - handleExportMcpJson, - }; -} diff --git a/web/src/pages/profile-setting/mcp/use-import-mcp.ts b/web/src/pages/profile-setting/mcp/use-import-mcp.ts deleted file mode 100644 index 33e844191..000000000 --- a/web/src/pages/profile-setting/mcp/use-import-mcp.ts +++ /dev/null @@ -1,73 +0,0 @@ -import message from '@/components/ui/message'; -import { FileMimeType } from '@/constants/common'; -import { useSetModalState } from '@/hooks/common-hooks'; -import { useImportMcpServer } from '@/hooks/use-mcp-request'; -import { isEmpty } from 'lodash'; -import { useCallback } from 'react'; -import { useTranslation } from 'react-i18next'; -import { z } from 'zod'; - -const ServerEntrySchema = z.object({ - authorization_token: z.string().optional(), - name: z.string().optional(), - tool_configuration: z.object({}).passthrough().optional(), - type: z.string(), - url: z.string().url(), -}); - -const McpConfigSchema = z.object({ - mcpServers: z.record(ServerEntrySchema), -}); - -export const useImportMcp = () => { - const { - visible: importVisible, - hideModal: hideImportModal, - showModal: showImportModal, - } = useSetModalState(); - const { t } = useTranslation(); - const { importMcpServer, loading } = useImportMcpServer(); - - const onImportOk = useCallback( - async ({ fileList }: { fileList: File[] }) => { - if (fileList.length > 0) { - const file = fileList[0]; - if (file.type !== FileMimeType.Json) { - message.error(t('flow.jsonUploadTypeErrorMessage')); - return; - } - - const mcpStr = await file.text(); - const errorMessage = t('flow.jsonUploadContentErrorMessage'); - try { - const mcp = JSON.parse(mcpStr); - try { - McpConfigSchema.parse(mcp); - } catch (error) { - message.error('Incorrect data format'); - return; - } - if (mcpStr && !isEmpty(mcp)) { - const ret = await importMcpServer(mcp); - if (ret.code === 0) { - hideImportModal(); - } - } else { - message.error(errorMessage); - } - } catch (error) { - message.error(errorMessage); - } - } - }, - [hideImportModal, importMcpServer, t], - ); - - return { - importVisible, - showImportModal, - hideImportModal, - onImportOk, - loading, - }; -}; diff --git a/web/src/pages/profile-setting/model/index.tsx b/web/src/pages/profile-setting/model/index.tsx deleted file mode 100644 index 3f4457f7a..000000000 --- a/web/src/pages/profile-setting/model/index.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Button } from '@/components/ui/button'; -import { Input } from '@/components/ui/input'; -import { - AddModelCard, - ModelLibraryCard, - SystemModelSetting, -} from './model-card'; - -const addedModelList = new Array(4).fill(1); - -const modelLibraryList = new Array(4).fill(1); - -export default function ModelManagement() { - return ( -
-
-

Team management

- -
-
- -
-

Added model

-
- {addedModelList.map((x, idx) => ( - - ))} -
-
-
-
-

Model library

- -
-
- {modelLibraryList.map((x, idx) => ( - - ))} -
-
-
-
- ); -} diff --git a/web/src/pages/profile-setting/model/model-card.tsx b/web/src/pages/profile-setting/model/model-card.tsx deleted file mode 100644 index dad059298..000000000 --- a/web/src/pages/profile-setting/model/model-card.tsx +++ /dev/null @@ -1,136 +0,0 @@ -import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; -import { Button } from '@/components/ui/button'; -import { Card, CardContent } from '@/components/ui/card'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@/components/ui/select'; -import { Key, MoreVertical, Plus, Trash2 } from 'lucide-react'; -import { PropsWithChildren } from 'react'; - -const settings = [ - { - title: 'GPT Model', - description: - 'The default chat LLM all the newly created knowledgebase will use.', - model: 'DeepseekChat', - }, - { - title: 'Embedding Model', - description: - 'The default embedding model all the newly created knowledgebase will use.', - model: 'DeepseekChat', - }, - { - title: 'Image Model', - description: - 'The default multi-capable model all the newly created knowledgebase will use. It can generate a picture or video.', - model: 'DeepseekChat', - }, - { - title: 'Speech2TXT Model', - description: - 'The default ASR model all the newly created knowledgebase will use. Use this model to translate voices to text something text.', - model: 'DeepseekChat', - }, - { - title: 'TTS Model', - description: - 'The default text to speech model all the newly created knowledgebase will use.', - model: 'DeepseekChat', - }, -]; - -function Title({ children }: PropsWithChildren) { - return {children}; -} - -export function SystemModelSetting() { - return ( - - - {settings.map((x, idx) => ( -
-
- {x.title} - - {x.description} - -
-
- -
-
- ))} -
-
- ); -} - -export function AddModelCard() { - return ( - - -
- - - CN - - -
- Deep seek -

LLM,TEXT EMBEDDING, SPEECH2TEXT, MODERATION

- - - - - - -
- - -
-
-
- ); -} - -export function ModelLibraryCard() { - return ( - - - - - CN - - - Deep seek -

LLM,TEXT EMBEDDING, SPEECH2TEXT, MODERATION

- -
- -
-
-
- ); -} diff --git a/web/src/pages/profile-setting/plan/index.tsx b/web/src/pages/profile-setting/plan/index.tsx deleted file mode 100644 index 2da8dad37..000000000 --- a/web/src/pages/profile-setting/plan/index.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import { Button } from '@/components/ui/button'; -import { Card, CardContent } from '@/components/ui/card'; -import { Segmented, SegmentedValue } from '@/components/ui/segmented'; -import { CircleCheckBig, LogOut } from 'lucide-react'; -import { useMemo, useState } from 'react'; -import { PricingCard } from './pricing-card'; - -const pricingData = [ - { - title: 'Free', - price: '$0', - description: 'Meh, just looking', - features: [ - { name: 'Project', value: '1 project' }, - { name: 'Storage', value: '1 Gb' }, - { name: 'Team', value: '2 members' }, - { name: 'Features', value: 'Basic features' }, - ], - buttonText: 'Current plan', - buttonVariant: 'outline' as const, - }, - { - title: 'Pro', - price: '$16.00', - description: 'For professional use.', - features: [ - { name: 'Project', value: 'Unlimited projects' }, - { name: 'Storage', value: '100 Gb' }, - { name: 'Team', value: 'Unlimited members' }, - { name: 'Features', value: 'Basic features All advanced features' }, - ], - buttonText: 'Upgrade', - buttonVariant: 'default' as const, - isPro: true, - }, - { - title: 'Enterprise', - price: 'Customed', - description: - 'Get full capabilities and support for large-scale mission-critical systems.', - features: [ - { name: 'Project', value: 'Unlimited projects' }, - { name: 'Storage', value: '100 Gb' }, - { name: 'Team', value: 'Unlimited members' }, - { name: 'Features', value: 'Basic features All advanced features' }, - ], - buttonText: 'Contact us', - buttonVariant: 'secondary' as const, - isEnterprise: true, - }, -]; - -export default function Plan() { - const [val, setVal] = useState('monthly'); - const options = useMemo(() => { - return [ - { - label: 'Monthly', - value: 'monthly', - }, - { - label: 'Yearly', - value: 'yearly', - }, - ]; - }, []); - - const handleChange = (path: SegmentedValue) => { - setVal(path as string); - }; - - const list = [ - 'Full access to pro features', - 'Exclusive analyze models', - 'Create more teams', - 'Invite more collaborators', - ]; - - return ( -
-

Plan & balance

- -
- Balance - $ 100.00 -
-
- The value equals to 1,000 tokens or 10.00 GBs of storage - -
-
- - -
Upgrade to access
-
- {list.map((x, idx) => ( -
- - {x} -
- ))} -
- -
- {pricingData.map((plan, index) => ( - - ))} -
-
-
-
- ); -} diff --git a/web/src/pages/profile-setting/plan/pricing-card.tsx b/web/src/pages/profile-setting/plan/pricing-card.tsx deleted file mode 100644 index 2f0024cdf..000000000 --- a/web/src/pages/profile-setting/plan/pricing-card.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { Badge } from '@/components/ui/badge'; -import { Button } from '@/components/ui/button'; -import { Card, CardContent, CardHeader } from '@/components/ui/card'; -import { cn } from '@/lib/utils'; -import { Mail, Zap } from 'lucide-react'; - -interface PricingFeature { - name: string; - value: string; - tooltip?: string; -} - -interface PricingCardProps { - title: string; - price: string; - description: string; - features: PricingFeature[]; - buttonText: string; - buttonVariant?: 'default' | 'outline' | 'secondary'; - badge?: string; - isPro?: boolean; - isEnterprise?: boolean; -} - -export function PricingCard({ - title, - price, - description, - features, - buttonText, - isPro, - isEnterprise, -}: PricingCardProps) { - const isFree = title === 'Free'; - - return ( - - -
-
- - {isPro && } - {isEnterprise && } - {title} - -
-

- {description} -

-
-
-
- {price} - {price !== 'Customed' && ( - /mo - )} -
- -
-
- -
    - {features.map((feature, index) => ( -
  • -
    - {feature.name} -
    - - {feature.value} - -
  • - ))} -
-
-
- ); -} diff --git a/web/src/pages/profile-setting/profile/hooks/use-profile.ts b/web/src/pages/profile-setting/profile/hooks/use-profile.ts deleted file mode 100644 index 5b8bdf7b5..000000000 --- a/web/src/pages/profile-setting/profile/hooks/use-profile.ts +++ /dev/null @@ -1,151 +0,0 @@ -// src/hooks/useProfile.ts -import { - useFetchUserInfo, - useSaveSetting, -} from '@/hooks/use-user-setting-request'; -import { rsaPsw } from '@/utils'; -import { useCallback, useEffect, useState } from 'react'; - -interface ProfileData { - userName: string; - timeZone: string; - currPasswd?: string; - newPasswd?: string; - avatar: string; - email: string; - confirmPasswd?: string; -} - -export const EditType = { - editName: 'editName', - editTimeZone: 'editTimeZone', - editPassword: 'editPassword', -} as const; - -export type IEditType = keyof typeof EditType; - -export const modalTitle = { - [EditType.editName]: 'Edit Name', - [EditType.editTimeZone]: 'Edit Time Zone', - [EditType.editPassword]: 'Edit Password', -} as const; - -export const useProfile = () => { - const { data: userInfo } = useFetchUserInfo(); - const [profile, setProfile] = useState({ - userName: '', - avatar: '', - timeZone: '', - email: '', - currPasswd: '', - }); - - const [editType, setEditType] = useState(EditType.editName); - const [isEditing, setIsEditing] = useState(false); - const [editForm, setEditForm] = useState>({}); - const { - saveSetting, - loading: submitLoading, - data: saveSettingData, - } = useSaveSetting(); - - useEffect(() => { - // form.setValue('currPasswd', ''); // current password - const profile = { - userName: userInfo.nickname, - timeZone: userInfo.timezone, - avatar: userInfo.avatar || '', - email: userInfo.email, - currPasswd: userInfo.password, - }; - setProfile(profile); - }, [userInfo, setProfile]); - - useEffect(() => { - if (saveSettingData === 0) { - setIsEditing(false); - setEditForm({}); - } - }, [saveSettingData]); - const onSubmit = (newProfile: ProfileData) => { - const payload: Partial<{ - nickname: string; - password: string; - new_password: string; - avatar: string; - timezone: string; - }> = { - nickname: newProfile.userName, - avatar: newProfile.avatar, - timezone: newProfile.timeZone, - }; - - if ( - 'currPasswd' in newProfile && - 'newPasswd' in newProfile && - newProfile.currPasswd && - newProfile.newPasswd - ) { - payload.password = rsaPsw(newProfile.currPasswd!) as string; - payload.new_password = rsaPsw(newProfile.newPasswd!) as string; - } - console.log('payload', payload); - if (editType === EditType.editName && payload.nickname) { - saveSetting({ nickname: payload.nickname }); - setProfile(newProfile); - } - if (editType === EditType.editTimeZone && payload.timezone) { - saveSetting({ timezone: payload.timezone }); - setProfile(newProfile); - } - if (editType === EditType.editPassword && payload.password) { - saveSetting({ - password: payload.password, - new_password: payload.new_password, - }); - setProfile(newProfile); - } - // saveSetting(payload); - }; - - const handleEditClick = useCallback( - (type: IEditType) => { - setEditForm(profile); - setEditType(type); - setIsEditing(true); - }, - [profile], - ); - - const handleCancel = useCallback(() => { - setIsEditing(false); - setEditForm({}); - }, []); - - const handleSave = (data: ProfileData) => { - console.log('handleSave', data); - const newProfile = { ...profile, ...data }; - - onSubmit(newProfile); - // setIsEditing(false); - // setEditForm({}); - }; - - const handleAvatarUpload = (avatar: string) => { - setProfile((prev) => ({ ...prev, avatar })); - saveSetting({ avatar }); - }; - - return { - profile, - setProfile, - submitLoading: submitLoading, - isEditing, - editType, - editForm, - handleEditClick, - handleCancel, - handleSave, - handleAvatarUpload, - }; -}; diff --git a/web/src/pages/profile-setting/profile/index.tsx b/web/src/pages/profile-setting/profile/index.tsx deleted file mode 100644 index 7f8cf5676..000000000 --- a/web/src/pages/profile-setting/profile/index.tsx +++ /dev/null @@ -1,412 +0,0 @@ -// src/components/ProfilePage.tsx -import { AvatarUpload } from '@/components/avatar-upload'; -import PasswordInput from '@/components/originui/password-input'; -import { Button } from '@/components/ui/button'; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from '@/components/ui/form'; -import { Input } from '@/components/ui/input'; -import { Modal } from '@/components/ui/modal/modal'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@/components/ui/select'; -import { useTranslate } from '@/hooks/common-hooks'; -import { TimezoneList } from '@/pages/user-setting/constants'; -import { zodResolver } from '@hookform/resolvers/zod'; -import { t } from 'i18next'; -import { Loader2Icon, PenLine } from 'lucide-react'; -import { FC, useEffect } from 'react'; -import { useForm } from 'react-hook-form'; -import { z } from 'zod'; -import { EditType, modalTitle, useProfile } from './hooks/use-profile'; - -const baseSchema = z.object({ - userName: z - .string() - .min(1, { message: t('setting.usernameMessage') }) - .trim(), - timeZone: z - .string() - .trim() - .min(1, { message: t('setting.timezonePlaceholder') }), -}); - -const nameSchema = baseSchema.extend({ - currPasswd: z.string().optional(), - newPasswd: z.string().optional(), - confirmPasswd: z.string().optional(), -}); - -const passwordSchema = baseSchema - .extend({ - currPasswd: z - .string({ - required_error: t('setting.currentPasswordMessage'), - }) - .trim(), - newPasswd: z - .string({ - required_error: t('setting.newPasswordMessage'), - }) - .trim() - .min(8, { message: t('setting.newPasswordDescription') }), - confirmPasswd: z - .string({ - required_error: t('setting.confirmPasswordMessage'), - }) - .trim() - .min(8, { message: t('setting.newPasswordDescription') }), - }) - .superRefine((data, ctx) => { - if ( - data.newPasswd && - data.confirmPasswd && - data.newPasswd !== data.confirmPasswd - ) { - ctx.addIssue({ - path: ['confirmPasswd'], - message: t('setting.confirmPasswordNonMatchMessage'), - code: z.ZodIssueCode.custom, - }); - } - }); -const ProfilePage: FC = () => { - const { t } = useTranslate('setting'); - - const { - profile, - editType, - isEditing, - submitLoading, - editForm, - handleEditClick, - handleCancel, - handleSave, - handleAvatarUpload, - } = useProfile(); - - const form = useForm>({ - resolver: zodResolver( - editType === EditType.editPassword ? passwordSchema : nameSchema, - ), - defaultValues: { - userName: '', - timeZone: '', - }, - // shouldUnregister: true, - }); - useEffect(() => { - form.reset({ ...editForm, currPasswd: undefined }); - }, [editForm, form]); - - // const ModalContent: FC = () => { - // // let content = null; - // // if (editType === EditType.editName) { - // // content = editName(); - // // } - // return ( - // <> - - // - // ); - // }; - - return ( -
- {/* Header */} -
-

{t('profile')}

-
- {t('profileDescription')} -
-
- - {/* Main Content */} -
- {/* Name */} -
- -
-
- {profile.userName} -
- -
-
- - {/* Avatar */} -
- -
- -
-
- - {/* Time Zone */} -
- -
-
- {profile.timeZone} -
- -
-
- - {/* Email Address */} -
- -
-
- {profile.email} -
- - {t('emailDescription')} - -
-
- - {/* Password */} -
- -
-
- {profile.currPasswd ? '********' : ''} -
- -
-
-
- - {editType && ( - { - if (!open) { - handleCancel(); - } - }} - className="!w-[480px]" - > - {/* */} -
- handleSave(data as any))} - className="flex flex-col mt-6 mb-8 ml-2 space-y-6 " - > - {editType === EditType.editName && ( - ( - -
- - {t('username')} - - - - -
-
-
- -
-
- )} - /> - )} - - {editType === EditType.editTimeZone && ( - ( - -
- - {t('timezone')} - - -
-
-
- -
-
- )} - /> - )} - - {editType === EditType.editPassword && ( - <> - ( - -
- - {t('currentPassword')} - - - - -
-
- -
-
- )} - /> - ( - -
- - {t('newPassword')} - - - - -
-
- -
-
- )} - /> - ( - -
- - {t('confirmPassword')} - - - { - form.trigger('confirmPasswd'); - }} - onChange={(ev) => { - form.setValue( - 'confirmPasswd', - ev.target.value.trim(), - ); - }} - /> - -
-
- -
-
- )} - /> - - )} - -
- - -
- - -
- )} -
- ); -}; - -export default ProfilePage; diff --git a/web/src/pages/profile-setting/prompt/index.tsx b/web/src/pages/profile-setting/prompt/index.tsx deleted file mode 100644 index 0c569f01c..000000000 --- a/web/src/pages/profile-setting/prompt/index.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { Button } from '@/components/ui/button'; -import { Card, CardContent } from '@/components/ui/card'; -import { Plus, Trash2 } from 'lucide-react'; -import { Title } from '../components'; - -const text = `You are an intelligent assistant. Please summarize the content of the knowledge base to answer the question. Please list the data in the knowledge base and answer in detail. When all knowledge base content is irrelevant to the question, your answer must include the sentence "The answer you are looking for is not found in the knowledge base!" Answers need to consider chat history. - Here is the knowledge base: - {knowledge} - The above is the knowledge base.`; - -const PromptManagement = () => { - const modelLibraryList = new Array(8).fill(1); - - return ( -
-
-
-

Prompt templates

- -
-
-
- {modelLibraryList.map((x, idx) => ( - - - Prompt name -

{text}

- -
- - -
-
-
- ))} -
-
- ); -}; - -export default PromptManagement; diff --git a/web/src/pages/profile-setting/sidebar/hooks.tsx b/web/src/pages/profile-setting/sidebar/hooks.tsx deleted file mode 100644 index b50d1f52f..000000000 --- a/web/src/pages/profile-setting/sidebar/hooks.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { useLogout } from '@/hooks/use-login-request'; -import { Routes } from '@/routes'; -import { useCallback, useState } from 'react'; -import { useNavigate } from 'umi'; - -export const useHandleMenuClick = () => { - const navigate = useNavigate(); - const [active, setActive] = useState(); - const { logout } = useLogout(); - - const handleMenuClick = useCallback( - (key: Routes) => () => { - if (key === Routes.Logout) { - logout(); - } else { - setActive(key); - navigate(`${Routes.ProfileSetting}${key}`); - } - }, - [logout, navigate], - ); - - return { handleMenuClick, active }; -}; diff --git a/web/src/pages/profile-setting/sidebar/index.tsx b/web/src/pages/profile-setting/sidebar/index.tsx deleted file mode 100644 index 98b62db91..000000000 --- a/web/src/pages/profile-setting/sidebar/index.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import { RAGFlowAvatar } from '@/components/ragflow-avatar'; -import ThemeToggle from '@/components/theme-toggle'; -import { Button } from '@/components/ui/button'; -import { useSecondPathName } from '@/hooks/route-hook'; -import { useLogout } from '@/hooks/use-login-request'; -import { useFetchUserInfo } from '@/hooks/use-user-setting-request'; -import { cn } from '@/lib/utils'; -import { Routes } from '@/routes'; -import { - AlignEndVertical, - Banknote, - Box, - FileCog, - User, - Users, -} from 'lucide-react'; -import { useHandleMenuClick } from './hooks'; - -const menuItems = [ - { - section: 'Account & collaboration', - items: [ - { icon: User, label: 'Profile', key: Routes.Profile }, - { icon: Users, label: 'Team', key: Routes.Team }, - { icon: Banknote, label: 'Plan', key: Routes.Plan }, - { icon: Banknote, label: 'MCP', key: Routes.Mcp }, - ], - }, - { - section: 'System configurations', - items: [ - { - icon: Box, - label: 'Model management', - key: Routes.Model, - }, - { - icon: FileCog, - label: 'Prompt management', - key: Routes.Prompt, - }, - { - icon: AlignEndVertical, - label: 'Chunking method', - key: Routes.Chunk, - }, - ], - }, -]; - -export function SideBar() { - const pathName = useSecondPathName(); - const { data: userInfo } = useFetchUserInfo(); - const { handleMenuClick, active } = useHandleMenuClick(); - - const { logout } = useLogout(); - - return ( - - ); -} diff --git a/web/src/pages/profile-setting/team/index.tsx b/web/src/pages/profile-setting/team/index.tsx deleted file mode 100644 index c04d03b60..000000000 --- a/web/src/pages/profile-setting/team/index.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import { Button } from '@/components/ui/button'; -import { Card } from '@/components/ui/card'; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from '@/components/ui/dropdown-menu'; -import { Table, TableBody, TableCell, TableRow } from '@/components/ui/table'; -import { ChevronDown, MoreVertical, Plus, UserPlus } from 'lucide-react'; - -interface TeamMember { - email: string; - name: string; - role: string; -} - -const TeamManagement = () => { - const teamMembers: TeamMember[] = [ - { email: 'yifanwu92@gmail.com', name: 'Yifan Wu', role: 'Admin' }, - { email: 'yifanwu92@gmail.com', name: 'Yifan Wu', role: 'Admin' }, - ]; - - const stats = { - project: 1, - token: '1,000', - storage: '1GB', - }; - - return ( -
-
-
-

Team management

- -
- -
-
-

Yifan's team

- -
- - -
-
-

Project

-

{stats.project}

-
-
-

Token

-

{stats.token}

-
-
-

Storage

-

{stats.storage}

-
-
-
- - - - - {teamMembers.map((member, idx) => ( - - {member.email} - {member.name} - - - {member.role} - - - - - - - Edit - - Remove - - - - - - ))} - -
- - -
-
-
-
- ); -}; - -export default TeamManagement; diff --git a/web/src/routes.ts b/web/src/routes.ts index 306a5225f..215eff345 100644 --- a/web/src/routes.ts +++ b/web/src/routes.ts @@ -268,41 +268,41 @@ const routes = [ layout: false, component: `@/pages${Routes.Chunk}`, }, - { - path: Routes.ProfileSetting, - layout: false, - component: `@/pages${Routes.ProfileSetting}`, - routes: [ - { - path: Routes.ProfileSetting, - redirect: `${Routes.ProfileProfile}`, - }, - { - path: `${Routes.ProfileProfile}`, - component: `@/pages${Routes.ProfileProfile}`, - }, - { - path: `${Routes.ProfileTeam}`, - component: `@/pages${Routes.ProfileTeam}`, - }, - { - path: `${Routes.ProfilePlan}`, - component: `@/pages${Routes.ProfilePlan}`, - }, - { - path: `${Routes.ProfileModel}`, - component: `@/pages${Routes.ProfileModel}`, - }, - { - path: `${Routes.ProfilePrompt}`, - component: `@/pages${Routes.ProfilePrompt}`, - }, - { - path: Routes.ProfileMcp, - component: `@/pages${Routes.ProfileMcp}`, - }, - ], - }, + // { + // path: Routes.ProfileSetting, + // layout: false, + // component: `@/pages${Routes.ProfileSetting}`, + // routes: [ + // { + // path: Routes.ProfileSetting, + // redirect: `${Routes.ProfileProfile}`, + // }, + // { + // path: `${Routes.ProfileProfile}`, + // component: `@/pages${Routes.ProfileProfile}`, + // }, + // { + // path: `${Routes.ProfileTeam}`, + // component: `@/pages${Routes.ProfileTeam}`, + // }, + // { + // path: `${Routes.ProfilePlan}`, + // component: `@/pages${Routes.ProfilePlan}`, + // }, + // { + // path: `${Routes.ProfileModel}`, + // component: `@/pages${Routes.ProfileModel}`, + // }, + // { + // path: `${Routes.ProfilePrompt}`, + // component: `@/pages${Routes.ProfilePrompt}`, + // }, + // { + // path: Routes.ProfileMcp, + // component: `@/pages${Routes.ProfileMcp}`, + // }, + // ], + // }, { path: '/user-setting', component: '@/pages/user-setting',