@hanzo/commerce 5.1.2 → 6.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/{buy-item/select-category-item-card.tsx → buy/_to_deprecate_select-category-item-card.tsx} +20 -31
- package/components/{select-category-item-panel.tsx → buy/_to_deprecate_select-category-item-panel.tsx} +12 -20
- package/components/{buy-item/buy-item-popup.tsx → buy/_unused_buy-popup.tsx_} +4 -4
- package/components/{add-to-cart-widget.tsx → buy/add-to-cart-widget.tsx} +5 -3
- package/components/buy/buy-button.tsx +31 -0
- package/components/buy/buy-card.tsx +169 -0
- package/components/buy/buy-drawer.tsx +78 -0
- package/components/buy/buy-trigger-wrapper.tsx +20 -0
- package/components/{cart-accordian.tsx → cart/cart-accordian.tsx} +2 -1
- package/components/{cart-panel → cart/cart-panel}/cart-line-item.tsx +28 -5
- package/components/{cart-panel → cart/cart-panel}/index.tsx +9 -5
- package/components/{cart-panel → cart/cart-panel}/promo-code.tsx +3 -3
- package/components/{payment-step-form → checkout/payment-step-form}/contact-form.tsx +1 -1
- package/components/{payment-step-form → checkout/payment-step-form}/index.tsx +3 -3
- package/components/{payment-step-form → checkout/payment-step-form}/methods/bank-transfer.tsx +1 -1
- package/components/{payment-step-form → checkout/payment-step-form}/methods/card.tsx +4 -4
- package/components/{payment-step-form → checkout/payment-step-form}/methods/crypto.tsx +3 -3
- package/components/{payment-step-form → checkout/payment-step-form}/methods/index.ts +1 -1
- package/components/{shipping-step-form.tsx → checkout/shipping-step-form.tsx} +4 -4
- package/components/facet-values-widget/facet-image.tsx +2 -2
- package/components/facet-values-widget/index.tsx +13 -12
- package/components/index.ts +19 -17
- package/components/item/item-media.tsx +58 -0
- package/components/{product-card.tsx → item/product-card.tsx} +5 -7
- package/components/select/carousel-selector.tsx +64 -0
- package/components/select/image-selector.tsx +125 -0
- package/components/select/radio-selector.tsx +66 -0
- package/package.json +2 -1
- package/service/context.tsx +4 -4
- package/service/impls/standalone/index.ts +4 -4
- package/service/impls/standalone/standalone-service.ts +74 -62
- package/types/commerce-service.ts +20 -16
- package/types/index.ts +2 -2
- package/types/item-selector.ts +12 -5
- package/types/product.ts +1 -0
- package/types/tree-node.ts +24 -0
- package/util/index.ts +9 -9
- package/util/use-sync-sku-param-w-current-item.ts +5 -5
- package/components/buy-item/buy-item-button-wrapper.tsx +0 -27
- package/components/buy-item/buy-item-button.tsx +0 -34
- package/components/buy-item/buy-item-card.tsx +0 -92
- package/components/buy-item/buy-item-mobile-drawer.tsx +0 -54
- package/components/buy-item/select-category-and-item-widget.tsx +0 -83
- package/components/category-item-radio-selector.tsx +0 -55
- package/components/category-item-scroll-selector.tsx +0 -40
- package/components/item-carousel.tsx +0 -80
- package/types/facet.ts +0 -35
- /package/components/{cart-icon.tsx → cart/cart-icon.tsx} +0 -0
- /package/components/{payment-step-form → checkout/payment-step-form}/card-icon-row.tsx +0 -0
- /package/components/{payment-step-form → checkout/payment-step-form}/card-icons/amex.tsx +0 -0
- /package/components/{payment-step-form → checkout/payment-step-form}/card-icons/diners-club.tsx +0 -0
- /package/components/{payment-step-form → checkout/payment-step-form}/card-icons/discover.tsx +0 -0
- /package/components/{payment-step-form → checkout/payment-step-form}/card-icons/jcb.tsx +0 -0
- /package/components/{payment-step-form → checkout/payment-step-form}/card-icons/mastercard.tsx +0 -0
- /package/components/{payment-step-form → checkout/payment-step-form}/card-icons/visa.tsx +0 -0
- /package/components/{payment-step-form → checkout/payment-step-form}/cc-button.tsx +0 -0
- /package/components/{payment-step-form → checkout/payment-step-form}/crypto-icons/btc.tsx +0 -0
- /package/components/{payment-step-form → checkout/payment-step-form}/crypto-icons/eth.tsx +0 -0
- /package/components/{payment-step-form → checkout/payment-step-form}/crypto-icons/usdt.tsx +0 -0
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
import React, { useState, type ReactNode } from 'react'
|
|
3
|
-
|
|
4
|
-
//import { X as LucideX} from 'lucide-react'
|
|
5
|
-
//import { Sheet, SheetContent, SheetTrigger } from '@hanzo/ui/primitives'
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
Drawer,
|
|
9
|
-
DrawerTrigger,
|
|
10
|
-
DrawerContent,
|
|
11
|
-
} from '@hanzo/ui/primitives'
|
|
12
|
-
|
|
13
|
-
import { cn } from '@hanzo/ui/util'
|
|
14
|
-
|
|
15
|
-
import BuyItemCard from './buy-item-card'
|
|
16
|
-
|
|
17
|
-
const BuyItemMobileDrawer: React.FC<{
|
|
18
|
-
skuPath: string
|
|
19
|
-
trigger: ReactNode
|
|
20
|
-
triggerClx?: string
|
|
21
|
-
drawerClx?: string
|
|
22
|
-
cardClx?: string
|
|
23
|
-
}> = ({
|
|
24
|
-
skuPath,
|
|
25
|
-
trigger,
|
|
26
|
-
triggerClx='',
|
|
27
|
-
drawerClx='',
|
|
28
|
-
cardClx=''
|
|
29
|
-
}) => {
|
|
30
|
-
|
|
31
|
-
const [open, setOpen] = useState<boolean>(false)
|
|
32
|
-
|
|
33
|
-
const onQuantityChanged = (sku: string, oldV: number, newV: number) => {
|
|
34
|
-
if (oldV === 0 && newV === 1) {
|
|
35
|
-
setTimeout(() => {setOpen(false)}, 150)
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return (
|
|
40
|
-
<Drawer open={open} onOpenChange={setOpen} >
|
|
41
|
-
<DrawerTrigger asChild className={triggerClx}>
|
|
42
|
-
{trigger}
|
|
43
|
-
</DrawerTrigger>
|
|
44
|
-
<DrawerContent
|
|
45
|
-
className={cn('rounded-tl-xl rounded-tr-xl p-0 overflow-hidden', drawerClx)}
|
|
46
|
-
// side="bottom"
|
|
47
|
-
>
|
|
48
|
-
<BuyItemCard skuPath={skuPath} mobile onQuantityChanged={onQuantityChanged} className={cn("w-full relative ", cardClx)}/>
|
|
49
|
-
</DrawerContent>
|
|
50
|
-
</Drawer>
|
|
51
|
-
)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export default BuyItemMobileDrawer
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
import React, { useEffect } from 'react'
|
|
3
|
-
import { observer } from 'mobx-react-lite'
|
|
4
|
-
|
|
5
|
-
import { ApplyTypography, ListBox } from '@hanzo/ui/primitives'
|
|
6
|
-
import { cn } from '@hanzo/ui/util'
|
|
7
|
-
|
|
8
|
-
import type { FacetValueDesc, FacetsValue, LineItem } from '../../types'
|
|
9
|
-
import { useCommerce } from '../../service/context'
|
|
10
|
-
import { formatCurrencyValue } from '../../util'
|
|
11
|
-
|
|
12
|
-
import FacetTogglesWidget from '../facet-values-widget'
|
|
13
|
-
|
|
14
|
-
const formatItem = (item: LineItem, withQuantity: boolean = false): string => (
|
|
15
|
-
`${item.titleAsOption}, ${formatCurrencyValue(item.price)}${(withQuantity && item.quantity > 0) ? ` (${item.quantity})` : ''}`
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
const SelectCategoryAndItemWidget: React.FC<{
|
|
19
|
-
categoryLevel: number
|
|
20
|
-
parentLevelToken: string
|
|
21
|
-
categoryLevelValues: FacetValueDesc[]
|
|
22
|
-
className?: string
|
|
23
|
-
}> = observer(({
|
|
24
|
-
categoryLevel,
|
|
25
|
-
parentLevelToken,
|
|
26
|
-
categoryLevelValues,
|
|
27
|
-
className=''
|
|
28
|
-
}) => {
|
|
29
|
-
const comm = useCommerce()
|
|
30
|
-
|
|
31
|
-
useEffect(() => {
|
|
32
|
-
const facets: FacetsValue = {}
|
|
33
|
-
facets[categoryLevel - 1] = [parentLevelToken]
|
|
34
|
-
facets[categoryLevel] = [categoryLevelValues[0].value]
|
|
35
|
-
comm.setFacets(facets)
|
|
36
|
-
comm.setCurrentItem(comm.specifiedCategories[0].products[0].sku)
|
|
37
|
-
}, [])
|
|
38
|
-
|
|
39
|
-
const onFacetTokenChanged = (token: string): void => {
|
|
40
|
-
const facets: FacetsValue = {}
|
|
41
|
-
facets[categoryLevel - 1] = [parentLevelToken]
|
|
42
|
-
facets[categoryLevel] = [token]
|
|
43
|
-
comm.setFacets(facets)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const currentFacetToken = (): string | null => {
|
|
47
|
-
if (comm.specifiedCategories.length === 0) return null
|
|
48
|
-
const skuPath = comm.specifiedCategories[0].id
|
|
49
|
-
const skuPathTokens = skuPath.split('-')
|
|
50
|
-
return skuPathTokens.length > 0 ? skuPathTokens[skuPathTokens.length - 1] : null
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return (
|
|
54
|
-
<div className={cn('flex flex-col justify-start gap-4 items-start pt-3', className)}>
|
|
55
|
-
<FacetTogglesWidget
|
|
56
|
-
facetValues={categoryLevelValues}
|
|
57
|
-
mutator={{
|
|
58
|
-
get: currentFacetToken, // computed's are accessed through their get()
|
|
59
|
-
set: onFacetTokenChanged
|
|
60
|
-
}}
|
|
61
|
-
/>
|
|
62
|
-
{comm.specifiedItems.length === 0 ? (
|
|
63
|
-
<ApplyTypography>
|
|
64
|
-
<h3>No Items</h3>
|
|
65
|
-
</ApplyTypography>
|
|
66
|
-
) : comm.specifiedItems.length === 1 ? (
|
|
67
|
-
<ApplyTypography>
|
|
68
|
-
<h4>{formatItem(comm.specifiedItems[0])}</h4>
|
|
69
|
-
</ApplyTypography>
|
|
70
|
-
) : (
|
|
71
|
-
<ListBox<string>
|
|
72
|
-
values={comm.specifiedItems.map((it) => (it.sku))}
|
|
73
|
-
labels={comm.specifiedItems.map((it) => (formatItem(it)))}
|
|
74
|
-
isEqual={(v1: string, v2: string) => (v1 === v2)}
|
|
75
|
-
value={comm.currentItem?.sku}
|
|
76
|
-
onValueChange={comm.setCurrentItem.bind(comm)}
|
|
77
|
-
/>
|
|
78
|
-
)}
|
|
79
|
-
</div>
|
|
80
|
-
)
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
export default SelectCategoryAndItemWidget
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import { observer } from 'mobx-react-lite'
|
|
4
|
-
|
|
5
|
-
import { Label, RadioGroup, RadioGroupItem } from '@hanzo/ui/primitives'
|
|
6
|
-
import type { ItemSelector, LineItem, Product } from '../types'
|
|
7
|
-
import { formatCurrencyValue } from '../util'
|
|
8
|
-
import { cn } from '@hanzo/ui/util'
|
|
9
|
-
|
|
10
|
-
const CategoryItemRadioSelector: React.FC<ItemSelector & {
|
|
11
|
-
groupClx?: string
|
|
12
|
-
itemClx?: string
|
|
13
|
-
}> = observer(({
|
|
14
|
-
category,
|
|
15
|
-
selectedItemRef: itemRef,
|
|
16
|
-
selectSku,
|
|
17
|
-
groupClx='',
|
|
18
|
-
itemClx='',
|
|
19
|
-
showPrice=true,
|
|
20
|
-
showQuantity=true
|
|
21
|
-
}) => {
|
|
22
|
-
|
|
23
|
-
const Choice: React.FC<{
|
|
24
|
-
item: Product
|
|
25
|
-
className?: string
|
|
26
|
-
}> = ({
|
|
27
|
-
item,
|
|
28
|
-
className=''
|
|
29
|
-
}) => (
|
|
30
|
-
<div className={cn(className, itemClx)}>
|
|
31
|
-
<RadioGroupItem value={item.sku} id={item.sku} />
|
|
32
|
-
<Label htmlFor={item.sku}>{item.titleAsOption + (showPrice ? (', ' + formatCurrencyValue(item.price)) : '')}</Label>
|
|
33
|
-
</div>
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
return ( category.products.length > 1 ? (
|
|
37
|
-
<RadioGroup
|
|
38
|
-
className={cn(showQuantity ? 'table' : '', groupClx)}
|
|
39
|
-
onValueChange={selectSku}
|
|
40
|
-
value={itemRef.item ? itemRef.item.sku : ''}
|
|
41
|
-
>
|
|
42
|
-
{(category.products as LineItem[]).map((item) => (showQuantity ? (
|
|
43
|
-
<div className='table-row' key={item.sku}>
|
|
44
|
-
<Choice item={item} className='table-cell pr-2 align-text-top pb-2'/>
|
|
45
|
-
<div className='table-cell font-semibold text-sm leading-none align-text-top pb-2'>{ item.quantity > 0 ? `(${item.quantity})` : ' '}</div>
|
|
46
|
-
</div>
|
|
47
|
-
) : (
|
|
48
|
-
<Choice item={item} className='mb-2' key={item.sku}/>
|
|
49
|
-
)))}
|
|
50
|
-
</RadioGroup>
|
|
51
|
-
) : (<p>TODO</p>)
|
|
52
|
-
)
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
export default CategoryItemRadioSelector
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import { observer } from 'mobx-react-lite'
|
|
4
|
-
|
|
5
|
-
import { cn } from '@hanzo/ui/util'
|
|
6
|
-
import { ScrollArea } from '@hanzo/ui/primitives'
|
|
7
|
-
|
|
8
|
-
import type { ItemSelector } from '../types'
|
|
9
|
-
import { formatCurrencyValue } from '../util'
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const CategoryItemScrollSelector: React.FC<ItemSelector & {
|
|
13
|
-
outerClx?: string
|
|
14
|
-
itemClx?: string
|
|
15
|
-
}> = observer(({
|
|
16
|
-
category,
|
|
17
|
-
selectedItemRef: iRef,
|
|
18
|
-
selectSku,
|
|
19
|
-
outerClx='',
|
|
20
|
-
itemClx=''
|
|
21
|
-
}) => {
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<ScrollArea className={cn('border border-muted-4 rounded-lg', outerClx)}>
|
|
25
|
-
{category.products.map((prod) => (
|
|
26
|
-
<div key={prod.sku} onClick={() => {selectSku(prod.sku)}}>
|
|
27
|
-
<div className={cn(
|
|
28
|
-
'h-10 border-b flex flex-col justify-center px-4',
|
|
29
|
-
(iRef.item?.sku === prod.sku) ? 'font-semibold text-accent' : 'text-muted',
|
|
30
|
-
itemClx
|
|
31
|
-
)}>
|
|
32
|
-
{prod.titleAsOption + ', ' + formatCurrencyValue(prod.price)}
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
35
|
-
))}
|
|
36
|
-
</ScrollArea>
|
|
37
|
-
)
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
export default CategoryItemScrollSelector
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
|
|
3
|
-
import Spline from '@splinetool/react-spline'
|
|
4
|
-
|
|
5
|
-
import { cn } from '@hanzo/ui/util'
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
type CarouselOptionsType,
|
|
9
|
-
Carousel,
|
|
10
|
-
CarouselContent,
|
|
11
|
-
CarouselItem,
|
|
12
|
-
CarouselPrevious,
|
|
13
|
-
CarouselNext
|
|
14
|
-
} from '@hanzo/ui/primitives'
|
|
15
|
-
|
|
16
|
-
import {
|
|
17
|
-
VideoBlockComponent,
|
|
18
|
-
ImageBlockComponent,
|
|
19
|
-
type ImageBlock,
|
|
20
|
-
type Block,
|
|
21
|
-
type VideoBlock
|
|
22
|
-
} from '@hanzo/ui/blocks'
|
|
23
|
-
|
|
24
|
-
import type { LineItem } from '../types'
|
|
25
|
-
import type { Dimensions } from '@hanzo/ui/types'
|
|
26
|
-
|
|
27
|
-
// Order of precedence of visuals: 3D > MP4 > Image
|
|
28
|
-
const ItemCarousel: React.FC<{
|
|
29
|
-
items: LineItem[]
|
|
30
|
-
constrainTo: Dimensions
|
|
31
|
-
options?: CarouselOptionsType
|
|
32
|
-
className?: string
|
|
33
|
-
itemClx?: string
|
|
34
|
-
}> = ({
|
|
35
|
-
items,
|
|
36
|
-
options,
|
|
37
|
-
className='',
|
|
38
|
-
constrainTo,
|
|
39
|
-
itemClx=''
|
|
40
|
-
}) => (
|
|
41
|
-
// className: 'w-full max-w-sm mx-auto
|
|
42
|
-
// itemClx: 'flex aspect-square items-center justify-center '
|
|
43
|
-
<Carousel options={options} className={cn('px-2', className)} >
|
|
44
|
-
<CarouselContent>
|
|
45
|
-
{items.map(({title, img, video, animation}, index) => (
|
|
46
|
-
<CarouselItem key={index} className={cn('p-2 flex flex-row justify-center items-center', itemClx)}>
|
|
47
|
-
{animation ? (
|
|
48
|
-
<Spline
|
|
49
|
-
scene={animation}
|
|
50
|
-
className='pointer-events-none' // !aspect-[12/10]
|
|
51
|
-
style={{
|
|
52
|
-
width: (6/5 * (typeof constrainTo.h === 'number' ? constrainTo.h as number : parseInt(constrainTo.h as string)) ),
|
|
53
|
-
height: constrainTo.h
|
|
54
|
-
}}
|
|
55
|
-
/>
|
|
56
|
-
) : video ? (
|
|
57
|
-
<VideoBlockComponent
|
|
58
|
-
constraint={constrainTo}
|
|
59
|
-
block={{blockType: 'video', ...video} satisfies VideoBlock as Block}
|
|
60
|
-
/>
|
|
61
|
-
) : (
|
|
62
|
-
<ImageBlockComponent
|
|
63
|
-
block={{
|
|
64
|
-
blockType: 'image',
|
|
65
|
-
src: img ?? '',
|
|
66
|
-
alt: title + ' image',
|
|
67
|
-
dim: constrainTo
|
|
68
|
-
} satisfies ImageBlock as Block}
|
|
69
|
-
className='m-auto'
|
|
70
|
-
/>
|
|
71
|
-
)}
|
|
72
|
-
</CarouselItem>
|
|
73
|
-
))}
|
|
74
|
-
</CarouselContent>
|
|
75
|
-
<CarouselPrevious className='left-1'/>
|
|
76
|
-
<CarouselNext className='right-1'/>
|
|
77
|
-
</Carousel>
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
export default ItemCarousel
|
package/types/facet.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from 'react'
|
|
2
|
-
|
|
3
|
-
interface FacetValueDesc {
|
|
4
|
-
value: string // a token in the sku
|
|
5
|
-
label: string
|
|
6
|
-
img? : string | ReactNode // icon is required
|
|
7
|
-
imgAR? : number // helps with svgs
|
|
8
|
-
sub?: FacetValueDesc[]
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/* *** FOR EXAMPLE **
|
|
12
|
-
{
|
|
13
|
-
1: [ {
|
|
14
|
-
token: 'AG',
|
|
15
|
-
label: 'Silver',
|
|
16
|
-
img: '/assets/img/cart/ui/facets/silver-swatch-200x200.png'
|
|
17
|
-
},
|
|
18
|
-
... more FaceValues describing the "type" level (Silver, Gold)
|
|
19
|
-
],
|
|
20
|
-
2 [
|
|
21
|
-
{
|
|
22
|
-
token: 'B'
|
|
23
|
-
label: 'Minted Bar
|
|
24
|
-
},
|
|
25
|
-
... more FaceValues describing the "form" level (Bar, Coin, )
|
|
26
|
-
]
|
|
27
|
-
}
|
|
28
|
-
*/
|
|
29
|
-
// Which facets tokens are on at each level
|
|
30
|
-
type FacetsValue = Record<number, string[]>
|
|
31
|
-
|
|
32
|
-
export type {
|
|
33
|
-
FacetValueDesc,
|
|
34
|
-
FacetsValue
|
|
35
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/components/{payment-step-form → checkout/payment-step-form}/card-icons/diners-club.tsx
RENAMED
|
File without changes
|
/package/components/{payment-step-form → checkout/payment-step-form}/card-icons/discover.tsx
RENAMED
|
File without changes
|
|
File without changes
|
/package/components/{payment-step-form → checkout/payment-step-form}/card-icons/mastercard.tsx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|