Chore: frontend infrastructure upgrade (#16420)
Co-authored-by: NFish <douxc512@gmail.com> Co-authored-by: zxhlyh <jasonapring2015@outlook.com> Co-authored-by: twwu <twwu@dify.ai> Co-authored-by: jZonG <jzongcode@gmail.com>
This commit is contained in:
parent
e61415223b
commit
7709d9df20
1435 changed files with 13372 additions and 11612 deletions
|
|
@ -83,13 +83,13 @@ const AvatarWithEdit = ({ onSave, ...props }: AvatarWithEditProps) => {
|
|||
return (
|
||||
<>
|
||||
<div>
|
||||
<div className="relative group">
|
||||
<div className="group relative">
|
||||
<Avatar {...props} />
|
||||
<div
|
||||
onClick={() => { setIsShowAvatarPicker(true) }}
|
||||
className="absolute inset-0 bg-black bg-opacity-50 rounded-full opacity-0 group-hover:opacity-100 transition-opacity cursor-pointer flex items-center justify-center"
|
||||
className="absolute inset-0 flex cursor-pointer items-center justify-center rounded-full bg-black bg-opacity-50 opacity-0 transition-opacity group-hover:opacity-100"
|
||||
>
|
||||
<span className="text-white text-xs">
|
||||
<span className="text-xs text-white">
|
||||
<RiPencilLine />
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -105,7 +105,7 @@ const AvatarWithEdit = ({ onSave, ...props }: AvatarWithEditProps) => {
|
|||
<ImageInput onImageInput={handleImageInput} cropShape='round' />
|
||||
<Divider className='m-0' />
|
||||
|
||||
<div className='w-full flex items-center justify-center p-3 gap-2'>
|
||||
<div className='flex w-full items-center justify-center gap-2 p-3'>
|
||||
<Button className='w-full' onClick={() => setIsShowAvatarPicker(false)}>
|
||||
{t('app.iconPicker.cancel')}
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -122,17 +122,17 @@ export default function AccountPage() {
|
|||
<div className='mr-3'>
|
||||
<AppIcon size='tiny' />
|
||||
</div>
|
||||
<div className='mt-[3px] system-sm-medium text-text-secondary'>{item.name}</div>
|
||||
<div className='system-sm-medium mt-[3px] text-text-secondary'>{item.name}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='pt-2 pb-3'>
|
||||
<div className='pb-3 pt-2'>
|
||||
<h4 className='title-2xl-semi-bold text-text-primary'>{t('common.account.myAccount')}</h4>
|
||||
</div>
|
||||
<div className='mb-8 p-6 rounded-xl flex items-center bg-gradient-to-r from-background-gradient-bg-fill-chat-bg-2 to-background-gradient-bg-fill-chat-bg-1'>
|
||||
<div className='mb-8 flex items-center rounded-xl bg-gradient-to-r from-background-gradient-bg-fill-chat-bg-2 to-background-gradient-bg-fill-chat-bg-1 p-6'>
|
||||
<AvatarWithEdit avatar={userProfile.avatar_url} name={userProfile.name} onSave={ mutateUserProfile } size={64} />
|
||||
<div className='ml-4'>
|
||||
<p className='system-xl-semibold text-text-primary'>{userProfile.name}</p>
|
||||
|
|
@ -141,19 +141,19 @@ export default function AccountPage() {
|
|||
</div>
|
||||
<div className='mb-8'>
|
||||
<div className={titleClassName}>{t('common.account.name')}</div>
|
||||
<div className='flex items-center justify-between gap-2 w-full mt-2'>
|
||||
<div className='flex-1 bg-components-input-bg-normal rounded-lg p-2 system-sm-regular text-components-input-text-filled '>
|
||||
<div className='mt-2 flex w-full items-center justify-between gap-2'>
|
||||
<div className='system-sm-regular flex-1 rounded-lg bg-components-input-bg-normal p-2 text-components-input-text-filled '>
|
||||
<span className='pl-1'>{userProfile.name}</span>
|
||||
</div>
|
||||
<div className='bg-components-button-tertiary-bg rounded-lg py-2 px-3 cursor-pointer system-sm-medium text-components-button-tertiary-text' onClick={handleEditName}>
|
||||
<div className='system-sm-medium cursor-pointer rounded-lg bg-components-button-tertiary-bg px-3 py-2 text-components-button-tertiary-text' onClick={handleEditName}>
|
||||
{t('common.operation.edit')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='mb-8'>
|
||||
<div className={titleClassName}>{t('common.account.email')}</div>
|
||||
<div className='flex items-center justify-between gap-2 w-full mt-2'>
|
||||
<div className='flex-1 bg-components-input-bg-normal rounded-lg p-2 system-sm-regular text-components-input-text-filled '>
|
||||
<div className='mt-2 flex w-full items-center justify-between gap-2'>
|
||||
<div className='system-sm-regular flex-1 rounded-lg bg-components-input-bg-normal p-2 text-components-input-text-filled '>
|
||||
<span className='pl-1'>{userProfile.email}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -162,8 +162,8 @@ export default function AccountPage() {
|
|||
systemFeatures.enable_email_password_login && (
|
||||
<div className='mb-8 flex justify-between gap-2'>
|
||||
<div>
|
||||
<div className='mb-1 system-sm-semibold text-text-secondary'>{t('common.account.password')}</div>
|
||||
<div className='mb-2 body-xs-regular text-text-tertiary'>{t('common.account.passwordTip')}</div>
|
||||
<div className='system-sm-semibold mb-1 text-text-secondary'>{t('common.account.password')}</div>
|
||||
<div className='body-xs-regular mb-2 text-text-tertiary'>{t('common.account.passwordTip')}</div>
|
||||
</div>
|
||||
<Button onClick={() => setEditPasswordModalVisible(true)}>{userProfile.is_password_set ? t('common.account.resetPassword') : t('common.account.setPassword')}</Button>
|
||||
</div>
|
||||
|
|
@ -190,13 +190,13 @@ export default function AccountPage() {
|
|||
onClose={() => setEditNameModalVisible(false)}
|
||||
className={s.modal}
|
||||
>
|
||||
<div className='mb-6 title-2xl-semi-bold text-text-primary'>{t('common.account.editName')}</div>
|
||||
<div className='title-2xl-semi-bold mb-6 text-text-primary'>{t('common.account.editName')}</div>
|
||||
<div className={titleClassName}>{t('common.account.name')}</div>
|
||||
<Input className='mt-2'
|
||||
value={editName}
|
||||
onChange={e => setEditName(e.target.value)}
|
||||
/>
|
||||
<div className='flex justify-end mt-10'>
|
||||
<div className='mt-10 flex justify-end'>
|
||||
<Button className='mr-2' onClick={() => setEditNameModalVisible(false)}>{t('common.operation.cancel')}</Button>
|
||||
<Button
|
||||
disabled={editing || !editName}
|
||||
|
|
@ -219,7 +219,7 @@ export default function AccountPage() {
|
|||
}}
|
||||
className={s.modal}
|
||||
>
|
||||
<div className='mb-6 title-2xl-semi-bold text-text-primary'>{userProfile.is_password_set ? t('common.account.resetPassword') : t('common.account.setPassword')}</div>
|
||||
<div className='title-2xl-semi-bold mb-6 text-text-primary'>{userProfile.is_password_set ? t('common.account.resetPassword') : t('common.account.setPassword')}</div>
|
||||
{userProfile.is_password_set && (
|
||||
<>
|
||||
<div className={titleClassName}>{t('common.account.currentPassword')}</div>
|
||||
|
|
@ -242,7 +242,7 @@ export default function AccountPage() {
|
|||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className='mt-8 system-sm-semibold text-text-secondary'>
|
||||
<div className='system-sm-semibold mt-8 text-text-secondary'>
|
||||
{userProfile.is_password_set ? t('common.account.newPassword') : t('common.account.password')}
|
||||
</div>
|
||||
<div className='relative mt-2'>
|
||||
|
|
@ -261,7 +261,7 @@ export default function AccountPage() {
|
|||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='mt-8 system-sm-semibold text-text-secondary'>{t('common.account.confirmPassword')}</div>
|
||||
<div className='system-sm-semibold mt-8 text-text-secondary'>{t('common.account.confirmPassword')}</div>
|
||||
<div className='relative mt-2'>
|
||||
<Input
|
||||
type={showConfirmPassword ? 'text' : 'password'}
|
||||
|
|
@ -278,7 +278,7 @@ export default function AccountPage() {
|
|||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex justify-end mt-10'>
|
||||
<div className='mt-10 flex justify-end'>
|
||||
<Button className='mr-2' onClick={() => {
|
||||
setEditPasswordModalVisible(false)
|
||||
resetPasswordForm()
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import { Fragment } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { Menu, Transition } from '@headlessui/react'
|
||||
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
|
||||
import Avatar from '@/app/components/base/avatar'
|
||||
import { logout } from '@/service/common'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { LogOut01 } from '@/app/components/base/icons/src/vender/line/general'
|
||||
|
||||
export interface IAppSelector {
|
||||
export type IAppSelector = {
|
||||
isMobile: boolean
|
||||
}
|
||||
|
||||
|
|
@ -36,17 +36,17 @@ export default function AppSelector() {
|
|||
({ open }) => (
|
||||
<>
|
||||
<div>
|
||||
<Menu.Button
|
||||
<MenuButton
|
||||
className={`
|
||||
inline-flex items-center
|
||||
rounded-[20px] p-1x text-sm
|
||||
p-1x inline-flex
|
||||
items-center rounded-[20px] text-sm
|
||||
text-text-primary
|
||||
mobile:px-1
|
||||
${open && 'bg-components-panel-bg-blur'}
|
||||
`}
|
||||
>
|
||||
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} size={32} />
|
||||
</Menu.Button>
|
||||
</MenuButton>
|
||||
</div>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
|
|
@ -57,35 +57,35 @@ export default function AppSelector() {
|
|||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items
|
||||
<MenuItems
|
||||
className="
|
||||
absolute -right-2 -top-1 w-60 max-w-80
|
||||
divide-y divide-divider-subtle origin-top-right rounded-lg bg-components-panel-bg-blur
|
||||
origin-top-right divide-y divide-divider-subtle rounded-lg bg-components-panel-bg-blur
|
||||
shadow-lg
|
||||
"
|
||||
>
|
||||
<Menu.Item>
|
||||
<MenuItem>
|
||||
<div className='p-1'>
|
||||
<div className='flex flex-nowrap items-center px-3 py-2'>
|
||||
<div className='grow'>
|
||||
<div className='system-md-medium text-text-primary break-all'>{userProfile.name}</div>
|
||||
<div className='system-xs-regular text-text-tertiary break-all'>{userProfile.email}</div>
|
||||
<div className='system-md-medium break-all text-text-primary'>{userProfile.name}</div>
|
||||
<div className='system-xs-regular break-all text-text-tertiary'>{userProfile.email}</div>
|
||||
</div>
|
||||
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} size={32} />
|
||||
</div>
|
||||
</div>
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
</MenuItem>
|
||||
<MenuItem>
|
||||
<div className='p-1' onClick={() => handleLogout()}>
|
||||
<div
|
||||
className='flex items-center justify-start h-9 px-3 rounded-lg cursor-pointer group hover:bg-state-base-hover'
|
||||
className='group flex h-9 cursor-pointer items-center justify-start rounded-lg px-3 hover:bg-state-base-hover'
|
||||
>
|
||||
<LogOut01 className='w-4 h-4 text-text-tertiary flex mr-1' />
|
||||
<div className='font-normal text-[14px] text-text-secondary'>{t('common.userProfile.logout')}</div>
|
||||
<LogOut01 className='mr-1 flex h-4 w-4 text-text-tertiary' />
|
||||
<div className='text-[14px] font-normal text-text-secondary'>{t('common.userProfile.logout')}</div>
|
||||
</div>
|
||||
</div>
|
||||
</Menu.Item>
|
||||
</Menu.Items>
|
||||
</MenuItem>
|
||||
</MenuItems>
|
||||
</Transition>
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -29,18 +29,18 @@ export default function CheckEmail(props: DeleteAccountProps) {
|
|||
}, [getDeleteEmailVerifyCode, props])
|
||||
|
||||
return <>
|
||||
<div className='py-1 text-text-destructive body-md-medium'>
|
||||
<div className='body-md-medium py-1 text-text-destructive'>
|
||||
{t('common.account.deleteTip')}
|
||||
</div>
|
||||
<div className='pt-1 pb-2 text-text-secondary body-md-regular'>
|
||||
<div className='body-md-regular pb-2 pt-1 text-text-secondary'>
|
||||
{t('common.account.deletePrivacyLinkTip')}
|
||||
<Link href='https://dify.ai/privacy' className='text-text-accent'>{t('common.account.deletePrivacyLink')}</Link>
|
||||
</div>
|
||||
<label className='mt-3 mb-1 h-6 flex items-center system-sm-semibold text-text-secondary'>{t('common.account.deleteLabel')}</label>
|
||||
<label className='system-sm-semibold mb-1 mt-3 flex h-6 items-center text-text-secondary'>{t('common.account.deleteLabel')}</label>
|
||||
<Input placeholder={t('common.account.deletePlaceholder') as string} onChange={(e) => {
|
||||
setUserInputEmail(e.target.value)
|
||||
}} />
|
||||
<div className='w-full flex flex-col mt-3 gap-2'>
|
||||
<div className='mt-3 flex w-full flex-col gap-2'>
|
||||
<Button className='w-full' disabled={userInputEmail !== userProfile.email || isSendingEmail} loading={isSendingEmail} variant='primary' onClick={handleConfirm}>{t('common.account.sendVerificationButton')}</Button>
|
||||
<Button className='w-full' onClick={props.onCancel}>{t('common.operation.cancel')}</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -56,11 +56,11 @@ export default function FeedBack(props: DeleteAccountProps) {
|
|||
className="max-w-[480px]"
|
||||
footer={false}
|
||||
>
|
||||
<label className='mt-3 mb-1 flex items-center system-sm-semibold text-text-secondary'>{t('common.account.feedbackLabel')}</label>
|
||||
<label className='system-sm-semibold mb-1 mt-3 flex items-center text-text-secondary'>{t('common.account.feedbackLabel')}</label>
|
||||
<Textarea rows={6} value={userFeedback} placeholder={t('common.account.feedbackPlaceholder') as string} onChange={(e) => {
|
||||
setUserFeedback(e.target.value)
|
||||
}} />
|
||||
<div className='w-full flex flex-col mt-3 gap-2'>
|
||||
<div className='mt-3 flex w-full flex-col gap-2'>
|
||||
<Button className='w-full' loading={isPending} variant='primary' onClick={handleSubmit}>{t('common.operation.submit')}</Button>
|
||||
<Button className='w-full' onClick={handleSkip}>{t('common.operation.skip')}</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -35,18 +35,18 @@ export default function VerifyEmail(props: DeleteAccountProps) {
|
|||
catch (error) { console.error(error) }
|
||||
}, [emailToken, verificationCode, confirmDeleteAccount, props])
|
||||
return <>
|
||||
<div className='pt-1 text-text-destructive body-md-medium'>
|
||||
<div className='body-md-medium pt-1 text-text-destructive'>
|
||||
{t('common.account.deleteTip')}
|
||||
</div>
|
||||
<div className='pt-1 pb-2 text-text-secondary body-md-regular'>
|
||||
<div className='body-md-regular pb-2 pt-1 text-text-secondary'>
|
||||
{t('common.account.deletePrivacyLinkTip')}
|
||||
<Link href='https://dify.ai/privacy' className='text-text-accent'>{t('common.account.deletePrivacyLink')}</Link>
|
||||
</div>
|
||||
<label className='mt-3 mb-1 h-6 flex items-center system-sm-semibold text-text-secondary'>{t('common.account.verificationLabel')}</label>
|
||||
<label className='system-sm-semibold mb-1 mt-3 flex h-6 items-center text-text-secondary'>{t('common.account.verificationLabel')}</label>
|
||||
<Input minLength={6} maxLength={6} placeholder={t('common.account.verificationPlaceholder') as string} onChange={(e) => {
|
||||
setVerificationCode(e.target.value)
|
||||
}} />
|
||||
<div className='w-full flex flex-col mt-3 gap-2'>
|
||||
<div className='mt-3 flex w-full flex-col gap-2'>
|
||||
<Button className='w-full' disabled={shouldButtonDisabled} loading={isDeleting} variant='warning' onClick={handleConfirm}>{t('common.account.permanentlyDeleteButton')}</Button>
|
||||
<Button className='w-full' onClick={props.onCancel}>{t('common.operation.cancel')}</Button>
|
||||
<Countdown onResend={sendEmail} />
|
||||
|
|
|
|||
|
|
@ -16,19 +16,19 @@ const Header = () => {
|
|||
return (
|
||||
<div className='flex flex-1 items-center justify-between px-4'>
|
||||
<div className='flex items-center gap-3'>
|
||||
<div className='flex items-center cursor-pointer' onClick={back}>
|
||||
<div className='flex cursor-pointer items-center' onClick={back}>
|
||||
<LogoSite className='object-contain' />
|
||||
</div>
|
||||
<div className='w-[1px] h-4 bg-divider-regular' />
|
||||
<p className='text-text-primary title-3xl-semi-bold'>{t('common.account.account')}</p>
|
||||
<div className='h-4 w-[1px] bg-divider-regular' />
|
||||
<p className='title-3xl-semi-bold text-text-primary'>{t('common.account.account')}</p>
|
||||
</div>
|
||||
<div className='flex items-center flex-shrink-0 gap-3'>
|
||||
<Button className='gap-2 py-2 px-3 system-sm-medium' onClick={back}>
|
||||
<RiRobot2Line className='w-4 h-4' />
|
||||
<div className='flex shrink-0 items-center gap-3'>
|
||||
<Button className='system-sm-medium gap-2 px-3 py-2' onClick={back}>
|
||||
<RiRobot2Line className='h-4 w-4' />
|
||||
<p>{t('common.account.studio')}</p>
|
||||
<RiArrowRightUpLine className='w-4 h-4' />
|
||||
<RiArrowRightUpLine className='h-4 w-4' />
|
||||
</Button>
|
||||
<div className='w-[1px] h-4 bg-divider-regular' />
|
||||
<div className='h-4 w-[1px] bg-divider-regular' />
|
||||
<Avatar />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ const Layout = ({ children }: { children: ReactNode }) => {
|
|||
<HeaderWrapper>
|
||||
<Header />
|
||||
</HeaderWrapper>
|
||||
<div className='relative flex flex-col overflow-y-auto bg-components-panel-bg shrink-0 h-0 grow'>
|
||||
<div className='relative flex h-0 shrink-0 grow flex-col overflow-y-auto bg-components-panel-bg'>
|
||||
{children}
|
||||
</div>
|
||||
</ModalContextProvider>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import AccountPage from './account-page'
|
||||
|
||||
export default function Account() {
|
||||
return <div className='max-w-[640px] w-full mx-auto pt-12 px-6'>
|
||||
return <div className='mx-auto w-full max-w-[640px] px-6 pt-12'>
|
||||
<AccountPage />
|
||||
</div>
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue