Skip to content

Commit

Permalink
feat: customer creation revamp (#1966)
Browse files Browse the repository at this point in the history
* feat: new customer page

* refactor: update customer information UI

* refactor: update billing section UI

* refactor: update metadata section UI

* refactor: update external app section UI

* feat: use new route and remove old drawer

* fix: e2e updates

* refactor: rename folder

* fix: add missing field in query

* fix: code review
  • Loading branch information
keellyp authored Jan 13, 2025
1 parent aa46bc4 commit 3a7ec1c
Show file tree
Hide file tree
Showing 19 changed files with 393 additions and 303 deletions.
14 changes: 9 additions & 5 deletions cypress/e2e/10-resources/t20-create-customer.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ describe('Create customer', () => {

it('should create customer', () => {
cy.get('[data-test="create-customer"]').click()
cy.get('input[name="name"]').should('exist').type(customerName, { scrollBehavior: false })
cy.url().should('include', '/customer/create')

cy.get('[data-test="submit-customer"]').should('be.disabled')

cy.get('[data-test="submit"]').should('be.disabled')
cy.get('input[name="externalId"]').type('id-george-de-la-jungle')
cy.get('[data-test="submit"]').click()

cy.get('input[name="name"]').should('exist').type(customerName, { scrollBehavior: false })

cy.get('[data-test="submit-customer"]').click()

cy.url().should('include', '/customer/')

Expand All @@ -26,9 +30,9 @@ describe('Create customer', () => {

cy.get('[data-test="create-customer"]').click()
cy.get('input[name="name"]').type(randomId, { scrollBehavior: false })
cy.get('[data-test="submit"]').should('be.disabled')
cy.get('[data-test="submit-customer"]').should('be.disabled')
cy.get('input[name="externalId"]').type(randomId)
cy.get('[data-test="submit"]').click()
cy.get('[data-test="submit-customer"]').click()
cy.url().should('include', '/customer/')
cy.contains(randomId).should('exist')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import { useInternationalization } from '~/hooks/core/useInternationalization'

const billingFields: Array<
{ name: keyof CustomerAddress; label?: string; placeholder?: string } & (
{ name: keyof CustomerAddress; label?: string; placeholder?: string; className?: string } & (
| {
type: 'text'
}
Expand All @@ -27,34 +27,43 @@ const billingFields: Array<
{
name: 'addressLine1',
type: 'text',
label: 'text_626c0c09812bbc00e4c59e1b',
placeholder: 'text_626c0c09812bbc00e4c59e1d',
label: 'text_626c0c09812bbc00e4c59e1d',
placeholder: 'text_1735653854525cemtriccmuh',
className: 'col-span-2',
},
{
name: 'addressLine2',
type: 'text',
placeholder: 'text_626c0c09812bbc00e4c59e1f',
label: 'text_626c0c09812bbc00e4c59e1f',
placeholder: 'text_1735653854525dq6plq7exd3',
className: 'col-span-2',
},
{
name: 'zipcode',
type: 'text',
placeholder: 'text_626c0c09812bbc00e4c59e21',
label: 'text_626c0c09812bbc00e4c59e21',
placeholder: 'text_1735654189136h4rgi3zdwaa',
},
{
name: 'city',
type: 'text',
placeholder: 'text_626c0c09812bbc00e4c59e23',
label: 'text_626c0c09812bbc00e4c59e23',
placeholder: 'text_1735654189136vn4mbzp4jhs',
},
{
name: 'state',
type: 'text',
placeholder: 'text_626c0c09812bbc00e4c59e25',
label: 'text_626c0c09812bbc00e4c59e25',
placeholder: 'text_173565418913690jb89ypb63',
className: 'col-span-2',
},
{
name: 'country',
type: 'combobox',
placeholder: 'text_626c0c09812bbc00e4c59e27',
label: 'text_626c0c09812bbc00e4c59e27',
data: countryDataForCombobox,
placeholder: 'text_1735654189136s548dkluunb',
className: 'col-span-2',
},
]

Expand Down Expand Up @@ -97,16 +106,16 @@ export const BillingAccordion: FC<BillingAccordionProps> = ({

return (
<Accordion
size="large"
variant="borderless"
summary={
<Typography variant="subhead">{translate('text_632b49e2620ea4c6d96c9662')}</Typography>
<div className="flex flex-col gap-2">
<Typography variant="subhead">{translate('text_632b49e2620ea4c6d96c9662')}</Typography>
<Typography variant="caption">{translate('text_1735653854525b68ew2qbpdp')}</Typography>
</div>
}
>
<div className="not-last-child:mb-8">
<div className="not-last-child:mb-6">
<Typography variant="bodyHl" color="textSecondary">
{translate('text_626c0c09812bbc00e4c59dff')}
</Typography>
<ComboBoxField
disabled={!!customer && !customer?.canEditAttributes}
label={translate('text_632c6e59b73f9a54d4c72247')}
Expand Down Expand Up @@ -164,33 +173,38 @@ export const BillingAccordion: FC<BillingAccordionProps> = ({
</div>
<div className="not-last-child:mb-4">
<Typography variant="bodyHl" color="textSecondary">
{translate('text_626c0c09812bbc00e4c59e19')}
{translate('text_626c0c301a16a600ea06148d')}
</Typography>

{billingFields.map((field) => {
if (field.type === 'text') {
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
{billingFields.map((field) => {
if (field.type === 'text') {
return (
<TextInputField
key={field.name}
name={field.name}
label={field.label && translate(field.label)}
className={field.className}
placeholder={field.placeholder && translate(field.placeholder)}
formikProps={formikProps}
/>
)
}

return (
<TextInputField
<ComboBoxField
key={field.name}
data={field.data}
name={field.name}
label={field.label && translate(field.label)}
containerClassName={field.className}
placeholder={field.placeholder && translate(field.placeholder)}
formikProps={formikProps}
PopperProps={{ displayInDialog: true }}
/>
)
}

return (
<ComboBoxField
key={field.name}
data={field.data}
name={field.name}
placeholder={field.placeholder && translate(field.placeholder)}
formikProps={formikProps}
PopperProps={{ displayInDialog: true }}
/>
)
})}
})}
</div>
</div>
<div className="not-last-child:mb-4">
<Typography variant="bodyHl" color="textSecondary">
Expand All @@ -201,32 +215,38 @@ export const BillingAccordion: FC<BillingAccordionProps> = ({
value={isShippingEqualBillingAddress}
onChange={() => setIsShippingEqualBillingAddress((prev) => !prev)}
/>
{billingFields.map((field) => {
if (field.type === 'text') {

<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
{billingFields.map((field) => {
if (field.type === 'text') {
return (
<TextInputField
key={`shippingAddress.${field.name}`}
name={`shippingAddress.${field.name}`}
label={field.label && translate(field.label)}
className={field.className}
placeholder={field.placeholder && translate(field.placeholder)}
formikProps={formikProps}
disabled={isShippingEqualBillingAddress}
/>
)
}

return (
<TextInputField
<ComboBoxField
key={`shippingAddress.${field.name}`}
name={`shippingAddress.${field.name}`}
label={field.label && translate(field.label)}
containerClassName={field.className}
placeholder={field.placeholder && translate(field.placeholder)}
formikProps={formikProps}
disabled={isShippingEqualBillingAddress}
PopperProps={{ displayInDialog: true }}
data={field.data}
/>
)
}

return (
<ComboBoxField
key={`shippingAddress.${field.name}`}
name={`shippingAddress.${field.name}`}
placeholder={field.placeholder && translate(field.placeholder)}
formikProps={formikProps}
disabled={isShippingEqualBillingAddress}
PopperProps={{ displayInDialog: true }}
data={field.data}
/>
)
})}
})}
</div>
</div>
</div>
</Accordion>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Grid } from '@mui/material'
import { FormikProps } from 'formik'
import { FC } from 'react'

import { TRANSLATIONS_MAP_CUSTOMER_TYPE } from '~/components/customers/utils'
import { Card, Typography } from '~/components/designSystem'
import { Typography } from '~/components/designSystem'
import { ComboBoxField, TextInputField } from '~/components/form'
import { ORGANIZATION_INFORMATIONS_ROUTE } from '~/core/router'
import { getTimezoneConfig } from '~/core/timezone'
Expand Down Expand Up @@ -34,8 +33,21 @@ export const CustomerInformation: FC<CustomerInformationProps> = ({
const { timezoneConfig } = useOrganizationInfos()

return (
<Card className="items-stretch">
<Typography variant="subhead">{translate('text_626c0c09812bbc00e4c59df1')}</Typography>
<div className="flex flex-col gap-6">
<div className="flex flex-col gap-2">
<Typography variant="subhead">{translate('text_6419c64eace749372fc72b07')}</Typography>
<Typography variant="caption">{translate('text_1735652987833k0i3l9ill5g')}</Typography>
</div>

<TextInputField
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus={!isEdition}
name="externalId"
disabled={isEdition && !customer?.canEditAttributes}
label={translate('text_624efab67eb2570101d117ce')}
placeholder={translate('text_624efab67eb2570101d117d6')}
formikProps={formikProps}
/>
<ComboBoxField
name="customerType"
label={translate('text_1726128938631ioz4orixel3')}
Expand All @@ -48,41 +60,28 @@ export const CustomerInformation: FC<CustomerInformationProps> = ({
}))}
/>
<TextInputField
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus={!isEdition}
name="name"
label={translate('text_624efab67eb2570101d117be')}
placeholder={translate('text_624efab67eb2570101d117c6')}
formikProps={formikProps}
/>
<Grid container spacing={4}>
<Grid item xs={12} md={6}>
<TextInputField
name="firstname"
label={translate('text_1726128938631ggtf2ggqs4b')}
placeholder={translate('text_1726128938631ntcpbzv7x7s')}
formikProps={formikProps}
/>
</Grid>
<Grid item xs={12} md={6}>
<TextInputField
name="lastname"
label={translate('text_1726128938631ymctg83bygm')}
placeholder={translate('text_1726128938631xmpsba9ssuo')}
formikProps={formikProps}
/>
</Grid>
</Grid>
<TextInputField
name="externalId"
disabled={isEdition && !customer?.canEditAttributes}
label={translate('text_624efab67eb2570101d117ce')}
placeholder={translate('text_624efab67eb2570101d117d6')}
helperText={
(!isEdition || customer?.canEditAttributes) && translate('text_624efab67eb2570101d117de')
}
formikProps={formikProps}
/>
<div className="flex gap-6">
<TextInputField
className="flex-1"
name="firstname"
label={translate('text_1726128938631ggtf2ggqs4b')}
placeholder={translate('text_1726128938631ntcpbzv7x7s')}
formikProps={formikProps}
/>

<TextInputField
className="flex-1"
name="lastname"
label={translate('text_1726128938631ymctg83bygm')}
placeholder={translate('text_1726128938631xmpsba9ssuo')}
formikProps={formikProps}
/>
</div>
<ComboBoxField
name="timezone"
label={translate('text_6390a4ffef9227ba45daca90')}
Expand Down Expand Up @@ -117,6 +116,6 @@ export const CustomerInformation: FC<CustomerInformationProps> = ({
helperText={translate('text_651fd41846f44c0064408b07')}
formikProps={formikProps}
/>
</Card>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ import {
ADD_CUSTOMER_TAX_PROVIDER_ACCORDION,
MUI_BUTTON_BASE_ROOT_CLASSNAME,
} from '~/core/constants/form'
import { INTEGRATIONS_ROUTE } from '~/core/router'
import {
CreateCustomerInput,
IntegrationTypeEnum,
ProviderTypeEnum,
UpdateCustomerInput,
} from '~/generated/graphql'
import { useInternationalization } from '~/hooks/core/useInternationalization'
import PSPIcons from '~/public/images/psp-icons.svg'
import { MenuPopper } from '~/styles'

import { AccountingProvidersAccordion } from './AccountingProvidersAccordion'
Expand Down Expand Up @@ -66,29 +64,15 @@ export const ExternalAppsAccordion = ({ formikProps, isEdition }: TExternalAppsA

return (
<Accordion
size="large"
variant="borderless"
summary={
<div className="flex items-center">
<div className="mr-3 h-6 [&>svg]:h-full">
<PSPIcons />
</div>
<div className="flex flex-col gap-2">
<Typography variant="subhead">{translate('text_66423cad72bbad009f2f5689')}</Typography>
<Typography variant="caption">{translate('text_1735828930375zjo8m3yh5ra')}</Typography>
</div>
}
>
<div className="flex flex-col gap-6">
<div>
<Typography variant="bodyHl" color="grey700">
{translate('text_66423dbab233e60111c49461')}
</Typography>
<Typography
variant="caption"
color="grey600"
html={translate('text_66423dbab233e60111c49462', {
href: INTEGRATIONS_ROUTE,
})}
/>
</div>
{showPaymentSection && (
<PaymentProvidersAccordion
formikProps={formikProps}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ export const MetadataAccordion: FC<MetadataAccordionProps> = ({ formikProps }) =

return (
<Accordion
size="large"
variant="borderless"
summary={
<Typography variant="subhead">{translate('text_63fcc3218d35b9377840f59b')}</Typography>
<div className="flex flex-col gap-2">
<Typography variant="subhead">{translate('text_63fcc3218d35b9377840f59b')}</Typography>
<Typography variant="caption">{translate('text_1735655045719sl0z0pooptb')}</Typography>
</div>
}
>
<div className="not-last-child:mb-4">
<Typography variant="body" color="grey600">
{translate('text_63fcc3218d35b9377840f59f')}
</Typography>
{!!formikProps?.values?.metadata?.length && (
<div>
<div className={tw(gridClassName, 'mb-1 [&>*:nth-child(3)]:col-span-2')}>
Expand Down
Loading

0 comments on commit 3a7ec1c

Please sign in to comment.