index.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. 'use client'
  2. import { useState } from 'react'
  3. import { useTranslation } from 'react-i18next'
  4. import classNames from 'classnames'
  5. import { useContext } from 'use-context-selector'
  6. import Collapse from '../collapse'
  7. import type { IItem } from '../collapse'
  8. import s from './index.module.css'
  9. import Modal from '@/app/components/base/modal'
  10. import Button from '@/app/components/base/button'
  11. import { updateUserProfile } from '@/service/common'
  12. import { useAppContext } from '@/context/app-context'
  13. import { ToastContext } from '@/app/components/base/toast'
  14. import AppIcon from '@/app/components/base/app-icon'
  15. import Avatar from '@/app/components/base/avatar'
  16. const titleClassName = `
  17. text-sm font-medium text-gray-900
  18. `
  19. const descriptionClassName = `
  20. mt-1 text-xs font-normal text-gray-500
  21. `
  22. const inputClassName = `
  23. mt-2 w-full px-3 py-2 bg-gray-100 rounded
  24. text-sm font-normal text-gray-800
  25. `
  26. export default function AccountPage() {
  27. const { mutateUserProfile, userProfile, apps } = useAppContext()
  28. const { notify } = useContext(ToastContext)
  29. const [editNameModalVisible, setEditNameModalVisible] = useState(false)
  30. const [editName, setEditName] = useState('')
  31. const [editing, setEditing] = useState(false)
  32. const { t } = useTranslation()
  33. const handleEditName = () => {
  34. setEditNameModalVisible(true)
  35. setEditName(userProfile.name)
  36. }
  37. const handleSaveName = async () => {
  38. try {
  39. setEditing(true)
  40. await updateUserProfile({ url: 'account/name', body: { name: editName } })
  41. notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
  42. mutateUserProfile()
  43. setEditNameModalVisible(false)
  44. setEditing(false)
  45. }
  46. catch (e) {
  47. notify({ type: 'error', message: (e as Error).message })
  48. setEditNameModalVisible(false)
  49. setEditing(false)
  50. }
  51. }
  52. const renderAppItem = (item: IItem) => {
  53. return (
  54. <div className='flex px-3 py-1'>
  55. <div className='mr-3'>
  56. <AppIcon size='tiny' />
  57. </div>
  58. <div className='mt-[3px] text-xs font-medium text-gray-700 leading-[18px]'>{item.name}</div>
  59. </div>
  60. )
  61. }
  62. return (
  63. <>
  64. <div className='mb-8'>
  65. <div className={titleClassName}>{t('common.account.avatar')}</div>
  66. <Avatar name={userProfile.name} size={64} className='mt-2' />
  67. </div>
  68. <div className='mb-8'>
  69. <div className={titleClassName}>{t('common.account.name')}</div>
  70. <div className={classNames('flex items-center justify-between mt-2 w-full h-9 px-3 bg-gray-100 rounded text-sm font-normal text-gray-800 cursor-pointer group')}>
  71. {userProfile.name}
  72. <div className='items-center hidden h-6 px-2 text-xs font-normal bg-white border border-gray-200 rounded-md group-hover:flex' onClick={handleEditName}>{t('common.operation.edit')}</div>
  73. </div>
  74. </div>
  75. <div className='mb-8'>
  76. <div className={titleClassName}>{t('common.account.email')}</div>
  77. <div className={classNames(inputClassName, 'cursor-pointer')}>{userProfile.email}</div>
  78. </div>
  79. {
  80. !!apps.length && (
  81. <>
  82. <div className='mb-6 border-[0.5px] border-gray-100' />
  83. <div className='mb-8'>
  84. <div className={titleClassName}>{t('common.account.langGeniusAccount')}</div>
  85. <div className={descriptionClassName}>{t('common.account.langGeniusAccountTip')}</div>
  86. <Collapse
  87. title={`${t('common.account.showAppLength', { length: apps.length })}`}
  88. items={apps.map(app => ({ key: app.id, name: app.name }))}
  89. renderItem={renderAppItem}
  90. wrapperClassName='mt-2'
  91. />
  92. </div>
  93. </>
  94. )
  95. }
  96. {
  97. editNameModalVisible && (
  98. <Modal
  99. isShow
  100. onClose={() => setEditNameModalVisible(false)}
  101. className={s.modal}
  102. >
  103. <div className='mb-6 text-lg font-medium text-gray-900'>{t('common.account.editName')}</div>
  104. <div className={titleClassName}>{t('common.account.name')}</div>
  105. <input
  106. className={inputClassName}
  107. value={editName}
  108. onChange={e => setEditName(e.target.value)}
  109. />
  110. <div className='flex justify-end mt-10'>
  111. <Button className='mr-2 text-sm font-medium' onClick={() => setEditNameModalVisible(false)}>{t('common.operation.cancel')}</Button>
  112. <Button
  113. disabled={editing || !editName}
  114. type='primary'
  115. className='text-sm font-medium'
  116. onClick={handleSaveName}
  117. >
  118. {t('common.operation.save')}
  119. </Button>
  120. </div>
  121. </Modal>
  122. )
  123. }
  124. </>
  125. )
  126. }