| | |
| | | 'use client' |
| | | import { useState } from 'react' |
| | | import { useTranslation } from 'react-i18next' |
| | | import { |
| | | RiGraduationCapFill, |
| | | } from '@remixicon/react' |
| | | |
| | | import { useContext } from 'use-context-selector' |
| | | import DeleteAccount from '../delete-account' |
| | | import s from './index.module.css' |
| | |
| | | import Button from '@/app/components/base/button' |
| | | import { updateUserProfile } from '@/service/common' |
| | | import { useAppContext } from '@/context/app-context' |
| | | import { useProviderContext } from '@/context/provider-context' |
| | | import { ToastContext } from '@/app/components/base/toast' |
| | | import AppIcon from '@/app/components/base/app-icon' |
| | | import { IS_CE_EDITION } from '@/config' |
| | | import Input from '@/app/components/base/input' |
| | | import PremiumBadge from '@/app/components/base/premium-badge' |
| | | |
| | | const titleClassName = ` |
| | | system-sm-semibold text-text-secondary |
| | |
| | | const { t } = useTranslation() |
| | | const { systemFeatures } = useAppContext() |
| | | const { mutateUserProfile, userProfile, apps } = useAppContext() |
| | | const { isEducationAccount } = useProviderContext() |
| | | const { notify } = useContext(ToastContext) |
| | | const [editNameModalVisible, setEditNameModalVisible] = useState(false) |
| | | const [editName, setEditName] = useState('') |
| | |
| | | <div className='mr-3'> |
| | | <AppIcon size='tiny' /> |
| | | </div> |
| | | <div className='system-sm-medium mt-[3px] text-text-secondary'>{item.name}</div> |
| | | <div className='mt-[3px] system-sm-medium text-text-secondary'>{item.name}</div> |
| | | </div> |
| | | ) |
| | | } |
| | | |
| | | return ( |
| | | <> |
| | | <div className='pb-3 pt-2'> |
| | | <div className='pt-2 pb-3'> |
| | | <h4 className='title-2xl-semi-bold text-text-primary'>{t('common.account.myAccount')}</h4> |
| | | </div> |
| | | <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'> |
| | | <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'> |
| | | <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} |
| | | {isEducationAccount && ( |
| | | <PremiumBadge size='s' color='blue' className='ml-1 !px-2'> |
| | | <RiGraduationCapFill className='mr-1 h-3 w-3' /> |
| | | <span className='system-2xs-medium'>EDU</span> |
| | | </PremiumBadge> |
| | | )} |
| | | </p> |
| | | <p className='system-xl-semibold text-text-primary'>{userProfile.name}</p> |
| | | <p className='system-xs-regular text-text-tertiary'>{userProfile.email}</p> |
| | | </div> |
| | | </div> |
| | | <div className='mb-8'> |
| | | <div className={titleClassName}>{t('common.account.name')}</div> |
| | | <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 '> |
| | | <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 '> |
| | | <span className='pl-1'>{userProfile.name}</span> |
| | | </div> |
| | | <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}> |
| | | <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}> |
| | | {t('common.operation.edit')} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className='mb-8'> |
| | | <div className={titleClassName}>{t('common.account.email')}</div> |
| | | <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 '> |
| | | <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 '> |
| | | <span className='pl-1'>{userProfile.email}</span> |
| | | </div> |
| | | </div> |
| | |
| | | systemFeatures.enable_email_password_login && ( |
| | | <div className='mb-8 flex justify-between gap-2'> |
| | | <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 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> |
| | | <Button onClick={() => setEditPasswordModalVisible(true)}>{userProfile.is_password_set ? t('common.account.resetPassword') : t('common.account.setPassword')}</Button> |
| | | </div> |
| | |
| | | onClose={() => setEditNameModalVisible(false)} |
| | | className={s.modal} |
| | | > |
| | | <div className='title-2xl-semi-bold mb-6 text-text-primary'>{t('common.account.editName')}</div> |
| | | <div className='mb-6 title-2xl-semi-bold 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='mt-10 flex justify-end'> |
| | | <div className='flex justify-end mt-10'> |
| | | <Button className='mr-2' onClick={() => setEditNameModalVisible(false)}>{t('common.operation.cancel')}</Button> |
| | | <Button |
| | | disabled={editing || !editName} |
| | |
| | | }} |
| | | className={s.modal} |
| | | > |
| | | <div className='title-2xl-semi-bold mb-6 text-text-primary'>{userProfile.is_password_set ? t('common.account.resetPassword') : t('common.account.setPassword')}</div> |
| | | <div className='mb-6 title-2xl-semi-bold 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> |
| | |
| | | </div> |
| | | </> |
| | | )} |
| | | <div className='system-sm-semibold mt-8 text-text-secondary'> |
| | | <div className='mt-8 system-sm-semibold text-text-secondary'> |
| | | {userProfile.is_password_set ? t('common.account.newPassword') : t('common.account.password')} |
| | | </div> |
| | | <div className='relative mt-2'> |
| | |
| | | </Button> |
| | | </div> |
| | | </div> |
| | | <div className='system-sm-semibold mt-8 text-text-secondary'>{t('common.account.confirmPassword')}</div> |
| | | <div className='mt-8 system-sm-semibold text-text-secondary'>{t('common.account.confirmPassword')}</div> |
| | | <div className='relative mt-2'> |
| | | <Input |
| | | type={showConfirmPassword ? 'text' : 'password'} |
| | |
| | | </Button> |
| | | </div> |
| | | </div> |
| | | <div className='mt-10 flex justify-end'> |
| | | <div className='flex justify-end mt-10'> |
| | | <Button className='mr-2' onClick={() => { |
| | | setEditPasswordModalVisible(false) |
| | | resetPasswordForm() |