@luxfi/core 5.3.1 → 5.3.2
Sign up to get free protection for your applications and to get access to all the features.
- package/commerce/ui/context.tsx +4 -7
- package/commerce/ui/store.ts +39 -54
- package/components/back-button.tsx +8 -1
- package/components/commerce/{checkout-widget/index.tsx → _to_deprecate_checkout-widget/index.tsx_} +0 -4
- package/components/commerce/checkout-panel/cart-accordian.tsx +66 -0
- package/components/commerce/checkout-panel/checkout-panel-props.ts +10 -0
- package/components/commerce/checkout-panel/desktop-cp.tsx +83 -0
- package/components/commerce/checkout-panel/index.tsx +16 -19
- package/components/commerce/checkout-panel/mobile-cp.tsx +67 -0
- package/components/commerce/checkout-panel/policy-links.tsx +29 -0
- package/components/commerce/drawer/index.tsx +2 -13
- package/components/commerce/drawer/micro.tsx +19 -19
- package/components/commerce/mobile-nav-menu-ai.tsx +0 -1
- package/components/copyright.tsx +3 -3
- package/components/index.ts +0 -2
- package/components/mini-chart/mini-chart.tsx +2 -2
- package/package.json +1 -1
- package/root-layout/index.tsx +1 -1
- package/tsconfig.json +1 -1
- package/components/commerce/add-widget.tsx +0 -20
- package/components/commerce/checkout-panel/dt-checkout-panel.tsx +0 -85
- package/components/commerce/checkout-panel/links-row.tsx +0 -21
- package/components/commerce/checkout-panel/mb-checkout-panel.tsx +0 -55
- /package/components/commerce/{checkout-widget → _to_deprecate_checkout-widget}/const.ts +0 -0
- /package/components/commerce/{checkout-widget → _to_deprecate_checkout-widget}/obs-string-set.ts +0 -0
- /package/components/commerce/{checkout-widget → _to_deprecate_checkout-widget}/use-anim-clx-set.ts +0 -0
- /package/components/commerce/checkout-panel/{dt-bag-carousel.tsx → desktop-bag-carousel.tsx} +0 -0
package/commerce/ui/context.tsx
CHANGED
@@ -15,7 +15,7 @@ import { useDebounceCallback } from 'usehooks-ts'
|
|
15
15
|
import { preset as twConfig } from '@hanzo/ui/tailwind'
|
16
16
|
import { useCommerce } from '@hanzo/commerce'
|
17
17
|
|
18
|
-
import type { CommerceDrawer, SelectAndBuy
|
18
|
+
import type { CommerceDrawer, SelectAndBuy } from './store'
|
19
19
|
import { CommerceUIStore } from './store'
|
20
20
|
import conf from './conf'
|
21
21
|
|
@@ -39,10 +39,6 @@ const useSelectAndBuy = (): SelectAndBuy => {
|
|
39
39
|
return useContext(CommerceUIContext) as SelectAndBuy
|
40
40
|
}
|
41
41
|
|
42
|
-
const useRecentActivity = (): RecentActivity => {
|
43
|
-
return useContext(CommerceUIContext) as RecentActivity
|
44
|
-
}
|
45
|
-
|
46
42
|
const CommerceUIProvider: React.FC<PropsWithChildren> = ({
|
47
43
|
children,
|
48
44
|
}) => {
|
@@ -78,6 +74,7 @@ const CommerceUIProvider: React.FC<PropsWithChildren> = ({
|
|
78
74
|
storeRef.current.initialize()
|
79
75
|
onResize()
|
80
76
|
window.addEventListener('resize', onResize_debounced);
|
77
|
+
|
81
78
|
return () => {
|
82
79
|
window.removeEventListener('resize', onResize_debounced)
|
83
80
|
storeRef.current.dispose()
|
@@ -104,8 +101,9 @@ const CommerceUIProvider: React.FC<PropsWithChildren> = ({
|
|
104
101
|
&&
|
105
102
|
prevPathRef.current !== pathname
|
106
103
|
) {
|
107
|
-
storeRef.current.
|
104
|
+
storeRef.current.newRoute()
|
108
105
|
prevPathRef.current = pathname
|
106
|
+
log("ROUTE CHANGE: " + pathname + ": " + storeRef.current._routeChangedTime)
|
109
107
|
}
|
110
108
|
}, [pathname])
|
111
109
|
|
@@ -120,7 +118,6 @@ const CommerceUIProvider: React.FC<PropsWithChildren> = ({
|
|
120
118
|
export {
|
121
119
|
useCommerceDrawer,
|
122
120
|
useSelectAndBuy,
|
123
|
-
useRecentActivity,
|
124
121
|
CommerceUIProvider
|
125
122
|
}
|
126
123
|
|
package/commerce/ui/store.ts
CHANGED
@@ -8,10 +8,9 @@ import {
|
|
8
8
|
type IReactionDisposer,
|
9
9
|
} from 'mobx'
|
10
10
|
|
11
|
-
import type { CommerceService
|
11
|
+
import type { CommerceService } from '@hanzo/commerce/types'
|
12
12
|
|
13
13
|
const LOG = false ////////////////////
|
14
|
-
|
15
14
|
const log = (s: string) => {
|
16
15
|
if (LOG) {
|
17
16
|
console.log('COMMERCE_UI ' + s)
|
@@ -32,14 +31,12 @@ type SnapPointsConfig = {
|
|
32
31
|
|
33
32
|
type DrawerState = 'closed' | 'micro' | 'full'
|
34
33
|
|
35
|
-
interface RecentActivity extends ObsLineItemRef {
|
36
|
-
quantityChanged(sku: string, val: number, prevVal: number): void
|
37
|
-
}
|
38
|
-
|
39
34
|
interface SelectAndBuy {
|
40
35
|
showVariants: (skuPath: string) => void
|
36
|
+
showRecentVariants: () => void
|
41
37
|
hideVariants: () => void
|
42
38
|
get currentSkuPath(): string | undefined
|
39
|
+
newRoute: () => void
|
43
40
|
}
|
44
41
|
|
45
42
|
interface CommerceDrawer {
|
@@ -54,7 +51,7 @@ interface CommerceDrawer {
|
|
54
51
|
// Called by UI Gesture
|
55
52
|
onActivePointChanged: (p: SnapPoint | null) => void
|
56
53
|
get showCheckout(): boolean
|
57
|
-
get
|
54
|
+
get showRecent(): boolean
|
58
55
|
get showBuy(): boolean
|
59
56
|
|
60
57
|
get microHeight(): SnapPoint
|
@@ -63,11 +60,11 @@ interface CommerceDrawer {
|
|
63
60
|
}
|
64
61
|
|
65
62
|
class CommerceUIStore implements
|
66
|
-
RecentActivity,
|
67
63
|
SelectAndBuy,
|
68
64
|
CommerceDrawer
|
69
65
|
{
|
70
66
|
_vHeight: number = 0
|
67
|
+
_routeChangedTime = 0
|
71
68
|
|
72
69
|
_currentSkuPath: string | undefined = undefined
|
73
70
|
_closedByUser: boolean = false
|
@@ -75,7 +72,6 @@ class CommerceUIStore implements
|
|
75
72
|
_ignoreStateChange: boolean = false
|
76
73
|
_activePoint: SnapPoint | null = null
|
77
74
|
|
78
|
-
_activeItem: LineItem | undefined = undefined
|
79
75
|
_reactionDisposers: IReactionDisposer[] = []
|
80
76
|
_service: CommerceService
|
81
77
|
_pointsConfig: SnapPointsConfig
|
@@ -88,32 +84,31 @@ class CommerceUIStore implements
|
|
88
84
|
|
89
85
|
makeObservable(this, {
|
90
86
|
_currentSkuPath: observable,
|
91
|
-
_activeItem: observable.ref,
|
92
87
|
_closedByUser: observable,
|
93
88
|
_checkingOut: observable,
|
94
89
|
_activePoint: observable,
|
95
90
|
_points: observable.ref,
|
96
91
|
_vHeight: observable,
|
92
|
+
_routeChangedTime: observable,
|
97
93
|
|
98
94
|
showVariants: action,
|
95
|
+
showRecentVariants: action,
|
99
96
|
hideVariants: action,
|
100
|
-
quantityChanged: action,
|
101
97
|
setClosedByUser: action,
|
102
98
|
setCheckingOut: action,
|
103
99
|
setActivePoint: action,
|
104
100
|
setMobile: action,
|
105
101
|
setViewportHeight: action,
|
106
|
-
|
102
|
+
setRouteChangedTime: action,
|
107
103
|
|
108
104
|
activePoint: computed,
|
109
105
|
checkingOut: computed,
|
110
106
|
closedByUser: computed,
|
111
107
|
currentSkuPath: computed,
|
112
|
-
item: computed,
|
113
108
|
microHeight: computed,
|
114
109
|
modal: computed,
|
115
110
|
points: computed,
|
116
|
-
|
111
|
+
showRecent: computed,
|
117
112
|
showBuy: computed,
|
118
113
|
showCheckout: computed,
|
119
114
|
snapPointPx: computed,
|
@@ -138,36 +133,38 @@ class CommerceUIStore implements
|
|
138
133
|
}
|
139
134
|
}
|
140
135
|
))
|
136
|
+
/*
|
141
137
|
this._reactionDisposers.push(autorun(() => {
|
142
138
|
log('AUTORUN: OPEN: ' + this.open)
|
143
139
|
log('AUTORUN:' + // ===============
|
144
140
|
'[showCheckout: ' + this.showCheckout +
|
145
|
-
'], [
|
141
|
+
'], [showRecent: ' + this.showRecent +
|
146
142
|
'], [showBuy: ' + this.showBuy +
|
147
143
|
'], [closedByUser: ' + this._closedByUser +
|
148
144
|
'], [checkingOut: ' + this._checkingOut + ']'
|
149
145
|
) // ===========
|
150
146
|
}))
|
147
|
+
*/
|
151
148
|
}
|
152
149
|
|
153
|
-
|
150
|
+
newRoute = () => {
|
151
|
+
this.setRouteChangedTime(new Date().getTime())
|
154
152
|
this.hideVariants()
|
155
153
|
this.setClosedByUser(false)
|
156
|
-
this.clearActiveItem()
|
157
154
|
// DO NOT reset _checkingOut!
|
158
155
|
}
|
159
156
|
|
160
|
-
onActivePointChanged = (
|
161
|
-
log("ON onActivePointChanged: " +
|
162
|
-
if (
|
157
|
+
onActivePointChanged = (newPoint: SnapPoint | null): void => {
|
158
|
+
log("ON onActivePointChanged: " + newPoint) // ===========
|
159
|
+
if (newPoint === this._points.micro && this.activePoint === this._points.full) {
|
163
160
|
this.setIgnoreStateChange(true)
|
164
161
|
this.hideVariants()
|
165
162
|
}
|
166
|
-
else if (
|
163
|
+
else if (newPoint === this._points.full && this.activePoint === this._points.micro) {
|
167
164
|
this.setIgnoreStateChange(true)
|
168
|
-
this.
|
165
|
+
this.showRecentVariants()
|
169
166
|
}
|
170
|
-
this.setActivePoint(
|
167
|
+
this.setActivePoint(newPoint)
|
171
168
|
}
|
172
169
|
|
173
170
|
showVariants = (skuPath: string): void => {
|
@@ -176,27 +173,17 @@ class CommerceUIStore implements
|
|
176
173
|
this._closedByUser = false
|
177
174
|
}
|
178
175
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
if (val === 0) {
|
186
|
-
if (this._activeItem?.sku === sku) {
|
187
|
-
this._activeItem = undefined
|
188
|
-
}
|
189
|
-
// otherwise ignore
|
190
|
-
}
|
191
|
-
else {
|
192
|
-
if (!this._activeItem || this._activeItem.sku !== sku) {
|
193
|
-
this._activeItem = this._service.getItemBySku(sku)
|
194
|
-
}
|
176
|
+
showRecentVariants = (): void => {
|
177
|
+
const recentItemInfo = this._service.recentItem
|
178
|
+
if (recentItemInfo) {
|
179
|
+
this._service.setCurrentItem(undefined)
|
180
|
+
this._currentSkuPath = recentItemInfo.item.sku
|
181
|
+
this._closedByUser = false
|
195
182
|
}
|
196
183
|
}
|
197
184
|
|
198
|
-
|
199
|
-
|
185
|
+
hideVariants = (): void => { this._currentSkuPath = undefined }
|
186
|
+
get currentSkuPath(): string | undefined { return this._currentSkuPath }
|
200
187
|
|
201
188
|
get closedByUser(): boolean { return this._closedByUser }
|
202
189
|
setClosedByUser = (b: boolean): void => { this._closedByUser = b}
|
@@ -210,13 +197,9 @@ class CommerceUIStore implements
|
|
210
197
|
get activePoint(): SnapPoint | null { return this._activePoint }
|
211
198
|
setActivePoint = (pt: SnapPoint | null): void => { this._activePoint = pt}
|
212
199
|
|
200
|
+
setRouteChangedTime = (t: number): void => {this._routeChangedTime = t}
|
201
|
+
|
213
202
|
get points(): SnapPoint[] {
|
214
|
-
if (this.showBuy && !(this.showAdded || this.showCheckout)) {
|
215
|
-
return [this._points.full]
|
216
|
-
}
|
217
|
-
else if (!this.showBuy && !this.showAdded && this.showCheckout) {
|
218
|
-
return [this._points.micro]
|
219
|
-
}
|
220
203
|
return [this._points.micro, this._points.full]
|
221
204
|
}
|
222
205
|
|
@@ -234,12 +217,10 @@ class CommerceUIStore implements
|
|
234
217
|
|
235
218
|
log('open():' + // ===============
|
236
219
|
' showCheckout: ' + this.showCheckout +
|
237
|
-
'
|
220
|
+
' showRecent: ' + this.showRecent +
|
238
221
|
' showBuy: ' + this.showBuy
|
239
222
|
) // ===========
|
240
223
|
|
241
|
-
|
242
|
-
|
243
224
|
return (
|
244
225
|
this._checkingOut !== undefined
|
245
226
|
&&
|
@@ -247,7 +228,7 @@ class CommerceUIStore implements
|
|
247
228
|
&&
|
248
229
|
!this.closedByUser
|
249
230
|
&&
|
250
|
-
(this.showCheckout || this.
|
231
|
+
(this.showCheckout || this.showRecent || this.showBuy)
|
251
232
|
)
|
252
233
|
}
|
253
234
|
|
@@ -256,15 +237,20 @@ class CommerceUIStore implements
|
|
256
237
|
if (this.showBuy) {
|
257
238
|
return 'full'
|
258
239
|
}
|
259
|
-
else if (this.
|
240
|
+
else if (this.showRecent || this.showCheckout) {
|
260
241
|
return 'micro'
|
261
242
|
}
|
262
243
|
}
|
263
244
|
return 'closed'
|
264
245
|
}
|
265
246
|
|
247
|
+
get showRecent(): boolean {
|
248
|
+
|
249
|
+
const recentInfo = this._service.recentItem
|
250
|
+
return !!recentInfo && recentInfo.modified > this._routeChangedTime
|
251
|
+
}
|
252
|
+
|
266
253
|
get showBuy(): boolean {return !!this.currentSkuPath}
|
267
|
-
get showAdded(): boolean { return !!this.item}
|
268
254
|
get showCheckout(): boolean { return !this._service.cartEmpty}
|
269
255
|
get modal(): boolean { return this.state !== 'micro'}
|
270
256
|
|
@@ -297,7 +283,6 @@ class CommerceUIStore implements
|
|
297
283
|
export {
|
298
284
|
CommerceUIStore,
|
299
285
|
type CommerceDrawer,
|
300
|
-
type RecentActivity,
|
301
286
|
type SelectAndBuy,
|
302
287
|
type SnapPointsConfig,
|
303
288
|
type SnapPoints,
|
@@ -15,6 +15,7 @@ import type { VariantProps } from '@hanzo/ui/util'
|
|
15
15
|
const BackButton: React.FC<{
|
16
16
|
variant?: VariantProps<typeof buttonVariants>['variant']
|
17
17
|
size?: VariantProps<typeof buttonVariants>['size']
|
18
|
+
onBack?: () => void
|
18
19
|
clx?: string
|
19
20
|
iconClx?: string
|
20
21
|
}> = ({
|
@@ -22,10 +23,16 @@ const BackButton: React.FC<{
|
|
22
23
|
size='default',
|
23
24
|
clx='',
|
24
25
|
iconClx='',
|
26
|
+
onBack
|
25
27
|
}) => {
|
26
28
|
|
27
29
|
const router = useRouter()
|
28
|
-
const back = () => {
|
30
|
+
const back = () => {
|
31
|
+
if (onBack) {
|
32
|
+
onBack()
|
33
|
+
}
|
34
|
+
router.back()
|
35
|
+
}
|
29
36
|
|
30
37
|
return (
|
31
38
|
<Button
|
package/components/commerce/{checkout-widget/index.tsx → _to_deprecate_checkout-widget/index.tsx_}
RENAMED
@@ -9,8 +9,6 @@ import { useStepAnimation } from '@hanzo/ui/util-client'
|
|
9
9
|
|
10
10
|
import { Image } from '@hanzo/ui/primitives'
|
11
11
|
|
12
|
-
import { useCommerceDrawer, useRecentActivity } from '../../../commerce/ui/context'
|
13
|
-
|
14
12
|
import CheckoutButton from '../checkout-button'
|
15
13
|
import useAnimationClxSet from './use-anim-clx-set'
|
16
14
|
import CONST from './const'
|
@@ -111,8 +109,6 @@ const CheckoutWidget: React.FC<{
|
|
111
109
|
const isCheckout = usePathname() === '/checkout'
|
112
110
|
const clxSet = useAnimationClxSet(isCheckout)
|
113
111
|
|
114
|
-
const recentActivity = useRecentActivity()
|
115
|
-
|
116
112
|
// for rendering content after recentActivity.item() would return false
|
117
113
|
const persistentRef = useRef<LineItem | undefined>(undefined)
|
118
114
|
|
@@ -0,0 +1,66 @@
|
|
1
|
+
'use client'
|
2
|
+
import React from 'react'
|
3
|
+
import { observer } from 'mobx-react-lite'
|
4
|
+
|
5
|
+
import { ChevronRight } from 'lucide-react'
|
6
|
+
|
7
|
+
import {
|
8
|
+
Accordion,
|
9
|
+
AccordionContent,
|
10
|
+
AccordionItem,
|
11
|
+
AccordionTrigger,
|
12
|
+
} from '@hanzo/ui/primitives'
|
13
|
+
import { cn } from '@hanzo/ui/util'
|
14
|
+
|
15
|
+
import { useCommerce, CartPanel, formatCurrencyValue } from '@hanzo/commerce'
|
16
|
+
|
17
|
+
const CartAccordian: React.FC<{
|
18
|
+
icon?: React.ReactNode
|
19
|
+
clx?: string
|
20
|
+
triggerClx?: string
|
21
|
+
panelClx?: string
|
22
|
+
scrollAfter: number
|
23
|
+
scrollHeightClx: string
|
24
|
+
}> = observer(({
|
25
|
+
icon,
|
26
|
+
clx='',
|
27
|
+
panelClx='',
|
28
|
+
triggerClx='',
|
29
|
+
scrollAfter,
|
30
|
+
scrollHeightClx
|
31
|
+
}) => {
|
32
|
+
const cmmc = useCommerce()
|
33
|
+
return (
|
34
|
+
<Accordion type="single" collapsible className={clx}>
|
35
|
+
<AccordionItem value="cart" className='w-full border-b-0'>
|
36
|
+
<AccordionTrigger className={'!no-underline group flex justify-between '} headerClx={ triggerClx}>
|
37
|
+
<div className='flex gap-0 items-center'>
|
38
|
+
{icon}
|
39
|
+
<h5 className='text-sm sm:text-xl grow'>
|
40
|
+
<span className='group-data-[state=open]:hidden' >Order Total:</span>
|
41
|
+
<span className='group-data-[state=closed]:hidden' >Your Order</span>
|
42
|
+
</h5>
|
43
|
+
</div>
|
44
|
+
<div className='flex gap-1 items-center'>
|
45
|
+
<h5 className='text-sm sm:text-xl grow truncate'>{formatCurrencyValue(cmmc.promoAppliedCartTotal)}</h5>
|
46
|
+
<ChevronRight className="h-5 w-5 -mr-2 shrink-0 transition-transform duration-200 group-data-[state=open]:rotate-90" />
|
47
|
+
</div>
|
48
|
+
</AccordionTrigger>
|
49
|
+
<AccordionContent className='data-[state=open]:mb-4'>
|
50
|
+
<CartPanel
|
51
|
+
className={cn('w-full', panelClx)}
|
52
|
+
scrollAfter={scrollAfter}
|
53
|
+
scrollHeightClx={scrollHeightClx}
|
54
|
+
listClx='mt-0'
|
55
|
+
itemClx='mt-0.5 mb-0'
|
56
|
+
totalClx='sticky px-1 pr-2 border-t -bottom-[1px] bg-background'
|
57
|
+
showShipping
|
58
|
+
showPromoCode
|
59
|
+
/>
|
60
|
+
</AccordionContent>
|
61
|
+
</AccordionItem>
|
62
|
+
</Accordion>
|
63
|
+
)
|
64
|
+
})
|
65
|
+
|
66
|
+
export default CartAccordian
|
@@ -0,0 +1,83 @@
|
|
1
|
+
'use client'
|
2
|
+
import React, { type PropsWithChildren } from 'react'
|
3
|
+
import { observer } from 'mobx-react-lite'
|
4
|
+
|
5
|
+
import { ScrollArea, StepIndicator } from '@hanzo/ui/primitives'
|
6
|
+
import { AuthWidget } from '@hanzo/auth/components'
|
7
|
+
import { CartPanel, useCommerce } from '@hanzo/commerce'
|
8
|
+
import { cn } from '@hanzo/ui/util'
|
9
|
+
|
10
|
+
import { BackButton, Logo, Tooltip } from '../..'
|
11
|
+
import DesktopBagCarousel from './desktop-bag-carousel'
|
12
|
+
import LinksRow from './policy-links'
|
13
|
+
import type CheckoutPanelProps from './checkout-panel-props'
|
14
|
+
|
15
|
+
const DesktopCheckoutPanel: React.FC<PropsWithChildren & CheckoutPanelProps> = observer(({
|
16
|
+
step,
|
17
|
+
stepNames,
|
18
|
+
onLeave,
|
19
|
+
clx='',
|
20
|
+
children
|
21
|
+
}) => {
|
22
|
+
|
23
|
+
const cmmc = useCommerce()
|
24
|
+
return (
|
25
|
+
<div /* id='CHECKOUT_PANEL' */ className={cn('grid grid-cols-2', clx)}>
|
26
|
+
<div key={1} className='w-full h-full bg-background flex flex-row items-start justify-end'>
|
27
|
+
<div className='w-full h-full max-w-[750px] relative flex flex-col items-stretch justify-start px-8 pb-8'>
|
28
|
+
<div key={1} className='h-[80px] grow-0 flex flex-row items-center z-10' >
|
29
|
+
<Logo size='md' href='/' onClick={onLeave} variant='text-only' outerClx='logo-outer-tooltip-class' />
|
30
|
+
<Tooltip select='.logo-outer-tooltip-class' text='home' position='right' offset={6}/>
|
31
|
+
</div>
|
32
|
+
<BackButton
|
33
|
+
size='sm'
|
34
|
+
clx={
|
35
|
+
'z-10 absolute top-14 left-6 !px-0 aspect-square ' +
|
36
|
+
'rounded-full hover:!bg-level-3 ' +
|
37
|
+
'back-button-tooltip-class '
|
38
|
+
}
|
39
|
+
onBack={onLeave}
|
40
|
+
/>
|
41
|
+
<Tooltip select='.back-button-tooltip-class' text='back' position='right' offset={5}/>
|
42
|
+
<div key={2} className={cn(
|
43
|
+
'w-full grow min-h-0 max-w-[550px] mx-auto flex flex-col gap-3',
|
44
|
+
(cmmc.cartItems.length > 4 ? 'justify-between' : 'justify-start gap-10 pt-10')
|
45
|
+
)}>
|
46
|
+
<DesktopBagCarousel className='grow-0 h-[260px] w-[360px] lg:w-[420px] mx-auto -mt-8' constrainTo={{w: 250, h: 250}}/>
|
47
|
+
<CartPanel
|
48
|
+
className='w-full border-none p-0'
|
49
|
+
itemClx='mb-2'
|
50
|
+
totalClx='sticky bottom-0 bg-background'
|
51
|
+
listClx='pr-3'
|
52
|
+
scrollAfter={4}
|
53
|
+
scrollHeightClx='min-h-[50vh] grow'
|
54
|
+
showPromoCode
|
55
|
+
showShipping
|
56
|
+
selectItems
|
57
|
+
/>
|
58
|
+
</div>
|
59
|
+
</div>
|
60
|
+
</div>
|
61
|
+
<div key={2} className='w-full h-full flex flex-col bg-level-1 min-h-screen justify-between'>
|
62
|
+
<ScrollArea className='w-full flex flex-row items-start justify-start overflow-y-auto'>
|
63
|
+
<div className='h-full w-full max-w-[750px] relative flex flex-col items-center px-8 pt-0'>
|
64
|
+
<div key={1} className='bg-level-1 sticky h-[80px] bg-[#aaaaff] w-full top-0 flex justify-center items-end'>
|
65
|
+
<AuthWidget noLogin className='hidden md:flex absolute top-4 right-4 '/>
|
66
|
+
<StepIndicator dotSizeRem={1.35} steps={stepNames} currentStep={step} className='gap-2 text-base w-pr-70' />
|
67
|
+
</div>
|
68
|
+
<div key={2} className='w-full max-w-[550px] mx-auto py-8'>
|
69
|
+
{children}
|
70
|
+
</div>
|
71
|
+
</div>
|
72
|
+
</ScrollArea>
|
73
|
+
<div className='w-full max-w-[750px] relative flex flex-col items-center px-8 pt-0'>
|
74
|
+
<div className='w-full max-w-[550px] mx-auto flex flex-col items-center'>
|
75
|
+
<LinksRow clx='w-full' />
|
76
|
+
</div>
|
77
|
+
</div>
|
78
|
+
</div>
|
79
|
+
</div>
|
80
|
+
)
|
81
|
+
})
|
82
|
+
|
83
|
+
export default DesktopCheckoutPanel
|
@@ -26,15 +26,13 @@ const STEPS = [
|
|
26
26
|
|
27
27
|
const STEP_NAMES = STEPS.map((s) => (s.label ? s.label : capitalize(s.name)))
|
28
28
|
|
29
|
-
import DesktopCP from './
|
30
|
-
import MobileCP from './
|
29
|
+
import DesktopCP from './desktop-cp'
|
30
|
+
import MobileCP from './mobile-cp'
|
31
31
|
|
32
32
|
const CheckoutPanel: React.FC<{
|
33
|
-
|
34
|
-
className?: string
|
33
|
+
clx?: string
|
35
34
|
}> = ({
|
36
|
-
|
37
|
-
className=''
|
35
|
+
clx=''
|
38
36
|
}) => {
|
39
37
|
|
40
38
|
const cmmc = useCommerce()
|
@@ -78,16 +76,15 @@ const CheckoutPanel: React.FC<{
|
|
78
76
|
|
79
77
|
const _close = () => {
|
80
78
|
setStep('first')
|
81
|
-
close()
|
82
79
|
}
|
83
80
|
|
84
|
-
|
85
|
-
|
81
|
+
// Determine if mobile or desktop layout based on visibility of desktopElement
|
82
|
+
// This prevents issues with multiple instances of 3rd party e-commerce widgets
|
83
|
+
// from ever being in the DOM.
|
84
|
+
// https://stackoverflow.com/a/21696585/11378853
|
86
85
|
const desktopElement = useRef<HTMLDivElement | null>(null)
|
87
|
-
const [layout, setLayout] = useState<'mobile' | 'desktop' | undefined>()
|
86
|
+
const [layout, setLayout] = useState<'mobile' | 'desktop' | undefined>(undefined)
|
88
87
|
|
89
|
-
// TODO :aa I assume it's becase we don't want two instance of the Square plugin....
|
90
|
-
// ... wondering if there is a simpler way.
|
91
88
|
useLayoutEffect(() => {
|
92
89
|
const checkLayout = () => {
|
93
90
|
setLayout(!!desktopElement.current?.offsetParent ? 'desktop' : 'mobile')
|
@@ -106,19 +103,19 @@ const CheckoutPanel: React.FC<{
|
|
106
103
|
|
107
104
|
return (<>
|
108
105
|
<DesktopCP
|
109
|
-
|
110
|
-
|
111
|
-
|
106
|
+
clx={cn('h-full', clx, 'hidden md:flex')}
|
107
|
+
onLeave={_close}
|
108
|
+
step={stepIndex}
|
112
109
|
stepNames={STEP_NAMES}
|
113
110
|
>
|
114
|
-
{/* Element required to determine if DesktopCP is visible */}
|
111
|
+
{/* Element required to determine if DesktopCP is visible. See above. */}
|
115
112
|
<div ref={desktopElement}/>
|
116
113
|
{layout === 'desktop' && <StepToRender onDone={() => {setStep('next')}} orderId={orderId} setOrderId={setOrderId}/>}
|
117
114
|
</DesktopCP>
|
118
115
|
<MobileCP
|
119
|
-
|
120
|
-
|
121
|
-
|
116
|
+
clx={cn('w-full h-full overflow-y-auto', clx, 'md:hidden' )}
|
117
|
+
onLeave={_close}
|
118
|
+
step={stepIndex}
|
122
119
|
stepNames={STEP_NAMES}
|
123
120
|
>
|
124
121
|
{layout === 'mobile' && <StepToRender onDone={() => {setStep('next')}} orderId={orderId} setOrderId={setOrderId}/>}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
'use client'
|
2
|
+
import React, { type PropsWithChildren } from 'react'
|
3
|
+
|
4
|
+
import { StepIndicator } from '@hanzo/ui/primitives'
|
5
|
+
import { cn } from '@hanzo/ui/util'
|
6
|
+
import { AuthWidget } from '@hanzo/auth/components'
|
7
|
+
|
8
|
+
import { BackButton, Logo } from '../..'
|
9
|
+
import BagButton from '../bag-button'
|
10
|
+
import PolicyLinks from './policy-links'
|
11
|
+
import CartAccordian from './cart-accordian'
|
12
|
+
import type CheckoutPanelProps from './checkout-panel-props'
|
13
|
+
|
14
|
+
|
15
|
+
const MobileCheckoutPanel: React.FC<PropsWithChildren & CheckoutPanelProps> = ({
|
16
|
+
step,
|
17
|
+
stepNames,
|
18
|
+
onLeave,
|
19
|
+
clx='',
|
20
|
+
children
|
21
|
+
}) => (
|
22
|
+
|
23
|
+
<div /* id='MOBILE_GRID' */ className={cn('bg-background flex flex-col justify-start px-4 pt-[101px]', clx)}>
|
24
|
+
<div className='fixed z-11 top-0 h-[45px] w-full flex justify-between items-stretch bg-background'>
|
25
|
+
<div className='flex items-stretch gap-1 grow-0'>
|
26
|
+
<BackButton
|
27
|
+
size='sm'
|
28
|
+
clx={
|
29
|
+
'-ml-5 !px-0 aspect-square h-full ' +
|
30
|
+
'rounded-full active:!bg-level-3 '
|
31
|
+
}
|
32
|
+
onBack={onLeave}
|
33
|
+
/>
|
34
|
+
<Logo size='xs' variant='text-only' href='/' onClick={onLeave} outerClx='-ml-2'/>
|
35
|
+
</div>
|
36
|
+
<StepIndicator
|
37
|
+
dotSizeRem={1}
|
38
|
+
steps={stepNames}
|
39
|
+
currentStep={step}
|
40
|
+
className='relative grow mx-2 top-[14px] text-xs font-semibold w-full'
|
41
|
+
/>
|
42
|
+
|
43
|
+
{/* 72px by observation (for centering). Need wrapper div since 'noLogin' returns null if no logged in user */}
|
44
|
+
<div className='w-[72px] grow-0 shrink-0 flex items-center justify-center'><AuthWidget noLogin className=''/></div>
|
45
|
+
</div>
|
46
|
+
<CartAccordian
|
47
|
+
icon={
|
48
|
+
<BagButton
|
49
|
+
animateOnHover={false}
|
50
|
+
showIfEmpty
|
51
|
+
size='sm'
|
52
|
+
className='mr-1 relative w-5 h-6 sm:w-6 sm:h-7'
|
53
|
+
iconClx='fill-foreground'
|
54
|
+
/>
|
55
|
+
}
|
56
|
+
clx='flex items-center justify-center w-full'
|
57
|
+
triggerClx='bg-background fixed z-11 top-[45px] left-0 right-0 !m-0 px-4'
|
58
|
+
panelClx='!py-0'
|
59
|
+
scrollAfter={3}
|
60
|
+
scrollHeightClx='h-[385px]'
|
61
|
+
/>
|
62
|
+
{children}
|
63
|
+
<PolicyLinks clx='mt-auto mb-3 pt-2' />
|
64
|
+
</div>
|
65
|
+
)
|
66
|
+
|
67
|
+
export default MobileCheckoutPanel
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import Link from 'next/link'
|
3
|
+
|
4
|
+
import { Separator, buttonVariants } from '@hanzo/ui/primitives'
|
5
|
+
import { cn } from '@hanzo/ui/util'
|
6
|
+
|
7
|
+
|
8
|
+
const linkClx = buttonVariants({
|
9
|
+
variant: 'linkMuted',
|
10
|
+
size: 'link',
|
11
|
+
rounded: 'none',
|
12
|
+
})
|
13
|
+
|
14
|
+
const PolicyLinks: React.FC<{
|
15
|
+
clx?: string
|
16
|
+
}> = ({
|
17
|
+
clx=''
|
18
|
+
}) => (
|
19
|
+
<div className={cn('flex flex-col items-center', clx)}>
|
20
|
+
<Separator/>
|
21
|
+
<div className='flex gap-4 py-2 text-sm'>
|
22
|
+
{/* TODO: add Refund policy and Privacy policy links */}
|
23
|
+
<Link className={linkClx} href=''>refund policy</Link>
|
24
|
+
<Link className={linkClx} href=''>privacy policy</Link>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
)
|
28
|
+
|
29
|
+
export default PolicyLinks
|
@@ -8,7 +8,6 @@ import { CarouselBuyCard } from '@hanzo/commerce'
|
|
8
8
|
import {
|
9
9
|
useSelectAndBuy,
|
10
10
|
useCommerceDrawer,
|
11
|
-
useRecentActivity
|
12
11
|
} from '../../../commerce/ui/context'
|
13
12
|
|
14
13
|
import CommerceDrawer from './shell'
|
@@ -19,33 +18,24 @@ const CommerceUIComponent: React.FC = observer(() => {
|
|
19
18
|
|
20
19
|
const buy = useSelectAndBuy()
|
21
20
|
const drawer = useCommerceDrawer()
|
22
|
-
const recent = useRecentActivity()
|
23
21
|
const router = useRouter()
|
24
|
-
|
25
22
|
|
26
23
|
const handleCheckout = (): void => {
|
27
24
|
router.push('/checkout')
|
28
25
|
}
|
29
26
|
|
30
|
-
|
31
27
|
const handleHandleClicked = (): void => {
|
32
28
|
|
33
29
|
if (drawer.state === 'full') {
|
34
30
|
buy.hideVariants()
|
35
31
|
}
|
36
32
|
else if (drawer.state === 'micro') {
|
37
|
-
|
38
|
-
buy.showVariants(recent.item?.sku ?? '')
|
39
|
-
}
|
40
|
-
// checkout only
|
41
|
-
else {
|
42
|
-
drawer.setClosedByUser(true)
|
43
|
-
}
|
33
|
+
buy.showRecentVariants()
|
44
34
|
}
|
45
35
|
}
|
46
36
|
|
47
37
|
const handleItemClicked = () => {
|
48
|
-
buy.
|
38
|
+
buy.showRecentVariants()
|
49
39
|
}
|
50
40
|
|
51
41
|
const handleCloseGesture = (): boolean => {
|
@@ -76,7 +66,6 @@ const CommerceUIComponent: React.FC = observer(() => {
|
|
76
66
|
className='w-full min-w-[160px] sm:max-w-[320px]'
|
77
67
|
/>
|
78
68
|
}
|
79
|
-
onQuantityChanged={recent.quantityChanged.bind(recent)}
|
80
69
|
clx='justify-between h-full pb-3 gap-8'
|
81
70
|
addBtnClx='w-full min-w-[160px] sm:max-w-[320px]'
|
82
71
|
buttonsAreaClx='grow-0 shrink-0 mt-0'
|
@@ -8,7 +8,7 @@ import type { LineItem } from '@hanzo/commerce/types'
|
|
8
8
|
import { useCommerce, formatCurrencyValue } from '@hanzo/commerce'
|
9
9
|
|
10
10
|
import CheckoutButton from '../checkout-button'
|
11
|
-
import { useCommerceDrawer
|
11
|
+
import { useCommerceDrawer } from '../../../commerce/ui/context'
|
12
12
|
|
13
13
|
const CN = {
|
14
14
|
// h: mind padding!
|
@@ -67,17 +67,16 @@ const Micro: React.FC<{
|
|
67
67
|
}) => {
|
68
68
|
|
69
69
|
const drawer = useCommerceDrawer()
|
70
|
-
const
|
71
|
-
const mobile = drawer.isMobile
|
70
|
+
const cmmc = useCommerce()
|
72
71
|
|
73
72
|
return (
|
74
73
|
<div className={cn(
|
75
|
-
(drawer.
|
76
|
-
(drawer.
|
74
|
+
(drawer.showRecent ? 'grid grid-cols-2' : 'flex justify-center items-center '),
|
75
|
+
(drawer.showRecent ? ((drawer.isMobile) ? '-mt-3' : '-mt-3') : ''),
|
77
76
|
'gap-2 md:gap-3 relative',
|
78
77
|
clx
|
79
78
|
)}>
|
80
|
-
{drawer.
|
79
|
+
{drawer.showRecent && (
|
81
80
|
<div className={'flex flex-col items-stretch ' + (drawer.isMobile ? 'justify-start' : 'group')}>
|
82
81
|
<p className={'relative text-muted text-xxs md:text-xs leading-none pl-1 self-start ' + (drawer.isMobile ? 'top-[3px]' : 'top-[1px]')}>
|
83
82
|
<span className='invisible'>scrictly for layout</span>
|
@@ -91,7 +90,7 @@ const Micro: React.FC<{
|
|
91
90
|
<Button
|
92
91
|
variant='ghost'
|
93
92
|
rounded={drawer.isMobile ? 'md' : 'lg'}
|
94
|
-
size={drawer.isMobile ? '
|
93
|
+
size={drawer.isMobile ? 'sm' : 'lg'}
|
95
94
|
onClick={handleItemClicked}
|
96
95
|
className={cn(
|
97
96
|
'box-content',
|
@@ -103,14 +102,14 @@ const Micro: React.FC<{
|
|
103
102
|
'group-hover:!bg-transparent '
|
104
103
|
)}
|
105
104
|
>
|
106
|
-
{
|
107
|
-
<Image def={
|
108
|
-
<Image def={
|
109
|
-
<Image def={
|
105
|
+
{cmmc.recentItem?.item.img && (<>
|
106
|
+
<Image def={cmmc.recentItem.item.img} constrainTo={CN.mobile} preload className='sm:hidden grow-0 shrink-0'/>
|
107
|
+
<Image def={cmmc.recentItem.item.img} constrainTo={CN.sm} preload className='hidden sm:block md:hidden grow-0 shrink-0'/>
|
108
|
+
<Image def={cmmc.recentItem.item.img} constrainTo={CN.desktop} preload className='hidden md:block grow-0 shrink-0'/>
|
110
109
|
</>)}
|
111
|
-
{
|
110
|
+
{cmmc.recentItem && (
|
112
111
|
<div className='grow w-full'>
|
113
|
-
<Info item={
|
112
|
+
<Info item={cmmc.recentItem.item} clx='w-full'/>
|
114
113
|
</div>
|
115
114
|
)}
|
116
115
|
</Button>
|
@@ -119,20 +118,21 @@ const Micro: React.FC<{
|
|
119
118
|
{drawer.showCheckout && (
|
120
119
|
<div className={cn(
|
121
120
|
'flex flex-col w-full',
|
122
|
-
(drawer.
|
121
|
+
(drawer.showRecent ? 'items-stretch' : 'items-center' ),
|
123
122
|
(drawer.isMobile ? 'justify-start' : 'justify-center')
|
124
123
|
)}>
|
125
|
-
{drawer.
|
124
|
+
{drawer.showRecent && <p className='invisible text-muted text-xxs md:text-xs leading-none pl-1 self-start'>for layout</p>}
|
126
125
|
<CheckoutButton
|
127
126
|
handleCheckout={handleCheckout}
|
128
127
|
variant='primary'
|
129
|
-
size={drawer.isMobile ? '
|
128
|
+
size={drawer.isMobile ? 'xs' : 'lg'}
|
130
129
|
rounded={drawer.isMobile ? 'md' : 'lg'}
|
131
|
-
centerText={drawer.isMobile ? !drawer.
|
130
|
+
centerText={drawer.isMobile ? !drawer.showRecent : true}
|
132
131
|
className={cn(drawer.isMobile ?
|
133
|
-
(drawer.
|
132
|
+
(drawer.showRecent ? 'pl-3.5 pr-2.5' : 'min-w-[320px]')
|
134
133
|
:
|
135
|
-
(drawer.
|
134
|
+
(drawer.showRecent ? '' : 'w-[320px]'),
|
135
|
+
'text-sm font-semibold'
|
136
136
|
)}
|
137
137
|
/>
|
138
138
|
</div>
|
package/components/copyright.tsx
CHANGED
@@ -5,7 +5,7 @@ const FIRST = 2020
|
|
5
5
|
const Copyright: React.FC<{
|
6
6
|
className?: string
|
7
7
|
}> = ({
|
8
|
-
className=''
|
8
|
+
className=''
|
9
9
|
}) => {
|
10
10
|
|
11
11
|
const year = new Date().getFullYear()
|
@@ -13,8 +13,8 @@ const Copyright: React.FC<{
|
|
13
13
|
|
14
14
|
return (
|
15
15
|
<div className={className}>
|
16
|
-
{`Copyright © ${yearString}`} <br className='sm:hidden'/>Lux Partners
|
17
|
-
</div>
|
16
|
+
{`Copyright © ${yearString}`} <br className='sm:hidden'/>Lux Partners Limited. <br className='md:hidden'/> All rights reserved.
|
17
|
+
</div>
|
18
18
|
)
|
19
19
|
}
|
20
20
|
|
package/components/index.ts
CHANGED
@@ -11,14 +11,12 @@ export { default as MiniChart } from './mini-chart'
|
|
11
11
|
export { default as NotFound } from './not-found'
|
12
12
|
|
13
13
|
export { default as AuthListener } from './auth/auth-listener'
|
14
|
-
export { default as AddWidget } from './commerce/add-widget'
|
15
14
|
export { default as BackButton } from './back-button'
|
16
15
|
export { default as BuyDrawer } from './commerce/drawer'
|
17
16
|
export { default as DrawerMargin } from './drawer-margin'
|
18
17
|
export { default as BuyButton } from './commerce/buy-button'
|
19
18
|
export { default as CheckoutButton } from './commerce/checkout-button'
|
20
19
|
export { default as CheckoutPanel } from './commerce/checkout-panel'
|
21
|
-
export { default as CheckoutWidget } from './commerce/checkout-widget'
|
22
20
|
export { default as LoginPanel } from './auth/login-panel'
|
23
21
|
export { default as Scripts } from './scripts'
|
24
22
|
export { default as Tooltip } from './tooltip'
|
@@ -39,7 +39,7 @@ const MiniChart: React.FC<MiniChartProps> = ({
|
|
39
39
|
iframe.style.colorScheme = 'normal'
|
40
40
|
setTimeout(() => {
|
41
41
|
const value = document.querySelector('#mini-symbol-overview-ticker')
|
42
|
-
console.log("TICKER: " + value)
|
42
|
+
//console.log("TICKER: " + value)
|
43
43
|
}, 1200) // from experimentation
|
44
44
|
|
45
45
|
|
@@ -47,7 +47,7 @@ const MiniChart: React.FC<MiniChartProps> = ({
|
|
47
47
|
|
48
48
|
const copyDiv = document.querySelector('.tradingview-widget-copyright')
|
49
49
|
if (copyDiv) {
|
50
|
-
console.log("COPY: " + copyDiv)
|
50
|
+
//console.log("COPY: " + copyDiv)
|
51
51
|
setTimeout(() => {
|
52
52
|
copyDiv.classList.remove('invisible')
|
53
53
|
}, 1200) // from experimentation
|
package/package.json
CHANGED
package/root-layout/index.tsx
CHANGED
@@ -44,7 +44,7 @@ const viewport = {
|
|
44
44
|
We cannot have these on body tag for scroll-snap to work on iOS!
|
45
45
|
*/
|
46
46
|
const bodyClasses =
|
47
|
-
'bg-background text-foreground flex flex-col min-h-full
|
47
|
+
'bg-background text-foreground flex flex-col min-h-full ' +
|
48
48
|
getAppRouterBodyFontClasses()
|
49
49
|
|
50
50
|
async function RootLayout({
|
package/tsconfig.json
CHANGED
@@ -1,20 +0,0 @@
|
|
1
|
-
'use client'
|
2
|
-
import React from 'react'
|
3
|
-
|
4
|
-
import type { LineItem } from '@hanzo/commerce/types'
|
5
|
-
import { AddToCartWidget } from '@hanzo/commerce'
|
6
|
-
|
7
|
-
import { useRecentActivity } from '../../commerce/ui/context'
|
8
|
-
|
9
|
-
const AddWidget: React.FC<{
|
10
|
-
item: LineItem
|
11
|
-
disabled?: boolean
|
12
|
-
className?: string
|
13
|
-
buttonClx?: string
|
14
|
-
variant?: 'minimal' | 'primary' | 'outline'
|
15
|
-
}> = (props) => {
|
16
|
-
const l = useRecentActivity()
|
17
|
-
return <AddToCartWidget {...props} onQuantityChanged={l.quantityChanged.bind(l)}/>
|
18
|
-
}
|
19
|
-
|
20
|
-
export default AddWidget
|
@@ -1,85 +0,0 @@
|
|
1
|
-
'use client'
|
2
|
-
import React, { type PropsWithChildren } from 'react'
|
3
|
-
import { observer } from 'mobx-react-lite'
|
4
|
-
|
5
|
-
import { ScrollArea, StepIndicator } from '@hanzo/ui/primitives'
|
6
|
-
import { AuthWidget } from '@hanzo/auth/components'
|
7
|
-
import { CartPanel, useCommerce } from '@hanzo/commerce'
|
8
|
-
import { cn } from '@hanzo/ui/util'
|
9
|
-
|
10
|
-
import { BackButton, Logo, Tooltip } from '../..'
|
11
|
-
import DesktopBagCarousel from './dt-bag-carousel'
|
12
|
-
import LinksRow from './links-row'
|
13
|
-
|
14
|
-
const DesktopCheckoutPanel: React.FC<PropsWithChildren & {
|
15
|
-
index: number
|
16
|
-
stepNames: string[]
|
17
|
-
close: () => void
|
18
|
-
className?: string
|
19
|
-
}> = observer(({
|
20
|
-
index,
|
21
|
-
stepNames,
|
22
|
-
close,
|
23
|
-
className='',
|
24
|
-
children
|
25
|
-
}) => {
|
26
|
-
|
27
|
-
const cmmc = useCommerce()
|
28
|
-
|
29
|
-
return (
|
30
|
-
<div /* id='CHECKOUT_PANEL' */ className={cn('grid grid-cols-2', className)}>
|
31
|
-
<div key={1} className='w-full h-full bg-background flex flex-row items-start justify-end'>
|
32
|
-
<div className='w-full h-full max-w-[750px] relative flex flex-col items-stretch justify-start px-8 pb-8'>
|
33
|
-
<div key={1} className='h-[80px] grow-0 flex flex-row items-center z-10' >
|
34
|
-
<Logo onClick={close} size='md' href='/' variant='text-only' outerClx='logo-outer-tooltip-class' />
|
35
|
-
<Tooltip select='.logo-outer-tooltip-class' text='home' position='right' offset={6}/>
|
36
|
-
</div>
|
37
|
-
<BackButton size='sm' clx={
|
38
|
-
'z-10 absolute top-14 left-6 !px-0 aspect-square ' +
|
39
|
-
'rounded-full hover:!bg-level-3 ' +
|
40
|
-
//'border border-transparent hover:border-muted-2 ' +
|
41
|
-
'back-button-tooltip-class '
|
42
|
-
}/>
|
43
|
-
<Tooltip select='.back-button-tooltip-class' text='back' position='right' offset={5}/>
|
44
|
-
<div key={2} className={cn(
|
45
|
-
'w-full grow min-h-0 max-w-[550px] mx-auto flex flex-col gap-3',
|
46
|
-
(cmmc.cartItems.length > 4 ? 'justify-between' : 'justify-start gap-10 pt-10')
|
47
|
-
)}>
|
48
|
-
<DesktopBagCarousel className='grow-0 h-[260px] w-[360px] lg:w-[420px] mx-auto -mt-8' constrainTo={{w: 250, h: 250}}/>
|
49
|
-
<CartPanel
|
50
|
-
className='w-full border-none p-0'
|
51
|
-
itemClx='mb-2'
|
52
|
-
totalClx='sticky bottom-0 bg-background'
|
53
|
-
listClx='pr-3'
|
54
|
-
scrollAfter={5}
|
55
|
-
scrollHeightClx='min-h-[50vh] grow'
|
56
|
-
showPromoCode
|
57
|
-
showShipping
|
58
|
-
selectItems
|
59
|
-
/>
|
60
|
-
</div>
|
61
|
-
</div>
|
62
|
-
</div>
|
63
|
-
<div key={2} className='w-full h-full flex flex-col bg-level-1 min-h-screen justify-between'>
|
64
|
-
<ScrollArea className='w-full flex flex-row items-start justify-start overflow-y-auto'>
|
65
|
-
<div className='h-full w-full max-w-[750px] relative flex flex-col items-center px-8 pt-0'>
|
66
|
-
<div key={1} className='bg-level-1 sticky h-30 pb-8 w-full top-0 flex justify-center items-end'>
|
67
|
-
<AuthWidget noLogin className='hidden md:flex absolute top-4 right-4 '/>
|
68
|
-
<StepIndicator dotSizeRem={1.5} steps={stepNames} currentStep={index} className='gap-2 text-base w-pr-70' />
|
69
|
-
</div>
|
70
|
-
<div key={2} className='w-full max-w-[550px] mx-auto pb-10'>
|
71
|
-
{children}
|
72
|
-
</div>
|
73
|
-
</div>
|
74
|
-
</ScrollArea>
|
75
|
-
<div className='w-full max-w-[750px] relative flex flex-col items-center px-8 pt-0'>
|
76
|
-
<div className='w-full max-w-[550px] mx-auto flex flex-col items-center'>
|
77
|
-
<LinksRow className='w-full' />
|
78
|
-
</div>
|
79
|
-
</div>
|
80
|
-
</div>
|
81
|
-
</div>
|
82
|
-
)
|
83
|
-
})
|
84
|
-
|
85
|
-
export default DesktopCheckoutPanel
|
@@ -1,21 +0,0 @@
|
|
1
|
-
import Link from 'next/link'
|
2
|
-
|
3
|
-
import { Separator } from '@hanzo/ui/primitives'
|
4
|
-
import { cn } from '@hanzo/ui/util'
|
5
|
-
|
6
|
-
const LinksRow: React.FC<{
|
7
|
-
className?: string
|
8
|
-
}> = ({
|
9
|
-
className=''
|
10
|
-
}) => (
|
11
|
-
<div className={cn('flex flex-col', className)}>
|
12
|
-
<Separator/>
|
13
|
-
<div className='flex gap-4 text-sm py-2'>
|
14
|
-
{/* TODO: add Refund policy and Privacy policy links */}
|
15
|
-
<Link href=''>Refund policy</Link>
|
16
|
-
<Link href=''>Privacy policy</Link>
|
17
|
-
</div>
|
18
|
-
</div>
|
19
|
-
)
|
20
|
-
|
21
|
-
export default LinksRow
|
@@ -1,55 +0,0 @@
|
|
1
|
-
'use client'
|
2
|
-
import React, { type PropsWithChildren } from 'react'
|
3
|
-
|
4
|
-
import { StepIndicator } from '@hanzo/ui/primitives'
|
5
|
-
import { cn } from '@hanzo/ui/util'
|
6
|
-
import { AuthWidget } from '@hanzo/auth/components'
|
7
|
-
import { CartAccordian } from '@hanzo/commerce'
|
8
|
-
|
9
|
-
import { Logo } from '../..'
|
10
|
-
import BagButton from '../bag-button'
|
11
|
-
import LinksRow from './links-row'
|
12
|
-
|
13
|
-
const MobileCheckoutPanel: React.FC<PropsWithChildren & {
|
14
|
-
index: number
|
15
|
-
stepNames: string[]
|
16
|
-
close:() => void
|
17
|
-
className?: string
|
18
|
-
}> = ({
|
19
|
-
index,
|
20
|
-
stepNames,
|
21
|
-
close,
|
22
|
-
className='',
|
23
|
-
children
|
24
|
-
}) => (
|
25
|
-
|
26
|
-
<div /* id='MOBILE_GRID' */ className={cn('bg-background flex flex-col justify-start px-4', className)}>
|
27
|
-
<div className='sticky top-0 w-full flex flex-row justify-between items-center bg-background'>
|
28
|
-
<Logo onClick={close} size='xs' href='/' />
|
29
|
-
{/* Need wrapper div since 'noLogin' returns null if no logged in user */}
|
30
|
-
<div className='w-10 h-10 flex items-center justify-center'><AuthWidget noLogin className=''/></div>
|
31
|
-
</div>
|
32
|
-
<CartAccordian
|
33
|
-
icon={
|
34
|
-
<BagButton
|
35
|
-
animateOnHover={false}
|
36
|
-
showIfEmpty
|
37
|
-
size='sm'
|
38
|
-
className='mr-1 relative w-5 h-6 sm:w-6 sm:h-7'
|
39
|
-
iconClx='fill-foreground'
|
40
|
-
/>
|
41
|
-
}
|
42
|
-
className='flex items-center justify-center w-full'
|
43
|
-
/>
|
44
|
-
<StepIndicator
|
45
|
-
dotSizeRem={1}
|
46
|
-
steps={stepNames}
|
47
|
-
currentStep={index}
|
48
|
-
className='text-xs font-semibold w-full pb-3'
|
49
|
-
/>
|
50
|
-
{children}
|
51
|
-
<LinksRow className='mt-auto mb-3 pt-2' />
|
52
|
-
</div>
|
53
|
-
)
|
54
|
-
|
55
|
-
export default MobileCheckoutPanel
|
File without changes
|
/package/components/commerce/{checkout-widget → _to_deprecate_checkout-widget}/obs-string-set.ts
RENAMED
File without changes
|
/package/components/commerce/{checkout-widget → _to_deprecate_checkout-widget}/use-anim-clx-set.ts
RENAMED
File without changes
|
/package/components/commerce/checkout-panel/{dt-bag-carousel.tsx → desktop-bag-carousel.tsx}
RENAMED
File without changes
|