index.tsx 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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/language'
  13. const titleClassName = `
  14. mb-2 text-sm font-medium text-gray-900
  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. />
  64. </div>
  65. <div className='mb-8'>
  66. <div className={titleClassName}>{t('common.language.timezone')}</div>
  67. <SimpleSelect
  68. defaultValue={userProfile.timezone}
  69. items={timezones}
  70. onSelect={item => handleSelectTimezone(item)}
  71. disabled={editing}
  72. />
  73. </div>
  74. </>
  75. )
  76. }