From e0c25ec2e1d2ae4b68953a1ce1696873ddb3e009 Mon Sep 17 00:00:00 2001 From: Alexander Saiannyi Date: Thu, 28 Mar 2024 20:38:45 +0100 Subject: [PATCH] feat(core): add tabs for customer account --- .changeset/fuzzy-colts-draw.md | 5 ++ .../[tab]/_components/account-tabs.tsx | 38 +++++++++++++ .../(default)/account/[tab]/layout.tsx | 39 +++++++++++++ .../[locale]/(default)/account/[tab]/page.tsx | 55 +++++++++++++++++++ .../app/[locale]/(default)/account/page.tsx | 4 +- apps/core/messages/en.json | 3 +- 6 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 .changeset/fuzzy-colts-draw.md create mode 100644 apps/core/app/[locale]/(default)/account/[tab]/_components/account-tabs.tsx create mode 100644 apps/core/app/[locale]/(default)/account/[tab]/layout.tsx create mode 100644 apps/core/app/[locale]/(default)/account/[tab]/page.tsx diff --git a/.changeset/fuzzy-colts-draw.md b/.changeset/fuzzy-colts-draw.md new file mode 100644 index 000000000..871fd4729 --- /dev/null +++ b/.changeset/fuzzy-colts-draw.md @@ -0,0 +1,5 @@ +--- +"@bigcommerce/catalyst-core": minor +--- + +Add tabs for customer account diff --git a/apps/core/app/[locale]/(default)/account/[tab]/_components/account-tabs.tsx b/apps/core/app/[locale]/(default)/account/[tab]/_components/account-tabs.tsx new file mode 100644 index 000000000..640bafe72 --- /dev/null +++ b/apps/core/app/[locale]/(default)/account/[tab]/_components/account-tabs.tsx @@ -0,0 +1,38 @@ +'use client'; + +import { Tabs, TabsContent, TabsList, TabsTrigger } from '@bigcommerce/components/tabs'; +import { useTranslations } from 'next-intl'; +import { PropsWithChildren } from 'react'; + +import { Link } from '~/components/link'; + +import { TabType } from '../layout'; + +interface Props extends PropsWithChildren { + tabs: TabType[]; + activeTab?: TabType; +} + +export const AccountTabs = ({ children, activeTab, tabs }: Props) => { + const t = useTranslations('Account.Home'); + + return ( + + + {tabs.map((tab) => ( + + + {tab === 'recently-viewed' ? t('recentlyViewed') : t(tab)} + + + ))} + + {children} + + ); +}; diff --git a/apps/core/app/[locale]/(default)/account/[tab]/layout.tsx b/apps/core/app/[locale]/(default)/account/[tab]/layout.tsx new file mode 100644 index 000000000..a09fa233b --- /dev/null +++ b/apps/core/app/[locale]/(default)/account/[tab]/layout.tsx @@ -0,0 +1,39 @@ +import { NextIntlClientProvider } from 'next-intl'; +import { getMessages, getTranslations, unstable_setRequestLocale } from 'next-intl/server'; +import { PropsWithChildren } from 'react'; + +import { LocaleType } from '~/i18n'; + +import { AccountTabs } from './_components/account-tabs'; + +const tabList = [ + 'orders', + 'messages', + 'addresses', + 'wishlists', + 'recently-viewed', + 'settings', +] as const; + +export type TabType = (typeof tabList)[number]; + +interface Props extends PropsWithChildren { + params: { locale: LocaleType; tab?: TabType }; +} + +export default async function AccountTabLayout({ children, params: { locale, tab } }: Props) { + unstable_setRequestLocale(locale); + + const t = await getTranslations({ locale, namespace: 'Account.Home' }); + + const messages = await getMessages(); + + return ( + +

{t('heading')}

+ + {children} + +
+ ); +} diff --git a/apps/core/app/[locale]/(default)/account/[tab]/page.tsx b/apps/core/app/[locale]/(default)/account/[tab]/page.tsx new file mode 100644 index 000000000..5588ee602 --- /dev/null +++ b/apps/core/app/[locale]/(default)/account/[tab]/page.tsx @@ -0,0 +1,55 @@ +import type { Metadata } from 'next'; +import { notFound } from 'next/navigation'; +import { getTranslations } from 'next-intl/server'; + +import { LocaleType } from '~/i18n'; + +import { TabType } from './layout'; + +interface Props { + params: { + locale: LocaleType; + tab: TabType; + }; +} + +export async function generateMetadata({ params: { tab, locale } }: Props): Promise { + const t = await getTranslations({ locale, namespace: 'Account.Home' }); + + return { + title: t(tab === 'recently-viewed' ? 'recentlyViewed' : tab), + }; +} + +const tabHeading = async (heading: string, locale: LocaleType) => { + const t = await getTranslations({ locale, namespace: 'Account.Home' }); + + return

{t(heading)}

; +}; + +export default async function AccountTabPage({ params: { tab, locale } }: Props) { + switch (tab) { + case 'orders': + return tabHeading(tab, locale); + + case 'messages': + return tabHeading(tab, locale); + + case 'addresses': + return tabHeading(tab, locale); + + case 'wishlists': + return tabHeading(tab, locale); + + case 'recently-viewed': + return tabHeading('recentlyViewed', locale); + + case 'settings': + return tabHeading(tab, locale); + + default: + return notFound(); + } +} + +export const runtime = 'edge'; diff --git a/apps/core/app/[locale]/(default)/account/page.tsx b/apps/core/app/[locale]/(default)/account/page.tsx index f7260d170..5eba8e83b 100644 --- a/apps/core/app/[locale]/(default)/account/page.tsx +++ b/apps/core/app/[locale]/(default)/account/page.tsx @@ -44,7 +44,7 @@ export default async function AccountPage({ params: { locale } }: Props) { } return ( -
+

{t('heading')}

@@ -63,7 +63,7 @@ export default async function AccountPage({ params: { locale } }: Props) { - +
diff --git a/apps/core/messages/en.json b/apps/core/messages/en.json index 1dbe5b086..f37bca4a1 100644 --- a/apps/core/messages/en.json +++ b/apps/core/messages/en.json @@ -166,12 +166,13 @@ "Account": { "Home": { "heading": "My Account", + "accountTabsLabel": "Account Tabs", "orders": "Orders", "messages": "Messages", "addresses": "Addresses", "wishlists": "Wish lists", "recentlyViewed": "Recently viewed", - "accountSettings": "Account settings" + "settings": "Account settings" }, "Login": { "heading": "Log In",