From 58eee729fb60e60cdbd53c08bff67866b88e275a Mon Sep 17 00:00:00 2001 From: Alessandro Casazza Date: Tue, 16 Jul 2024 19:04:38 +0200 Subject: [PATCH 1/8] Add multi fields validation --- .../checkout/002.addresses.stories.tsx | 68 +++++++++++++++++++ .../addresses/BillingAddressForm.tsx | 49 ++++++++++--- .../addresses/ShippingAddressForm.tsx | 49 ++++++++++--- .../src/reducers/AddressReducer.ts | 8 ++- 4 files changed, 153 insertions(+), 21 deletions(-) diff --git a/packages/docs/stories/examples/checkout/002.addresses.stories.tsx b/packages/docs/stories/examples/checkout/002.addresses.stories.tsx index edec82fe..171701fb 100644 --- a/packages/docs/stories/examples/checkout/002.addresses.stories.tsx +++ b/packages/docs/stories/examples/checkout/002.addresses.stories.tsx @@ -720,6 +720,37 @@ export const CustomErrorMessages: StoryFn = () => { ) { return 'Validation error - The address should be 1-20 characters long - this is a custom message' } + if (props.field === 'billing_address_line_1') { + const country = props.values?.country_code + if (country === 'IT' && props.value !== 'Via Roma') { + return 'The address should be Via Roma' + } + return null + } + if (props.field === 'billing_address_country_code') { + const address = props.values?.line_1 + if (props.value === 'IT') { + if (address !== 'Via Roma') { + return [ + { + field: 'billing_address_line_1', + isValid: false, + message: 'The address should be Via Roma', + value: address + } + ] + } + } else { + return [ + { + field: 'billing_address_line_1', + isValid: true, + value: address + } + ] + } + return null + } return null }} > @@ -791,6 +822,43 @@ export const CustomErrorMessages: StoryFn = () => { /> +
+
+ + + +
+ +
+ + + +
+
diff --git a/packages/react-components/src/components/addresses/BillingAddressForm.tsx b/packages/react-components/src/components/addresses/BillingAddressForm.tsx index 8bc2a72e..74542b5b 100644 --- a/packages/react-components/src/components/addresses/BillingAddressForm.tsx +++ b/packages/react-components/src/components/addresses/BillingAddressForm.tsx @@ -93,20 +93,49 @@ export function BillingAddressForm(props: Props): JSX.Element { ) { const customMessage = customFieldMessageError({ field: fieldName, - value + value, + values }) if (customMessage != null) { - if (inError) { - const errorMsg = errors[fieldName]?.message - if (errorMsg != null && errorMsg !== customMessage) { - // @ts-expect-error no type - errors[fieldName].message = customMessage + if (typeof customMessage === 'string') { + if (inError) { + const errorMsg = errors[fieldName]?.message + if (errorMsg != null && errorMsg !== customMessage) { + // @ts-expect-error no type + errors[fieldName].message = customMessage + } + } else { + setErrorForm({ + name: fieldName, + code: 'VALIDATION_ERROR', + message: customMessage + }) } } else { - setErrorForm({ - name: fieldName, - code: 'VALIDATION_ERROR', - message: customMessage + const elements = customMessage + elements.forEach((element) => { + const { field, value, isValid, message } = element + const fieldInError = errors[field] != null + if (!isValid) { + if (fieldInError) { + const errorMsg = errors[field]?.message + if (errorMsg != null && errorMsg !== message) { + // @ts-expect-error no type + errors[field].message = message + } + } else { + setErrorForm({ + name: field, + code: 'VALIDATION_ERROR', + message: message + }) + } + } else { + if (fieldInError) { + delete errors[field] + setValueForm(field, value ?? '') + } + } }) } } diff --git a/packages/react-components/src/components/addresses/ShippingAddressForm.tsx b/packages/react-components/src/components/addresses/ShippingAddressForm.tsx index 72451991..c353022f 100644 --- a/packages/react-components/src/components/addresses/ShippingAddressForm.tsx +++ b/packages/react-components/src/components/addresses/ShippingAddressForm.tsx @@ -92,20 +92,49 @@ export function ShippingAddressForm(props: Props): JSX.Element { ) { const customMessage = customFieldMessageError({ field: fieldName, - value + value, + values }) if (customMessage != null) { - if (inError) { - const errorMsg = errors[fieldName]?.message - if (errorMsg != null && errorMsg !== customMessage) { - // @ts-expect-error no type - errors[fieldName].message = customMessage + if (typeof customMessage === 'string') { + if (inError) { + const errorMsg = errors[fieldName]?.message + if (errorMsg != null && errorMsg !== customMessage) { + // @ts-expect-error no type + errors[fieldName].message = customMessage + } + } else { + setErrorForm({ + name: fieldName, + code: 'VALIDATION_ERROR', + message: customMessage + }) } } else { - setErrorForm({ - name: fieldName, - code: 'VALIDATION_ERROR', - message: customMessage + const elements = customMessage + elements.forEach((element) => { + const { field, value, isValid, message } = element + const fieldInError = errors[field] != null + if (!isValid) { + if (fieldInError) { + const errorMsg = errors[field]?.message + if (errorMsg != null && errorMsg !== message) { + // @ts-expect-error no type + errors[field].message = message + } + } else { + setErrorForm({ + name: field, + code: 'VALIDATION_ERROR', + message: message + }) + } + } else { + if (fieldInError) { + delete errors[field] + setValueForm(field, value ?? '') + } + } }) } } diff --git a/packages/react-components/src/reducers/AddressReducer.ts b/packages/react-components/src/reducers/AddressReducer.ts index fa565625..cacaf307 100644 --- a/packages/react-components/src/reducers/AddressReducer.ts +++ b/packages/react-components/src/reducers/AddressReducer.ts @@ -24,7 +24,13 @@ export type CustomFieldMessageError = (props: { code?: Extract | undefined message?: string | undefined value: string -}) => string | null + values?: Record +}) => string | null | { + field: Extract | string + value: string + isValid: boolean + message?: string +}[] export type AddressActionType = | 'setErrors' From 2266ca231200c83b65e72e857322486fed94308f Mon Sep 17 00:00:00 2001 From: Alessandro Casazza Date: Tue, 16 Jul 2024 19:23:00 +0200 Subject: [PATCH 2/8] v4.15.0-beta.0 --- lerna.json | 2 +- packages/react-components/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lerna.json b/lerna.json index b9868e36..5c4afc15 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useNx": false, "npmClient": "pnpm", - "version": "4.14.5", + "version": "4.15.0-beta.0", "command": { "version": { "preid": "beta" diff --git a/packages/react-components/package.json b/packages/react-components/package.json index c62f9f2e..cf71f66e 100644 --- a/packages/react-components/package.json +++ b/packages/react-components/package.json @@ -1,6 +1,6 @@ { "name": "@commercelayer/react-components", - "version": "4.14.5", + "version": "4.15.0-beta.0", "description": "The Official Commerce Layer React Components", "main": "lib/cjs/index.js", "module": "lib/esm/index.js", From df4f951cbd76483c27a01caf3eff130236518a9f Mon Sep 17 00:00:00 2001 From: Alessandro Casazza Date: Thu, 18 Jul 2024 11:11:53 +0200 Subject: [PATCH 3/8] Fix show error message for state field --- .../checkout/002.addresses.stories.tsx | 78 +++++++++++-------- .../addresses/BillingAddressForm.tsx | 27 ++----- .../addresses/ShippingAddressForm.tsx | 26 ++----- 3 files changed, 59 insertions(+), 72 deletions(-) diff --git a/packages/docs/stories/examples/checkout/002.addresses.stories.tsx b/packages/docs/stories/examples/checkout/002.addresses.stories.tsx index 171701fb..42272a32 100644 --- a/packages/docs/stories/examples/checkout/002.addresses.stories.tsx +++ b/packages/docs/stories/examples/checkout/002.addresses.stories.tsx @@ -699,8 +699,8 @@ export const CustomErrorMessages: StoryFn = () => { customFieldMessageError={(props) => { const regex = /[a-zA-Z]+/g const phoneRegex = /^\d+$/ - const textWithSpace = /^[a-zA-Z0-9\s]{1,20}$/ - console.log('props.value billing', props.value) + // const textWithSpace = /^[a-zA-Z0-9\s]{1,20}$/ + console.log('props', props) if ( props.field === 'billing_address_first_name' && !regex.test(props.value) @@ -714,42 +714,22 @@ export const CustomErrorMessages: StoryFn = () => { ? 'Validation error - only numbers are allowed - this is a custom message' : null } - if ( - props.field === 'billing_address_line_1' && - !textWithSpace.test(props.value) - ) { - return 'Validation error - The address should be 1-20 characters long - this is a custom message' - } - if (props.field === 'billing_address_line_1') { - const country = props.values?.country_code - if (country === 'IT' && props.value !== 'Via Roma') { - return 'The address should be Via Roma' - } - return null - } if (props.field === 'billing_address_country_code') { - const address = props.values?.line_1 - if (props.value === 'IT') { - if (address !== 'Via Roma') { - return [ - { - field: 'billing_address_line_1', - isValid: false, - message: 'The address should be Via Roma', - value: address - } - ] - } - } else { + const state = props.values?.state_code as string + console.log('state', state) + if ( + ['US', 'CN', 'JP', 'AU', 'CA'].includes(props.value) && + !state + ) { return [ { - field: 'billing_address_line_1', - isValid: true, - value: address + field: 'billing_address_state_code', + value: state, + isValid: false, + message: 'State is required for this country' } ] } - return null } return null }} @@ -859,6 +839,40 @@ export const CustomErrorMessages: StoryFn = () => { /> +
+
+ + + +
+ +
+ + + +
+
diff --git a/packages/react-components/src/components/addresses/BillingAddressForm.tsx b/packages/react-components/src/components/addresses/BillingAddressForm.tsx index 74542b5b..1f37cb6d 100644 --- a/packages/react-components/src/components/addresses/BillingAddressForm.tsx +++ b/packages/react-components/src/components/addresses/BillingAddressForm.tsx @@ -115,6 +115,7 @@ export function BillingAddressForm(props: Props): JSX.Element { const elements = customMessage elements.forEach((element) => { const { field, value, isValid, message } = element + console.log('element', element) const fieldInError = errors[field] != null if (!isValid) { if (fieldInError) { @@ -148,26 +149,12 @@ export function BillingAddressForm(props: Props): JSX.Element { for (const fieldName in errors) { const code = errors[fieldName]?.code const message = errors[fieldName]?.message - if (['billing_address_state_code'].includes(fieldName)) { - if (!values?.['state_code']) { - // eslint-disable-next-line @typescript-eslint/no-dynamic-delete - delete errors[fieldName] - } else { - formErrors.push({ - code: code as CodeErrorType, - message: message || '', - resource: 'billing_address', - field: fieldName - }) - } - } else { - formErrors.push({ - code: code as CodeErrorType, - message: message ?? '', - resource: 'billing_address', - field: fieldName - }) - } + formErrors.push({ + code: code as CodeErrorType, + message: message ?? '', + resource: 'billing_address', + field: fieldName + }) } setAddressErrors(formErrors, 'billing_address') } else if (values && Object.keys(values).length > 0) { diff --git a/packages/react-components/src/components/addresses/ShippingAddressForm.tsx b/packages/react-components/src/components/addresses/ShippingAddressForm.tsx index c353022f..62749774 100644 --- a/packages/react-components/src/components/addresses/ShippingAddressForm.tsx +++ b/packages/react-components/src/components/addresses/ShippingAddressForm.tsx @@ -147,26 +147,12 @@ export function ShippingAddressForm(props: Props): JSX.Element { for (const fieldName in errors) { const code = errors[fieldName]?.code const message = errors[fieldName]?.message - if (['shipping_address_state_code'].includes(fieldName)) { - if (!values['state_code']) { - // eslint-disable-next-line @typescript-eslint/no-dynamic-delete - delete errors[fieldName] - } else { - formErrors.push({ - code: code as CodeErrorType, - message: message || '', - resource: 'shipping_address', - field: fieldName - }) - } - } else { - formErrors.push({ - code: code as CodeErrorType, - message: message ?? '', - resource: 'shipping_address', - field: fieldName - }) - } + formErrors.push({ + code: code as CodeErrorType, + message: message ?? '', + resource: 'shipping_address', + field: fieldName + }) } if (shipToDifferentAddress || invertAddresses) { setAddressErrors(formErrors, 'shipping_address') From 8e7af0d5ce81496f172e722ea7bc8638aea3c644 Mon Sep 17 00:00:00 2001 From: Alessandro Casazza Date: Thu, 18 Jul 2024 11:14:11 +0200 Subject: [PATCH 4/8] v4.15.0-beta.1 --- lerna.json | 2 +- .../checkout/002.addresses.stories.tsx | 52 +++++++++++++------ packages/react-components/package.json | 2 +- .../addresses/BillingAddressForm.tsx | 1 + .../addresses/ShippingAddressForm.tsx | 1 + 5 files changed, 39 insertions(+), 19 deletions(-) diff --git a/lerna.json b/lerna.json index 5c4afc15..ec9faec3 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useNx": false, "npmClient": "pnpm", - "version": "4.15.0-beta.0", + "version": "4.15.0-beta.1", "command": { "version": { "preid": "beta" diff --git a/packages/docs/stories/examples/checkout/002.addresses.stories.tsx b/packages/docs/stories/examples/checkout/002.addresses.stories.tsx index 42272a32..7cbd8a81 100644 --- a/packages/docs/stories/examples/checkout/002.addresses.stories.tsx +++ b/packages/docs/stories/examples/checkout/002.addresses.stories.tsx @@ -274,20 +274,7 @@ export const CustomerInvertAddresses: StoryFn = (args) => { {/* Use `key` to re-render the ShippingAddressForm once we have the order from `fetchOrder`. */} {/* When you are in your own project, you can retrieve the order before rendering the form. */} - { - const textWithSpace = /^[a-zA-Z0-9\s]{1,20}$/ - console.log('props.value', props.value) - if ( - props.field === 'shipping_address_line_1' && - !textWithSpace.test(props.value) - ) { - return 'Validation error - The address should be 1-20 characters long - this is a custom message' - } - return null - }} - > +