index.tsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. 'use client'
  2. import { useState } from 'react'
  3. import { useTranslation } from 'react-i18next'
  4. import { useContext } from 'use-context-selector'
  5. import { useAppContext } from '@/context/app-context'
  6. import { SimpleSelect } from '@/app/components/base/select'
  7. import type { Item } from '@/app/components/base/select'
  8. import { updateUserProfile } from '@/service/common'
  9. import { ToastContext } from '@/app/components/base/toast'
  10. import I18n from '@/context/i18n'
  11. import { timezones } from '@/utils/timezone'
  12. import { languages } from '@/i18n-config/language'
  13. const titleClassName = `
  14. mb-2 system-sm-semibold text-text-secondary
  15. `
  16. export default function LanguagePage() {
  17. const { locale, setLocaleOnClient } = useContext(I18n)
  18. const { userProfile, mutateUserProfile } = useAppContext()
  19. const { notify } = useContext(ToastContext)
  20. const [editing, setEditing] = useState(false)
  21. const { t } = useTranslation()
  22. const handleSelectLanguage = async (item: Item) => {
  23. const url = '/account/interface-language'
  24. const bodyKey = 'interface_language'
  25. setEditing(true)
  26. try {
  27. await updateUserProfile({ url, body: { [bodyKey]: item.value } })
  28. notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
  29. setLocaleOnClient(item.value.toString())
  30. }
  31. catch (e) {
  32. notify({ type: 'error', message: (e as Error).message })
  33. }
  34. finally {
  35. setEditing(false)
  36. }
  37. }
  38. const handleSelectTimezone = async (item: Item) => {
  39. const url = '/account/timezone'
  40. const bodyKey = 'timezone'
  41. setEditing(true)
  42. try {
  43. await updateUserProfile({ url, body: { [bodyKey]: item.value } })
  44. notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
  45. mutateUserProfile()
  46. }
  47. catch (e) {
  48. notify({ type: 'error', message: (e as Error).message })
  49. }
  50. finally {
  51. setEditing(false)
  52. }
  53. }
  54. return (
  55. <>
  56. <div className='mb-8'>
  57. <div className={titleClassName}>{t('common.language.displayLanguage')}</div>
  58. <SimpleSelect
  59. defaultValue={locale || userProfile.interface_language}
  60. items={languages.filter(item => item.supported)}
  61. onSelect={item => handleSelectLanguage(item)}
  62. disabled={editing}
  63. notClearable={true}
  64. />
  65. </div>
  66. <div className='mb-8'>
  67. <div className={titleClassName}>{t('common.language.timezone')}</div>
  68. <SimpleSelect
  69. defaultValue={userProfile.timezone}
  70. items={timezones}
  71. onSelect={item => handleSelectTimezone(item)}
  72. disabled={editing}
  73. notClearable={true}
  74. />
  75. </div>
  76. </>
  77. )
  78. }