-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core): add update customer form (#794)
- Loading branch information
1 parent
6661e3e
commit 956d738
Showing
15 changed files
with
509 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@bigcommerce/catalyst-core": minor | ||
--- | ||
|
||
add update customer form |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 14 additions & 6 deletions
20
core/app/[locale]/(default)/account/[tab]/_components/settings-content.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,38 @@ | ||
import { NextIntlClientProvider } from 'next-intl'; | ||
import { getLocale, getMessages } from 'next-intl/server'; | ||
|
||
import { TabType } from '../layout'; | ||
import { getCustomerSettingsQuery } from '../page-data'; | ||
|
||
import { ChangePasswordForm } from './change-password-form'; | ||
import { TabHeading } from './tab-heading'; | ||
import { UpdateSettingsForm } from './update-settings-form'; | ||
|
||
interface Props { | ||
title: TabType; | ||
action?: string | string[]; | ||
customerSettings: CustomerSettings; | ||
} | ||
|
||
export const SettingsContent = async ({ title, action }: Props) => { | ||
type CustomerSettings = NonNullable<Awaited<ReturnType<typeof getCustomerSettingsQuery>>>; | ||
|
||
export const SettingsContent = async ({ action, customerSettings }: Props) => { | ||
const locale = await getLocale(); | ||
const messages = await getMessages({ locale }); | ||
|
||
if (action === 'change-password') { | ||
if (action === 'change_password') { | ||
return ( | ||
<div className="mx-auto lg:w-2/3"> | ||
<TabHeading heading={action} locale={locale} /> | ||
<TabHeading heading={action} /> | ||
<NextIntlClientProvider locale={locale} messages={{ Account: messages.Account ?? {} }}> | ||
<ChangePasswordForm /> | ||
</NextIntlClientProvider> | ||
</div> | ||
); | ||
} | ||
|
||
return <TabHeading heading={title} locale={locale} />; | ||
return ( | ||
<div className="mx-auto lg:w-2/3"> | ||
<TabHeading heading="settings" /> | ||
<UpdateSettingsForm {...customerSettings} /> | ||
</div> | ||
); | ||
}; |
13 changes: 4 additions & 9 deletions
13
core/app/[locale]/(default)/account/[tab]/_components/tab-heading.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,12 @@ | ||
import { getTranslations } from 'next-intl/server'; | ||
import { getLocale, getTranslations } from 'next-intl/server'; | ||
|
||
import { TabType } from '../layout'; | ||
|
||
export const TabHeading = async ({ | ||
heading, | ||
locale, | ||
}: { | ||
heading: TabType | 'change-password'; | ||
locale: string; | ||
}) => { | ||
export const TabHeading = async ({ heading }: { heading: TabType | 'change_password' }) => { | ||
const locale = await getLocale(); | ||
const t = await getTranslations({ locale, namespace: 'Account.Home' }); | ||
const tab = heading === 'recently-viewed' ? 'recentlyViewed' : heading; | ||
const title = tab === 'change-password' ? 'changePassword' : tab; | ||
const title = tab === 'change_password' ? 'changePassword' : tab; | ||
|
||
return <h2 className="mb-8 text-3xl font-black lg:text-4xl">{t(title)}</h2>; | ||
}; |
36 changes: 36 additions & 0 deletions
36
...ale]/(default)/account/[tab]/_components/update-settings-form/_actions/update-customer.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
'use server'; | ||
|
||
import { updateCustomer as updateCustomerClient } from '~/client/mutations/update-customer'; | ||
|
||
interface UpdateCustomerForm { | ||
formData: FormData; | ||
reCaptchaToken?: string; | ||
} | ||
|
||
export const updateCustomer = async ({ formData, reCaptchaToken }: UpdateCustomerForm) => { | ||
formData.delete('g-recaptcha-response'); | ||
|
||
const formFields = Object.fromEntries(formData.entries()); | ||
|
||
const response = await updateCustomerClient({ formFields, reCaptchaToken }); | ||
|
||
if (response.errors.length === 0) { | ||
const { customer } = response; | ||
|
||
if (!customer) { | ||
return { | ||
status: 'error', | ||
error: 'Customer does not exist', | ||
}; | ||
} | ||
|
||
const { firstName, lastName } = customer; | ||
|
||
return { status: 'success', data: { firstName, lastName } }; | ||
} | ||
|
||
return { | ||
status: 'error', | ||
error: response.errors.map((error) => error.message).join('\n'), | ||
}; | ||
}; |
58 changes: 58 additions & 0 deletions
58
core/app/[locale]/(default)/account/[tab]/_components/update-settings-form/fields/text.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { useTranslations } from 'next-intl'; | ||
import { ChangeEvent } from 'react'; | ||
|
||
import { Field, FieldControl, FieldLabel, FieldMessage } from '~/components/ui/form'; | ||
import { Input } from '~/components/ui/input'; | ||
|
||
import { FieldNameToFieldId } from '..'; | ||
|
||
interface TextProps { | ||
defaultValue?: string; | ||
entityId: number; | ||
isRequired?: boolean; | ||
isValid?: boolean; | ||
label: string; | ||
onChange: (e: ChangeEvent<HTMLInputElement>) => void; | ||
type?: 'text' | 'email'; | ||
} | ||
|
||
export const Text = ({ | ||
defaultValue, | ||
entityId, | ||
isRequired = false, | ||
isValid, | ||
label, | ||
onChange, | ||
type = 'text', | ||
}: TextProps) => { | ||
const t = useTranslations('Account.Settings.validationMessages'); | ||
const fieldName = FieldNameToFieldId[entityId]; | ||
const name = fieldName ?? `field-${entityId}`; | ||
|
||
return ( | ||
<Field className="relative space-y-2 pb-7" name={name}> | ||
<FieldLabel htmlFor={name} isRequired={isRequired}> | ||
{label} | ||
</FieldLabel> | ||
<FieldControl asChild> | ||
<Input | ||
defaultValue={defaultValue} | ||
id={`field-${entityId}`} | ||
onChange={isRequired ? onChange : undefined} | ||
onInvalid={isRequired ? onChange : undefined} | ||
required={isRequired} | ||
type={type} | ||
variant={isValid === false ? 'error' : undefined} | ||
/> | ||
</FieldControl> | ||
{isRequired && ( | ||
<FieldMessage | ||
className="absolute inset-x-0 bottom-0 inline-flex w-full text-xs font-normal text-error-secondary" | ||
match="valueMissing" | ||
> | ||
{t(fieldName ?? 'empty')} | ||
</FieldMessage> | ||
)} | ||
</Field> | ||
); | ||
}; |
Oops, something went wrong.