Skip to content

Commit

Permalink
Merge branch 'main' into improve-account-ux
Browse files Browse the repository at this point in the history
  • Loading branch information
bc-yevhenii-buliuk authored Nov 12, 2024
2 parents bee0653 + 16e3a76 commit 327011c
Show file tree
Hide file tree
Showing 67 changed files with 1,056 additions and 805 deletions.
5 changes: 5 additions & 0 deletions .changeset/bright-dancers-turn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bigcommerce/catalyst-core": minor
---

Next 15 upgrade
5 changes: 5 additions & 0 deletions .changeset/lemon-insects-kiss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bigcommerce/eslint-config-catalyst": patch
---

allow props not to be spread
5 changes: 5 additions & 0 deletions .changeset/smooth-carrots-punch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bigcommerce/catalyst-client": minor
---

Adds async support to beforeRequest hook
5 changes: 5 additions & 0 deletions .changeset/translations-patch-627308ed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bigcommerce/catalyst-core": patch
---

Update translations.
2 changes: 1 addition & 1 deletion .github/workflows/regression-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ jobs:
- name: Run Playwright tests
run: |
cd core
npx playwright test tests/ui/ --project=tests-chromium
npx playwright test tests/ui/ --project=tests-chromium
- uses: actions/upload-artifact@v4
if: failure()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use client';

import { useTranslations } from 'next-intl';
import { ChangeEvent, useRef, useState } from 'react';
import { useFormState, useFormStatus } from 'react-dom';
import { ChangeEvent, useActionState, useRef, useState } from 'react';
import { useFormStatus } from 'react-dom';

import { Button } from '~/components/ui/button';
import {
Expand Down Expand Up @@ -48,7 +48,7 @@ export const ChangePasswordForm = ({ customerId, customerToken }: Props) => {

const form = useRef<HTMLFormElement>(null);
const router = useRouter();
const [state, formAction] = useFormState(changePassword, {
const [state, formAction] = useActionState(changePassword, {
status: 'idle',
message: '',
});
Expand Down
17 changes: 7 additions & 10 deletions core/app/[locale]/(default)/(auth)/change-password/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useLocale, useTranslations } from 'next-intl';
import { getTranslations } from 'next-intl/server';
import { getLocale, getTranslations } from 'next-intl/server';

import { redirect } from '~/i18n/routing';

Expand All @@ -14,18 +13,16 @@ export async function generateMetadata() {
}

interface Props {
searchParams: {
searchParams: Promise<{
c?: string;
t?: string;
};
}>;
}

export default function ChangePassword({ searchParams }: Props) {
const t = useTranslations('ChangePassword');
const locale = useLocale();

const customerId = searchParams.c;
const customerToken = searchParams.t;
export default async function ChangePassword({ searchParams }: Props) {
const { c: customerId, t: customerToken } = await searchParams;
const t = await getTranslations('ChangePassword');
const locale = await getLocale();

if (!customerId || !customerToken) {
redirect({ href: '/login', locale });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use client';

import { useTranslations } from 'next-intl';
import { ChangeEvent, useState } from 'react';
import { useFormState, useFormStatus } from 'react-dom';
import { ChangeEvent, useActionState, useState } from 'react';
import { useFormStatus } from 'react-dom';

import { Link } from '~/components/link';
import { Button } from '~/components/ui/button';
Expand Down Expand Up @@ -41,7 +41,7 @@ export const LoginForm = () => {

const [isEmailValid, setIsEmailValid] = useState(true);
const [isPasswordValid, setIsPasswordValid] = useState(true);
const [state, formAction] = useFormState(login, { status: 'idle' });
const [state, formAction] = useActionState(login, { status: 'idle' });
const { accountState } = useAccountStatusContext();

const isFormInvalid = state?.status === 'error';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ export default async function Reset() {
fetchOptions: { next: { revalidate } },
});

const recaptchaSettings = await bypassReCaptcha(data.site.settings?.reCaptcha);

return (
<div className="mx-auto my-6 max-w-4xl">
<h2 className="mb-8 text-4xl font-black lg:text-5xl">{t('heading')}</h2>
<ResetPasswordForm reCaptchaSettings={bypassReCaptcha(data.site.settings?.reCaptcha)} />
<ResetPasswordForm reCaptchaSettings={recaptchaSettings} />
</div>
);
}
Expand Down
15 changes: 10 additions & 5 deletions core/app/[locale]/(default)/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useTranslations } from 'next-intl';
import { getTranslations, setRequestLocale } from 'next-intl/server';

import { Link } from '~/components/link';
Expand All @@ -7,7 +6,11 @@ import { locales, LocaleType } from '~/i18n/routing';

import { LoginForm } from './_components/login-form';

export async function generateMetadata() {
export async function generateMetadata({ params }: Props) {
const { locale } = await params;

setRequestLocale(locale);

const t = await getTranslations('Login');

return {
Expand All @@ -16,13 +19,15 @@ export async function generateMetadata() {
}

interface Props {
params: { locale: LocaleType };
params: Promise<{ locale: LocaleType }>;
}

export default function Login({ params: { locale } }: Props) {
export default async function Login({ params }: Props) {
const { locale } = await params;

setRequestLocale(locale);

const t = useTranslations('Login');
const t = await getTranslations('Login');

return (
<div className="mx-auto my-6 max-w-4xl">
Expand Down
2 changes: 1 addition & 1 deletion core/app/[locale]/(default)/(auth)/register/page-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const getRegisterCustomerQuery = cache(async ({ address, customer }: Prop
const countries = response.data.geography.countries;
const defaultCountry = response.data.site.settings?.contact?.country;

const reCaptchaSettings = bypassReCaptcha(response.data.site.settings?.reCaptcha);
const reCaptchaSettings = await bypassReCaptcha(response.data.site.settings?.reCaptcha);

if (!addressFields || !customerFields || !countries) {
return null;
Expand Down
3 changes: 2 additions & 1 deletion core/app/[locale]/(default)/(auth)/register/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ export default async function Register() {
}

const { addressFields, customerFields, reCaptchaSettings } = registerCustomerData;
const reCaptcha = await bypassReCaptcha(reCaptchaSettings);

return (
<div className="mx-auto mb-10 mt-8 text-base lg:w-2/3">
<h1 className="my-6 text-4xl font-black lg:my-8 lg:text-5xl">{t('heading')}</h1>
<RegisterCustomerForm
addressFields={addressFields}
customerFields={customerFields}
reCaptchaSettings={bypassReCaptcha(reCaptchaSettings)}
reCaptchaSettings={reCaptcha}
/>
</div>
);
Expand Down
16 changes: 11 additions & 5 deletions core/app/[locale]/(default)/(faceted)/brand/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ import { fetchFacetedSearch } from '../../fetch-faceted-search';
import { getBrand } from './page-data';

interface Props {
params: {
params: Promise<{
slug: string;
locale: LocaleType;
};
searchParams: Record<string, string | string[] | undefined>;
}>;
searchParams: Promise<Record<string, string | string[] | undefined>>;
}

export async function generateMetadata({ params }: Props): Promise<Metadata> {
export async function generateMetadata(props: Props): Promise<Metadata> {
const params = await props.params;
const brandId = Number(params.slug);

const brand = await getBrand({ entityId: brandId });
Expand All @@ -39,7 +40,12 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
};
}

export default async function Brand({ params: { slug, locale }, searchParams }: Props) {
export default async function Brand(props: Props) {
const searchParams = await props.searchParams;
const params = await props.params;

const { slug, locale } = params;

setRequestLocale(locale);

const t = await getTranslations('Brand');
Expand Down
16 changes: 11 additions & 5 deletions core/app/[locale]/(default)/(faceted)/category/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ import { SubCategories } from './_components/sub-categories';
import { getCategoryPageData } from './page-data';

interface Props {
params: {
params: Promise<{
slug: string;
locale: LocaleType;
};
searchParams: Record<string, string | string[] | undefined>;
}>;
searchParams: Promise<Record<string, string | string[] | undefined>>;
}

export async function generateMetadata({ params }: Props): Promise<Metadata> {
const categoryId = Number(params.slug);
const { slug } = await params;
const categoryId = Number(slug);

const data = await getCategoryPageData({
categoryId,
Expand All @@ -47,7 +48,12 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
};
}

export default async function Category({ params: { locale, slug }, searchParams }: Props) {
export default async function Category(props: Props) {
const searchParams = await props.searchParams;
const params = await props.params;

const { locale, slug } = params;

setRequestLocale(locale);

const t = await getTranslations('Category');
Expand Down
5 changes: 3 additions & 2 deletions core/app/[locale]/(default)/(faceted)/search/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ export async function generateMetadata() {
}

interface Props {
searchParams: Record<string, string | string[] | undefined>;
searchParams: Promise<Record<string, string | string[] | undefined>>;
}

export default async function Search({ searchParams }: Props) {
export default async function Search(props: Props) {
const searchParams = await props.searchParams;
const t = await getTranslations('Search');

const searchTerm = typeof searchParams.term === 'string' ? searchParams.term : undefined;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useTranslations } from 'next-intl';
import { getTranslations } from 'next-intl/server';

import { TabType } from './tab-navigation';

export const TabHeading = ({ heading }: { heading: TabType }) => {
const t = useTranslations('Account.Home');
export const TabHeading = async ({ heading }: { heading: TabType }) => {
const t = await getTranslations('Account.Home');

return <h2 className="mb-8 text-3xl font-black lg:text-4xl">{t(heading)}</h2>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ export default async function AddPage() {
});

const addressFields = [...(data.site.settings?.formFields.shippingAddress ?? [])];
const reCaptchaSettings = data.site.settings?.reCaptcha;
const countries = data.geography.countries;
const defaultCountry = data.site.settings?.contact?.country || FALLBACK_COUNTRY.name;

Expand All @@ -91,14 +90,16 @@ export default async function AddPage() {
statesOrProvinces: defaultCountryStates = FALLBACK_COUNTRY.states,
} = countries?.find(({ name: country }) => country === defaultCountry) || {};

const recaptchaSettings = await bypassReCaptcha(data.site.settings?.reCaptcha);

return (
<div className="mx-auto mb-14 lg:w-2/3">
<h1 className="mb-8 text-3xl font-black lg:text-4xl">{t('heading')}</h1>
<AddAddressForm
addressFields={addressFields}
countries={countries || []}
defaultCountry={{ id: entityId, code, states: defaultCountryStates }}
reCaptchaSettings={bypassReCaptcha(reCaptchaSettings)}
reCaptchaSettings={recaptchaSettings}
/>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,12 @@ export async function generateMetadata() {
}

interface Props {
params: { slug: string };
searchParams: Record<string, string | string[] | undefined>;
params: Promise<{ slug: string }>;
}

export default async function Edit({ params: { slug } }: Props) {
export default async function Edit({ params }: Props) {
const { slug } = await params;

const t = await getTranslations('Account.Addresses.Edit');
const customerAccessToken = await getSessionCustomerAccessToken();

Expand All @@ -116,7 +117,6 @@ export default async function Edit({ params: { slug } }: Props) {
},
});

const reCaptchaSettings = data.site.settings?.reCaptcha;
const countries = data.geography.countries;
const addressFields = [...(data.site.settings?.formFields.shippingAddress ?? [])];
const addresses = removeEdgesAndNodes({ edges: data.customer?.addresses.edges });
Expand All @@ -131,6 +131,8 @@ export default async function Edit({ params: { slug } }: Props) {
return notFound();
}

const reCaptchaSettings = await bypassReCaptcha(data.site.settings?.reCaptcha);

return (
<div className="mx-auto mb-14 lg:w-2/3">
<h1 className="mb-8 text-3xl font-black lg:text-4xl">{t('heading')}</h1>
Expand All @@ -139,7 +141,7 @@ export default async function Edit({ params: { slug } }: Props) {
addressFields={addressFields}
countries={countries || []}
isAddressRemovable={addresses.length > 1}
reCaptchaSettings={bypassReCaptcha(reCaptchaSettings)}
reCaptchaSettings={reCaptchaSettings}
/>
</div>
);
Expand Down
6 changes: 3 additions & 3 deletions core/app/[locale]/(default)/account/(tabs)/addresses/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import { AddressBook } from './_components/address-book';
import { getCustomerAddresses } from './page-data';

interface Props {
searchParams: {
searchParams: Promise<{
[key: string]: string | string[] | undefined;
before?: string;
after?: string;
};
}>;
}

export async function generateMetadata() {
Expand All @@ -25,7 +25,7 @@ export async function generateMetadata() {
}

export default async function Addresses({ searchParams }: Props) {
const { before, after } = searchParams;
const { before, after } = await searchParams;

const data = await getCustomerAddresses({
...(after && { after }),
Expand Down
8 changes: 5 additions & 3 deletions core/app/[locale]/(default)/account/(tabs)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { PropsWithChildren } from 'react';

import { LocaleType } from '~/i18n/routing';

import { TabNavigation } from './_components/tab-navigation';
import { TabNavigation, TabType } from './_components/tab-navigation';

interface Props extends PropsWithChildren {
params: { locale: LocaleType };
params: Promise<{ locale: LocaleType; tab?: TabType }>;
}

export default function AccountTabLayout({ children, params: { locale } }: Props) {
export default async function AccountTabLayout({ children, params }: Props) {
const { locale } = await params;

setRequestLocale(locale);

return (
Expand Down
Loading

0 comments on commit 327011c

Please sign in to comment.