1
- import React , { useState } from 'react'
2
- import AddressForm from '../Address/AddressForm'
3
1
import {
4
2
Elements ,
5
- CardElement ,
6
- IbanElement ,
7
- useStripe ,
3
+ PaymentElement ,
8
4
useElements ,
5
+ useStripe ,
9
6
} from '@stripe/react-stripe-js'
10
7
import { loadStripe } from '@stripe/stripe-js'
11
- import CreditCardForm from '../PaymentCard/CreditCardForm'
12
- import { RadioTileGroup } from 'ui/RadioTileGroup'
13
- import Icon from 'ui/Icon'
8
+ import React , { useState } from 'react'
9
+
10
+ import Button from 'ui/Button'
11
+
12
+ import AddressForm from '../Address/AddressForm'
14
13
15
- // Load your Stripe public key
16
- const stripePromise = loadStripe ( 'your-publishable-key-here' )
14
+ // TODO - fetch from API
15
+ const STRIPE_PUBLISHABLE_KEY =
16
+ 'pk_test_514SJTOGlVGuVgOrkRgh7zxp3tQ7bX4CY6pnxxw6zRZZSoDVtUUjArPKC7oXeeIbJNICTqS7H88FRfwZnWMskPKxo00bAnu2i9I'
17
+ const MANUALLY_FETCHED_CLIENT_SECRET =
18
+ 'seti_1QcfpCGlVGuVgOrkS4ABlEkc_secret_RVhDX8wtSc5T4NSHJZxeeiCzumvt8r8'
19
+
20
+ const stripePromise = loadStripe ( STRIPE_PUBLISHABLE_KEY )
17
21
18
22
interface PaymentFormProps {
19
23
clientSecret : string
20
24
}
21
25
22
- const PaymentForm : React . FC < PaymentFormProps > = ( { clientSecret } ) => {
26
+ const PaymentForm : React . FC < PaymentFormProps > = ( ) => {
23
27
const stripe = useStripe ( )
24
28
const elements = useElements ( )
25
- const [ paymentMethod , setPaymentMethod ] = useState < 'card' | 'bank' > ( 'card' )
26
29
const [ isSubmitting , setIsSubmitting ] = useState ( false )
27
30
const [ errorMessage , setErrorMessage ] = useState < string | null > ( null )
28
31
@@ -37,21 +40,11 @@ const PaymentForm: React.FC<PaymentFormProps> = ({ clientSecret }) => {
37
40
return
38
41
}
39
42
40
- const paymentElement = elements . getElement (
41
- paymentMethod === 'card' ? CardElement : IbanElement
42
- )
43
-
44
- if ( ! paymentElement ) {
45
- setErrorMessage ( 'Payment element is missing.' )
46
- setIsSubmitting ( false )
47
- return
48
- }
49
-
50
- // Confirm payment based on selected method
51
43
const { error } = await stripe . confirmPayment ( {
52
44
elements,
53
45
confirmParams : {
54
- return_url : 'https://your-website.com/order-complete' , // Redirect URL
46
+ // eslint-disable-next-line camelcase
47
+ return_url : 'https://codecov.io' ,
55
48
} ,
56
49
} )
57
50
@@ -64,73 +57,50 @@ const PaymentForm: React.FC<PaymentFormProps> = ({ clientSecret }) => {
64
57
}
65
58
66
59
return (
67
- < form onSubmit = { handleSubmit } className = "space-y-4" >
68
- < h2 className = "text-lg font-bold" > Choose Payment Method</ h2 >
69
-
70
- < RadioTileGroup
71
- value = { paymentMethod }
72
- onValueChange = { ( value : 'card' | 'bank' ) => setPaymentMethod ( value ) }
73
- className = "flex-row"
74
- >
75
- < RadioTileGroup . Item value = "card" data-testid = "card-radio" >
76
- < RadioTileGroup . Label >
77
- < div className = "flex items-center gap-2" >
78
- < Icon name = "checkCircle" > </ Icon >
79
- Card
80
- </ div >
81
- </ RadioTileGroup . Label >
82
- </ RadioTileGroup . Item >
83
- < RadioTileGroup . Item value = "bank" data-testid = "bank-radio" >
84
- < RadioTileGroup . Label >
85
- < div className = "flex items-center gap-2" >
86
- < Icon name = "checkCircle" > </ Icon >
87
- Bank Account
88
- </ div >
89
- </ RadioTileGroup . Label >
90
- </ RadioTileGroup . Item >
91
- </ RadioTileGroup >
92
-
93
- { /* Payment Element */ }
94
- { paymentMethod === 'card' && (
95
- < div >
96
- < h3 className = "font-semibold" > Card Details</ h3 >
97
- < CreditCardForm
98
- closeForm = { function ( ) : void {
99
- throw new Error ( 'Function not implemented.' )
100
- } }
101
- provider = { '' }
102
- owner = { '' }
103
- />
104
- </ div >
105
- ) }
106
-
107
- { paymentMethod === 'bank' && (
108
- < div >
109
- < h3 className = "font-semibold" > Bank Account Details</ h3 >
110
- < IbanElement
111
- className = "border p-2 rounded"
112
- options = { {
113
- supportedCountries : [ 'SEPA' ] , // Specify the supported countries
114
- } }
115
- />
116
- </ div >
117
- ) }
60
+ < div >
61
+ < PaymentElement
62
+ options = { {
63
+ layout : 'tabs' ,
64
+ defaultValues : {
65
+ billingDetails : {
66
+ name : 'John Doe' ,
67
+ } ,
68
+ } ,
69
+ } }
70
+ />
71
+ < div className = "mb-8 mt-4 flex gap-1" >
72
+ < Button
73
+ hook = "submit-address-update"
74
+ type = "submit"
75
+ variant = "primary"
76
+ disabled = { isSubmitting } // TODO - handle loading state
77
+ onClick = { handleSubmit }
78
+ to = { undefined }
79
+ >
80
+ Save
81
+ </ Button >
82
+ < Button
83
+ type = "button"
84
+ hook = "cancel-address-update"
85
+ variant = "plain"
86
+ // disabled={isLoading}
87
+ onClick = { ( ) => console . log ( 'TODO - implement me' ) } // TODO - implement me
88
+ to = { undefined }
89
+ >
90
+ Cancel
91
+ </ Button >
92
+ </ div >
118
93
119
94
{ errorMessage && < div className = "text-red-500" > { errorMessage } </ div > }
120
- </ form >
95
+ </ div >
121
96
)
122
97
}
123
98
124
- // Wrapper Component to provide Stripe Elements
125
99
const PaymentPage : React . FC < { clientSecret : string } > = ( { clientSecret } ) => {
126
- // if (!clientSecret) {
127
- // return <div>Loading...</div>
128
- // }
129
-
130
100
const options = {
131
101
clientSecret,
132
102
appearance : {
133
- theme : 'stripe' ,
103
+ theme : 'stripe' as const ,
134
104
} ,
135
105
}
136
106
@@ -145,20 +115,48 @@ interface EditablePaymentMethodProps {
145
115
clientSecret : string
146
116
}
147
117
148
- const EditPaymentMethod : React . FC < EditablePaymentMethodProps > = ( {
149
- clientSecret,
150
- } ) => {
118
+ const EditPaymentMethod : React . FC < EditablePaymentMethodProps > = ( ) => {
119
+ const clientSecret = MANUALLY_FETCHED_CLIENT_SECRET // TODO - fetch from API
120
+
121
+ const [ activeTab , setActiveTab ] = useState < 'primary' | 'secondary' > ( 'primary' )
122
+
151
123
return (
152
124
< div className = "flex flex-col gap-4 p-4" >
153
125
< h3 className = "font-semibold" > Edit payment method</ h3 >
154
- < PaymentPage clientSecret = { clientSecret } />
155
- < AddressForm
156
- closeForm = { function ( ) : void {
157
- throw new Error ( 'TODO' )
158
- } }
159
- provider = { '' }
160
- owner = { '' }
161
- />
126
+ < div >
127
+ { /* Tabs for Primary and Secondary Payment Methods */ }
128
+ < div className = "ml-2 flex border-b border-ds-gray-tertiary" >
129
+ { [ 'primary' , 'secondary' ] . map ( ( tab ) => (
130
+ < button
131
+ key = { tab }
132
+ className = { `py-2 ${ tab === 'primary' ? 'mr-4' : '' } ${
133
+ activeTab === tab
134
+ ? 'border-b-2 border-ds-gray-octonary font-semibold text-ds-gray-octonary'
135
+ : 'text-ds-gray-quinary hover:border-b-2 hover:border-ds-gray-quinary'
136
+ } `}
137
+ onClick = { ( ) => setActiveTab ( tab as 'primary' | 'secondary' ) }
138
+ >
139
+ { tab === 'primary' ? 'Primary' : 'Secondary' } Payment Method
140
+ </ button >
141
+ ) ) }
142
+ </ div >
143
+
144
+ { /* Payment Details for the selected tab */ }
145
+ < div className = "m-4" >
146
+ { activeTab === 'primary' && (
147
+ < div >
148
+ < PaymentPage clientSecret = { clientSecret } />
149
+ < AddressForm closeForm = { ( ) => { } } provider = { '' } owner = { '' } />
150
+ </ div >
151
+ ) }
152
+ { activeTab === 'secondary' && (
153
+ < div >
154
+ < PaymentPage clientSecret = { clientSecret } />
155
+ < AddressForm closeForm = { ( ) => { } } provider = { '' } owner = { '' } />
156
+ </ div >
157
+ ) }
158
+ </ div >
159
+ </ div >
162
160
</ div >
163
161
)
164
162
}
0 commit comments