diff --git a/packages/frontend/common/enums/languages.ts b/packages/frontend/common/enums/languages.ts new file mode 100644 index 000000000..0ccb17942 --- /dev/null +++ b/packages/frontend/common/enums/languages.ts @@ -0,0 +1,5 @@ +export const Languages = { + UA: 'ua', + EN: 'en', + DEFAULT: 'en', +}; diff --git a/packages/frontend/components/header/component.tsx b/packages/frontend/components/header/component.tsx index b5f70277e..ad2bd25bc 100644 --- a/packages/frontend/components/header/component.tsx +++ b/packages/frontend/components/header/component.tsx @@ -1,4 +1,11 @@ -import { Button, Container, Flex, IconButton, Loader } from '@primitives'; +import { + Button, + Container, + FlagsDropdown, + Flex, + IconButton, + Loader, +} from '@primitives'; import { useTranslation } from 'next-i18next'; import Link from 'next/link'; import { Fragment, useState, useEffect, Suspense } from 'react'; @@ -36,10 +43,8 @@ export const Header = () => { const size = useWindowSize(); useEffect(() => { - if (!categories.length) { - dispatch(fetchCategories()); - } - }, [dispatch, locale, categories]); + dispatch(fetchCategories()); + }, [dispatch, locale]); const renderAuthButtons = () => (
@@ -87,11 +92,13 @@ export const Header = () => {
- {isMounted && ( <> }> +
+ +
{size.width > 600 ? ( ) : ( diff --git a/packages/frontend/components/header/styles.ts b/packages/frontend/components/header/styles.ts index 0413225b0..80fa5d9a7 100644 --- a/packages/frontend/components/header/styles.ts +++ b/packages/frontend/components/header/styles.ts @@ -117,3 +117,6 @@ export const burgerOverlay = (theme: Theme) => css` export const searchButton = ({ spaces }: Theme) => css` margin-left: ${spaces.xs}; `; +export const flagsDropdown = ({ spaces }: Theme) => css` + margin-right: ${spaces.md}; +`; diff --git a/packages/frontend/components/primitives/flags-dropdown/component.tsx b/packages/frontend/components/primitives/flags-dropdown/component.tsx new file mode 100644 index 000000000..05644c5cc --- /dev/null +++ b/packages/frontend/components/primitives/flags-dropdown/component.tsx @@ -0,0 +1,57 @@ +import uaImg from 'public/images/flags/ua.svg'; +import enImg from 'public/images/flags/gb.svg'; +import { useRouter } from 'next/router'; +import Image from 'next/future/image'; +import { Languages } from 'common/enums/languages'; +import { Dropdown } from '../menu-dropdown'; +import * as styles from './styles'; + +const dropdownLanguages = [ + { src: enImg, locale: Languages.EN }, + { src: uaImg, locale: Languages.UA }, +]; + +export function FlagsDropdown() { + const { push, asPath, locale } = useRouter(); + + const getAltToImage = (locale: string): string => { + if (locale === Languages.UA) return Languages.UA; + if (locale === Languages.EN) return Languages.EN; + + return Languages.DEFAULT; + }; + + const getSrcToImage = (locale: string): string => { + if (locale === Languages.UA) return uaImg.src; + if (locale === Languages.EN) return enImg.src; + + return enImg.src; + }; + + return ( + ({ + cssExtend: styles.option, + image: { + alt: lang.locale, + src: lang.src, + width: 40, + height: 38, + css: styles.optionImage, + }, + disabled: locale === lang.locale, + value: lang.locale, + onClick: () => push(asPath, asPath, { locale: lang.locale }), + }))} + > + {getAltToImage(locale)} + + ); +} diff --git a/packages/frontend/components/primitives/flags-dropdown/index.ts b/packages/frontend/components/primitives/flags-dropdown/index.ts new file mode 100644 index 000000000..bb824842c --- /dev/null +++ b/packages/frontend/components/primitives/flags-dropdown/index.ts @@ -0,0 +1 @@ +export * from './component'; diff --git a/packages/frontend/components/primitives/flags-dropdown/styles.tsx b/packages/frontend/components/primitives/flags-dropdown/styles.tsx new file mode 100644 index 000000000..9e26f0949 --- /dev/null +++ b/packages/frontend/components/primitives/flags-dropdown/styles.tsx @@ -0,0 +1,37 @@ +import type { Theme } from '@emotion/react'; +import { css } from '@emotion/react'; + +export const dropdown = ({ spaces }: Theme) => css` + top: 110%; + left: -11px; + padding: ${spaces.xs} ${spaces.xs} 0; +`; +export const imageBtn = ({ radiuses }: Theme) => css` + object-fit: cover; + border-radius: ${radiuses.circle}; +`; +export const option = ({ radiuses, colors, spaces }: Theme) => css` + position: relative; + padding: 0; + margin-bottom: ${spaces.xs}; + height: ${spaces.xl3}; + border: 2px solid ${colors.backgroundDark}; + border-radius: ${radiuses.circle}; + overflow: hidden; + transition: 200ms linear; + + &:last-child { + margin-bottom: 0; + } + &:hover { + border-color: ${colors.active}; + } + &:disabled { + border-color: ${colors.active}; + /* display: none; */ + } +`; + +export const optionImage = css` + object-fit: cover; +`; diff --git a/packages/frontend/components/primitives/index.ts b/packages/frontend/components/primitives/index.ts index 10e8262ba..d17813b25 100644 --- a/packages/frontend/components/primitives/index.ts +++ b/packages/frontend/components/primitives/index.ts @@ -20,3 +20,4 @@ export { Range } from './range'; export { ButtonGroup } from './button-group'; export { CategoryBadges } from './category-badge'; export { ImageWithFallback } from './image-with-fallback'; +export { FlagsDropdown } from './flags-dropdown'; diff --git a/packages/frontend/components/primitives/menu-dropdown/component.tsx b/packages/frontend/components/primitives/menu-dropdown/component.tsx index f72249ede..13c8398b6 100644 --- a/packages/frontend/components/primitives/menu-dropdown/component.tsx +++ b/packages/frontend/components/primitives/menu-dropdown/component.tsx @@ -1,6 +1,7 @@ import { useOutsideClick, useWindowSize } from '@hooks'; import { useCallback, useState } from 'react'; import { Icon } from '@primitives'; +import Image from 'next/future/image'; import * as styles from './styles'; import type { DropdownProps } from './types'; @@ -58,6 +59,7 @@ export const Dropdown = ({ disabled, icon, cssExtend: optionCss, + image, } = item; const onClick = (e) => { @@ -81,7 +83,7 @@ export const Dropdown = ({ size={icon.size} /> )} - {value} + {image ? : value} ); })} diff --git a/packages/frontend/components/primitives/menu-dropdown/styles.ts b/packages/frontend/components/primitives/menu-dropdown/styles.ts index 70e2ba046..2fa088460 100644 --- a/packages/frontend/components/primitives/menu-dropdown/styles.ts +++ b/packages/frontend/components/primitives/menu-dropdown/styles.ts @@ -95,3 +95,6 @@ export const dropdownItem = ({ export const icon = ({ colors }: Theme) => css` color: ${colors.extraDark}; `; +export const image = css` + object-fit: cover; +`; diff --git a/packages/frontend/components/primitives/menu-dropdown/types.ts b/packages/frontend/components/primitives/menu-dropdown/types.ts index c1fde4366..35b137b39 100644 --- a/packages/frontend/components/primitives/menu-dropdown/types.ts +++ b/packages/frontend/components/primitives/menu-dropdown/types.ts @@ -1,4 +1,5 @@ import type { Interpolation, Theme } from '@emotion/react'; +import type { ImageProps } from 'next/future/image'; import type { IconProps } from '../icon/types'; export type DropdownProps = { @@ -15,4 +16,9 @@ export type DropdownOptionProps = { icon?: IconProps; disabled?: boolean; cssExtend?: Interpolation; + image?: DropdownImage; }; + +interface DropdownImage extends ImageProps { + css: Interpolation; +} diff --git a/packages/frontend/public/images/flags/gb.svg b/packages/frontend/public/images/flags/gb.svg new file mode 100644 index 000000000..689bd3e65 --- /dev/null +++ b/packages/frontend/public/images/flags/gb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/frontend/public/images/flags/ua.svg b/packages/frontend/public/images/flags/ua.svg new file mode 100644 index 000000000..4d09b7c8e --- /dev/null +++ b/packages/frontend/public/images/flags/ua.svg @@ -0,0 +1 @@ + \ No newline at end of file