@hanzo/commerce 2.0.0 → 3.0.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.
- package/components/add-to-cart-widget.tsx +3 -3
- package/components/buy-item/buy-item-button.tsx +28 -0
- package/components/buy-item/buy-item-card.tsx +82 -0
- package/components/buy-item/buy-item-popup.tsx +38 -0
- package/components/{select-category-and-item-widget.tsx → buy-item/select-category-and-item-widget.tsx} +4 -4
- package/components/buy-item/select-category-item-card.tsx +111 -0
- package/components/{cart-line-item.tsx → cart-panel/cart-line-item.tsx} +4 -3
- package/components/{cart.tsx → cart-panel/index.tsx} +24 -17
- package/components/category-item-ios-wheel-selector.tsx +60 -0
- package/components/category-item-radio-selector.tsx +55 -0
- package/components/{checkout → checkout-panel}/confirm-order.tsx +3 -2
- package/components/{checkout → checkout-panel}/index.tsx +26 -69
- package/components/checkout-panel/payment/contact-info.tsx +59 -0
- package/components/checkout-panel/payment/index.tsx +118 -0
- package/components/checkout-panel/payment/pay-with-bank-transfer.tsx +106 -0
- package/components/checkout-panel/payment/pay-with-card.tsx +198 -0
- package/components/{checkout → checkout-panel/payment}/pay-with-crypto.tsx +52 -30
- package/components/checkout-panel/payment/payment-methods/amex.tsx +32 -0
- package/components/checkout-panel/payment/payment-methods/diners-club.tsx +13 -0
- package/components/checkout-panel/payment/payment-methods/discover.tsx +25 -0
- package/components/checkout-panel/payment/payment-methods/index.tsx +24 -0
- package/components/checkout-panel/payment/payment-methods/jcb.tsx +26 -0
- package/components/checkout-panel/payment/payment-methods/mastercard.tsx +27 -0
- package/components/checkout-panel/payment/payment-methods/visa.tsx +25 -0
- package/components/{checkout → checkout-panel}/shipping-info.tsx +4 -10
- package/components/{facet-toggles-widget → facet-values-widget}/facet-image.tsx +7 -3
- package/components/{facet-toggles-widget → facet-values-widget}/index.tsx +7 -5
- package/components/index.ts +11 -9
- package/components/{select-item-in-category-view.tsx → select-category-item-panel.tsx} +72 -76
- package/index.ts +2 -2
- package/package.json +11 -4
- package/service/context.tsx +4 -4
- package/service/impls/standalone/index.ts +4 -4
- package/service/impls/standalone/orders/index.ts +42 -20
- package/service/impls/standalone/standalone-service.ts +128 -44
- package/types/category.ts +3 -2
- package/types/checkout.ts +6 -0
- package/types/commerce-service.ts +20 -7
- package/types/facet.ts +1 -3
- package/types/index.ts +4 -4
- package/types/item-selector.ts +14 -0
- package/util/index.ts +31 -1
- package/util/square-payment.ts +43 -0
- package/util/use-sync-sku-param-w-current-item.ts +4 -1
- package/blocks/components/commerce-cat-and-item-block.tsx +0 -13
- package/blocks/def/commerce-cat-and-item-block.ts +0 -9
- package/components/checkout/contact-info.tsx +0 -83
- package/components/checkout/pay-by-bank-transfer.tsx +0 -76
- package/components/facets-widget.tsx +0 -55
- package/components/product-selection-mobile-picker.tsx +0 -78
- package/components/product-selection-radio-group.tsx +0 -38
- /package/components/{checkout → checkout-panel}/countries.ts +0 -0
- /package/components/{checkout → checkout-panel}/icons/btc.tsx +0 -0
- /package/components/{checkout → checkout-panel}/icons/eth.tsx +0 -0
- /package/components/{checkout → checkout-panel}/icons/usdt.tsx +0 -0
- /package/components/{checkout → checkout-panel}/thank-you.tsx +0 -0
|
@@ -6,35 +6,36 @@ import { observer } from 'mobx-react-lite'
|
|
|
6
6
|
import { cn } from '@hanzo/ui/util'
|
|
7
7
|
import { Skeleton } from '@hanzo/ui/primitives'
|
|
8
8
|
|
|
9
|
-
import type {
|
|
9
|
+
import type { ItemSelector } from '../types'
|
|
10
10
|
import { formatPrice } from '../util'
|
|
11
11
|
import { Icons } from './Icons'
|
|
12
12
|
|
|
13
13
|
import AddToCartWidget from './add-to-cart-widget'
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
import CategoryItemRadioSelector from './category-item-radio-selector'
|
|
15
|
+
import CategoryItemIOSWheelSelector from './category-item-ios-wheel-selector'
|
|
16
|
+
|
|
17
|
+
const SelectCategoryItemPanel: React.FC<
|
|
18
|
+
React.HTMLAttributes<HTMLDivElement> & ItemSelector &
|
|
19
|
+
{
|
|
20
|
+
isLoading?: boolean
|
|
21
|
+
mobile?: boolean
|
|
22
|
+
}
|
|
23
|
+
> = /* NOT observer */ ({
|
|
24
24
|
category,
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
selectedItemRef,
|
|
26
|
+
selectSku,
|
|
27
27
|
className,
|
|
28
|
+
showQuantity=true,
|
|
28
29
|
isLoading = false,
|
|
29
30
|
mobile = false,
|
|
30
31
|
...props
|
|
31
32
|
}) => {
|
|
32
33
|
|
|
33
|
-
const
|
|
34
|
+
const soleOption = category.products.length === 1
|
|
34
35
|
|
|
35
36
|
const CategoryImage: React.FC<{ className?: string }> = ({ className = '' }) => {
|
|
36
37
|
|
|
37
|
-
if (
|
|
38
|
+
if (isLoading) {
|
|
38
39
|
// deliberately not Skeleton to have a better overall pulse effect.
|
|
39
40
|
return <div className={cn(
|
|
40
41
|
'bg-level-1 rounded-xl aspect-square w-full min-h-1 ', // +
|
|
@@ -42,25 +43,13 @@ const SelectItemInCategoryView: React.FC<React.HTMLAttributes<HTMLDivElement> &
|
|
|
42
43
|
className)} />
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
<div
|
|
48
|
-
aria-label='Placeholder'
|
|
49
|
-
role='img'
|
|
50
|
-
aria-roledescription='placeholder'
|
|
51
|
-
className={cn('w-full flex items-center justify-center aspect-square' , className)}
|
|
52
|
-
>
|
|
53
|
-
<Icons.barcode className='h-9 w-9 text-muted' aria-hidden='true' />
|
|
54
|
-
</div>
|
|
55
|
-
)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return (
|
|
46
|
+
return category.img ? (
|
|
47
|
+
// TODO: Why so many div's?
|
|
59
48
|
<div className={cn('flex flex-col justify-start', className)}>
|
|
60
49
|
<div className={cn('w-full border rounded-xl p-6 ')}>
|
|
61
50
|
<div className={cn('w-full aspect-square relative')}>
|
|
62
51
|
<Image
|
|
63
|
-
src={category.img
|
|
52
|
+
src={category.img}
|
|
64
53
|
fill
|
|
65
54
|
sizes="(max-width: 480px) 100vw, (max-width: 768px) 50vw, (max-width: 1200px) 50vw, 20vw"
|
|
66
55
|
alt={category.title}
|
|
@@ -70,81 +59,88 @@ const SelectItemInCategoryView: React.FC<React.HTMLAttributes<HTMLDivElement> &
|
|
|
70
59
|
</div>
|
|
71
60
|
</div>
|
|
72
61
|
</div>
|
|
62
|
+
) : (
|
|
63
|
+
<div
|
|
64
|
+
aria-label='Placeholder'
|
|
65
|
+
role='img'
|
|
66
|
+
aria-roledescription='placeholder'
|
|
67
|
+
className={cn('w-full flex items-center justify-center aspect-square' , className)}
|
|
68
|
+
>
|
|
69
|
+
<Icons.barcode className='h-9 w-9 text-muted' aria-hidden='true' />
|
|
70
|
+
</div>
|
|
73
71
|
)
|
|
74
72
|
}
|
|
75
73
|
|
|
76
74
|
const AvailableAmounts: React.FC<{ className?: string }> = observer(({ className = '' }) => {
|
|
77
75
|
|
|
78
|
-
|
|
79
|
-
const mobilePicker =
|
|
76
|
+
if (soleOption) return null
|
|
77
|
+
const mobilePicker = (mobile && category.products.length > 8)
|
|
80
78
|
|
|
81
|
-
return
|
|
79
|
+
return isLoading ? (
|
|
82
80
|
<Skeleton className={'min-h-[120px] w-pr-60 mx-auto ' + className} />
|
|
83
81
|
) : (
|
|
84
82
|
<div /* id='CV_AVAIL_AMOUNTS' */ className={cn(
|
|
85
83
|
'sm:w-pr-80 sm:mx-auto md:w-full flex flex-col justify-start items-center',
|
|
86
|
-
(
|
|
84
|
+
(mobilePicker ? 'gap-4' : 'gap-8'),
|
|
87
85
|
className
|
|
88
86
|
)}>
|
|
89
87
|
<div className='w-full flex flex-col justify-start items-center'>
|
|
90
|
-
<h6 className='text-center font-semibold'>
|
|
91
|
-
<div className={'h-[1px] bg-muted-3 ' + (mobilePicker ? 'w-pr-55' : 'w-pr-
|
|
88
|
+
<h6 className='text-center font-semibold'>Available options</h6>
|
|
89
|
+
<div className={'h-[1px] bg-muted-3 ' + (mobilePicker ? 'w-pr-55' : 'w-pr-60') } />
|
|
92
90
|
</div>
|
|
93
|
-
{
|
|
94
|
-
<
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
)
|
|
91
|
+
{mobilePicker ? (
|
|
92
|
+
<CategoryItemIOSWheelSelector
|
|
93
|
+
category={category}
|
|
94
|
+
selectedItemRef={selectedItemRef}
|
|
95
|
+
selectSku={selectSku}
|
|
96
|
+
showQuantity={showQuantity}
|
|
97
|
+
height={180}
|
|
98
|
+
itemHeight={30}
|
|
99
|
+
outerClx='mb-4'
|
|
100
|
+
/>
|
|
101
|
+
) : (
|
|
102
|
+
<CategoryItemRadioSelector
|
|
103
|
+
category={category}
|
|
104
|
+
selectedItemRef={selectedItemRef}
|
|
105
|
+
selectSku={selectSku}
|
|
106
|
+
showQuantity={showQuantity}
|
|
107
|
+
groupClx='block columns-2 gap-4'
|
|
108
|
+
itemClx='flex flex-row gap-2 items-center mb-2.5'
|
|
109
|
+
/>
|
|
113
110
|
)}
|
|
114
111
|
</div>
|
|
115
112
|
)
|
|
116
113
|
})
|
|
117
114
|
|
|
118
115
|
const AddToCartArea: React.FC<{ className?: string }> = observer(({ className = '' }) => (
|
|
119
|
-
(
|
|
120
|
-
<AddToCartWidget size='default' item={
|
|
116
|
+
(selectedItemRef.item && !isLoading) ? (
|
|
117
|
+
<AddToCartWidget size='default' item={selectedItemRef.item} className={className}/>
|
|
121
118
|
) : (
|
|
122
119
|
<div className={cn('h-6 w-12 invisible', className)} />
|
|
123
120
|
)
|
|
124
121
|
))
|
|
125
122
|
|
|
126
123
|
const TitleArea: React.FC<{ className?: string }> = observer(({ className = '' }) => (
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
</span>
|
|
124
|
+
|
|
125
|
+
isLoading ? (<Skeleton className={'h-12 w-pr-80 mx-auto ' + className} />) : (
|
|
126
|
+
|
|
127
|
+
<div className={cn('flex flex-col justify-start items-center', className)}>
|
|
128
|
+
<h3 className='text-base md:text-lg lg:text-2xl font-nav text-center'>
|
|
129
|
+
{category.parentTitle && (
|
|
130
|
+
<span>{category.parentTitle}<br className='md:hidden' /><span className='xs:hidden md:inline '>, </span></span>
|
|
131
|
+
)}
|
|
132
|
+
<span>{category.title}</span>
|
|
137
133
|
</h3>
|
|
138
|
-
{
|
|
134
|
+
{selectedItemRef.item?.sku ? (
|
|
139
135
|
<h6 className='text-center font-semibold'>
|
|
140
|
-
{
|
|
136
|
+
{(soleOption ? '' : (selectedItemRef.item.titleAsOption + ': ')) + formatPrice(selectedItemRef.item.price)}
|
|
141
137
|
</h6>
|
|
142
138
|
) : ''}
|
|
143
139
|
</div>
|
|
144
140
|
)))
|
|
145
141
|
|
|
146
142
|
const Desc: React.FC<{ className?: string }> = ({ className = '' }) => (
|
|
147
|
-
|
|
143
|
+
isLoading ? (
|
|
148
144
|
<Skeleton className={'min-h-20 w-full grow mx-auto ' + className} />
|
|
149
145
|
) : (
|
|
150
146
|
<p className={cn('text-base lg:text-lg mb-6 xs:mb-0', className)}>{category.desc}</p>
|
|
@@ -161,7 +157,7 @@ const SelectItemInCategoryView: React.FC<React.HTMLAttributes<HTMLDivElement> &
|
|
|
161
157
|
{...props}
|
|
162
158
|
>
|
|
163
159
|
<div /* id='CV_TITLE_AND_IMAGE_ROW' */ className='flex flex-row justify-between items-start w-full'>
|
|
164
|
-
{
|
|
160
|
+
{isLoading ? ( <Skeleton className={'min-h-30 w-full '} /> ) : (<>
|
|
165
161
|
<CategoryImage className='w-pr-33' />
|
|
166
162
|
<TitleArea className='grow pt-3 mb-0' />
|
|
167
163
|
</>)}
|
|
@@ -176,17 +172,17 @@ const SelectItemInCategoryView: React.FC<React.HTMLAttributes<HTMLDivElement> &
|
|
|
176
172
|
<div /* id='CV_IMAGE_COL_SEP' */ className={'relative ' + (!isLoading ? 'md:hidden sm:min-w-[185px] xl:flex xl:w-pr-40' : '')}>
|
|
177
173
|
<CategoryImage className='w-full' />
|
|
178
174
|
</div>
|
|
179
|
-
<div /* id='CV_CONTENT_COL */ className='flex flex-col
|
|
175
|
+
<div /* id='CV_CONTENT_COL */ className={'flex flex-col xl:w-pr-60 justify-center ' + (soleOption ? '' : 'gap-6') }>
|
|
180
176
|
<div /* id='CV_MD_IMAGE_AND_TITLE */ className='hidden md:flex xl:hidden flex-row gap-x-3'>
|
|
181
177
|
<CategoryImage className='min-w-pr-30' />
|
|
182
178
|
<TitleArea className='grow' />
|
|
183
179
|
</div>
|
|
184
|
-
|
|
180
|
+
|
|
185
181
|
<div /* id='CV_CONTENT' */ className={'flex flex-col gap-2.5 ' + (isLoading ? 'justify-between h-full' : '')}>
|
|
186
182
|
<TitleArea className='md:hidden xl:flex' />
|
|
187
183
|
<Desc className='' />
|
|
188
184
|
</div>
|
|
189
|
-
<div /* id='CV_CTA_AREA_BIG' */ className='hidden lg:flex
|
|
185
|
+
<div /* id='CV_CTA_AREA_BIG' */ className='hidden lg:flex flex-col justify-start items-center gap-6'>
|
|
190
186
|
<AvailableAmounts />
|
|
191
187
|
<AddToCartArea className='' />
|
|
192
188
|
</div>
|
|
@@ -201,4 +197,4 @@ const SelectItemInCategoryView: React.FC<React.HTMLAttributes<HTMLDivElement> &
|
|
|
201
197
|
}
|
|
202
198
|
|
|
203
199
|
|
|
204
|
-
export default
|
|
200
|
+
export default SelectCategoryItemPanel
|
package/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from './types'
|
|
2
1
|
export * from './service/context'
|
|
2
|
+
export * from './components'
|
|
3
3
|
export type { StandaloneServiceOptions as ServiceOptions } from './service/impls/standalone/standalone-service'
|
|
4
|
-
export { useSyncSkuParamWithCurrentItem } from './util'
|
|
4
|
+
export { useSyncSkuParamWithCurrentItem, getFacetValuesMutator, formatPrice } from './util'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/commerce",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Library with shopping cart components.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/",
|
|
@@ -26,19 +26,26 @@
|
|
|
26
26
|
"tc": "tsc",
|
|
27
27
|
"clean": "rm -rf dist && rm -rf node_modules"
|
|
28
28
|
},
|
|
29
|
+
"exports": {
|
|
30
|
+
".": "./index.ts",
|
|
31
|
+
"./types": "./types/index.ts"
|
|
32
|
+
},
|
|
29
33
|
"dependencies": {
|
|
30
34
|
"ethers": "^6.11.1",
|
|
31
35
|
"next-usequerystate": "^1.17.0",
|
|
32
|
-
"react-mobile-picker": "^1.0.0"
|
|
36
|
+
"react-mobile-picker": "^1.0.0",
|
|
37
|
+
"react-square-web-payments-sdk": "^3.2.1",
|
|
38
|
+
"square": "^35.0.0"
|
|
33
39
|
},
|
|
34
40
|
"peerDependencies": {
|
|
35
|
-
"@hanzo/auth": "^2.0.
|
|
36
|
-
"@hanzo/ui": "^3.0.
|
|
41
|
+
"@hanzo/auth": "^2.0.2",
|
|
42
|
+
"@hanzo/ui": "^3.0.2",
|
|
37
43
|
"@hookform/resolvers": "^3.3.4",
|
|
38
44
|
"firebase": "^10.8.0",
|
|
39
45
|
"lucide-react": "^0.307.0",
|
|
40
46
|
"mobx": "^6.12.0",
|
|
41
47
|
"mobx-react-lite": "^4.0.5",
|
|
48
|
+
"mobx-utils": "^6.0.8",
|
|
42
49
|
"next": "^14.1.0",
|
|
43
50
|
"react": "^18.2.0",
|
|
44
51
|
"react-dom": "^18.2.0",
|
package/service/context.tsx
CHANGED
|
@@ -9,7 +9,7 @@ enableStaticRendering(typeof window === "undefined")
|
|
|
9
9
|
import type CommerceService from '../types/commerce-service'
|
|
10
10
|
import type { ServiceOptions } from '..'
|
|
11
11
|
import getServiceSingleton from './impls'
|
|
12
|
-
import type { Category,
|
|
12
|
+
import type { Category, FacetValueDesc } from '../types'
|
|
13
13
|
|
|
14
14
|
const CommerceServiceContext = createContext<CommerceService | undefined>(undefined)
|
|
15
15
|
|
|
@@ -20,16 +20,16 @@ const useCommerce = (): CommerceService => {
|
|
|
20
20
|
|
|
21
21
|
const CommerceServiceProvider: React.FC<PropsWithChildren & {
|
|
22
22
|
productsByCategory: Category[]
|
|
23
|
-
|
|
23
|
+
rootFacet: FacetValueDesc
|
|
24
24
|
options?: ServiceOptions
|
|
25
25
|
}> = ({
|
|
26
26
|
children,
|
|
27
27
|
productsByCategory,
|
|
28
|
-
|
|
28
|
+
rootFacet,
|
|
29
29
|
options
|
|
30
30
|
}) => {
|
|
31
31
|
|
|
32
|
-
const serviceRef = useRef<CommerceService>(getServiceSingleton(productsByCategory,
|
|
32
|
+
const serviceRef = useRef<CommerceService>(getServiceSingleton(productsByCategory, rootFacet, options))
|
|
33
33
|
return (
|
|
34
34
|
<CommerceServiceContext.Provider value={serviceRef.current}>
|
|
35
35
|
{children}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { enableStaticRendering } from 'mobx-react-lite'
|
|
2
2
|
|
|
3
|
-
import type { CommerceService, Category,
|
|
3
|
+
import type { CommerceService, Category, FacetValueDesc } from '../../../types'
|
|
4
4
|
import StandaloneService, {type StandaloneServiceOptions} from './standalone-service'
|
|
5
5
|
|
|
6
6
|
import { readSnapshot, listenAndWriteSnapshots } from './localStorage'
|
|
@@ -19,7 +19,7 @@ let instance: StandaloneService | undefined = undefined
|
|
|
19
19
|
|
|
20
20
|
export const getInstance = (
|
|
21
21
|
categories: Category[],
|
|
22
|
-
|
|
22
|
+
rootFacet: FacetValueDesc,
|
|
23
23
|
options?: StandaloneServiceOptions
|
|
24
24
|
): CommerceService => {
|
|
25
25
|
|
|
@@ -31,7 +31,7 @@ export const getInstance = (
|
|
|
31
31
|
//_log("NEW INSTANCE FOR SERVER")
|
|
32
32
|
return new StandaloneService(
|
|
33
33
|
categories,
|
|
34
|
-
|
|
34
|
+
rootFacet,
|
|
35
35
|
options
|
|
36
36
|
)
|
|
37
37
|
}
|
|
@@ -42,7 +42,7 @@ export const getInstance = (
|
|
|
42
42
|
const snapShot = readSnapshot()
|
|
43
43
|
instance = new StandaloneService(
|
|
44
44
|
categories,
|
|
45
|
-
|
|
45
|
+
rootFacet,
|
|
46
46
|
options,
|
|
47
47
|
snapShot
|
|
48
48
|
)
|
|
@@ -23,9 +23,10 @@ const getDBInstance = (name: string): Firestore => {
|
|
|
23
23
|
|
|
24
24
|
interface SavedOrder {
|
|
25
25
|
email: string
|
|
26
|
-
|
|
26
|
+
name: string
|
|
27
27
|
// TODO: add shippingInfo type
|
|
28
28
|
shippingInfo?: any
|
|
29
|
+
paymentInfo?: any
|
|
29
30
|
status: string
|
|
30
31
|
timestamp: FieldValue
|
|
31
32
|
items: ActualLineItemSnapshot[]
|
|
@@ -33,16 +34,16 @@ interface SavedOrder {
|
|
|
33
34
|
|
|
34
35
|
const createOrder = async (
|
|
35
36
|
email: string,
|
|
36
|
-
paymentMethod: string,
|
|
37
37
|
items: ActualLineItemSnapshot[],
|
|
38
38
|
options: {
|
|
39
39
|
dbName: string
|
|
40
40
|
ordersTable: string
|
|
41
|
-
}
|
|
41
|
+
},
|
|
42
|
+
name?: string
|
|
42
43
|
): Promise<{
|
|
43
44
|
success: boolean,
|
|
44
45
|
error: any,
|
|
45
|
-
id?: string
|
|
46
|
+
id?: string,
|
|
46
47
|
}> => {
|
|
47
48
|
|
|
48
49
|
let error: any | null = null
|
|
@@ -52,7 +53,7 @@ const createOrder = async (
|
|
|
52
53
|
try {
|
|
53
54
|
await setDoc(doc(ordersRef, orderId), {
|
|
54
55
|
email,
|
|
55
|
-
|
|
56
|
+
name: name ?? '',
|
|
56
57
|
status: 'open',
|
|
57
58
|
timestamp: serverTimestamp(),
|
|
58
59
|
items,
|
|
@@ -67,17 +68,13 @@ const createOrder = async (
|
|
|
67
68
|
return { success: !error, error }
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
const
|
|
71
|
+
const updateOrderShippingInfo = async (
|
|
71
72
|
orderId: string,
|
|
72
|
-
|
|
73
|
-
paymentMethod: string,
|
|
74
|
-
// TODO: add shippingInfo type
|
|
75
|
-
items: ActualLineItemSnapshot[],
|
|
73
|
+
shippingInfo: any,
|
|
76
74
|
options: {
|
|
77
75
|
dbName: string
|
|
78
76
|
ordersTable: string
|
|
79
|
-
}
|
|
80
|
-
shippingInfo?: any
|
|
77
|
+
}
|
|
81
78
|
): Promise<{
|
|
82
79
|
success: boolean,
|
|
83
80
|
error: any
|
|
@@ -88,20 +85,45 @@ const updateOrder = async (
|
|
|
88
85
|
|
|
89
86
|
try {
|
|
90
87
|
await setDoc(doc(ordersRef, orderId), {
|
|
91
|
-
email,
|
|
92
|
-
paymentMethod,
|
|
93
88
|
shippingInfo,
|
|
94
|
-
status: 'open',
|
|
95
89
|
timestamp: serverTimestamp(),
|
|
96
|
-
|
|
97
|
-
} satisfies SavedOrder)
|
|
90
|
+
}, { merge: true })
|
|
98
91
|
}
|
|
99
92
|
catch (e) {
|
|
100
|
-
|
|
101
|
-
|
|
93
|
+
console.error('Error writing item document: ', e)
|
|
94
|
+
error = e
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return { success: !error, error }
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const updateOrderPaymentInfo = async (
|
|
101
|
+
orderId: string,
|
|
102
|
+
paymentInfo: any,
|
|
103
|
+
options: {
|
|
104
|
+
dbName: string
|
|
105
|
+
ordersTable: string
|
|
106
|
+
}
|
|
107
|
+
): Promise<{
|
|
108
|
+
success: boolean,
|
|
109
|
+
error: any
|
|
110
|
+
}> => {
|
|
111
|
+
|
|
112
|
+
let error: any | null = null
|
|
113
|
+
const ordersRef = collection(getDBInstance(options.dbName), options.ordersTable)
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
await setDoc(doc(ordersRef, orderId), {
|
|
117
|
+
paymentInfo,
|
|
118
|
+
timestamp: serverTimestamp(),
|
|
119
|
+
}, { merge: true })
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
console.error('Error writing item document: ', e)
|
|
123
|
+
error = e
|
|
102
124
|
}
|
|
103
125
|
|
|
104
126
|
return { success: !error, error }
|
|
105
127
|
}
|
|
106
128
|
|
|
107
|
-
export { createOrder,
|
|
129
|
+
export { createOrder, updateOrderShippingInfo, updateOrderPaymentInfo }
|