mirror of
https://github.com/vercel/commerce.git
synced 2025-05-15 05:56:59 +00:00
Locale switcher
This commit is contained in:
parent
da630eced6
commit
4327a10dc9
@ -1,18 +0,0 @@
|
||||
|
||||
export default function FlagEn ({ className = "w-6 h-auto" }: { className?: string }) {
|
||||
return (
|
||||
<svg
|
||||
className={className}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 30.6 20.4"
|
||||
>
|
||||
<path className="fill-[#293476]" d="M.1.1h30.5v20.3H.1z"/>
|
||||
<path className="fill-[#fff]" d="M30.5 7.2H18.3V.1h-6v7.1H.1v6.1h12.2v7.1h6v-7.1h12.2z"/>
|
||||
<path className="fill-[#fff]" d="M30.5 18L3.6.1H.1v2.3l26.9 18h3.5z"/>
|
||||
<path className="fill-[#fff]" d="M.1 18L27 .1h3.5v2.3l-26.9 18H.1z"/>
|
||||
<path className="fill-[#ce202d]" d="M30.5 8.4H17.1V.1h-3.6v8.3H.1V12h13.4v8.4h3.6V12h13.4z"/>
|
||||
<path className="fill-[#ce202d]" d="M30.5 20.3v-1.6l-8.2-5.4h-2.4zm0-20.2h-2.4l-9.8 6.5v.6h1.6L30.5.1zM10.7 13.3l-10.6 7v.1h2.3l9.9-6.6v-.5zM.1.1v1.6l8.2 5.5h2.4z"/>
|
||||
<path className="fill-none" d="M0 20.4V0h30.6v20.5H0zm30.5 0zM.1 20.3h30.3V.1H.1v20.2z"/>
|
||||
</svg>
|
||||
)
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
|
||||
export default function FlagSv ({ className = "w-6 h-auto" }: { className?: string }) {
|
||||
return (
|
||||
<svg
|
||||
className={className}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 640 480"
|
||||
>
|
||||
<defs>
|
||||
<clipPath id="a">
|
||||
<path fillOpacity=".67" d="M-53.421 0h682.67v512h-682.67z"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g clipPath="url(#a)" transform="translate(50.082) scale(.9375)">
|
||||
<g fillRule="evenodd" strokeWidth="1pt">
|
||||
<path fill="#006aa7" d="M-121.103.302h256V205.1h-256zm0 306.876h256v204.8h-256z"/>
|
||||
<path fill="#fecc00" d="M-121.103 204.984h256v102.4h-256z"/>
|
||||
<path fill="#fecc00" d="M133.843.01h102.4v511.997h-102.4z"/>
|
||||
<path fill="#fecc00" d="M232.995 205.013h460.798v102.4H232.995z"/>
|
||||
<path fill="#006aa7" d="M236.155 307.208h460.797v204.799H236.155zm0-306.906h460.797V205.1H236.155z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
export default function GitHubIcon({ className }: { className?: string }) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
shapeRendering="geometricPrecision"
|
||||
className={className}
|
||||
>
|
||||
<path d="M12 0C5.37 0 0 5.50583 0 12.3035C0 17.7478 3.435 22.3463 8.205 23.9765C8.805 24.0842 9.03 23.715 9.03 23.3921C9.03 23.0999 9.015 22.131 9.015 21.1005C6 21.6696 5.22 20.347 4.98 19.6549C4.845 19.3012 4.26 18.2092 3.75 17.917C3.33 17.6863 2.73 17.1173 3.735 17.1019C4.68 17.0865 5.355 17.9939 5.58 18.363C6.66 20.2239 8.385 19.701 9.075 19.3781C9.18 18.5783 9.495 18.04 9.84 17.7325C7.17 17.4249 4.38 16.3637 4.38 11.6576C4.38 10.3196 4.845 9.21227 5.61 8.35102C5.49 8.04343 5.07 6.78232 5.73 5.09058C5.73 5.09058 6.735 4.76762 9.03 6.3517C9.99 6.07487 11.01 5.93645 12.03 5.93645C13.05 5.93645 14.07 6.07487 15.03 6.3517C17.325 4.75224 18.33 5.09058 18.33 5.09058C18.99 6.78232 18.57 8.04343 18.45 8.35102C19.215 9.21227 19.68 10.3042 19.68 11.6576C19.68 16.3791 16.875 17.4249 14.205 17.7325C14.64 18.1169 15.015 18.8552 15.015 20.0086C15.015 21.6542 15 22.9768 15 23.3921C15 23.715 15.225 24.0995 15.825 23.9765C18.2072 23.1519 20.2773 21.5822 21.7438 19.4882C23.2103 17.3942 23.9994 14.8814 24 12.3035C24 5.50583 18.63 0 12 0Z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
18
components/icons/language.tsx
Normal file
18
components/icons/language.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
export default function LanguageIcon({ className }: { className?: string }) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth="1.5"
|
||||
stroke="currentColor"
|
||||
className={className}
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M10.5 21l5.25-11.25L21 21m-9-3h7.5M3 5.621a48.474 48.474 0 016-.371m0 0c1.12 0 2.233.038 3.334.114M9 5.25V3m3.334 2.364C11.176 10.658 7.69 15.08 3 17.502m9.334-12.138c.896.061 1.785.147 2.666.257m-4.589 8.495a18.023 18.023 0 01-3.827-5.802"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
@ -1,104 +1,68 @@
|
||||
import FlagEn from 'components/icons/flag-en';
|
||||
import FlagSv from 'components/icons/flag-sv';
|
||||
import LanguageIcon from 'components/icons/language';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuTrigger
|
||||
} from 'components/ui/dropdown/dropdown';
|
||||
import { useLocale } from 'next-intl';
|
||||
import Link from 'next/link';
|
||||
import { usePathname, useRouter } from 'next/navigation';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { useState } from 'react';
|
||||
import { i18n } from '../../../i18n-config';
|
||||
|
||||
export default function LocaleSwitcher() {
|
||||
const pathName = usePathname()
|
||||
const locale = useLocale();
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
const router = useRouter();
|
||||
interface LocaleSwitcherProps {
|
||||
current: string;
|
||||
pageData: object;
|
||||
}
|
||||
|
||||
export default function LocaleSwitcher({ current, pageData }: LocaleSwitcherProps) {
|
||||
const pathName = usePathname();
|
||||
|
||||
console.log(pageData);
|
||||
|
||||
// Handle redirected pathname.
|
||||
const redirectedPathName = (locale: string) => {
|
||||
if (!pathName) return '/'
|
||||
const segments = pathName.split('/')
|
||||
segments[1] = locale
|
||||
return segments.join('/')
|
||||
}
|
||||
if (!pathName) return '/';
|
||||
const segments = pathName.split('/');
|
||||
segments[1] = locale;
|
||||
return segments.join('/');
|
||||
};
|
||||
|
||||
// Handle click on dropdown menu item (<li>).
|
||||
const handleClick = (e: any, locale: string) => {
|
||||
e.preventDefault()
|
||||
|
||||
const parent = e.target
|
||||
|
||||
if (parent.nodeName !== 'LI') {
|
||||
return
|
||||
}
|
||||
|
||||
let href = '/'
|
||||
|
||||
const hasChildLink = parent.querySelector('a').href !== null
|
||||
|
||||
if (hasChildLink) {
|
||||
href = parent.querySelector('a').href
|
||||
}
|
||||
|
||||
router.push(`${redirectedPathName(locale)}`)
|
||||
|
||||
setIsOpen(false)
|
||||
}
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
<DropdownMenu open={isOpen} onOpenChange={() => setIsOpen(!isOpen)}>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<button
|
||||
className={
|
||||
'duration-200 bg-app shrink-0 uppercase space-x-2 text-sm flex items-center justify-center transition hover:scale-105'
|
||||
'flex shrink-0 items-center justify-center space-x-1 rounded bg-app p-2 text-sm font-bold uppercase outline-none ring-2 ring-transparent transition duration-200 hover:ring-ui-border focus:ring-ui-border'
|
||||
}
|
||||
aria-label="Language selector"
|
||||
>
|
||||
{locale === "sv" && (
|
||||
<FlagSv />
|
||||
)}
|
||||
{locale === "en" && (
|
||||
<FlagEn />
|
||||
)}
|
||||
<span className="sr-only">{locale}</span>
|
||||
<LanguageIcon className="h-6 w-6" />
|
||||
<span>{current}</span>
|
||||
</button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="drop-shadow-xl">
|
||||
<ul className="">
|
||||
{i18n.locales.map((locale) => {
|
||||
let FlagIcon: any
|
||||
|
||||
FlagIcon = i18n.flags[locale]
|
||||
|
||||
if (current === locale.id) {
|
||||
return;
|
||||
} else {
|
||||
return (
|
||||
<DropdownMenuItem
|
||||
className='p-0'
|
||||
key={locale}
|
||||
asChild
|
||||
onClick={(e) => handleClick(e, locale)}
|
||||
>
|
||||
<li className="flex" key={locale}>
|
||||
<li className="" key={locale.id}>
|
||||
<Link
|
||||
className="flex w-full cursor-pointer uppercase space-x-2 text-sm p-2"
|
||||
onClick={() => setIsOpen(false)}
|
||||
href={redirectedPathName(locale)}
|
||||
className="flex w-full cursor-pointer px-4 py-2 text-sm"
|
||||
href={redirectedPathName(locale.id)}
|
||||
>
|
||||
<FlagIcon />
|
||||
<span>{locale}</span>
|
||||
{locale.title}
|
||||
</Link>
|
||||
</li>
|
||||
</DropdownMenuItem>
|
||||
)
|
||||
);
|
||||
}
|
||||
})}
|
||||
</ul>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
@ -1,13 +1,15 @@
|
||||
import FlagEn from "components/icons/flag-en"
|
||||
import FlagSv from "components/icons/flag-sv"
|
||||
|
||||
export const i18n = {
|
||||
defaultLocale: 'sv',
|
||||
locales: ['sv', 'en'],
|
||||
flags: {
|
||||
sv: FlagSv,
|
||||
en: FlagEn
|
||||
locales: [
|
||||
{
|
||||
id: 'sv',
|
||||
title: 'Swedish'
|
||||
},
|
||||
{
|
||||
id: 'en',
|
||||
title: 'English'
|
||||
}
|
||||
],
|
||||
} as const
|
||||
|
||||
export type Locale = typeof i18n['locales'][number]
|
@ -2,7 +2,7 @@ export const docQuery = `*[_type in ["home", "page", "category", "product"] && d
|
||||
_type,
|
||||
"slug": slug.current,
|
||||
"locale": language
|
||||
}`
|
||||
}`;
|
||||
|
||||
export const imageFields = `
|
||||
alt,
|
||||
@ -13,7 +13,7 @@ export const imageFields = `
|
||||
_type,
|
||||
_ref,
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
export const seoFields = `
|
||||
title,
|
||||
@ -21,7 +21,7 @@ export const seoFields = `
|
||||
image {
|
||||
${imageFields}
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
// Construct our "Modules" GROQ
|
||||
export const modules = `
|
||||
@ -141,7 +141,7 @@ export const modules = `
|
||||
},
|
||||
},
|
||||
}
|
||||
`
|
||||
`;
|
||||
export const reusableSection = `
|
||||
_type == 'reusableSection' => {
|
||||
disabled,
|
||||
@ -157,7 +157,7 @@ export const reusableSection = `
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
// Homepage query
|
||||
export const homePageQuery = `*[_type == "home" && slug.current == "/" && language == $locale][0] {
|
||||
@ -167,7 +167,7 @@ export const homePageQuery = `*[_type == "home" && slug.current == "/" && langua
|
||||
"locale": language,
|
||||
"translations": *[_type == "translation.metadata" && references(^._id)].translations[].value->{
|
||||
title,
|
||||
slug,
|
||||
"slug": slug.current,
|
||||
"locale": language
|
||||
},
|
||||
content[] {
|
||||
@ -177,7 +177,7 @@ export const homePageQuery = `*[_type == "home" && slug.current == "/" && langua
|
||||
seo {
|
||||
${seoFields}
|
||||
}
|
||||
}`
|
||||
}`;
|
||||
|
||||
// Page query
|
||||
export const pageQuery = `*[_type == "page" && slug.current == $slug && language == $locale][0] {
|
||||
@ -187,7 +187,7 @@ export const pageQuery = `*[_type == "page" && slug.current == $slug && language
|
||||
"locale": language,
|
||||
"translations": *[_type == "translation.metadata" && references(^._id)].translations[].value->{
|
||||
title,
|
||||
slug,
|
||||
"slug": slug.current,
|
||||
"locale": language
|
||||
},
|
||||
content[] {
|
||||
@ -196,7 +196,7 @@ export const pageQuery = `*[_type == "page" && slug.current == $slug && language
|
||||
seo {
|
||||
${seoFields}
|
||||
}
|
||||
}`
|
||||
}`;
|
||||
|
||||
// Product query
|
||||
export const productQuery = `*[_type == "product" && slug.current == $slug && language == $locale][0] {
|
||||
@ -206,7 +206,7 @@ export const productQuery = `*[_type == "product" && slug.current == $slug && la
|
||||
"locale": language,
|
||||
"translations": *[_type == "translation.metadata" && references(^._id)].translations[].value->{
|
||||
title,
|
||||
slug,
|
||||
"slug": slug.current,
|
||||
"locale": language
|
||||
},
|
||||
"product": {
|
||||
@ -235,7 +235,7 @@ export const productQuery = `*[_type == "product" && slug.current == $slug && la
|
||||
seo {
|
||||
${seoFields}
|
||||
}
|
||||
}`
|
||||
}`;
|
||||
|
||||
// Category query
|
||||
export const categoryQuery = `*[_type == "category" && slug.current == $slug && language == $locale][0] {
|
||||
@ -255,13 +255,13 @@ export const categoryQuery = `*[_type == "category" && slug.current == $slug &&
|
||||
},
|
||||
"translations": *[_type == "translation.metadata" && references(^._id)].translations[].value->{
|
||||
title,
|
||||
slug,
|
||||
"slug": slug.current,
|
||||
"locale": language
|
||||
},
|
||||
seo {
|
||||
${seoFields}
|
||||
}
|
||||
}`
|
||||
}`;
|
||||
|
||||
// Site settings query
|
||||
export const siteSettingsQuery = `*[_type == "settings" && language == $locale][0] {
|
||||
@ -301,4 +301,4 @@ export const siteSettingsQuery = `*[_type == "settings" && language == $locale][
|
||||
reference->
|
||||
}
|
||||
}
|
||||
}`
|
||||
}`;
|
||||
|
Loading…
x
Reference in New Issue
Block a user