Files
FastGPT/projects/app/src/pageComponents/account/team/EditInfoModal.tsx
Archer 0720bbe4da V4.9.7 feature (#4669)
* update doc

* feat: Add coupon redemption feature for team subscriptions (#4595)

* feat: Add coupon redemption feature for team subscriptions

- Introduced `TeamCouponSub` and `TeamCouponSchema` types
- Added `redeemCoupon` API endpoint
- Updated UI to include a modal for coupon redemption
- Added new icon and translations for "Redeem coupon"

* perf: remove field teamId

* perf: use dynamic import

* refactor: move to page component

* perf: coupon code

* perf: mcp server

* perf: test

* auto layout (#4634)

* fix 4.9.6 (#4631)

* fix debug quote list

* delete next text node match

* fix extract default boolean value

* export latest 100 chat items

* fix quote item ui

* doc

* fix doc

* feat: auto layout

* perf: auto layout

* fix: auto layout null

* add start node

---------

Co-authored-by: heheer <heheer@sealos.io>

* fix: share link (#4644)

* Add workflow run duration;Get audio duration (#4645)

* add duration

* get audio duration

* Custom config path (#4649)

* feat: 通过环境变量DATA_PATH获取配置文件目录 (#4622)

通过环境变量DATA_PATH获取配置文件目录,以应对不同的部署方式的多样化需求

* feat: custom configjson path

* doc

---------

Co-authored-by: John Chen <sss1991@163.com>

* 程序api调用场景下,如果大量调用带有图片或视频,产生的聊天记录会导致后台mongo数据库异常。这个修改给api客户端一个禁止生成聊天记录的选项,避免这个后果。 (#3964)

* update special chatId

* perf: vector db rename

* update operationLog (#4647)

* update operationLog

* combine operationLogMap

* solve operationI18nLogMap bug

* remoce log

* feat: Rerank usage (#4654)

* refresh concat when update (#4655)

* fix: refresh code

* perf: timer lock

* Fix operationLog (#4657)

* perf: http streamable mcp

* add alipay (#4630)

* perf: subplan ui

* perf: pay code

* hiden bank tip

* Fix: pay error (#4665)

* fix quote number (#4666)

* remove log

---------

Co-authored-by: a.e. <49438478+I-Info@users.noreply.github.com>
Co-authored-by: heheer <heheer@sealos.io>
Co-authored-by: John Chen <sss1991@163.com>
Co-authored-by: gaord <bengao168@msn.com>
Co-authored-by: gggaaallleee <91131304+gggaaallleee@users.noreply.github.com>
2025-04-26 16:17:21 +08:00

205 lines
5.8 KiB
TypeScript

import React from 'react';
import { useForm } from 'react-hook-form';
import { useTranslation } from 'next-i18next';
import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
import { useRequest } from '@fastgpt/web/hooks/useRequest';
import MyModal from '@fastgpt/web/components/common/MyModal';
import {
Box,
Button,
Flex,
HStack,
Input,
ModalBody,
ModalFooter,
useDisclosure
} from '@chakra-ui/react';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import Avatar from '@fastgpt/web/components/common/Avatar';
import { postCreateTeam, putUpdateTeam } from '@/web/support/user/team/api';
import { CreateTeamProps } from '@fastgpt/global/support/user/team/controller.d';
import { DEFAULT_TEAM_AVATAR } from '@fastgpt/global/common/system/constants';
import Icon from '@fastgpt/web/components/common/Icon';
import dynamic from 'next/dynamic';
const UpdateContact = dynamic(() => import('@/components/support/user/inform/UpdateContactModal'));
export type EditTeamFormDataType = CreateTeamProps & {
id?: string;
notificationAccount?: string;
};
export const defaultForm = {
name: '',
avatar: DEFAULT_TEAM_AVATAR
};
function EditModal({
defaultData = defaultForm,
onClose,
onSuccess
}: {
defaultData?: EditTeamFormDataType;
onClose: () => void;
onSuccess: () => void;
}) {
const { t } = useTranslation();
const { register, setValue, handleSubmit, watch } = useForm<CreateTeamProps>({
defaultValues: defaultData
});
const avatar = watch('avatar');
const notificationAccount = watch('notificationAccount');
const {
File,
onOpen: onOpenSelectFile,
onSelectImage
} = useSelectFile({
fileType: '.jpg,.png,.svg',
multiple: false
});
const { mutate: onclickCreate, isLoading: creating } = useRequest({
mutationFn: async (data: CreateTeamProps) => {
return postCreateTeam(data);
},
onSuccess() {
onSuccess();
onClose();
},
successToast: t('common:common.Create Success'),
errorToast: t('common:common.Create Failed')
});
const { mutate: onclickUpdate, isLoading: updating } = useRequest({
mutationFn: async (data: EditTeamFormDataType) => {
if (!data.id) return Promise.resolve('');
return putUpdateTeam({
name: data.name,
avatar: data.avatar
});
},
onSuccess() {
onSuccess();
onClose();
},
successToast: t('common:common.Update Success'),
errorToast: t('common:common.Update Failed')
});
const { isOpen: isOpenContact, onClose: onCloseContact, onOpen: onOpenContact } = useDisclosure();
return (
<MyModal
isOpen
onClose={onClose}
iconSrc="support/team/group"
iconColor="primary.600"
title={defaultData.id ? t('user:team.Update Team') : t('user:team.Create Team')}
>
<ModalBody>
<Box color={'myGray.800'} fontWeight={'bold'}>
{t('account_team:set_name_avatar')}
</Box>
<Flex mt={3} alignItems={'center'}>
<MyTooltip label={t('common:common.Set Avatar')}>
<Avatar
flexShrink={0}
src={avatar}
w={['28px', '32px']}
h={['28px', '32px']}
cursor={'pointer'}
borderRadius={'md'}
onClick={onOpenSelectFile}
/>
</MyTooltip>
<Input
flex={1}
ml={4}
autoFocus
bg={'myWhite.600'}
maxLength={100}
placeholder={t('user:team.Team Name')}
{...register('name', {
required: t('common:common.Please Input Name')
})}
/>
</Flex>
<Box color={'myGray.800'} fontWeight={'bold'} mt={4}>
{t('account_team:notification_recieve')}
</Box>
<HStack w="full" justifyContent={'space-between'}>
{(() => {
return notificationAccount ? (
<Box width="full">{notificationAccount}</Box>
) : (
<HStack
px="3"
py="1"
color="red.600"
bgColor="red.50"
borderRadius="md"
fontSize={'sm'}
width={'fit-content'}
>
<Icon name="common/info" w="1rem" />
<Box width="fit-content">{t('account_team:please_bind_contact')}</Box>
</HStack>
);
})()}
<Button
variant={'whiteBase'}
leftIcon={<Icon name="common/setting" w="1rem" />}
onClick={() => {
onOpenContact();
}}
>
{t('common:common.Setting')}
</Button>
</HStack>
</ModalBody>
<ModalFooter>
{!!defaultData.id ? (
<>
<Box flex={1} />
<Button variant={'whiteBase'} mr={3} onClick={onClose}>
{t('common:common.Close')}
</Button>
<Button isLoading={updating} onClick={handleSubmit((data) => onclickUpdate(data))}>
{t('common:common.Confirm Update')}
</Button>
</>
) : (
<Button
w={'100%'}
isLoading={creating}
onClick={handleSubmit((data) => onclickCreate(data))}
>
{t('common:common.Confirm Create')}
</Button>
)}
</ModalFooter>
<File
onSelect={(e) =>
onSelectImage(e, {
maxH: 300,
maxW: 300,
callback: (e) => setValue('avatar', e)
})
}
/>
{isOpenContact && (
<UpdateContact
onClose={onCloseContact}
onSuccess={(val) => {
setValue('notificationAccount', val);
}}
mode="notification_account"
/>
)}
</MyModal>
);
}
export default React.memo(EditModal);