89 lines
2.7 KiB
TypeScript
89 lines
2.7 KiB
TypeScript
import { useMemo, useState } from 'react'
|
|
import Avatar from '@/components/ui/Avatar'
|
|
import Dropdown from '@/components/ui/Dropdown'
|
|
import Spinner from '@/components/ui/Spinner'
|
|
import classNames from 'classnames'
|
|
import withHeaderItem from '@/utils/hoc/withHeaderItem'
|
|
import { useStoreState, useStoreActions } from '@/store'
|
|
import { dateLocales } from '@/locales'
|
|
import dayjs from 'dayjs'
|
|
// eslint-disable-next-line import/no-named-as-default
|
|
import i18n from 'i18next'
|
|
import { HiCheck } from 'react-icons/hi'
|
|
import type { CommonProps } from '@/@types/common'
|
|
import appConfig from '@/configs/app.config'
|
|
|
|
const _LanguageSelector = ({ className }: CommonProps) => {
|
|
const [loading, setLoading] = useState(false)
|
|
|
|
const { setLang } = useStoreActions((actions) => actions.locale)
|
|
const { config } = useStoreState((state) => state.abpConfig)
|
|
const languageList = config?.localization.languages
|
|
const currentLang = config?.localization?.currentCulture?.cultureName
|
|
|
|
const selectLangFlag = useMemo(() => {
|
|
return languageList?.find((lang) => lang.cultureName === currentLang)?.cultureName
|
|
}, [currentLang, languageList])
|
|
|
|
const selectedLanguage = (
|
|
<div className={classNames(className, 'flex items-center')}>
|
|
{loading ? (
|
|
<Spinner size={20} />
|
|
) : (
|
|
selectLangFlag && (
|
|
<Avatar size={24} shape="circle" src={`/img/countries/${selectLangFlag}.png`} />
|
|
)
|
|
)}
|
|
</div>
|
|
)
|
|
|
|
const onLanguageSelect = (cultureName = appConfig.locale) => {
|
|
setLoading(true)
|
|
|
|
const dispatchLang = () => {
|
|
i18n.changeLanguage(cultureName)
|
|
setLang(cultureName)
|
|
setLoading(false)
|
|
}
|
|
|
|
if (dateLocales[cultureName]) {
|
|
dateLocales[cultureName]()
|
|
.then(() => {
|
|
dayjs.locale(cultureName)
|
|
dispatchLang()
|
|
})
|
|
.catch(() => {
|
|
dispatchLang()
|
|
})
|
|
} else {
|
|
dispatchLang()
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Dropdown renderTitle={selectedLanguage} placement="bottom-end">
|
|
{languageList?.map((lang) => (
|
|
<Dropdown.Item
|
|
key={lang.cultureName}
|
|
className="justify-between"
|
|
eventKey={lang.cultureName}
|
|
onClick={() => onLanguageSelect(lang.cultureName)}
|
|
>
|
|
<span className="flex items-center">
|
|
<Avatar
|
|
size={18}
|
|
shape="circle"
|
|
src={`/img/countries/${lang.cultureName ?? 'default'}.png`}
|
|
/>
|
|
<span className="ltr:ml-2 rtl:mr-2">{lang.displayName}</span>
|
|
</span>
|
|
{currentLang === lang.cultureName && <HiCheck className="text-emerald-500 text-lg" />}
|
|
</Dropdown.Item>
|
|
))}
|
|
</Dropdown>
|
|
)
|
|
}
|
|
|
|
const LanguageSelector = withHeaderItem(_LanguageSelector)
|
|
|
|
export default LanguageSelector
|