@hanzo/commerce 7.3.1 → 7.3.2
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.
- package/components/Icons.tsx +34 -34
- package/components/add-to-cart-widget.tsx +183 -183
- package/components/buy/buy-card.tsx +259 -259
- package/components/buy/carousel-buy-card.tsx +242 -242
- package/components/buy/multi-family/all-variants-carousel.tsx +261 -261
- package/components/buy/multi-family/family-carousel/index.tsx +77 -77
- package/components/buy/multi-family/family-carousel/slide.tsx +83 -83
- package/components/buy/multi-family/family-carousel/state.ts +87 -87
- package/components/buy/multi-family/index.ts +2 -2
- package/components/buy/single-family-selector.tsx +90 -90
- package/components/buy/title-and-byline.tsx +25 -25
- package/components/cart/cart-panel/cart-line-item.tsx +76 -76
- package/components/cart/cart-panel/index.tsx +154 -154
- package/components/cart/cart-panel/promo-code.tsx +106 -106
- package/components/cart/cart-panel/total-area.tsx +60 -60
- package/components/checkout/payment-step-form/card-icon-row.tsx +26 -26
- package/components/checkout/payment-step-form/card-icons/amex.tsx +32 -32
- package/components/checkout/payment-step-form/card-icons/diners-club.tsx +13 -13
- package/components/checkout/payment-step-form/card-icons/discover.tsx +25 -25
- package/components/checkout/payment-step-form/card-icons/jcb.tsx +26 -26
- package/components/checkout/payment-step-form/card-icons/mastercard.tsx +27 -27
- package/components/checkout/payment-step-form/card-icons/visa.tsx +25 -25
- package/components/checkout/payment-step-form/cc-button.tsx +17 -17
- package/components/checkout/payment-step-form/contact-form.tsx +49 -49
- package/components/checkout/payment-step-form/crypto-icons/btc.tsx +11 -11
- package/components/checkout/payment-step-form/crypto-icons/eth.tsx +20 -20
- package/components/checkout/payment-step-form/crypto-icons/usdt.tsx +13 -13
- package/components/checkout/payment-step-form/index.tsx +122 -122
- package/components/checkout/payment-step-form/methods/bank-transfer.tsx +79 -79
- package/components/checkout/payment-step-form/methods/card.tsx +232 -232
- package/components/checkout/payment-step-form/methods/crypto.tsx +227 -227
- package/components/checkout/payment-step-form/methods/index.ts +22 -22
- package/components/checkout/shipping-step-form.tsx +172 -172
- package/components/index.ts +11 -11
- package/components/item/product-card.tsx +48 -48
- package/components/item-selector/button.tsx +188 -188
- package/components/item-selector/carousel/index.tsx +197 -197
- package/components/item-selector/carousel/slider.tsx +40 -40
- package/components/item-selector/index.ts +5 -5
- package/components/item-selector/quantity-indicator.tsx +48 -48
- package/components/node-tabs/index.tsx +91 -91
- package/components/node-tabs/node-image.tsx +31 -31
- package/index.ts +12 -12
- package/package.json +60 -60
- package/service/context.tsx +45 -45
- package/service/debug.ts +41 -41
- package/service/impls/standalone/actual-line-item.ts +135 -135
- package/service/impls/standalone/get-instance.ts +64 -64
- package/service/impls/standalone/index.ts +579 -579
- package/service/impls/standalone/order/firebase.ts +14 -14
- package/service/impls/standalone/order/index.ts +128 -128
- package/service/impls/standalone/persistence.ts +33 -33
- package/service/path-utils.ts +25 -25
- package/service/sep.ts +6 -6
- package/tsconfig.json +10 -10
- package/types/README.md +1 -1
- package/types/category-node.ts +49 -49
- package/types/checkout.ts +46 -46
- package/types/commerce-config.ts +13 -13
- package/types/commerce-service.ts +127 -127
- package/types/family.ts +25 -25
- package/types/index.ts +15 -15
- package/types/item-selector.ts +96 -96
- package/types/line-item.ts +29 -29
- package/types/multi-family-selector-props.ts +19 -19
- package/types/product.ts +20 -20
- package/types/promo.ts +9 -9
- package/types/selection-ui-specifier.ts +51 -51
- package/types/string-mutator.ts +13 -13
- package/types/token-separators.ts +7 -7
- package/util/analytics.ts +20 -20
- package/util/countries.ts +195 -195
- package/util/error.ts +34 -34
- package/util/index.ts +70 -70
- package/util/item-selector-options-accessor.ts +34 -34
- package/util/line-item-ref.ts +23 -23
- package/util/multi-family-selector-options-accessor.ts +14 -14
- package/util/obs-string-mutator.ts +22 -22
- package/util/product-media-accessor.ts +58 -58
- package/util/promo-codes.ts +108 -108
- package/util/selection-ui-specifiers.ts +29 -29
- package/util/square-payment.ts +42 -42
- package/util/use-sync-sku-param-w-current-item.ts +88 -88
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { type LucideProps } from 'lucide-react'
|
|
3
|
-
|
|
4
|
-
const Btc: React.FC<LucideProps> = (props: LucideProps) => (
|
|
5
|
-
<svg viewBox="0.004 0 64 64" {...props}>
|
|
6
|
-
<path d="M63.04 39.741c-4.274 17.143-21.638 27.575-38.783 23.301C7.12 58.768-3.313 41.404.962 24.262 5.234 7.117 22.597-3.317 39.737.957c17.144 4.274 27.576 21.64 23.302 38.784z" fill="#f7931a"/>
|
|
7
|
-
<path d="M46.11 27.441c.636-4.258-2.606-6.547-7.039-8.074l1.438-5.768-3.512-.875-1.4 5.616c-.922-.23-1.87-.447-2.812-.662l1.41-5.653-3.509-.875-1.439 5.766c-.764-.174-1.514-.346-2.242-.527l.004-.018-4.842-1.209-.934 3.75s2.605.597 2.55.634c1.422.355 1.68 1.296 1.636 2.042l-1.638 6.571c.098.025.225.061.365.117l-.37-.092-2.297 9.205c-.174.432-.615 1.08-1.609.834.035.051-2.552-.637-2.552-.637l-1.743 4.02 4.57 1.139c.85.213 1.683.436 2.502.646l-1.453 5.835 3.507.875 1.44-5.772c.957.26 1.887.5 2.797.726L27.504 50.8l3.511.875 1.453-5.823c5.987 1.133 10.49.676 12.383-4.738 1.527-4.36-.075-6.875-3.225-8.516 2.294-.531 4.022-2.04 4.483-5.157zM38.087 38.69c-1.086 4.36-8.426 2.004-10.807 1.412l1.928-7.729c2.38.594 10.011 1.77 8.88 6.317zm1.085-11.312c-.99 3.966-7.1 1.951-9.083 1.457l1.748-7.01c1.983.494 8.367 1.416 7.335 5.553z" fill="#ffffff"/>
|
|
8
|
-
</svg>
|
|
9
|
-
)
|
|
10
|
-
|
|
11
|
-
export default Btc
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { type LucideProps } from 'lucide-react'
|
|
3
|
+
|
|
4
|
+
const Btc: React.FC<LucideProps> = (props: LucideProps) => (
|
|
5
|
+
<svg viewBox="0.004 0 64 64" {...props}>
|
|
6
|
+
<path d="M63.04 39.741c-4.274 17.143-21.638 27.575-38.783 23.301C7.12 58.768-3.313 41.404.962 24.262 5.234 7.117 22.597-3.317 39.737.957c17.144 4.274 27.576 21.64 23.302 38.784z" fill="#f7931a"/>
|
|
7
|
+
<path d="M46.11 27.441c.636-4.258-2.606-6.547-7.039-8.074l1.438-5.768-3.512-.875-1.4 5.616c-.922-.23-1.87-.447-2.812-.662l1.41-5.653-3.509-.875-1.439 5.766c-.764-.174-1.514-.346-2.242-.527l.004-.018-4.842-1.209-.934 3.75s2.605.597 2.55.634c1.422.355 1.68 1.296 1.636 2.042l-1.638 6.571c.098.025.225.061.365.117l-.37-.092-2.297 9.205c-.174.432-.615 1.08-1.609.834.035.051-2.552-.637-2.552-.637l-1.743 4.02 4.57 1.139c.85.213 1.683.436 2.502.646l-1.453 5.835 3.507.875 1.44-5.772c.957.26 1.887.5 2.797.726L27.504 50.8l3.511.875 1.453-5.823c5.987 1.133 10.49.676 12.383-4.738 1.527-4.36-.075-6.875-3.225-8.516 2.294-.531 4.022-2.04 4.483-5.157zM38.087 38.69c-1.086 4.36-8.426 2.004-10.807 1.412l1.928-7.729c2.38.594 10.011 1.77 8.88 6.317zm1.085-11.312c-.99 3.966-7.1 1.951-9.083 1.457l1.748-7.01c1.983.494 8.367 1.416 7.335 5.553z" fill="#ffffff"/>
|
|
8
|
+
</svg>
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
export default Btc
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { type LucideProps } from 'lucide-react'
|
|
3
|
-
|
|
4
|
-
const Eth: React.FC<LucideProps> = (props: LucideProps) => (
|
|
5
|
-
<svg viewBox="0 0 32 32" {...props}>
|
|
6
|
-
<g fill="none" fillRule="evenodd">
|
|
7
|
-
<circle cx="16" cy="16" r="16" fill="#627EEA"/>
|
|
8
|
-
<g fill="#FFF" fillRule="nonzero">
|
|
9
|
-
<path fillOpacity=".602" d="M16.498 4v8.87l7.497 3.35z"/>
|
|
10
|
-
<path d="M16.498 4L9 16.22l7.498-3.35z"/>
|
|
11
|
-
<path fillOpacity=".602" d="M16.498 21.968v6.027L24 17.616z"/>
|
|
12
|
-
<path d="M16.498 27.995v-6.028L9 17.616z"/>
|
|
13
|
-
<path fillOpacity=".2" d="M16.498 20.573l7.497-4.353-7.497-3.348z"/>
|
|
14
|
-
<path fillOpacity=".602" d="M9 16.22l7.498 4.353v-7.701z"/>
|
|
15
|
-
</g>
|
|
16
|
-
</g>
|
|
17
|
-
</svg>
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
export default Eth
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { type LucideProps } from 'lucide-react'
|
|
3
|
+
|
|
4
|
+
const Eth: React.FC<LucideProps> = (props: LucideProps) => (
|
|
5
|
+
<svg viewBox="0 0 32 32" {...props}>
|
|
6
|
+
<g fill="none" fillRule="evenodd">
|
|
7
|
+
<circle cx="16" cy="16" r="16" fill="#627EEA"/>
|
|
8
|
+
<g fill="#FFF" fillRule="nonzero">
|
|
9
|
+
<path fillOpacity=".602" d="M16.498 4v8.87l7.497 3.35z"/>
|
|
10
|
+
<path d="M16.498 4L9 16.22l7.498-3.35z"/>
|
|
11
|
+
<path fillOpacity=".602" d="M16.498 21.968v6.027L24 17.616z"/>
|
|
12
|
+
<path d="M16.498 27.995v-6.028L9 17.616z"/>
|
|
13
|
+
<path fillOpacity=".2" d="M16.498 20.573l7.497-4.353-7.497-3.348z"/>
|
|
14
|
+
<path fillOpacity=".602" d="M9 16.22l7.498 4.353v-7.701z"/>
|
|
15
|
+
</g>
|
|
16
|
+
</g>
|
|
17
|
+
</svg>
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
export default Eth
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { type LucideProps } from 'lucide-react'
|
|
3
|
-
|
|
4
|
-
const Usdt: React.FC<LucideProps> = (props: LucideProps) => (
|
|
5
|
-
<svg viewBox="0 0 32 32" {...props}>
|
|
6
|
-
<g fill="none" fill-rule="evenodd">
|
|
7
|
-
<circle cx="16" cy="16" r="16" fill="#26A17B"/>
|
|
8
|
-
<path fill="#FFF" d="M17.922 17.383v-.002c-.11.008-.677.042-1.942.042-1.01 0-1.721-.03-1.971-.042v.003c-3.888-.171-6.79-.848-6.79-1.658 0-.809 2.902-1.486 6.79-1.66v2.644c.254.018.982.061 1.988.061 1.207 0 1.812-.05 1.925-.06v-2.643c3.88.173 6.775.85 6.775 1.658 0 .81-2.895 1.485-6.775 1.657m0-3.59v-2.366h5.414V7.819H8.595v3.608h5.414v2.365c-4.4.202-7.709 1.074-7.709 2.118 0 1.044 3.309 1.915 7.709 2.118v7.582h3.913v-7.584c4.393-.202 7.694-1.073 7.694-2.116 0-1.043-3.301-1.914-7.694-2.117"/>
|
|
9
|
-
</g>
|
|
10
|
-
</svg>
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
export default Usdt
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { type LucideProps } from 'lucide-react'
|
|
3
|
+
|
|
4
|
+
const Usdt: React.FC<LucideProps> = (props: LucideProps) => (
|
|
5
|
+
<svg viewBox="0 0 32 32" {...props}>
|
|
6
|
+
<g fill="none" fill-rule="evenodd">
|
|
7
|
+
<circle cx="16" cy="16" r="16" fill="#26A17B"/>
|
|
8
|
+
<path fill="#FFF" d="M17.922 17.383v-.002c-.11.008-.677.042-1.942.042-1.01 0-1.721-.03-1.971-.042v.003c-3.888-.171-6.79-.848-6.79-1.658 0-.809 2.902-1.486 6.79-1.66v2.644c.254.018.982.061 1.988.061 1.207 0 1.812-.05 1.925-.06v-2.643c3.88.173 6.775.85 6.775 1.658 0 .81-2.895 1.485-6.775 1.657m0-3.59v-2.366h5.414V7.819H8.595v3.608h5.414v2.365c-4.4.202-7.709 1.074-7.709 2.118 0 1.044 3.309 1.915 7.709 2.118v7.582h3.913v-7.584c4.393-.202 7.694-1.073 7.694-2.116 0-1.043-3.301-1.914-7.694-2.117"/>
|
|
9
|
+
</g>
|
|
10
|
+
</svg>
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
export default Usdt
|
|
@@ -1,122 +1,122 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
import React, { useEffect, useState } from 'react'
|
|
3
|
-
import { observer } from 'mobx-react-lite'
|
|
4
|
-
|
|
5
|
-
import { zodResolver } from '@hookform/resolvers/zod'
|
|
6
|
-
import * as z from 'zod'
|
|
7
|
-
import { useForm } from 'react-hook-form'
|
|
8
|
-
|
|
9
|
-
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@hanzo/ui/primitives'
|
|
10
|
-
import { useAuth } from '@hanzo/auth/service'
|
|
11
|
-
|
|
12
|
-
import { useCommerce } from '../../../service/context'
|
|
13
|
-
import { sendFBEvent, sendGAEvent } from '../../../util/analytics'
|
|
14
|
-
import type { CheckoutStepComponentProps, TransactionStatus } from '../../../types'
|
|
15
|
-
|
|
16
|
-
import METHODS from './methods'
|
|
17
|
-
|
|
18
|
-
const contactFormSchema = z.object({
|
|
19
|
-
name: z.string().min(1, 'Enter your full name.'),
|
|
20
|
-
email: z.string().email(),
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
const PaymentStepForm: React.FC<CheckoutStepComponentProps> = observer(({
|
|
24
|
-
onDone,
|
|
25
|
-
orderId,
|
|
26
|
-
setOrderId
|
|
27
|
-
}) => {
|
|
28
|
-
const cmmc = useCommerce()
|
|
29
|
-
const auth = useAuth() // may be null in some cases
|
|
30
|
-
|
|
31
|
-
const [transactionStatus, setTransactionStatus] = useState<TransactionStatus>('unpaid')
|
|
32
|
-
|
|
33
|
-
if (!auth) {
|
|
34
|
-
console.log("PAYMENT STEP FORM: auth service is null! ")
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const contactForm = useForm<z.infer<typeof contactFormSchema>>({
|
|
38
|
-
resolver: zodResolver(contactFormSchema),
|
|
39
|
-
defaultValues: {
|
|
40
|
-
name: auth?.user?.displayName ?? '',
|
|
41
|
-
email: auth?.user?.email ?? '',
|
|
42
|
-
},
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
if (auth?.loggedIn) {
|
|
47
|
-
contactForm.setValue('name', auth!.user?.displayName ?? '')
|
|
48
|
-
contactForm.setValue('email', auth!.user?.email ?? '')
|
|
49
|
-
}
|
|
50
|
-
}, [auth?.loggedIn])
|
|
51
|
-
|
|
52
|
-
const storePaymentInfo = async (paymentInfo: any) => {
|
|
53
|
-
const {name, email} = contactForm.getValues()
|
|
54
|
-
let id: string | undefined = undefined
|
|
55
|
-
if (!orderId) {
|
|
56
|
-
id = await cmmc.createOrder(email, name)
|
|
57
|
-
setOrderId(id)
|
|
58
|
-
}
|
|
59
|
-
if (id) {
|
|
60
|
-
sendGAEvent('add_payment_info', {
|
|
61
|
-
items: cmmc.cartItems.map((item) => ({
|
|
62
|
-
item_id: item.sku,
|
|
63
|
-
item_name: item.title,
|
|
64
|
-
item_category: item.familyId,
|
|
65
|
-
price: item.price,
|
|
66
|
-
quantity: item.quantity
|
|
67
|
-
})),
|
|
68
|
-
value: cmmc.promoAppliedCartTotal,
|
|
69
|
-
currency: 'USD',
|
|
70
|
-
payment_type: paymentInfo.paymentMethod ?? ''
|
|
71
|
-
})
|
|
72
|
-
sendFBEvent('AddPaymentInfo', {
|
|
73
|
-
contents: cmmc.cartItems.map(item => ({
|
|
74
|
-
id: item.sku,
|
|
75
|
-
quantity: item.quantity
|
|
76
|
-
})),
|
|
77
|
-
value: cmmc.promoAppliedCartTotal,
|
|
78
|
-
currency: 'USD'
|
|
79
|
-
})
|
|
80
|
-
await cmmc.updateOrderPaymentInfo(id, paymentInfo)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const groupClx = 'grid w-full grid-cols-3 mx-auto ' +
|
|
85
|
-
'p-0 h-auto overflow-hidden ' +
|
|
86
|
-
'border-2 bg-background border-level-2 md:bg-level-1 md:border-level-3 '
|
|
87
|
-
|
|
88
|
-
const tabClx = 'whitespace-normal h-full text-xs sm:text-base px-1 text-muted ' +
|
|
89
|
-
'data-[state=active]:text-accent data-[state=active]:bg-level-2 md:data-[state=active]:bg-level-3'
|
|
90
|
-
|
|
91
|
-
const disabled = transactionStatus === 'paid' || transactionStatus === 'confirmed'
|
|
92
|
-
|
|
93
|
-
return (
|
|
94
|
-
<Tabs defaultValue='card' className='w-full'>
|
|
95
|
-
<TabsList className={groupClx}>
|
|
96
|
-
{METHODS.map(({ label, value }) => (
|
|
97
|
-
<TabsTrigger
|
|
98
|
-
value={value}
|
|
99
|
-
className={tabClx}
|
|
100
|
-
disabled={disabled}
|
|
101
|
-
key={`tabs-${value}`}
|
|
102
|
-
>
|
|
103
|
-
{label}
|
|
104
|
-
</TabsTrigger>
|
|
105
|
-
))}
|
|
106
|
-
</TabsList>
|
|
107
|
-
{METHODS.map(({Comp: PaymentMethodComp, value}) => (
|
|
108
|
-
<TabsContent value={value} key={`content-${value}`}>
|
|
109
|
-
<PaymentMethodComp
|
|
110
|
-
onDone={onDone}
|
|
111
|
-
transactionStatus={transactionStatus}
|
|
112
|
-
setTransactionStatus={setTransactionStatus}
|
|
113
|
-
storePaymentInfo={storePaymentInfo}
|
|
114
|
-
contactForm={contactForm}
|
|
115
|
-
/>
|
|
116
|
-
</TabsContent>
|
|
117
|
-
))}
|
|
118
|
-
</Tabs>
|
|
119
|
-
)
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
export default PaymentStepForm
|
|
1
|
+
'use client'
|
|
2
|
+
import React, { useEffect, useState } from 'react'
|
|
3
|
+
import { observer } from 'mobx-react-lite'
|
|
4
|
+
|
|
5
|
+
import { zodResolver } from '@hookform/resolvers/zod'
|
|
6
|
+
import * as z from 'zod'
|
|
7
|
+
import { useForm } from 'react-hook-form'
|
|
8
|
+
|
|
9
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@hanzo/ui/primitives'
|
|
10
|
+
import { useAuth } from '@hanzo/auth/service'
|
|
11
|
+
|
|
12
|
+
import { useCommerce } from '../../../service/context'
|
|
13
|
+
import { sendFBEvent, sendGAEvent } from '../../../util/analytics'
|
|
14
|
+
import type { CheckoutStepComponentProps, TransactionStatus } from '../../../types'
|
|
15
|
+
|
|
16
|
+
import METHODS from './methods'
|
|
17
|
+
|
|
18
|
+
const contactFormSchema = z.object({
|
|
19
|
+
name: z.string().min(1, 'Enter your full name.'),
|
|
20
|
+
email: z.string().email(),
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const PaymentStepForm: React.FC<CheckoutStepComponentProps> = observer(({
|
|
24
|
+
onDone,
|
|
25
|
+
orderId,
|
|
26
|
+
setOrderId
|
|
27
|
+
}) => {
|
|
28
|
+
const cmmc = useCommerce()
|
|
29
|
+
const auth = useAuth() // may be null in some cases
|
|
30
|
+
|
|
31
|
+
const [transactionStatus, setTransactionStatus] = useState<TransactionStatus>('unpaid')
|
|
32
|
+
|
|
33
|
+
if (!auth) {
|
|
34
|
+
console.log("PAYMENT STEP FORM: auth service is null! ")
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const contactForm = useForm<z.infer<typeof contactFormSchema>>({
|
|
38
|
+
resolver: zodResolver(contactFormSchema),
|
|
39
|
+
defaultValues: {
|
|
40
|
+
name: auth?.user?.displayName ?? '',
|
|
41
|
+
email: auth?.user?.email ?? '',
|
|
42
|
+
},
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (auth?.loggedIn) {
|
|
47
|
+
contactForm.setValue('name', auth!.user?.displayName ?? '')
|
|
48
|
+
contactForm.setValue('email', auth!.user?.email ?? '')
|
|
49
|
+
}
|
|
50
|
+
}, [auth?.loggedIn])
|
|
51
|
+
|
|
52
|
+
const storePaymentInfo = async (paymentInfo: any) => {
|
|
53
|
+
const {name, email} = contactForm.getValues()
|
|
54
|
+
let id: string | undefined = undefined
|
|
55
|
+
if (!orderId) {
|
|
56
|
+
id = await cmmc.createOrder(email, name)
|
|
57
|
+
setOrderId(id)
|
|
58
|
+
}
|
|
59
|
+
if (id) {
|
|
60
|
+
sendGAEvent('add_payment_info', {
|
|
61
|
+
items: cmmc.cartItems.map((item) => ({
|
|
62
|
+
item_id: item.sku,
|
|
63
|
+
item_name: item.title,
|
|
64
|
+
item_category: item.familyId,
|
|
65
|
+
price: item.price,
|
|
66
|
+
quantity: item.quantity
|
|
67
|
+
})),
|
|
68
|
+
value: cmmc.promoAppliedCartTotal,
|
|
69
|
+
currency: 'USD',
|
|
70
|
+
payment_type: paymentInfo.paymentMethod ?? ''
|
|
71
|
+
})
|
|
72
|
+
sendFBEvent('AddPaymentInfo', {
|
|
73
|
+
contents: cmmc.cartItems.map(item => ({
|
|
74
|
+
id: item.sku,
|
|
75
|
+
quantity: item.quantity
|
|
76
|
+
})),
|
|
77
|
+
value: cmmc.promoAppliedCartTotal,
|
|
78
|
+
currency: 'USD'
|
|
79
|
+
})
|
|
80
|
+
await cmmc.updateOrderPaymentInfo(id, paymentInfo)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const groupClx = 'grid w-full grid-cols-3 mx-auto ' +
|
|
85
|
+
'p-0 h-auto overflow-hidden ' +
|
|
86
|
+
'border-2 bg-background border-level-2 md:bg-level-1 md:border-level-3 '
|
|
87
|
+
|
|
88
|
+
const tabClx = 'whitespace-normal h-full text-xs sm:text-base px-1 text-muted ' +
|
|
89
|
+
'data-[state=active]:text-accent data-[state=active]:bg-level-2 md:data-[state=active]:bg-level-3'
|
|
90
|
+
|
|
91
|
+
const disabled = transactionStatus === 'paid' || transactionStatus === 'confirmed'
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<Tabs defaultValue='card' className='w-full'>
|
|
95
|
+
<TabsList className={groupClx}>
|
|
96
|
+
{METHODS.map(({ label, value }) => (
|
|
97
|
+
<TabsTrigger
|
|
98
|
+
value={value}
|
|
99
|
+
className={tabClx}
|
|
100
|
+
disabled={disabled}
|
|
101
|
+
key={`tabs-${value}`}
|
|
102
|
+
>
|
|
103
|
+
{label}
|
|
104
|
+
</TabsTrigger>
|
|
105
|
+
))}
|
|
106
|
+
</TabsList>
|
|
107
|
+
{METHODS.map(({Comp: PaymentMethodComp, value}) => (
|
|
108
|
+
<TabsContent value={value} key={`content-${value}`}>
|
|
109
|
+
<PaymentMethodComp
|
|
110
|
+
onDone={onDone}
|
|
111
|
+
transactionStatus={transactionStatus}
|
|
112
|
+
setTransactionStatus={setTransactionStatus}
|
|
113
|
+
storePaymentInfo={storePaymentInfo}
|
|
114
|
+
contactForm={contactForm}
|
|
115
|
+
/>
|
|
116
|
+
</TabsContent>
|
|
117
|
+
))}
|
|
118
|
+
</Tabs>
|
|
119
|
+
)
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
export default PaymentStepForm
|
|
@@ -1,79 +1,79 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import React from 'react'
|
|
4
|
-
import { Copy } from 'lucide-react'
|
|
5
|
-
|
|
6
|
-
import { Button, toast } from '@hanzo/ui/primitives'
|
|
7
|
-
|
|
8
|
-
import type { PaymentMethodComponentProps } from '../../../../types'
|
|
9
|
-
|
|
10
|
-
import ContactForm from '../contact-form'
|
|
11
|
-
|
|
12
|
-
const InfoField: React.FC<{
|
|
13
|
-
label: string,
|
|
14
|
-
value: React.ReactNode,
|
|
15
|
-
copyValue: string
|
|
16
|
-
}> = ({
|
|
17
|
-
label,
|
|
18
|
-
value,
|
|
19
|
-
copyValue
|
|
20
|
-
}) => {
|
|
21
|
-
|
|
22
|
-
const copyToClipboard = (label: string, text: string) => {
|
|
23
|
-
navigator.clipboard.writeText(text)
|
|
24
|
-
toast(`${label} copied to clipboard.`)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<div className='flex flex-col gap-1'>
|
|
29
|
-
<p className='text-xs'>{label}</p>
|
|
30
|
-
<div className='flex items-center justify-between sm:text-lg border rounded-lg py-2 px-4'>
|
|
31
|
-
{value}
|
|
32
|
-
<Button variant='ghost' size='icon' onClick={() => copyToClipboard(label, copyValue)}>
|
|
33
|
-
<Copy className='h-4 w-4'/>
|
|
34
|
-
</Button>
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
37
|
-
)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const PayWithBankTransfer: React.FC<PaymentMethodComponentProps> = ({
|
|
41
|
-
onDone,
|
|
42
|
-
storePaymentInfo,
|
|
43
|
-
contactForm
|
|
44
|
-
}) => {
|
|
45
|
-
|
|
46
|
-
const payByBankTransfer = async () => {
|
|
47
|
-
contactForm.handleSubmit( async () => {
|
|
48
|
-
await storePaymentInfo({paymentMethod: 'bank-transfer'})
|
|
49
|
-
onDone()
|
|
50
|
-
})()
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return (
|
|
54
|
-
<div className='flex flex-col gap-2 mt-6'>
|
|
55
|
-
<ContactForm form={contactForm}/>
|
|
56
|
-
<div className='w-full mx-auto max-w-[50rem]'>
|
|
57
|
-
<div className='flex flex-col gap-4 w-full'>
|
|
58
|
-
<InfoField
|
|
59
|
-
label='Beneficiary Bank'
|
|
60
|
-
value={<div>Bank of America<br/>NA 222 Broadway<br/>New York, New York. 10038</div>}
|
|
61
|
-
copyValue='Bank of America, NA 222 Broadway, New York, New York. 10038'
|
|
62
|
-
/>
|
|
63
|
-
<InfoField
|
|
64
|
-
label='Beneficiary'
|
|
65
|
-
value={<div>Hanzo, Inc<br/>4811 Mastin Street<br/>Merriam, KS 66203</div>}
|
|
66
|
-
copyValue='Hanzo, Inc, 4811 Mastin Street, Merriam, KS 66203'
|
|
67
|
-
/>
|
|
68
|
-
<InfoField label='Routing Number - ACH' value='113000023 / 111000025' copyValue='113000023 / 111000025'/>
|
|
69
|
-
<InfoField label='Routing Number - Wire' value='026009593' copyValue='026009593'/>
|
|
70
|
-
<InfoField label='Routing Number - SWIFT' value='BOFAUS3N' copyValue='BOFAUS3N'/>
|
|
71
|
-
<InfoField label='Reference' value='Lux' copyValue='Lux'/>
|
|
72
|
-
</div>
|
|
73
|
-
</div>
|
|
74
|
-
<Button onClick={payByBankTransfer} className='mx-auto w-full mt-4'>Continue</Button>
|
|
75
|
-
</div>
|
|
76
|
-
)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export default PayWithBankTransfer
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { Copy } from 'lucide-react'
|
|
5
|
+
|
|
6
|
+
import { Button, toast } from '@hanzo/ui/primitives'
|
|
7
|
+
|
|
8
|
+
import type { PaymentMethodComponentProps } from '../../../../types'
|
|
9
|
+
|
|
10
|
+
import ContactForm from '../contact-form'
|
|
11
|
+
|
|
12
|
+
const InfoField: React.FC<{
|
|
13
|
+
label: string,
|
|
14
|
+
value: React.ReactNode,
|
|
15
|
+
copyValue: string
|
|
16
|
+
}> = ({
|
|
17
|
+
label,
|
|
18
|
+
value,
|
|
19
|
+
copyValue
|
|
20
|
+
}) => {
|
|
21
|
+
|
|
22
|
+
const copyToClipboard = (label: string, text: string) => {
|
|
23
|
+
navigator.clipboard.writeText(text)
|
|
24
|
+
toast(`${label} copied to clipboard.`)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<div className='flex flex-col gap-1'>
|
|
29
|
+
<p className='text-xs'>{label}</p>
|
|
30
|
+
<div className='flex items-center justify-between sm:text-lg border rounded-lg py-2 px-4'>
|
|
31
|
+
{value}
|
|
32
|
+
<Button variant='ghost' size='icon' onClick={() => copyToClipboard(label, copyValue)}>
|
|
33
|
+
<Copy className='h-4 w-4'/>
|
|
34
|
+
</Button>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const PayWithBankTransfer: React.FC<PaymentMethodComponentProps> = ({
|
|
41
|
+
onDone,
|
|
42
|
+
storePaymentInfo,
|
|
43
|
+
contactForm
|
|
44
|
+
}) => {
|
|
45
|
+
|
|
46
|
+
const payByBankTransfer = async () => {
|
|
47
|
+
contactForm.handleSubmit( async () => {
|
|
48
|
+
await storePaymentInfo({paymentMethod: 'bank-transfer'})
|
|
49
|
+
onDone()
|
|
50
|
+
})()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<div className='flex flex-col gap-2 mt-6'>
|
|
55
|
+
<ContactForm form={contactForm}/>
|
|
56
|
+
<div className='w-full mx-auto max-w-[50rem]'>
|
|
57
|
+
<div className='flex flex-col gap-4 w-full'>
|
|
58
|
+
<InfoField
|
|
59
|
+
label='Beneficiary Bank'
|
|
60
|
+
value={<div>Bank of America<br/>NA 222 Broadway<br/>New York, New York. 10038</div>}
|
|
61
|
+
copyValue='Bank of America, NA 222 Broadway, New York, New York. 10038'
|
|
62
|
+
/>
|
|
63
|
+
<InfoField
|
|
64
|
+
label='Beneficiary'
|
|
65
|
+
value={<div>Hanzo, Inc<br/>4811 Mastin Street<br/>Merriam, KS 66203</div>}
|
|
66
|
+
copyValue='Hanzo, Inc, 4811 Mastin Street, Merriam, KS 66203'
|
|
67
|
+
/>
|
|
68
|
+
<InfoField label='Routing Number - ACH' value='113000023 / 111000025' copyValue='113000023 / 111000025'/>
|
|
69
|
+
<InfoField label='Routing Number - Wire' value='026009593' copyValue='026009593'/>
|
|
70
|
+
<InfoField label='Routing Number - SWIFT' value='BOFAUS3N' copyValue='BOFAUS3N'/>
|
|
71
|
+
<InfoField label='Reference' value='Lux' copyValue='Lux'/>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
<Button onClick={payByBankTransfer} className='mx-auto w-full mt-4'>Continue</Button>
|
|
75
|
+
</div>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export default PayWithBankTransfer
|