1
1
mirror of https://github.com/theoludwig/theoludwig.git synced 2024-11-05 04:51:30 +01:00
.profile/components/Header/Locales/index.tsx
Théo LUDWIG 6b29ce9b15
feat: rewrite to Next.js v13 app directory
Improvements:
- Hide switch theme input (ugly little white square)
- i18n without subpath (e.g: /fr or /en), same url whatever the locale used
2023-07-31 19:06:46 +02:00

95 lines
2.6 KiB
TypeScript

'use client'
import { useCallback, useEffect, useState, useRef } from 'react'
import classNames from 'clsx'
import { AVAILABLE_LOCALES } from '@/utils/constants'
import type { CookiesStore } from '@/i18n/i18n.client'
import { Arrow } from './Arrow'
import { LocaleFlag } from './LocaleFlag'
export interface LocalesProps {
currentLocale: string
cookiesStore: CookiesStore
}
export const Locales = (props: LocalesProps): JSX.Element => {
const { currentLocale, cookiesStore } = props
const [hiddenMenu, setHiddenMenu] = useState(true)
const languageClickRef = useRef<HTMLDivElement | null>(null)
const handleHiddenMenu = useCallback(() => {
setHiddenMenu((oldHiddenMenu) => {
return !oldHiddenMenu
})
}, [])
useEffect(() => {
const handleClickEvent = (event: MouseEvent): void => {
if (languageClickRef.current == null || event.target == null) {
return
}
if (!languageClickRef.current.contains(event.target as Node)) {
setHiddenMenu(true)
}
}
window.document.addEventListener('click', handleClickEvent)
return () => {
return window.removeEventListener('click', handleClickEvent)
}
}, [])
const handleLocale = async (locale: string): Promise<void> => {
const { setLocale } = await import('@/i18n/i18n.server')
setLocale(locale)
}
return (
<div className='flex cursor-pointer flex-col items-center justify-center'>
<div
ref={languageClickRef}
data-cy='locale-click'
className='mr-5 flex items-center'
onClick={handleHiddenMenu}
>
<LocaleFlag
locale={currentLocale}
cookiesStore={cookiesStore?.toString()}
/>
<Arrow />
</div>
<ul
data-cy='locales-list'
className={classNames(
'absolute top-14 z-10 mr-4 mt-3 flex w-32 list-none flex-col items-center justify-center rounded-lg bg-white p-0 shadow-lightFlag dark:bg-black dark:shadow-darkFlag',
{ hidden: hiddenMenu }
)}
>
{AVAILABLE_LOCALES.filter((locale) => {
return locale !== currentLocale
}).map((locale) => {
return (
<li
key={locale}
className='flex h-12 w-full items-center justify-center hover:bg-[#4f545c] hover:bg-opacity-20'
onClick={async () => {
return await handleLocale(locale)
}}
>
<LocaleFlag
locale={locale}
cookiesStore={cookiesStore?.toString()}
/>
</li>
)
})}
</ul>
</div>
)
}