fix(SW-705): Updated logic for language switcher
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import { usePathname } from "next/navigation"
|
import { usePathname } from "next/navigation"
|
||||||
import { Suspense } from "react"
|
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { logout } from "@/constants/routes/handleAuth"
|
import { logout } from "@/constants/routes/handleAuth"
|
||||||
@@ -10,7 +9,6 @@ import useDropdownStore from "@/stores/main-menu"
|
|||||||
import Image from "@/components/Image"
|
import Image from "@/components/Image"
|
||||||
import LoginButton from "@/components/LoginButton"
|
import LoginButton from "@/components/LoginButton"
|
||||||
import Avatar from "@/components/MyPages/Avatar"
|
import Avatar from "@/components/MyPages/Avatar"
|
||||||
import SkeletonShimmer from "@/components/SkeletonShimmer"
|
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
import useLang from "@/hooks/useLang"
|
import useLang from "@/hooks/useLang"
|
||||||
import { trackClick } from "@/utils/tracking"
|
import { trackClick } from "@/utils/tracking"
|
||||||
@@ -190,13 +188,7 @@ export function MainMenu({
|
|||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
{languageSwitcher ? (
|
{languageSwitcher ? (
|
||||||
<li className={styles.mobileLi}>
|
<li className={styles.mobileLi}>{languageSwitcher}</li>
|
||||||
<Suspense
|
|
||||||
fallback={<SkeletonShimmer height="20px" width="10ch" />}
|
|
||||||
>
|
|
||||||
{languageSwitcher}
|
|
||||||
</Suspense>
|
|
||||||
</li>
|
|
||||||
) : null}
|
) : null}
|
||||||
{!!user ? (
|
{!!user ? (
|
||||||
<li className={`${styles.mobileLi} ${styles.logout}`}>
|
<li className={`${styles.mobileLi} ${styles.logout}`}>
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
import { Suspense } from "react"
|
|
||||||
|
|
||||||
import { logout } from "@/constants/routes/handleAuth"
|
import { logout } from "@/constants/routes/handleAuth"
|
||||||
import { overview } from "@/constants/routes/myPages"
|
import { overview } from "@/constants/routes/myPages"
|
||||||
import { getName } from "@/lib/trpc/memoizedRequests"
|
import { getName } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import LoginButton from "@/components/LoginButton"
|
import LoginButton from "@/components/LoginButton"
|
||||||
import SkeletonShimmer from "@/components/SkeletonShimmer"
|
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
import { getLang } from "@/i18n/serverContext"
|
import { getLang } from "@/i18n/serverContext"
|
||||||
@@ -35,13 +32,7 @@ export default async function TopMenu({
|
|||||||
|
|
||||||
<ul className={styles.list}>
|
<ul className={styles.list}>
|
||||||
{languageSwitcher ? (
|
{languageSwitcher ? (
|
||||||
<li className={styles.langSwitcher}>
|
<li className={styles.langSwitcher}>{languageSwitcher}</li>
|
||||||
<Suspense
|
|
||||||
fallback={<SkeletonShimmer height="20px" width="10ch" />}
|
|
||||||
>
|
|
||||||
{languageSwitcher}
|
|
||||||
</Suspense>
|
|
||||||
</li>
|
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{links.map(({ link }, i) => (
|
{links.map(({ link }, i) => (
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { Suspense } from "react"
|
|
||||||
|
|
||||||
import { getFooter, getLanguageSwitcher } from "@/lib/trpc/memoizedRequests"
|
import { getFooter, getLanguageSwitcher } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import { getIconByIconName } from "@/components/Icons/get-icon-by-icon-name"
|
import { getIconByIconName } from "@/components/Icons/get-icon-by-icon-name"
|
||||||
@@ -88,9 +86,7 @@ export default async function FooterDetails() {
|
|||||||
)}
|
)}
|
||||||
</nav>
|
</nav>
|
||||||
{languages?.urls ? (
|
{languages?.urls ? (
|
||||||
<Suspense fallback={<SkeletonShimmer height="20px" width="10ch" />}>
|
<LanguageSwitcher type="footer" urls={languages.urls} />
|
||||||
<LanguageSwitcher type="footer" urls={languages.urls} />
|
|
||||||
</Suspense>
|
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
|
import { usePathname, useSearchParams } from "next/navigation"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { Lang, languages } from "@/constants/languages"
|
import { Lang, languages } from "@/constants/languages"
|
||||||
@@ -10,6 +11,8 @@ import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
|||||||
import useLang from "@/hooks/useLang"
|
import useLang from "@/hooks/useLang"
|
||||||
import { useTrapFocus } from "@/hooks/useTrapFocus"
|
import { useTrapFocus } from "@/hooks/useTrapFocus"
|
||||||
|
|
||||||
|
import { replaceUrlPart } from "./utils"
|
||||||
|
|
||||||
import styles from "./languageSwitcherContent.module.css"
|
import styles from "./languageSwitcherContent.module.css"
|
||||||
|
|
||||||
import type { LanguageSwitcherContentProps } from "@/types/components/languageSwitcher/languageSwitcher"
|
import type { LanguageSwitcherContentProps } from "@/types/components/languageSwitcher/languageSwitcher"
|
||||||
@@ -18,12 +21,15 @@ export default function LanguageSwitcherContent({
|
|||||||
urls,
|
urls,
|
||||||
onLanguageSwitch,
|
onLanguageSwitch,
|
||||||
}: LanguageSwitcherContentProps) {
|
}: LanguageSwitcherContentProps) {
|
||||||
|
console.log(urls)
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const currentLanguage = useLang()
|
const currentLanguage = useLang()
|
||||||
|
|
||||||
const languageSwitcherRef = useTrapFocus()
|
const languageSwitcherRef = useTrapFocus()
|
||||||
const urlKeys = Object.keys(urls) as Lang[]
|
const urlKeys = Object.keys(urls) as Lang[]
|
||||||
|
|
||||||
|
const pathname = usePathname()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.languageSwitcherContent} ref={languageSwitcherRef}>
|
<div className={styles.languageSwitcherContent} ref={languageSwitcherRef}>
|
||||||
<div className={styles.languageWrapper}>
|
<div className={styles.languageWrapper}>
|
||||||
@@ -39,8 +45,9 @@ export default function LanguageSwitcherContent({
|
|||||||
<li key={key}>
|
<li key={key}>
|
||||||
<Link
|
<Link
|
||||||
className={`${styles.link} ${isActive ? styles.active : ""}`}
|
className={`${styles.link} ${isActive ? styles.active : ""}`}
|
||||||
href={url}
|
href={replaceUrlPart(pathname, url)}
|
||||||
onClick={onLanguageSwitch}
|
onClick={onLanguageSwitch}
|
||||||
|
keepSearchParams
|
||||||
>
|
>
|
||||||
{languages[key]}
|
{languages[key]}
|
||||||
{isActive ? <CheckIcon color="burgundy" /> : null}
|
{isActive ? <CheckIcon color="burgundy" /> : null}
|
||||||
|
|||||||
19
components/LanguageSwitcher/LanguageSwitcherContent/utils.ts
Normal file
19
components/LanguageSwitcher/LanguageSwitcherContent/utils.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
export function replaceUrlPart(currentPath: string, newPart: string): string {
|
||||||
|
const pathSegments = currentPath.split("/").filter((segment) => segment)
|
||||||
|
|
||||||
|
const newPathSegments = newPart
|
||||||
|
.replace(/\/$/, "")
|
||||||
|
.split("/")
|
||||||
|
.filter((segment) => segment)
|
||||||
|
|
||||||
|
const isFullPathReplacement = newPathSegments.length > 1
|
||||||
|
|
||||||
|
if (isFullPathReplacement) {
|
||||||
|
return `/${newPathSegments.join("/")}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedPathSegments = pathSegments.slice(1)
|
||||||
|
const updatedPath = `/${newPathSegments.concat(updatedPathSegments).join("/")}`
|
||||||
|
|
||||||
|
return updatedPath
|
||||||
|
}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { usePathname, useSearchParams } from "next/navigation"
|
import { Suspense, useRef } from "react"
|
||||||
import { useRef } from "react"
|
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { Lang, languages } from "@/constants/languages"
|
import { languages } from "@/constants/languages"
|
||||||
import useDropdownStore from "@/stores/main-menu"
|
import useDropdownStore from "@/stores/main-menu"
|
||||||
|
|
||||||
import { ChevronDownSmallIcon, GlobeIcon } from "@/components/Icons"
|
import { ChevronDownSmallIcon, GlobeIcon } from "@/components/Icons"
|
||||||
@@ -24,7 +23,6 @@ import {
|
|||||||
type LanguageSwitcherProps,
|
type LanguageSwitcherProps,
|
||||||
LanguageSwitcherTypesEnum,
|
LanguageSwitcherTypesEnum,
|
||||||
} from "@/types/components/languageSwitcher/languageSwitcher"
|
} from "@/types/components/languageSwitcher/languageSwitcher"
|
||||||
import type { LanguageSwitcherData } from "@/types/requests/languageSwitcher"
|
|
||||||
|
|
||||||
export default function LanguageSwitcher({
|
export default function LanguageSwitcher({
|
||||||
urls,
|
urls,
|
||||||
@@ -38,23 +36,12 @@ export default function LanguageSwitcher({
|
|||||||
isHeaderLanguageSwitcherMobileOpen,
|
isHeaderLanguageSwitcherMobileOpen,
|
||||||
isHeaderLanguageSwitcherOpen,
|
isHeaderLanguageSwitcherOpen,
|
||||||
} = useDropdownStore()
|
} = useDropdownStore()
|
||||||
const searchParams = useSearchParams()
|
|
||||||
const pathname = usePathname()
|
|
||||||
const queryParams = new URLSearchParams(searchParams.toString())
|
|
||||||
|
|
||||||
const languageSwitcherRef = useRef<HTMLDivElement>(null)
|
const languageSwitcherRef = useRef<HTMLDivElement>(null)
|
||||||
const isFooter = type === LanguageSwitcherTypesEnum.Footer
|
const isFooter = type === LanguageSwitcherTypesEnum.Footer
|
||||||
const isHeader = !isFooter
|
const isHeader = !isFooter
|
||||||
const globeIconSize = type === "desktopHeader" ? 16 : 20
|
const globeIconSize = type === "desktopHeader" ? 16 : 20
|
||||||
|
|
||||||
const currentUrl = `${pathname}?${queryParams.toString()}`
|
|
||||||
|
|
||||||
const fullUrls = Object.entries(urls).reduce((acc, [lang, { url }]) => {
|
|
||||||
const newUrl = currentUrl.replace(/^\/[a-z]{2}\//, url)
|
|
||||||
acc[lang as Lang] = { url: newUrl }
|
|
||||||
return acc
|
|
||||||
}, {} as LanguageSwitcherData)
|
|
||||||
|
|
||||||
const position = isFooter ? "footer" : "header"
|
const position = isFooter ? "footer" : "header"
|
||||||
|
|
||||||
const dropdownType = {
|
const dropdownType = {
|
||||||
@@ -119,7 +106,7 @@ export default function LanguageSwitcher({
|
|||||||
{isLanguageSwitcherOpen ? (
|
{isLanguageSwitcherOpen ? (
|
||||||
<LanguageSwitcherContainer type={type}>
|
<LanguageSwitcherContainer type={type}>
|
||||||
<LanguageSwitcherContent
|
<LanguageSwitcherContent
|
||||||
urls={fullUrls}
|
urls={urls}
|
||||||
onLanguageSwitch={() => toggleDropdown(dropdownType)}
|
onLanguageSwitch={() => toggleDropdown(dropdownType)}
|
||||||
/>
|
/>
|
||||||
</LanguageSwitcherContainer>
|
</LanguageSwitcherContainer>
|
||||||
|
|||||||
Reference in New Issue
Block a user