Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): add tabs for customer account #719

Merged
merged 1 commit into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fuzzy-colts-draw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bigcommerce/catalyst-core": minor
---

Add tabs for customer account
Original file line number Diff line number Diff line change
@@ -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 activationMode="manual" defaultValue={activeTab}>
<TabsList aria-label={t('accountTabsLabel')} className="mb-5 pb-3">
{tabs.map((tab) => (
<TabsTrigger asChild key={tab} value={tab}>
<Link
className="whitespace-nowrap font-semibold"
href={`/account/${tab}`}
prefetch="viewport"
prefetchKind="full"
>
{tab === 'recently-viewed' ? t('recentlyViewed') : t(tab)}
</Link>
</TabsTrigger>
))}
</TabsList>
<TabsContent value={activeTab ?? ''}>{children}</TabsContent>
</Tabs>
);
};
39 changes: 39 additions & 0 deletions apps/core/app/[locale]/(default)/account/[tab]/layout.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<NextIntlClientProvider locale={locale} messages={{ Account: messages.Account ?? {} }}>
<h1 className="my-6 my-8 text-4xl font-black lg:my-8 lg:text-5xl">{t('heading')}</h1>
<AccountTabs activeTab={tab} tabs={[...tabList]}>
{children}
</AccountTabs>
</NextIntlClientProvider>
);
}
55 changes: 55 additions & 0 deletions apps/core/app/[locale]/(default)/account/[tab]/page.tsx
Original file line number Diff line number Diff line change
@@ -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<Metadata> {
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 <h2 className="mb-8 text-3xl font-black lg:text-4xl">{t(heading)}</h2>;
};

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';
4 changes: 2 additions & 2 deletions apps/core/app/[locale]/(default)/account/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default async function AccountPage({ params: { locale } }: Props) {
}

return (
<div className="mx-auto max-w-screen-xl">
<div className="mx-auto">
<h1 className="my-6 my-8 text-4xl font-black lg:my-8 lg:text-5xl">{t('heading')}</h1>

<div className="mb-14 grid gap-6 md:grid-cols-2 lg:grid-cols-3">
Expand All @@ -63,7 +63,7 @@ export default async function AccountPage({ params: { locale } }: Props) {
<AccountItem href="/account/recently-viewed" title={t('recentlyViewed')}>
<Eye className="me-8" height={48} width={48} />
</AccountItem>
<AccountItem href="/account/settings" title={t('accountSettings')}>
<AccountItem href="/account/settings" title={t('settings')}>
<Settings className="me-8" height={48} width={48} />
</AccountItem>
</div>
Expand Down
3 changes: 2 additions & 1 deletion apps/core/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading