Skip to content

Commit

Permalink
refactor(core) improve account forms submit error
Browse files Browse the repository at this point in the history
  • Loading branch information
bc-alexsaiannyi committed Dec 9, 2024
1 parent 4da6442 commit f363a2b
Show file tree
Hide file tree
Showing 21 changed files with 116 additions and 152 deletions.
5 changes: 5 additions & 0 deletions .changeset/afraid-eels-complain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bigcommerce/catalyst-core": patch
---

improve account forms submit errors message
Original file line number Diff line number Diff line change
Expand Up @@ -62,30 +62,28 @@ export const changePassword = async (_previousState: unknown, formData: FormData
const result = response.data.customer.resetPassword;

if (result.errors.length === 0) {
return { status: 'success', message: '' };
return { status: 'success', messages: [''] };
}

return {
status: 'error',
message: result.errors.map((error) => error.message).join('\n'),
messages: result.errors.map((error) => error.message),
};
} catch (error: unknown) {
if (error instanceof ZodError) {
return {
status: 'error',
message: error.issues
.map(({ path, message }) => `${path.toString()}: ${message}.`)
.join('\n'),
messages: error.issues.map(({ path, message }) => `${path.toString()}: ${message}.`),
};
}

if (error instanceof Error) {
return {
status: 'error',
message: error.message,
messages: [error.message],
};
}

return { status: 'error', message: t('Errors.error') };
return { status: 'error', messages: [t('Errors.error')] };
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { Message } from '~/components/ui/message';
import { useRouter } from '~/i18n/routing';

import { useAccountStatusContext } from '../../../account/(tabs)/_components/account-status-provider';
import { SubmitMessagesList } from '../../../account/(tabs)/_components/submit-messages-list';
import { changePassword } from '../_actions/change-password';

interface Props {
Expand Down Expand Up @@ -50,19 +51,13 @@ export const ChangePasswordForm = ({ customerId, customerToken }: Props) => {
const router = useRouter();
const [state, formAction] = useActionState(changePassword, {
status: 'idle',
message: '',
messages: [''],
});

const [newPassword, setNewPasssword] = useState('');
const [isConfirmPasswordValid, setIsConfirmPasswordValid] = useState(true);
const { setAccountState } = useAccountStatusContext();

let messageText = '';

if (state.status === 'error') {
messageText = state.message;
}

const handleNewPasswordChange = (e: ChangeEvent<HTMLInputElement>) =>
setNewPasssword(e.target.value);
const handleConfirmPasswordValidation = (e: ChangeEvent<HTMLInputElement>) => {
Expand All @@ -72,15 +67,15 @@ export const ChangePasswordForm = ({ customerId, customerToken }: Props) => {
};

if (state.status === 'success') {
setAccountState({ status: 'success', message: t('confirmChangePassword') });
setAccountState({ status: 'success', messages: [t('confirmChangePassword')] });
router.push('/login');
}

return (
<>
{state.status === 'error' && (
<Message className="mb-8 w-full text-gray-500" variant={state.status}>
<p>{messageText}</p>
<SubmitMessagesList messages={state.messages} />
</Message>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
import { Message } from '~/components/ui/message';

import { useAccountStatusContext } from '../../../account/(tabs)/_components/account-status-provider';
import { SubmitMessagesList } from '../../../account/(tabs)/_components/submit-messages-list';
import { login } from '../_actions/login';

const SubmitButton = () => {
Expand Down Expand Up @@ -66,7 +67,7 @@ export const LoginForm = () => {
<>
{accountState.status === 'success' && (
<Message className="col-span-full mb-8 w-full text-gray-500" variant={accountState.status}>
<p>{accountState.message}</p>
<SubmitMessagesList messages={accountState.messages} />
</Message>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,12 @@ const processZodErrors = (err: z.ZodError) => {
}));

if (formErrors.length > 0) {
return formErrors.join('\n');
return formErrors.map(({ message }) => message);
}

return Object.entries(fieldErrors)
.map(([, errorList]) => {
return `${errorList?.map(({ message }) => message).join('\n')}`;
})
.join('\n');
return Object.entries(fieldErrors).flatMap(([, errorList]) => {
return errorList?.map(({ message }) => message) ?? [''];
});
};

const ResetPasswordMutation = graphql(`
Expand Down Expand Up @@ -82,20 +80,20 @@ export const resetPassword = async ({

return {
status: 'error',
error: result.errors.map((error) => error.message).join('\n'),
errors: result.errors.map((error) => error.message),
};
} catch (error: unknown) {
if (error instanceof z.ZodError) {
return {
status: 'error',
error: processZodErrors(error),
errors: processZodErrors(error),
};
}

if (error instanceof Error) {
return { status: 'error', error: error.message };
return { status: 'error', errors: [error.message] };
}

return { status: 'error', error: t('Errors.error') };
return { status: 'error', errors: [t('Errors.error')] };
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import { ChangeEvent, useEffect, useRef, useState } from 'react';
import { useFormStatus } from 'react-dom';
import ReCaptcha from 'react-google-recaptcha';

import { useAccountStatusContext } from '~/app/[locale]/(default)/account/(tabs)/_components/account-status-provider';
import {
AccountState as FormStatus,
useAccountStatusContext,
} from '~/app/[locale]/(default)/account/(tabs)/_components/account-status-provider';
import { SubmitMessagesList } from '~/app/[locale]/(default)/account/(tabs)/_components/submit-messages-list';
import { type FragmentOf } from '~/client/graphql';
import { Button } from '~/components/ui/button';
import {
Expand All @@ -28,11 +32,6 @@ interface Props {
reCaptchaSettings?: FragmentOf<typeof ResetPasswordFormFragment>;
}

interface FormStatus {
status: 'success' | 'error';
message: string;
}

const SubmitButton = () => {
const t = useTranslations('Login.ForgotPassword.Form');

Expand Down Expand Up @@ -65,7 +64,7 @@ export const ResetPasswordForm = ({ reCaptchaSettings }: Props) => {
const router = useRouter();

useEffect(() => {
setAccountState({ status: 'idle' });
setAccountState({ status: 'idle', messages: [''] });
}, [setAccountState]);

const onReCatpchaChange = (token: string | null) => {
Expand Down Expand Up @@ -107,13 +106,13 @@ export const ResetPasswordForm = ({ reCaptchaSettings }: Props) => {

setAccountState({
status: 'success',
message: t('confirmResetPassword', { email: customerEmail?.toString() }),
messages: [t('confirmResetPassword', { email: customerEmail?.toString() })],
});
router.push('/login');
}

if (submit.status === 'error') {
setFormStatus({ status: 'error', message: submit.error ?? '' });
setFormStatus({ status: 'error', messages: submit.errors ?? [''] });
}

reCaptchaRef.current?.reset();
Expand All @@ -123,7 +122,7 @@ export const ResetPasswordForm = ({ reCaptchaSettings }: Props) => {
<>
{formStatus?.status === 'error' && (
<Message className="mb-8 w-full whitespace-pre" variant={formStatus.status}>
<p>{formStatus.message}</p>
<SubmitMessagesList messages={formStatus.messages} />
</Message>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import { ChangeEvent, MouseEvent, useRef, useState } from 'react';
import { useFormStatus } from 'react-dom';
import ReCaptcha from 'react-google-recaptcha';

import { useAccountStatusContext } from '~/app/[locale]/(default)/account/(tabs)/_components/account-status-provider';
import {
AccountState as FormStatus,
useAccountStatusContext,
} from '~/app/[locale]/(default)/account/(tabs)/_components/account-status-provider';
import { ExistingResultType } from '~/client/util';
import {
Checkboxes,
Expand Down Expand Up @@ -35,16 +38,11 @@ import { Button } from '~/components/ui/button';
import { Field, Form, FormSubmit } from '~/components/ui/form';
import { Message } from '~/components/ui/message';

import { SubmitErrorsList } from '../../../account/(tabs)/_components/submit-errors-list';
import { SubmitMessagesList } from '../../../account/(tabs)/_components/submit-messages-list';
import { login } from '../_actions/login';
import { registerCustomer } from '../_actions/register-customer';
import { getRegisterCustomerQuery } from '../page-data';

interface FormStatus {
status: 'success' | 'error';
messages: string[];
}

type CustomerFields = ExistingResultType<typeof getRegisterCustomerQuery>['customerFields'];
type AddressFields = ExistingResultType<typeof getRegisterCustomerQuery>['addressFields'];

Expand Down Expand Up @@ -225,7 +223,7 @@ export const RegisterCustomerForm = ({
const submit = await registerCustomer({ formData, reCaptchaToken });

if (submit.status === 'success') {
setAccountState({ status: 'success' });
setAccountState({ status: 'success', messages: [''] });

await login(formData);
}
Expand All @@ -242,9 +240,9 @@ export const RegisterCustomerForm = ({

return (
<>
{formStatus && (
{formStatus && formStatus.status !== 'idle' && (
<Message className="mb-8" variant={formStatus.status}>
<SubmitErrorsList errors={formStatus.messages} />
<SubmitMessagesList messages={formStatus.messages} />
</Message>
)}
<Form action={onSubmit} onClick={preSubmitFieldsValidation} ref={form}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ import { createContext, ReactNode, useContext, useEffect, useState } from 'react

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

import { State as AccountState } from '../settings/change-password/_actions/change-password';
// import { State as AccountState } from '../settings/change-password/_actions/change-password';

const defaultState: AccountState = { status: 'idle', message: '' };
export interface AccountState {
status: 'idle' | 'error' | 'success';
messages: string[];
}

const defaultState: AccountState = { status: 'idle', messages: [''] };

export const AccountStatusContext = createContext<{
accountState: AccountState;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const SubmitMessagesList = ({ messages }: { messages: string[] }) => (
<ul className={messages.length === 1 ? 'list-none' : 'ms-2 list-disc'}>
{messages.map((message) => (
<li key={message}>{message}</li>
))}
</ul>
);
15 changes: 0 additions & 15 deletions core/app/[locale]/(default)/account/(tabs)/_components/utils.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,21 @@ export const deleteAddress = async (addressId: number): Promise<State> => {
revalidatePath('/account/addresses', 'page');

if (result.errors.length === 0) {
return { status: 'success', message: t('success') };
return { status: 'success', messages: [t('success')] };
}

return {
status: 'error',
message: result.errors.map((error) => error.message).join('\n'),
messages: result.errors.map((error) => error.message),
};
} catch (error: unknown) {
if (error instanceof Error) {
return {
status: 'error',
message: error.message,
messages: [error.message],
};
}

return { status: 'error', message: t('error') };
return { status: 'error', messages: [t('error')] };
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Message } from '~/components/ui/message';

import { useAccountStatusContext } from '../../_components/account-status-provider';
import { Modal } from '../../_components/modal';
import { SubmitMessagesList } from '../../_components/submit-messages-list';
import { deleteAddress } from '../_actions/delete-address';
import { getCustomerAddresses } from '../page-data';

Expand All @@ -35,7 +36,7 @@ const AddressChangeButtons = ({ addressId, isAddressRemovable, onDelete }: Addre

setAccountState({
status: 'success',
message: submit.message || '',
messages: submit.messages || [''],
});
}
};
Expand Down Expand Up @@ -76,7 +77,7 @@ export const AddressBook = ({
<>
{(accountState.status === 'error' || accountState.status === 'success') && (
<Message className="mb-8 w-full text-gray-500" variant={accountState.status}>
<p>{accountState.message}</p>
<SubmitMessagesList messages={accountState.messages} />
</Message>
)}
{!addressesCount && <p className="border-t py-12 text-center">{t('emptyAddresses')}</p>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const addAddress = async ({
if (!isAddCustomerAddressInput(parsed)) {
return {
status: 'error',
error: t('Errors.inputError'),
errors: [t('Errors.inputError')],
};
}

Expand All @@ -83,21 +83,21 @@ export const addAddress = async ({
revalidatePath('/account/addresses', 'page');

if (result.errors.length === 0) {
return { status: 'success', message: t('success') };
return { status: 'success', messages: [t('success')] };
}

return {
status: 'error',
message: result.errors.map((error) => error.message).join('\n'),
messages: result.errors.map((error) => error.message),
};
} catch (error: unknown) {
if (error instanceof Error) {
return {
status: 'error',
message: error.message,
messages: [error.message],
};
}

return { status: 'error', message: t('Errors.error') };
return { status: 'error', messages: [t('Errors.error')] };
}
};
Loading

0 comments on commit f363a2b

Please sign in to comment.