refactor(web): migrate remaining toast usage (#34433)

This commit is contained in:
yyh
2026-04-02 12:16:50 +08:00
committed by GitHub
parent 2d29345f26
commit f9d9ad7a38
273 changed files with 3491 additions and 6996 deletions

View File

@@ -8,15 +8,14 @@ import { RiDeleteBin5Line, RiPencilLine } from '@remixicon/react'
import * as React from 'react'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import ImageInput from '@/app/components/base/app-icon-picker/ImageInput'
import getCroppedImg from '@/app/components/base/app-icon-picker/utils'
import { Avatar } from '@/app/components/base/avatar'
import Button from '@/app/components/base/button'
import Divider from '@/app/components/base/divider'
import { useLocalFileUploader } from '@/app/components/base/image-uploader/hooks'
import Modal from '@/app/components/base/modal'
import { ToastContext } from '@/app/components/base/toast/context'
import { Dialog, DialogContent } from '@/app/components/base/ui/dialog'
import { toast } from '@/app/components/base/ui/toast'
import { DISABLE_UPLOAD_IMAGE_AS_ICON } from '@/config'
import { updateUserProfile } from '@/service/common'
@@ -25,7 +24,6 @@ type AvatarWithEditProps = AvatarProps & { onSave?: () => void }
const AvatarWithEdit = ({ onSave, ...props }: AvatarWithEditProps) => {
const { t } = useTranslation()
const { notify } = useContext(ToastContext)
const [inputImageInfo, setInputImageInfo] = useState<InputImageInfo>()
const [isShowAvatarPicker, setIsShowAvatarPicker] = useState(false)
@@ -48,24 +46,24 @@ const AvatarWithEdit = ({ onSave, ...props }: AvatarWithEditProps) => {
await updateUserProfile({ url: 'account/avatar', body: { avatar: uploadedFileId } })
setIsShowAvatarPicker(false)
onSave?.()
notify({ type: 'success', message: t('actionMsg.modifiedSuccessfully', { ns: 'common' }) })
toast.success(t('actionMsg.modifiedSuccessfully', { ns: 'common' }))
}
catch (e) {
notify({ type: 'error', message: (e as Error).message })
toast.error((e as Error).message)
}
}, [notify, onSave, t])
}, [onSave, t])
const handleDeleteAvatar = useCallback(async () => {
try {
await updateUserProfile({ url: 'account/avatar', body: { avatar: '' } })
notify({ type: 'success', message: t('actionMsg.modifiedSuccessfully', { ns: 'common' }) })
toast.success(t('actionMsg.modifiedSuccessfully', { ns: 'common' }))
setIsShowDeleteConfirm(false)
onSave?.()
}
catch (e) {
notify({ type: 'error', message: (e as Error).message })
toast.error((e as Error).message)
}
}, [notify, onSave, t])
}, [onSave, t])
const { handleLocalFileUpload } = useLocalFileUploader({
limit: 3,
@@ -134,45 +132,39 @@ const AvatarWithEdit = ({ onSave, ...props }: AvatarWithEditProps) => {
</div>
</div>
<Modal
closable
className="!w-[362px] !p-0"
isShow={isShowAvatarPicker}
onClose={() => setIsShowAvatarPicker(false)}
>
<ImageInput onImageInput={handleImageInput} cropShape="round" />
<Divider className="m-0" />
<Dialog open={isShowAvatarPicker} onOpenChange={open => !open && setIsShowAvatarPicker(false)}>
<DialogContent className="!w-[362px] !p-0">
<ImageInput onImageInput={handleImageInput} cropShape="round" />
<Divider className="m-0" />
<div className="flex w-full items-center justify-center gap-2 p-3">
<Button className="w-full" onClick={() => setIsShowAvatarPicker(false)}>
{t('iconPicker.cancel', { ns: 'app' })}
</Button>
<div className="flex w-full items-center justify-center gap-2 p-3">
<Button className="w-full" onClick={() => setIsShowAvatarPicker(false)}>
{t('iconPicker.cancel', { ns: 'app' })}
</Button>
<Button variant="primary" className="w-full" disabled={uploading || !inputImageInfo} loading={uploading} onClick={handleSelect}>
{t('iconPicker.ok', { ns: 'app' })}
</Button>
</div>
</Modal>
<Button variant="primary" className="w-full" disabled={uploading || !inputImageInfo} loading={uploading} onClick={handleSelect}>
{t('iconPicker.ok', { ns: 'app' })}
</Button>
</div>
</DialogContent>
</Dialog>
<Modal
closable
className="!w-[362px] !p-6"
isShow={isShowDeleteConfirm}
onClose={() => setIsShowDeleteConfirm(false)}
>
<div className="mb-3 text-text-primary title-2xl-semi-bold">{t('avatar.deleteTitle', { ns: 'common' })}</div>
<p className="mb-8 text-text-secondary">{t('avatar.deleteDescription', { ns: 'common' })}</p>
<Dialog open={isShowDeleteConfirm} onOpenChange={open => !open && setIsShowDeleteConfirm(false)}>
<DialogContent className="!w-[362px] !p-6">
<div className="mb-3 text-text-primary title-2xl-semi-bold">{t('avatar.deleteTitle', { ns: 'common' })}</div>
<p className="mb-8 text-text-secondary">{t('avatar.deleteDescription', { ns: 'common' })}</p>
<div className="flex w-full items-center justify-center gap-2">
<Button className="w-full" onClick={() => setIsShowDeleteConfirm(false)}>
{t('operation.cancel', { ns: 'common' })}
</Button>
<div className="flex w-full items-center justify-center gap-2">
<Button className="w-full" onClick={() => setIsShowDeleteConfirm(false)}>
{t('operation.cancel', { ns: 'common' })}
</Button>
<Button variant="warning" className="w-full" onClick={handleDeleteAvatar}>
{t('operation.delete', { ns: 'common' })}
</Button>
</div>
</Modal>
<Button variant="warning" className="w-full" onClick={handleDeleteAvatar}>
{t('operation.delete', { ns: 'common' })}
</Button>
</div>
</DialogContent>
</Dialog>
</>
)
}