@hanzo/commerce 4.7.0 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/components/add-to-cart-widget.tsx +2 -2
  2. package/components/cart-panel/index.tsx +12 -15
  3. package/components/checkout-panel/cart-accordian.tsx +14 -6
  4. package/components/checkout-panel/close-button.tsx +3 -3
  5. package/components/checkout-panel/desktop.tsx +46 -0
  6. package/components/checkout-panel/index.tsx +85 -85
  7. package/components/checkout-panel/mobile.tsx +41 -0
  8. package/components/checkout-panel/{payment/payment-methods → steps/payment/cards}/index.tsx +2 -1
  9. package/components/checkout-panel/steps/payment/cc-button.tsx +17 -0
  10. package/components/checkout-panel/{payment → steps/payment}/contact-info.tsx +5 -6
  11. package/components/checkout-panel/{payment → steps/payment}/index.tsx +27 -21
  12. package/components/checkout-panel/{payment → steps/payment}/pay-with-bank-transfer.tsx +11 -7
  13. package/components/checkout-panel/steps/payment/pay-with-card.tsx +246 -0
  14. package/components/checkout-panel/{payment → steps/payment}/pay-with-crypto.tsx +7 -7
  15. package/components/checkout-panel/{shipping-info.tsx → steps/shipping-info.tsx} +8 -9
  16. package/components/checkout-panel/{thank-you.tsx → steps/thank-you.tsx} +4 -1
  17. package/components/checkout-panel/steps/types.ts +14 -0
  18. package/package.json +3 -3
  19. package/{components/checkout-panel → util}/countries.ts +1 -1
  20. package/components/checkout-panel/payment/pay-with-card.tsx +0 -222
  21. package/components/checkout-panel/step-indicator.tsx +0 -30
  22. package/components/checkout-panel/step.ts +0 -11
  23. /package/components/checkout-panel/{confirm-order.tsx → _confirm-order.tsx_unused} +0 -0
  24. /package/components/checkout-panel/{payment/payment-methods → steps/payment/cards}/amex.tsx +0 -0
  25. /package/components/checkout-panel/{payment/payment-methods → steps/payment/cards}/diners-club.tsx +0 -0
  26. /package/components/checkout-panel/{payment/payment-methods → steps/payment/cards}/discover.tsx +0 -0
  27. /package/components/checkout-panel/{payment/payment-methods → steps/payment/cards}/jcb.tsx +0 -0
  28. /package/components/checkout-panel/{payment/payment-methods → steps/payment/cards}/mastercard.tsx +0 -0
  29. /package/components/checkout-panel/{payment/payment-methods → steps/payment/cards}/visa.tsx +0 -0
@@ -0,0 +1,246 @@
1
+ 'use client'
2
+ import React from 'react'
3
+
4
+ import type { UseFormReturn } from 'react-hook-form'
5
+ // @ts-ignore
6
+ import { ApplePay, GooglePay, CreditCard, PaymentForm } from 'react-square-web-payments-sdk'
7
+
8
+ import { ChevronRight } from 'lucide-react'
9
+
10
+ import {
11
+ Accordion,
12
+ AccordionContent,
13
+ AccordionItem,
14
+ AccordionTrigger,
15
+ ApplyTypography,
16
+ Button,
17
+ buttonVariants
18
+ } from '@hanzo/ui/primitives'
19
+
20
+ import { cn } from '@hanzo/ui/util'
21
+
22
+ import { processSquareCardPayment } from '../../../../util'
23
+ import { useCommerce } from '../../../../service/context'
24
+ import type { TransactionStatus } from '../../../../types'
25
+
26
+ import ContactInfo from './contact-info'
27
+ import { sendFBEvent, sendGAEvent } from '../../../../util/analytics'
28
+ import PaymentMethods from './cards'
29
+
30
+ const PayWithCard: React.FC<{
31
+ onDone: () => void
32
+ transactionStatus: TransactionStatus
33
+ setTransactionStatus: (status: TransactionStatus) => void
34
+ storePaymentInfo: (paymentInfo: any) => Promise<void>
35
+ contactForm: UseFormReturn<{
36
+ name: string
37
+ email: string
38
+ }, any, {
39
+ name: string
40
+ email: string
41
+ }>
42
+ }> = ({
43
+ onDone,
44
+ transactionStatus,
45
+ setTransactionStatus,
46
+ storePaymentInfo,
47
+ contactForm,
48
+ }) => {
49
+ const cmmc = useCommerce()
50
+
51
+ const cardTokenizeResponseReceived = async (
52
+ token: any,
53
+ verifiedBuyer: any
54
+ ) => {
55
+ contactForm.handleSubmit(async () => {
56
+ setTransactionStatus('paid')
57
+ const res = await processSquareCardPayment(token.token, cmmc.cartTotal, verifiedBuyer.token)
58
+ if (res) {
59
+ console.log(token)
60
+ await storePaymentInfo({paymentMethod: token.details.method ?? null, processed: res})
61
+ setTransactionStatus('confirmed')
62
+ sendGAEvent('purchase', {
63
+ transaction_id: res.payment?.id,
64
+ value: res.payment?.amountMoney?.amount,
65
+ currency: res.payment?.amountMoney?.currency,
66
+ items: cmmc.cartItems.map((item) => ({
67
+ item_id: item.sku,
68
+ item_name: item.title,
69
+ item_category: item.categoryId,
70
+ price: item.price,
71
+ quantity: item.quantity
72
+ })),
73
+ })
74
+ sendFBEvent('Purchase', {
75
+ content_ids: cmmc.cartItems.map((item) => item.sku),
76
+ contents: cmmc.cartItems.map(item => ({
77
+ id: item.sku,
78
+ quantity: item.quantity
79
+ })),
80
+ num_items: cmmc.cartItems.length,
81
+ value: cmmc.cartTotal,
82
+ currency: 'USD',
83
+ })
84
+ } else {
85
+ setTransactionStatus('error')
86
+ }
87
+ })()
88
+ }
89
+
90
+ const createVerificationDetails = () => {
91
+ const {name, email} = contactForm.getValues()
92
+ return {
93
+ amount: cmmc.cartTotal.toFixed(2),
94
+ billingContact: {
95
+ givenName: name,
96
+ email,
97
+ },
98
+ currencyCode: 'USD',
99
+ intent: 'CHARGE',
100
+ }
101
+ }
102
+
103
+ const createPaymentRequest= () => ({
104
+ countryCode: "US",
105
+ currencyCode: "USD",
106
+ lineItems: cmmc.cartItems.map(item => ({
107
+ amount: item.price.toFixed(2),
108
+ label: item.title,
109
+ id: item.sku,
110
+ })),
111
+ requestBillingContact: false,
112
+ requestShippingContact: false,
113
+ total: {
114
+ amount: cmmc.cartTotal.toFixed(2),
115
+ label: "Total",
116
+ },
117
+ })
118
+
119
+ return (
120
+ <PaymentForm
121
+ /**
122
+ * Identifies the calling form with a verified application ID generated from
123
+ * the Square Application Dashboard.
124
+ */
125
+ applicationId={process.env.NEXT_PUBLIC_SQUARE_APPLICATION_ID}
126
+ /**
127
+ * Invoked when payment form receives the result of a tokenize generation
128
+ * request. The result will be a valid credit card or wallet token, or an error.
129
+ */
130
+ cardTokenizeResponseReceived={cardTokenizeResponseReceived}
131
+ /**
132
+ * This function enable the Strong Customer Authentication (SCA) flow
133
+ *
134
+ * We strongly recommend use this function to verify the buyer and reduce
135
+ * the chance of fraudulent transactions.
136
+ */
137
+ createVerificationDetails={createVerificationDetails}
138
+ /**
139
+ * This function is required for digital wallets (Apple Pay, Google Pay)
140
+ */
141
+ createPaymentRequest={createPaymentRequest}
142
+ /**
143
+ * Identifies the location of the merchant that is taking the payment.
144
+ * Obtained from the Square Application Dashboard - Locations tab.
145
+ */
146
+ locationId={process.env.NEXT_PUBLIC_SQUARE_LOCATION_ID}
147
+ >
148
+ <ApplyTypography className='flex flex-col mt-6 gap-1'>
149
+ {transactionStatus === 'paid' ? (
150
+ <h6 className='mx-auto font-nav'>Processing your payment...</h6>
151
+ ) : transactionStatus === 'confirmed' ? (
152
+ <div className='flex flex-col gap-4'>
153
+ <h5 className='mx-auto font-nav'>Payment confirmed!</h5>
154
+ <p className='mx-auto'>Thank you for your purchase.</p>
155
+ <Button onClick={onDone}>Continue</Button>
156
+ </div>
157
+ ) : (
158
+ <>
159
+ <GooglePay/>
160
+ <ApplePay/>
161
+
162
+ <div className='flex gap-2 whitespace-nowrap items-center my-0.5 sm:my-1 text-xs text-muted'>
163
+ <hr className='grow border'/><div className='shrink-0 mx-1'>or</div><hr className='grow border'/>
164
+ </div>
165
+
166
+ <Accordion type="single" collapsible className={''}>
167
+ <AccordionItem value="cart" className='w-full border-b-0 data-[state=open]:border data-[state=open]:px-3 rounded '>
168
+ <AccordionTrigger className={cn(
169
+ buttonVariants({variant: 'outline', size: 'lg'}),
170
+ '!no-underline group flex justify-between ',
171
+ 'bg-transparent hover:bg-transparent border-muted-2 hover:border-muted-2',
172
+ 'data-[state=open]:border-none data-[state=open]:py-0 px-4 data-[state=open]:px-1'
173
+ )}>
174
+ <div className='font-sans text-base mr-2 text-muted'>CC</div>
175
+ <PaymentMethods />
176
+ <div>
177
+ <ChevronRight className="h-5 w-5 -mr-2 text-muted shrink-0 transition-transform duration-200 group-data-[state=open]:rotate-90 hidden group-data-[state=open]:block" />
178
+ </div>
179
+ </AccordionTrigger>
180
+ <AccordionContent className='data-[state=open]:mb-4 data-[state=open]:mt-1'>
181
+ <ContactInfo form={contactForm}/>
182
+ {/* Imitates hanzo/ui Button and Input styles, I was unable to render the
183
+ hanzo/ui button outright and keeping the submit form functionality*/}
184
+ <CreditCard
185
+ style={{
186
+ '.input-container': {
187
+ borderColor: '#404040',
188
+ borderRadius: '6px',
189
+ },
190
+ '.input-container.is-focus': {
191
+ borderColor: '#ffffff',
192
+ },
193
+ '.input-container.is-error': {
194
+ borderColor: '#ff1600',
195
+ },
196
+ '.message-text': {
197
+ color: '#999999',
198
+ },
199
+ '.message-icon': {
200
+ color: '#999999',
201
+ },
202
+ '.message-text.is-error': {
203
+ color: '#ff1600',
204
+ },
205
+ '.message-icon.is-error': {
206
+ color: '#ff1600',
207
+ },
208
+ input: {
209
+ backgroundColor: '#1f1f1f',
210
+ color: '#FFFFFF',
211
+ fontSize: '15px',
212
+ fontFamily: 'helvetica neue, sans-serif',
213
+ },
214
+ 'input::placeholder': {
215
+ color: '#999999',
216
+ },
217
+ 'input.is-error': {
218
+ color: '#ff1600',
219
+ },
220
+ }}
221
+ render={(Button: any) => (
222
+ <Button className={cn(
223
+ 'items-center justify-center font-medium transition-colors focus-visible:outline-none focus-visible:ring-2',
224
+ 'focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background',
225
+ '!bg-primary !text-primary-fg hover:!bg-primary-hover font-nav whitespace-nowrap not-typography h-10 py-2 px-4',
226
+ '!text-sm rounded-md lg:min-w-[220px] sm:min-w-[220px] flex'
227
+ )}>
228
+ Pay
229
+ </Button>
230
+ )}
231
+ />
232
+ {transactionStatus === 'error' && (
233
+ <p className='mx-auto text-destructive'>There was an error processing your payment.</p>
234
+ )}
235
+ </AccordionContent>
236
+ </AccordionItem>
237
+ </Accordion>
238
+
239
+ </>
240
+ )}
241
+ </ApplyTypography>
242
+ </PaymentForm>
243
+ )
244
+ }
245
+
246
+ export default PayWithCard
@@ -20,12 +20,12 @@ import {
20
20
 
21
21
  import { useAuth } from '@hanzo/auth/service'
22
22
 
23
- import Eth from '../icons/eth'
24
- import { useCommerce } from '../../../service/context'
25
- import type { TransactionStatus } from '../../../types'
23
+ import Eth from '../../icons/eth'
24
+ import { useCommerce } from '../../../../service/context'
25
+ import type { TransactionStatus } from '../../../../types'
26
26
  import ContactInfo from './contact-info'
27
27
  import type { UseFormReturn } from 'react-hook-form'
28
- import { sendFBEvent, sendGAEvent } from '../../../util/analytics'
28
+ import { sendFBEvent, sendGAEvent } from '../../../../util/analytics'
29
29
 
30
30
  declare global {
31
31
  interface Window{
@@ -34,7 +34,7 @@ declare global {
34
34
  }
35
35
 
36
36
  const PayWithCrypto: React.FC<{
37
- setStep: (currentStep: number) => void
37
+ onDone: () => void
38
38
  transactionStatus: TransactionStatus
39
39
  setTransactionStatus: (status: TransactionStatus) => void
40
40
  storePaymentInfo: (paymentInfo: any) => Promise<void>
@@ -46,7 +46,7 @@ const PayWithCrypto: React.FC<{
46
46
  email: string
47
47
  }>
48
48
  }> = observer(({
49
- setStep,
49
+ onDone,
50
50
  transactionStatus,
51
51
  setTransactionStatus,
52
52
  storePaymentInfo,
@@ -182,7 +182,7 @@ const PayWithCrypto: React.FC<{
182
182
  await storePaymentInfo({
183
183
  paymentMethod: 'crypto'
184
184
  })
185
- setStep(2)
185
+ onDone()
186
186
  }
187
187
 
188
188
  return (
@@ -21,10 +21,12 @@ import {
21
21
  SelectValue
22
22
  } from '@hanzo/ui/primitives'
23
23
 
24
- import { useCommerce } from '../..'
24
+ import { useCommerce } from '../../..'
25
25
 
26
- import { countries } from './countries'
27
- import { sendGAEvent } from '../../util/analytics'
26
+ import countries from '../../../util/countries'
27
+ import { sendGAEvent } from '../../../util/analytics'
28
+
29
+ import type { StepComponentProps } from './types'
28
30
 
29
31
  const shippingFormSchema = z.object({
30
32
  addressLine1: z.string().min(2, 'Address must be at least 2 characters.'),
@@ -35,12 +37,9 @@ const shippingFormSchema = z.object({
35
37
  country: z.string().min(2, 'Country is invalid.'),
36
38
  })
37
39
 
38
- const ShippingInfo: React.FC<{
39
- orderId?: string,
40
- setStep: (currentStep: number) => void
41
- }> = ({
40
+ const ShippingInfo: React.FC<StepComponentProps> = ({
42
41
  orderId,
43
- setStep
42
+ onDone
44
43
  }) => {
45
44
  const cmmc = useCommerce()
46
45
 
@@ -72,7 +71,7 @@ const ShippingInfo: React.FC<{
72
71
  value: cmmc.cartTotal,
73
72
  currency: 'USD',
74
73
  })
75
- setStep(3)
74
+ onDone()
76
75
  }
77
76
 
78
77
  return (
@@ -1,8 +1,11 @@
1
1
  import React from 'react'
2
2
  import Link from 'next/link'
3
+
3
4
  import { ApplyTypography } from '@hanzo/ui/primitives'
4
5
 
5
- const ThankYou: React.FC = () => (
6
+ import type { StepComponentProps } from './types'
7
+
8
+ const ThankYou: React.FC<StepComponentProps> = ({}) => (
6
9
  <ApplyTypography className='flex flex-col gap-4 text-center mt-10'>
7
10
  <h3>Thank you for your order!</h3>
8
11
  <h6>Once your payment has been confirmed we will send additional information to your email.</h6>
@@ -0,0 +1,14 @@
1
+ import type { ComponentType } from 'react'
2
+
3
+ export interface StepComponentProps {
4
+ onDone: () => void
5
+ orderId: string | undefined
6
+ setOrderId: (orderId: string | undefined) => void
7
+ }
8
+
9
+ export interface CheckoutStep {
10
+ name: string
11
+ label?: string
12
+ Comp: ComponentType<StepComponentProps>
13
+ }
14
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzo/commerce",
3
- "version": "4.7.0",
3
+ "version": "4.8.0",
4
4
  "description": "Library with shopping cart components.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/",
@@ -39,8 +39,8 @@
39
39
  "square": "^35.0.0"
40
40
  },
41
41
  "peerDependencies": {
42
- "@hanzo/auth": "^2.3.1",
43
- "@hanzo/ui": "^3.0.9",
42
+ "@hanzo/auth": "^2.3.2",
43
+ "@hanzo/ui": "^3.0.10",
44
44
  "@hookform/resolvers": "^3.3.4",
45
45
  "firebase": "^10.8.0",
46
46
  "lucide-react": "^0.307.0",
@@ -1,5 +1,5 @@
1
1
  //https://stefangabos.github.io/world_countries/
2
- export const countries = [
2
+ export default [
3
3
  {"id":4,"alpha2":"af","alpha3":"afg","name":"Afghanistan"},
4
4
  {"id":8,"alpha2":"al","alpha3":"alb","name":"Albania"},
5
5
  {"id":12,"alpha2":"dz","alpha3":"dza","name":"Algeria"},
@@ -1,222 +0,0 @@
1
- 'use client'
2
- import React from 'react'
3
-
4
- import type { UseFormReturn } from 'react-hook-form'
5
- // @ts-ignore
6
- import { ApplePay, GooglePay, CreditCard, PaymentForm } from 'react-square-web-payments-sdk'
7
-
8
- import { ApplyTypography, Button } from '@hanzo/ui/primitives'
9
- import { cn } from '@hanzo/ui/util'
10
-
11
- import { processSquareCardPayment } from '../../../util'
12
- import { useCommerce } from '../../../service/context'
13
- import type { TransactionStatus } from '../../../types'
14
-
15
- import PaymentMethods from './payment-methods'
16
- import ContactInfo from './contact-info'
17
- import { sendFBEvent, sendGAEvent } from '../../../util/analytics'
18
-
19
- const PayWithCard: React.FC<{
20
- setStep: (currentStep: number) => void
21
- transactionStatus: TransactionStatus
22
- setTransactionStatus: (status: TransactionStatus) => void
23
- storePaymentInfo: (paymentInfo: any) => Promise<void>
24
- contactForm: UseFormReturn<{
25
- name: string
26
- email: string
27
- }, any, {
28
- name: string
29
- email: string
30
- }>
31
- }> = ({
32
- setStep,
33
- transactionStatus,
34
- setTransactionStatus,
35
- storePaymentInfo,
36
- contactForm,
37
- }) => {
38
- const cmmc = useCommerce()
39
-
40
- const cardTokenizeResponseReceived = async (
41
- token: any,
42
- verifiedBuyer: any
43
- ) => {
44
- contactForm.handleSubmit(async () => {
45
- setTransactionStatus('paid')
46
- const res = await processSquareCardPayment(token.token, cmmc.cartTotal, verifiedBuyer.token)
47
- if (res) {
48
- console.log(token)
49
- await storePaymentInfo({paymentMethod: token.details.method ?? null, processed: res})
50
- setTransactionStatus('confirmed')
51
- sendGAEvent('purchase', {
52
- transaction_id: res.payment?.id,
53
- value: res.payment?.amountMoney?.amount,
54
- currency: res.payment?.amountMoney?.currency,
55
- items: cmmc.cartItems.map((item) => ({
56
- item_id: item.sku,
57
- item_name: item.title,
58
- item_category: item.categoryId,
59
- price: item.price,
60
- quantity: item.quantity
61
- })),
62
- })
63
- sendFBEvent('Purchase', {
64
- content_ids: cmmc.cartItems.map((item) => item.sku),
65
- contents: cmmc.cartItems.map(item => ({
66
- id: item.sku,
67
- quantity: item.quantity
68
- })),
69
- num_items: cmmc.cartItems.length,
70
- value: cmmc.cartTotal,
71
- currency: 'USD',
72
- })
73
- } else {
74
- setTransactionStatus('error')
75
- }
76
- })()
77
- }
78
-
79
- const createVerificationDetails = () => {
80
- const {name, email} = contactForm.getValues()
81
- return {
82
- amount: cmmc.cartTotal.toFixed(2),
83
- billingContact: {
84
- givenName: name,
85
- email,
86
- },
87
- currencyCode: 'USD',
88
- intent: 'CHARGE',
89
- }
90
- }
91
-
92
- const createPaymentRequest= () => ({
93
- countryCode: "US",
94
- currencyCode: "USD",
95
- lineItems: cmmc.cartItems.map(item => ({
96
- amount: item.price.toFixed(2),
97
- label: item.title,
98
- id: item.sku,
99
- })),
100
- requestBillingContact: false,
101
- requestShippingContact: false,
102
- total: {
103
- amount: cmmc.cartTotal.toFixed(2),
104
- label: "Total",
105
- },
106
- })
107
-
108
- return (
109
- <PaymentForm
110
- /**
111
- * Identifies the calling form with a verified application ID generated from
112
- * the Square Application Dashboard.
113
- */
114
- applicationId={process.env.NEXT_PUBLIC_SQUARE_APPLICATION_ID}
115
- /**
116
- * Invoked when payment form receives the result of a tokenize generation
117
- * request. The result will be a valid credit card or wallet token, or an error.
118
- */
119
- cardTokenizeResponseReceived={cardTokenizeResponseReceived}
120
- /**
121
- * This function enable the Strong Customer Authentication (SCA) flow
122
- *
123
- * We strongly recommend use this function to verify the buyer and reduce
124
- * the chance of fraudulent transactions.
125
- */
126
- createVerificationDetails={createVerificationDetails}
127
- /**
128
- * This function is required for digital wallets (Apple Pay, Google Pay)
129
- */
130
- createPaymentRequest={createPaymentRequest}
131
- /**
132
- * Identifies the location of the merchant that is taking the payment.
133
- * Obtained from the Square Application Dashboard - Locations tab.
134
- */
135
- locationId={process.env.NEXT_PUBLIC_SQUARE_LOCATION_ID}
136
- >
137
- <ApplyTypography className='flex flex-col mt-6'>
138
- {transactionStatus === 'paid' ? (
139
- <h6 className='mx-auto font-nav'>Processing your payment...</h6>
140
- ) : transactionStatus === 'confirmed' ? (
141
- <div className='flex flex-col gap-4'>
142
- <h5 className='mx-auto font-nav'>Payment confirmed!</h5>
143
- <p className='mx-auto'>Thank you for your purchase.</p>
144
- <Button onClick={() => setStep(2)}>Continue</Button>
145
- </div>
146
- ) : (
147
- <>
148
- <GooglePay/>
149
- <ApplePay/>
150
-
151
- <div className='flex gap-2 whitespace-nowrap items-center my-1 sm:my-2 text-xs text-foreground/60'>
152
- <hr className='bg-foreground/60 w-full border'/> or pay with card <hr className='bg-foreground/60 w-full border'/>
153
- </div>
154
-
155
- <ContactInfo form={contactForm}/>
156
-
157
- {/* Imitates hanzo/ui Button and Input styles, I was unable to render the
158
- hanzo/ui button outright and keeping the submit form functionality*/}
159
- <CreditCard
160
- style={{
161
- '.input-container': {
162
- borderColor: '#404040',
163
- borderRadius: '6px',
164
- },
165
- '.input-container.is-focus': {
166
- borderColor: '#ffffff',
167
- },
168
- '.input-container.is-error': {
169
- borderColor: '#ff1600',
170
- },
171
- '.message-text': {
172
- color: '#999999',
173
- },
174
- '.message-icon': {
175
- color: '#999999',
176
- },
177
- '.message-text.is-error': {
178
- color: '#ff1600',
179
- },
180
- '.message-icon.is-error': {
181
- color: '#ff1600',
182
- },
183
- input: {
184
- backgroundColor: '#1f1f1f',
185
- color: '#FFFFFF',
186
- fontSize: '15px',
187
- fontFamily: 'helvetica neue, sans-serif',
188
- },
189
- 'input::placeholder': {
190
- color: '#999999',
191
- },
192
- 'input.is-error': {
193
- color: '#ff1600',
194
- },
195
- }}
196
- render={(Button: any) => (<>
197
- <PaymentMethods/>
198
- <Button className={cn(
199
- 'items-center justify-center font-medium transition-colors focus-visible:outline-none focus-visible:ring-2',
200
- 'focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background',
201
- '!bg-primary !text-primary-fg hover:!bg-primary-hover font-nav whitespace-nowrap not-typography h-10 py-2 px-4',
202
- '!text-sm rounded-md lg:min-w-[220px] sm:min-w-[220px] flex'
203
- )}
204
- >
205
- Pay
206
- </Button>
207
- </>)}
208
- >
209
-
210
- </CreditCard>
211
-
212
- {transactionStatus === 'error' && (
213
- <p className='mx-auto text-destructive'>There was an error processing your payment.</p>
214
- )}
215
- </>
216
- )}
217
- </ApplyTypography>
218
- </PaymentForm>
219
- )
220
- }
221
-
222
- export default PayWithCard
@@ -1,30 +0,0 @@
1
- import React from 'react'
2
-
3
- import { Separator } from '@hanzo/ui/primitives'
4
- import { cn } from '@hanzo/ui/util'
5
-
6
- import type { CheckoutSteps } from './step'
7
-
8
- const StepIndicator: React.FC<{
9
- steps: CheckoutSteps
10
- currentStep: number
11
- className?: string
12
- }> = ({
13
- steps,
14
- currentStep,
15
- className=''
16
- }) => (
17
- <div className={className}>
18
- {Object.keys(steps).map((key, index) => (<>
19
- {index !== 0 && (<Separator className='w-[4rem] sm:w-[6rem]'/>)}
20
- <div className={cn(
21
- 'w-6 h-6 rounded-full border border-foreground flex flex-col justify-center items-center',
22
- currentStep === parseInt(key) ? 'bg-foreground text-muted-4' : ''
23
- )}>
24
- <div className='relative text-foreground top-4 h-0 whitespace-nowrap'>{steps[parseInt(key)].label}</div>
25
- </div>
26
- </>))}
27
- </div>
28
- )
29
-
30
- export default StepIndicator
@@ -1,11 +0,0 @@
1
- interface CheckoutStep {
2
- label: string
3
- element: JSX.Element
4
- }
5
-
6
- type CheckoutSteps = Record<number, CheckoutStep>
7
-
8
- export {
9
- type CheckoutStep,
10
- type CheckoutSteps
11
- }