Skip to content

Commit

Permalink
feat(core): add store selector page and link in footer
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgemoya committed Jun 25, 2024
1 parent 982b19c commit 0be98b4
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/mean-poets-tease.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bigcommerce/catalyst-core": patch
---

Add store selector page.
60 changes: 60 additions & 0 deletions core/app/[locale]/store-selector/_components/locale-link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Link } from '~/components/link';
import { LocaleType } from '~/i18n';
import { cn } from '~/lib/utils';

/**
* Custom map of locale to language and region
* Temporary solution until we have a better way to include regions for all locales
*/
const localeLanguageRegionMap = {
da: { language: 'Dansk', region: 'Danmark', flag: 'dk' },
en: { language: 'English', region: 'United States', flag: 'us' },
'es-419': { language: 'Español', region: 'America Latina', flag: '' },
'es-AR': { language: 'Español', region: 'Argentina', flag: 'ar' },
'es-CL': { language: 'Español', region: 'Chile', flag: 'cl' },
'es-CO': { language: 'Español', region: 'Colombia', flag: 'co' },
'es-LA': { language: 'Español', region: 'America Latina', flag: '' },
'es-MX': { language: 'Español', region: 'México', flag: 'mx' },
'es-PE': { language: 'Español', region: 'Perú', flag: 'pe' },
es: { language: 'Español', region: 'España', flag: 'es' },
it: { language: 'Italiano', region: 'Italia', flag: 'it' },
nl: { language: 'Nederlands', region: 'Nederland', flag: 'nl' },
pl: { language: 'Polski', region: 'Polska', flag: 'pl' },
pt: { language: 'Português', region: 'Portugal', flag: 'pt' },
de: { language: 'Deutsch', region: 'Deutschland', flag: 'de' },
fr: { language: 'Français', region: 'France', flag: 'fr' },
ja: { language: '日本語', region: '日本', flag: 'jp' },
no: { language: 'Norsk', region: 'Norge', flag: 'no' },
'pt-BR': { language: 'Português', region: 'Brasil', flag: 'br' },
sv: { language: 'Svenska', region: 'Sverige', flag: 'se' },
};

const getCountryFlagEmoji = (countryCode: string) => {
const codePoints = countryCode
.toUpperCase()
.split('')
.map((char) => 127397 + char.charCodeAt(0));

return String.fromCodePoint(...codePoints);
};

export const LocaleLink = ({ locale, selected }: { locale: LocaleType; selected: boolean }) => {
return (
<Link
className={cn(
'border border-gray-200 px-3 py-2 text-xs hover:bg-gray-100 hover:text-black',
selected && 'border-black',
)}
href="/"
locale={locale}
>
<div className="flex h-full items-center gap-2">
<div className="text-2xl">{getCountryFlagEmoji(localeLanguageRegionMap[locale].flag)}</div>
<div className="flex flex-col gap-1">
<span className="font-bold">{localeLanguageRegionMap[locale].language}</span>
<span>{localeLanguageRegionMap[locale].region}</span>
</div>
</div>
</Link>
);
};
76 changes: 76 additions & 0 deletions core/app/[locale]/store-selector/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { getTranslations, unstable_setRequestLocale } from 'next-intl/server';

import { client } from '~/client';
import { graphql } from '~/client/graphql';
import { Link } from '~/components/link';
import { StoreLogo, StoreLogoFragment } from '~/components/store-logo';
import { NavigationMenu, NavigationMenuLink } from '~/components/ui/navigation-menu';
import { locales, LocaleType } from '~/i18n';

import { LocaleLink } from './_components/locale-link';

export const metadata = {
title: 'Location selector',
};

const StoreSelectorPageQuery = graphql(
`
query LocationSelectorPageQuery {
site {
settings {
...StoreLogoFragment
}
}
}
`,
[StoreLogoFragment],
);

export default async function StoreSelector({
params: { locale: selectedLocale },
}: {
params: { locale: LocaleType };
}) {
unstable_setRequestLocale(selectedLocale);

const t = await getTranslations('StoreSelector');

const { data } = await client.fetch({
document: StoreSelectorPageQuery,
});

const storeSettings = data.site.settings;

return (
<>
<header>
<NavigationMenu>
<NavigationMenuLink asChild>
{storeSettings && (
<Link className="p-0" href="/">
<StoreLogo data={storeSettings} />
</Link>
)}
</NavigationMenuLink>
</NavigationMenu>
</header>

<div className="px-4 lg:container sm:px-10 lg:mx-auto lg:max-w-[1000px] lg:px-12">
<h1 className="text-3xl font-black lg:text-4xl">{t('heading')}</h1>
<p className="py-2 text-lg">{t('message')}</p>

<div className="grid grid-cols-1 gap-6 py-6 md:grid-cols-3 md:gap-11 lg:grid-cols-4 lg:gap-8">
{locales.map((locale) => (
<LocaleLink key={locale} locale={locale} selected={selectedLocale === locale} />
))}
</div>
</div>
</>
);
}

export function generateStaticParams() {
return locales.map((locale) => ({ locale }));
}

export const dynamic = 'force-static';
16 changes: 14 additions & 2 deletions core/components/footer/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
CategoryFooterMenuFragment,
} from './footer-menus';
import { WebPageFooterMenu, WebPageFooterMenuFragment } from './footer-menus/web-page-footer-menu';
import { Locale } from './locale';
import { PaymentMethods } from './payment-methods';
import { SocialIcons, SocialIconsFragment } from './social-icons';

Expand Down Expand Up @@ -69,10 +70,21 @@ export const Footer = ({ data }: Props) => {
</div>
</FooterSection>

<FooterSection className="flex flex-col justify-between gap-10 sm:flex-row sm:gap-8 sm:py-6">
<PaymentMethods />
<FooterSection className="flex flex-col gap-10 sm:gap-8 sm:py-6 lg:hidden">
<Locale />

<div className="flex w-full flex-col justify-between gap-10 sm:flex-row sm:gap-8">
<PaymentMethods />
{data.settings && <Copyright data={data.settings} />}
</div>
</FooterSection>

<FooterSection className="hidden justify-between gap-8 py-6 lg:flex">
{data.settings && <Copyright data={data.settings} />}
<div className="flex gap-8">
<Locale />
<PaymentMethods />
</div>
</FooterSection>
</ComponentsFooter>
);
Expand Down
14 changes: 14 additions & 0 deletions core/components/footer/locale.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Globe } from 'lucide-react';
import { getLocale } from 'next-intl/server';

import { Link } from '../link';

export const Locale = async () => {
const locale = await getLocale();

return (
<Link className="flex gap-2" href="/store-selector">
<Globe /> {locale.toUpperCase()}
</Link>
);
};
4 changes: 4 additions & 0 deletions core/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -396,5 +396,9 @@
"processing": "Processing...",
"addedProductQuantity": "{cartItems, plural, =1 {1 Item} other {# Items}} added to <cartLink> your cart</cartLink>",
"errorAddingProductToCart": "Error adding product to cart. Please try again."
},
"StoreSelector": {
"heading": "Store selector",
"message": "Select your preferred language and delivery location"
}
}

0 comments on commit 0be98b4

Please sign in to comment.