1
1
import {
2
- type Address ,
3
- type CheckoutParams ,
4
- type CheckoutSelectors ,
5
- type Consignment ,
6
- type Country ,
7
- type FormField ,
8
- type RequestOptions ,
9
- type ShippingInitializeOptions ,
10
- type ShippingRequestOptions ,
2
+ type Address ,
3
+ type CheckoutParams ,
4
+ type CheckoutSelectors ,
5
+ type Consignment ,
6
+ type Country ,
7
+ type FormField ,
8
+ type RequestOptions ,
9
+ type ShippingInitializeOptions ,
10
+ type ShippingRequestOptions ,
11
11
} from '@bigcommerce/checkout-sdk' ;
12
12
import { type FormikProps } from 'formik' ;
13
13
import { noop } from 'lodash' ;
14
- import React , { PureComponent , type ReactNode } from 'react' ;
14
+ import React , { useCallback , useState } from 'react' ;
15
15
import { lazy , object } from 'yup' ;
16
-
17
16
import { withLanguage , type WithLanguageProps } from '@bigcommerce/checkout/locale' ;
18
- import { FormContext } from '@bigcommerce/checkout/ui' ;
19
17
20
18
import {
21
- type AddressFormValues ,
22
- getAddressFormFieldsValidationSchema ,
23
- getTranslateAddressError ,
24
- mapAddressToFormValues ,
19
+ type AddressFormValues ,
20
+ getAddressFormFieldsValidationSchema ,
21
+ getTranslateAddressError ,
22
+ mapAddressToFormValues ,
25
23
} from '../../address' ;
24
+
26
25
import type CheckoutStepStatus from '../../checkout/CheckoutStepStatus' ;
27
26
import { withFormikExtended } from '../../common/form' ;
28
27
import { getCustomFormFieldsValidationSchema } from '../../formFields' ;
@@ -34,190 +33,169 @@ import ShippingFormFooter from '../ShippingFormFooter';
34
33
import StripeShippingAddress from './StripeShippingAddress' ;
35
34
36
35
export interface SingleShippingFormProps {
37
- isBillingSameAsShipping : boolean ;
38
- cartHasChanged : boolean ;
39
- consignments : Consignment [ ] ;
40
- countries : Country [ ] ;
41
- customerMessage : string ;
42
- isLoading : boolean ;
43
- isShippingMethodLoading : boolean ;
44
- isMultiShippingMode : boolean ;
45
- methodId ?: string ;
46
- shippingAddress ?: Address ;
47
- shouldShowOrderComments : boolean ;
48
- step : CheckoutStepStatus ;
49
- isInitialValueLoaded : boolean ;
50
- isStripeLoading ?( ) : void ;
51
- isStripeAutoStep ?( ) : void ;
52
- deinitialize ( options : ShippingRequestOptions ) : Promise < CheckoutSelectors > ;
53
- getFields ( countryCode ?: string ) : FormField [ ] ;
54
- initialize ( options : ShippingInitializeOptions ) : Promise < CheckoutSelectors > ;
55
- onSubmit ( values : SingleShippingFormValues ) : void ;
56
- onUnhandledError ?( error : Error ) : void ;
57
- updateAddress (
58
- address : Partial < Address > ,
59
- options ?: RequestOptions < CheckoutParams > ,
60
- ) : Promise < CheckoutSelectors > ;
36
+ isBillingSameAsShipping : boolean ;
37
+ cartHasChanged : boolean ;
38
+ consignments : Consignment [ ] ;
39
+ countries : Country [ ] ;
40
+ customerMessage : string ;
41
+ isLoading : boolean ;
42
+ isShippingMethodLoading : boolean ;
43
+ isMultiShippingMode : boolean ;
44
+ methodId ?: string ;
45
+ shippingAddress ?: Address ;
46
+ shouldShowOrderComments : boolean ;
47
+ step : CheckoutStepStatus ;
48
+ isInitialValueLoaded : boolean ;
49
+ isStripeLoading ?( ) : void ;
50
+ isStripeAutoStep ?( ) : void ;
51
+ deinitialize ( options : ShippingRequestOptions ) : Promise < CheckoutSelectors > ;
52
+ getFields ( countryCode ?: string ) : FormField [ ] ;
53
+ initialize ( options : ShippingInitializeOptions ) : Promise < CheckoutSelectors > ;
54
+ onSubmit ( values : SingleShippingFormValues ) : void ;
55
+ onUnhandledError ?( error : Error ) : void ;
56
+ updateAddress (
57
+ address : Partial < Address > ,
58
+ options ?: RequestOptions < CheckoutParams > ,
59
+ ) : Promise < CheckoutSelectors > ;
61
60
}
62
61
63
62
export interface SingleShippingFormValues {
64
- billingSameAsShipping : boolean ;
65
- shippingAddress ?: AddressFormValues ;
66
- orderComment : string ;
67
- }
68
-
69
- interface SingleShippingFormState {
70
- isUpdatingShippingData : boolean ;
63
+ billingSameAsShipping : boolean ;
64
+ shippingAddress ?: AddressFormValues ;
65
+ orderComment : string ;
71
66
}
72
67
73
- class StripeShippingForm extends PureComponent <
74
- SingleShippingFormProps & WithLanguageProps & FormikProps < SingleShippingFormValues >
75
- > {
76
- static contextType = FormContext ;
77
-
78
- state : SingleShippingFormState = {
79
- isUpdatingShippingData : false ,
80
- } ;
81
-
82
- render ( ) : ReactNode {
83
- const {
84
- cartHasChanged,
85
- isInitialValueLoaded,
86
- isLoading,
87
- countries,
88
- isStripeLoading,
89
- shippingAddress,
90
- consignments,
91
- shouldShowOrderComments,
92
- initialize,
93
- isValid,
94
- deinitialize,
95
- onSubmit,
96
- isStripeAutoStep,
97
- step,
98
- isShippingMethodLoading,
99
- } = this . props ;
100
-
101
- const { isUpdatingShippingData } = this . state ;
102
-
103
- return (
104
- < Form autoComplete = "on" >
105
- < Fieldset >
106
- < StripeShippingAddress
107
- consignments = { consignments }
108
- countries = { countries }
109
- deinitialize = { deinitialize }
110
- initialize = { initialize }
111
- isShippingMethodLoading = { isShippingMethodLoading }
112
- isStripeAutoStep = { isStripeAutoStep }
113
- isStripeLoading = { isStripeLoading }
114
- onAddressSelect = { this . handleAddressSelect }
115
- onSubmit = { onSubmit }
116
- shippingAddress = { shippingAddress }
117
- shouldDisableSubmit = { this . shouldDisableSubmit ( ) }
118
- step = { step }
119
- />
120
- < div className = "form-body" >
121
- < BillingSameAsShippingField />
122
- </ div >
123
- </ Fieldset >
124
-
125
- < ShippingFormFooter
126
- cartHasChanged = { cartHasChanged }
127
- isInitialValueLoaded = { isInitialValueLoaded }
128
- isLoading = { isLoading || isUpdatingShippingData }
129
- isMultiShippingMode = { false }
130
- shouldDisableSubmit = { this . shouldDisableSubmit ( ) }
131
- shouldShowOrderComments = { shouldShowOrderComments }
132
- shouldShowShippingOptions = { isValid }
133
- />
134
- </ Form >
135
- ) ;
68
+ const StripeShippingForm : React . FC < SingleShippingFormProps & WithLanguageProps & FormikProps < SingleShippingFormValues > > = ( props ) => {
69
+ const [ isUpdatingShippingData ] = useState ( false ) ;
70
+
71
+ const {
72
+ cartHasChanged,
73
+ isInitialValueLoaded,
74
+ isLoading,
75
+ countries,
76
+ isStripeLoading,
77
+ shippingAddress,
78
+ consignments,
79
+ shouldShowOrderComments,
80
+ initialize,
81
+ isValid,
82
+ deinitialize,
83
+ onSubmit,
84
+ isStripeAutoStep,
85
+ step,
86
+ isShippingMethodLoading,
87
+ updateAddress,
88
+ onUnhandledError = noop ,
89
+ values,
90
+ setValues,
91
+ getFields,
92
+ } = props ;
93
+
94
+ const shouldDisableSubmit = ( ) => {
95
+ if ( ! isValid ) {
96
+ return false ;
136
97
}
137
98
138
- private shouldDisableSubmit : ( ) => boolean = ( ) => {
139
- const { isLoading, consignments, isValid } = this . props ;
140
-
141
- const { isUpdatingShippingData } = this . state ;
142
-
143
- if ( ! isValid ) {
144
- return false ;
145
- }
146
-
147
- return isLoading || isUpdatingShippingData || ! hasSelectedShippingOptions ( consignments ) ;
148
- } ;
149
-
150
- private handleAddressSelect : ( address : Address ) => void = async ( address ) => {
151
- const { updateAddress, onUnhandledError = noop , values, setValues } = this . props ;
152
-
153
- try {
154
- await updateAddress ( address ) ;
155
-
156
- setValues ( {
157
- ...values ,
158
- shippingAddress : mapAddressToFormValues (
159
- this . getFields ( address . countryCode ) ,
160
- address ,
161
- ) ,
162
- } ) ;
163
- } catch ( error ) {
164
- onUnhandledError ( error ) ;
165
- }
166
- } ;
167
-
168
- private getFields ( countryCode : string | undefined ) : FormField [ ] {
169
- const { getFields } = this . props ;
170
-
171
- return getFields ( countryCode ) ;
99
+ return isLoading || isUpdatingShippingData || ! hasSelectedShippingOptions ( consignments ) ;
100
+ } ;
101
+
102
+ const handleAddressSelect = useCallback ( async ( address : Address ) => {
103
+ try {
104
+ await updateAddress ( address ) ;
105
+
106
+ setValues ( {
107
+ ...values ,
108
+ shippingAddress : mapAddressToFormValues (
109
+ getFields ( address . countryCode ) ,
110
+ address ,
111
+ ) ,
112
+ } ) ;
113
+ } catch ( error ) {
114
+ onUnhandledError ( error ) ;
172
115
}
173
- }
174
-
116
+ } , [ values , setValues , onUnhandledError ] ) ;
117
+
118
+ return (
119
+ < Form autoComplete = "on" >
120
+ < Fieldset >
121
+ < StripeShippingAddress
122
+ consignments = { consignments }
123
+ countries = { countries }
124
+ deinitialize = { deinitialize }
125
+ initialize = { initialize }
126
+ isShippingMethodLoading = { isShippingMethodLoading }
127
+ isStripeAutoStep = { isStripeAutoStep }
128
+ isStripeLoading = { isStripeLoading }
129
+ onAddressSelect = { handleAddressSelect }
130
+ onSubmit = { onSubmit }
131
+ shippingAddress = { shippingAddress }
132
+ shouldDisableSubmit = { shouldDisableSubmit ( ) }
133
+ step = { step }
134
+ />
135
+
136
+ < div className = "form-body" >
137
+ < BillingSameAsShippingField />
138
+ </ div >
139
+ </ Fieldset >
140
+
141
+ < ShippingFormFooter
142
+ cartHasChanged = { cartHasChanged }
143
+ isInitialValueLoaded = { isInitialValueLoaded }
144
+ isLoading = { isLoading || isUpdatingShippingData }
145
+ isMultiShippingMode = { false }
146
+ shouldDisableSubmit = { shouldDisableSubmit ( ) }
147
+ shouldShowOrderComments = { shouldShowOrderComments }
148
+ shouldShowShippingOptions = { isValid }
149
+ />
150
+ </ Form >
151
+ ) ;
152
+ } ;
175
153
export default withLanguage (
176
- withFormikExtended < SingleShippingFormProps & WithLanguageProps , SingleShippingFormValues > ( {
177
- handleSubmit : ( values , { props : { onSubmit } } ) => {
178
- onSubmit ( values ) ;
179
- } ,
180
- mapPropsToValues : ( {
181
- getFields,
182
- shippingAddress,
183
- isBillingSameAsShipping,
184
- customerMessage,
185
- } ) => ( {
186
- billingSameAsShipping : isBillingSameAsShipping ,
187
- orderComment : customerMessage ,
188
- shippingAddress : mapAddressToFormValues (
189
- getFields ( shippingAddress && shippingAddress . countryCode ) ,
190
- shippingAddress ,
191
- ) ,
192
- } ) ,
193
- isInitialValid : ( { shippingAddress, getFields, language } ) =>
194
- ! ! shippingAddress &&
154
+ withFormikExtended < SingleShippingFormProps & WithLanguageProps , SingleShippingFormValues > ( {
155
+ handleSubmit : ( values , { props : { onSubmit } } ) => {
156
+ onSubmit ( values ) ;
157
+ } ,
158
+ mapPropsToValues : ( {
159
+ getFields,
160
+ shippingAddress,
161
+ isBillingSameAsShipping,
162
+ customerMessage,
163
+ } ) => ( {
164
+ billingSameAsShipping : isBillingSameAsShipping ,
165
+ orderComment : customerMessage ,
166
+ shippingAddress : mapAddressToFormValues (
167
+ getFields ( shippingAddress && shippingAddress . countryCode ) ,
168
+ shippingAddress ,
169
+ ) ,
170
+ } ) ,
171
+ isInitialValid : ( { shippingAddress, getFields, language } ) =>
172
+ ! ! shippingAddress &&
173
+ getAddressFormFieldsValidationSchema ( {
174
+ language,
175
+ formFields : getFields ( shippingAddress . countryCode ) ,
176
+ } ) . isValidSync ( shippingAddress ) ,
177
+ validationSchema : ( {
178
+ language,
179
+ getFields,
180
+ methodId,
181
+ } : SingleShippingFormProps & WithLanguageProps ) =>
182
+ methodId
183
+ ? object ( {
184
+ shippingAddress : lazy < Partial < AddressFormValues > > ( ( formValues ) =>
185
+ getCustomFormFieldsValidationSchema ( {
186
+ translate : getTranslateAddressError ( language ) ,
187
+ formFields : getFields ( formValues && formValues . countryCode ) ,
188
+ } ) ,
189
+ ) ,
190
+ } )
191
+ : object ( {
192
+ shippingAddress : lazy < Partial < AddressFormValues > > ( ( formValues ) =>
195
193
getAddressFormFieldsValidationSchema ( {
196
- language,
197
- formFields : getFields ( shippingAddress . countryCode ) ,
198
- } ) . isValidSync ( shippingAddress ) ,
199
- validationSchema : ( {
200
- language,
201
- getFields,
202
- methodId,
203
- } : SingleShippingFormProps & WithLanguageProps ) =>
204
- methodId
205
- ? object ( {
206
- shippingAddress : lazy < Partial < AddressFormValues > > ( ( formValues ) =>
207
- getCustomFormFieldsValidationSchema ( {
208
- translate : getTranslateAddressError ( language ) ,
209
- formFields : getFields ( formValues && formValues . countryCode ) ,
210
- } ) ,
211
- ) ,
212
- } )
213
- : object ( {
214
- shippingAddress : lazy < Partial < AddressFormValues > > ( ( formValues ) =>
215
- getAddressFormFieldsValidationSchema ( {
216
- language,
217
- formFields : getFields ( formValues && formValues . countryCode ) ,
218
- } ) ,
219
- ) ,
220
- } ) ,
221
- enableReinitialize : false ,
222
- } ) ( StripeShippingForm ) ,
194
+ language,
195
+ formFields : getFields ( formValues && formValues . countryCode ) ,
196
+ } ) ,
197
+ ) ,
198
+ } ) ,
199
+ enableReinitialize : false ,
200
+ } ) ( StripeShippingForm ) ,
223
201
) ;
0 commit comments