@akinon/projectzero 2.0.0-beta.19 → 2.0.0-beta.20
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/CHANGELOG.md +9 -7
- package/app-template/CHANGELOG.md +251 -204
- package/app-template/akinon.json +1 -1
- package/app-template/package.json +28 -28
- package/app-template/public/amex.svg +12 -0
- package/app-template/public/apple-pay.svg +16 -0
- package/app-template/public/assets/images/product-placeholder-1.jpg +0 -0
- package/app-template/public/assets/images/product-placeholder-2.jpg +0 -0
- package/app-template/public/assets/images/product-placeholder-3.jpg +0 -0
- package/app-template/public/assets/images/product-placeholder-4.jpg +0 -0
- package/app-template/public/google-pay.svg +16 -0
- package/app-template/public/locales/en/account.json +6 -3
- package/app-template/public/locales/en/auth.json +6 -7
- package/app-template/public/locales/en/basket.json +6 -6
- package/app-template/public/locales/en/blog.json +7 -0
- package/app-template/public/locales/en/category.json +3 -1
- package/app-template/public/locales/en/checkout.json +5 -4
- package/app-template/public/locales/en/common.json +11 -2
- package/app-template/public/locales/en/forgot_password.json +6 -7
- package/app-template/public/locales/en/product.json +4 -3
- package/app-template/public/locales/tr/account.json +6 -3
- package/app-template/public/locales/tr/auth.json +16 -17
- package/app-template/public/locales/tr/basket.json +4 -4
- package/app-template/public/locales/tr/blog.json +7 -0
- package/app-template/public/locales/tr/category.json +3 -1
- package/app-template/public/locales/tr/checkout.json +39 -38
- package/app-template/public/locales/tr/common.json +10 -1
- package/app-template/public/locales/tr/forgot_password.json +12 -13
- package/app-template/public/locales/tr/product.json +1 -0
- package/app-template/public/logo.svg +3 -27
- package/app-template/public/mastercard.svg +14 -0
- package/app-template/public/promotion-banner.jpg +0 -0
- package/app-template/public/shop-pay.svg +12 -0
- package/app-template/public/visa.svg +12 -0
- package/app-template/src/app/[commerce]/[locale]/[currency]/blog/[slug]/page.tsx +118 -0
- package/app-template/src/app/[commerce]/[locale]/[currency]/pages/[slug]/page.tsx +15 -0
- package/app-template/src/app/api/theme-settings/route.ts +12 -0
- package/app-template/src/assets/fonts/pz-icon.css +211 -49
- package/app-template/src/assets/fonts/pz-icon.eot +0 -0
- package/app-template/src/assets/fonts/pz-icon.html +486 -0
- package/app-template/src/assets/fonts/pz-icon.scss +373 -49
- package/app-template/src/assets/fonts/pz-icon.svg +215 -53
- package/app-template/src/assets/fonts/pz-icon.ttf +0 -0
- package/app-template/src/assets/fonts/pz-icon.woff +0 -0
- package/app-template/src/assets/fonts/pz-icon.woff2 +0 -0
- package/app-template/src/assets/globals.scss +4 -0
- package/app-template/src/assets/icons/arrow-right.svg +3 -0
- package/app-template/src/assets/icons/cart.svg +4 -12
- package/app-template/src/assets/icons/check.svg +2 -18
- package/app-template/src/assets/icons/chevron-down.svg +2 -7
- package/app-template/src/assets/icons/delete.svg +3 -0
- package/app-template/src/assets/icons/facebook.svg +2 -8
- package/app-template/src/assets/icons/fav-off.svg +5 -0
- package/app-template/src/assets/icons/fav-on.svg +5 -0
- package/app-template/src/assets/icons/filter-and-sort.svg +3 -0
- package/app-template/src/assets/icons/heart.svg +3 -0
- package/app-template/src/assets/icons/instagram.svg +2 -13
- package/app-template/src/assets/icons/materials.svg +3 -0
- package/app-template/src/assets/icons/person.svg +4 -0
- package/app-template/src/assets/icons/pinterest.svg +5 -11
- package/app-template/src/assets/icons/ruler.svg +3 -0
- package/app-template/src/assets/icons/search.svg +8 -11
- package/app-template/src/assets/icons/share.svg +2 -9
- package/app-template/src/assets/icons/snapchat.svg +3 -0
- package/app-template/src/assets/icons/tiktok.svg +3 -0
- package/app-template/src/assets/icons/tumblr.svg +6 -0
- package/app-template/src/assets/icons/twitter.svg +2 -10
- package/app-template/src/assets/icons/vimeo.svg +3 -0
- package/app-template/src/assets/icons/youtube.svg +3 -0
- package/app-template/src/assets/icons/zoom.svg +8 -0
- package/app-template/src/components/accordion.tsx +33 -11
- package/app-template/src/components/action-tooltip.tsx +160 -0
- package/app-template/src/components/currency-select.tsx +149 -4
- package/app-template/src/components/icon.tsx +5 -6
- package/app-template/src/components/index.ts +4 -1
- package/app-template/src/components/language-select.tsx +88 -2
- package/app-template/src/components/pagination.tsx +132 -20
- package/app-template/src/components/quantity-input.tsx +63 -0
- package/app-template/src/components/quantity-selector.tsx +203 -0
- package/app-template/src/components/route-handler.tsx +50 -0
- package/app-template/src/components/select.tsx +89 -69
- package/app-template/src/components/types/index.ts +26 -0
- package/app-template/src/components/widget-content.tsx +323 -0
- package/app-template/src/data/server/theme.ts +70 -0
- package/app-template/src/hooks/use-fav-button.tsx +5 -2
- package/app-template/src/hooks/use-product-cart.ts +11 -8
- package/app-template/src/hooks/use-theme-settings.ts +42 -0
- package/app-template/src/lib/fonts.ts +149 -0
- package/app-template/src/settings.js +2 -2
- package/app-template/src/types/hookform-resolvers-yup.d.ts +28 -0
- package/app-template/src/types/widget.ts +169 -0
- package/app-template/src/utils/formatDate.ts +48 -0
- package/app-template/src/utils/styles.ts +71 -0
- package/app-template/src/views/account/contact-form.tsx +147 -130
- package/app-template/src/views/basket/basket-item.tsx +691 -107
- package/app-template/src/views/basket/basket-summary-context.tsx +560 -0
- package/app-template/src/views/basket/designer-context.tsx +617 -0
- package/app-template/src/views/basket/index.ts +2 -0
- package/app-template/src/views/basket/summary.tsx +496 -75
- package/app-template/src/views/breadcrumb/breadcrumb-client.tsx +190 -0
- package/app-template/src/views/breadcrumb/breadcrumb-registrar.tsx +286 -0
- package/app-template/src/views/breadcrumb/constants.ts +15 -0
- package/app-template/src/views/breadcrumb/index.tsx +127 -0
- package/app-template/src/views/breadcrumb.tsx +13 -38
- package/app-template/src/views/category/category-banner.tsx +4 -23
- package/app-template/src/views/category/category-header.tsx +289 -66
- package/app-template/src/views/category/category-info.tsx +173 -24
- package/app-template/src/views/category/filters/filter-item.tsx +138 -42
- package/app-template/src/views/category/filters/index.tsx +208 -48
- package/app-template/src/views/category/layout.tsx +7 -4
- package/app-template/src/views/category/native-widget-context.tsx +257 -0
- package/app-template/src/views/category/product-list-registrar.tsx +665 -0
- package/app-template/src/views/checkout/auth.tsx +64 -40
- package/app-template/src/views/checkout/checkout-address-registrar.tsx +254 -0
- package/app-template/src/views/checkout/checkout-buttons-registrar.tsx +183 -0
- package/app-template/src/views/checkout/checkout-delivery-method-registrar.tsx +259 -0
- package/app-template/src/views/checkout/checkout-payment-options-registrar.tsx +253 -0
- package/app-template/src/views/checkout/checkout-summary-registrar.tsx +183 -0
- package/app-template/src/views/checkout/constants.ts +5 -0
- package/app-template/src/views/checkout/index.tsx +5 -0
- package/app-template/src/views/checkout/layout/header.tsx +9 -5
- package/app-template/src/views/checkout/steps/payment/index.tsx +5 -2
- package/app-template/src/views/checkout/steps/payment/options/credit-card/index.tsx +72 -1
- package/app-template/src/views/checkout/steps/payment/options/masterpass-rest.tsx +15 -0
- package/app-template/src/views/checkout/steps/payment/options/saved-card.tsx +18 -0
- package/app-template/src/views/checkout/steps/payment/payment-option-buttons.tsx +171 -40
- package/app-template/src/views/checkout/steps/shipping/address-box.tsx +74 -12
- package/app-template/src/views/checkout/steps/shipping/addresses.tsx +128 -45
- package/app-template/src/views/checkout/steps/shipping/shipping-options.tsx +232 -27
- package/app-template/src/views/checkout/summary.tsx +303 -29
- package/app-template/src/views/footer/footer-app-banner-context.tsx +326 -0
- package/app-template/src/views/footer/footer-bottom-context.tsx +215 -0
- package/app-template/src/views/footer/footer-bottom-wrapper.tsx +74 -0
- package/app-template/src/views/footer/footer-layout-constants.ts +35 -0
- package/app-template/src/views/footer/footer-layout-registrar.tsx +342 -0
- package/app-template/src/views/footer/footer-layout-switcher.tsx +110 -0
- package/app-template/src/views/footer/footer-menu-context.tsx +211 -0
- package/app-template/src/views/footer/footer-native-widgets.tsx +60 -0
- package/app-template/src/views/footer/footer-social-context.tsx +254 -0
- package/app-template/src/views/footer/footer-subscription-context.tsx +210 -0
- package/app-template/src/views/footer/footer-utils.ts +43 -0
- package/app-template/src/views/footer/footer-value-props-context.tsx +326 -0
- package/app-template/src/views/footer/logo-settings.ts +183 -0
- package/app-template/src/views/footer/native-widget-config.ts +262 -0
- package/app-template/src/views/footer/subscription-settings.ts +122 -0
- package/app-template/src/views/footer/use-footer-logo.ts +162 -0
- package/app-template/src/views/footer.tsx +415 -13
- package/app-template/src/views/guest-login/index.tsx +62 -58
- package/app-template/src/views/header/action-menu.tsx +277 -45
- package/app-template/src/views/header/band.tsx +6 -21
- package/app-template/src/views/header/designer-context.tsx +261 -0
- package/app-template/src/views/header/header-announcement-registrar.tsx +267 -0
- package/app-template/src/views/header/header-client-wrapper.tsx +496 -0
- package/app-template/src/views/header/header-content.tsx +1026 -0
- package/app-template/src/views/header/header-currency-registrar.tsx +348 -0
- package/app-template/src/views/header/header-icons-context.tsx +262 -0
- package/app-template/src/views/header/header-language-registrar.tsx +348 -0
- package/app-template/src/views/header/header-layout-context.tsx +143 -0
- package/app-template/src/views/header/header-layout-registrar.tsx +658 -0
- package/app-template/src/views/header/header-logo-context.tsx +228 -0
- package/app-template/src/views/header/header-logo.tsx +118 -0
- package/app-template/src/views/header/header-mini-basket-context.tsx +524 -0
- package/app-template/src/views/header/header-search-registrar.tsx +511 -0
- package/app-template/src/views/header/header-text-slider-registrar.tsx +382 -0
- package/app-template/src/views/header/index.tsx +109 -47
- package/app-template/src/views/header/inline-search.tsx +262 -0
- package/app-template/src/views/header/mini-basket.tsx +819 -44
- package/app-template/src/views/header/mobile-hamburger-button.tsx +5 -8
- package/app-template/src/views/header/mobile-menu.tsx +12 -0
- package/app-template/src/views/header/navbar-menu-context.tsx +219 -0
- package/app-template/src/views/header/navbar.tsx +178 -111
- package/app-template/src/views/header/search/index.tsx +71 -32
- package/app-template/src/views/header/search/results.tsx +127 -65
- package/app-template/src/views/header/search/search-input.tsx +61 -0
- package/app-template/src/views/header/server-settings-parser.ts +1105 -0
- package/app-template/src/views/header/use-header-icons.ts +241 -0
- package/app-template/src/views/header/use-header-logo.ts +213 -0
- package/app-template/src/views/header/use-navbar-menu.ts +179 -0
- package/app-template/src/views/login/index.tsx +54 -46
- package/app-template/src/views/product/accordion-section.tsx +61 -0
- package/app-template/src/views/product/accordion-wrapper.tsx +135 -43
- package/app-template/src/views/product/custom-button-group.tsx +69 -0
- package/app-template/src/views/product/favorites-button-section.tsx +69 -0
- package/app-template/src/views/product/find-in-store-section.tsx +60 -0
- package/app-template/src/views/product/index.ts +1 -0
- package/app-template/src/views/product/layout.tsx +6 -5
- package/app-template/src/views/product/misc-buttons.tsx +339 -25
- package/app-template/src/views/product/price-wrapper.tsx +3 -29
- package/app-template/src/views/product/product-actions.tsx +137 -8
- package/app-template/src/views/product/product-info-section.tsx +140 -0
- package/app-template/src/views/product/product-info.tsx +69 -31
- package/app-template/src/views/product/product-share.tsx +13 -8
- package/app-template/src/views/product/product-variants.tsx +2 -2
- package/app-template/src/views/product/quantity-section.tsx +73 -0
- package/app-template/src/views/product/sale-tag.tsx +10 -0
- package/app-template/src/views/product/share-section.tsx +357 -0
- package/app-template/src/views/product/slider.tsx +117 -79
- package/app-template/src/views/product/variant.tsx +69 -41
- package/app-template/src/views/product/variants-section.tsx +126 -0
- package/app-template/src/views/product-detail/constants.ts +272 -0
- package/app-template/src/views/product-detail/index.ts +10 -0
- package/app-template/src/views/product-detail/product-detail-registrar.tsx +616 -0
- package/app-template/src/views/product-item/index.tsx +119 -46
- package/app-template/src/views/register/index.tsx +14 -25
- package/app-template/src/views/share/index.tsx +9 -6
- package/app-template/src/views/widgets/home-hero-slider-content.tsx +41 -39
- package/app-template/src/widgets/flatpages/about-us/index.tsx +78 -0
- package/app-template/src/widgets/flatpages/blog-list/index.tsx +129 -0
- package/app-template/src/widgets/footer-app-banner.tsx +444 -0
- package/app-template/src/widgets/footer-bottom.tsx +127 -0
- package/app-template/src/widgets/footer-menu-compact.tsx +238 -0
- package/app-template/src/widgets/footer-menu-two.tsx +298 -0
- package/app-template/src/widgets/footer-social-client.tsx +251 -0
- package/app-template/src/widgets/footer-social.tsx +47 -16
- package/app-template/src/widgets/footer-subscription/footer-subscription-form.tsx +17 -14
- package/app-template/src/widgets/footer-subscription/index.tsx +183 -17
- package/app-template/src/widgets/footer-value-props.tsx +201 -0
- package/app-template/src/widgets/index.ts +7 -0
- package/app-template/src/widgets/schemas/about-us.json +46 -0
- package/app-template/src/widgets/schemas/blog-list.json +37 -0
- package/app-template/src/widgets/schemas/blog.json +29 -0
- package/app-template/tailwind.config.js +18 -2
- package/package.json +1 -1
|
@@ -19,15 +19,44 @@ import {
|
|
|
19
19
|
} from '@akinon/next/hooks';
|
|
20
20
|
import { Image } from '@akinon/next/components/image';
|
|
21
21
|
import { pushRemoveFromCart } from '@theme/utils/gtm';
|
|
22
|
+
import {
|
|
23
|
+
useHeaderMiniBasket,
|
|
24
|
+
HEADER_MINI_BASKET_PLACEHOLDER_ID,
|
|
25
|
+
HEADER_MINI_BASKET_SECTION_ID
|
|
26
|
+
} from './header-mini-basket-context';
|
|
22
27
|
|
|
23
28
|
interface MiniBasketItemProps {
|
|
24
29
|
basketItem: BasketItem;
|
|
25
30
|
highlightedItem: number;
|
|
26
31
|
miniBasketListRef: MutableRefObject<HTMLUListElement>;
|
|
32
|
+
isDesigner?: boolean;
|
|
33
|
+
selectedBlockId?: string;
|
|
34
|
+
onBlockClick?: (blockId: string, e?: React.MouseEvent) => void;
|
|
35
|
+
itemStyles?: React.CSSProperties;
|
|
36
|
+
imageStyles?: React.CSSProperties;
|
|
37
|
+
nameStyles?: React.CSSProperties;
|
|
38
|
+
priceStyles?: React.CSSProperties;
|
|
39
|
+
removeButtonStyles?: React.CSSProperties;
|
|
40
|
+
removeButtonContent?: string;
|
|
41
|
+
attributeStyles?: React.CSSProperties;
|
|
27
42
|
}
|
|
28
43
|
|
|
29
44
|
function MiniBasketItem(props: MiniBasketItemProps) {
|
|
30
|
-
const {
|
|
45
|
+
const {
|
|
46
|
+
basketItem,
|
|
47
|
+
highlightedItem,
|
|
48
|
+
miniBasketListRef,
|
|
49
|
+
isDesigner = false,
|
|
50
|
+
selectedBlockId = '',
|
|
51
|
+
onBlockClick,
|
|
52
|
+
itemStyles,
|
|
53
|
+
imageStyles,
|
|
54
|
+
nameStyles,
|
|
55
|
+
priceStyles,
|
|
56
|
+
removeButtonStyles,
|
|
57
|
+
removeButtonContent,
|
|
58
|
+
attributeStyles
|
|
59
|
+
} = props;
|
|
31
60
|
const dispatch = useAppDispatch();
|
|
32
61
|
const [updateQuantityMutation] = useUpdateQuantityMutation();
|
|
33
62
|
const commonProductAttributes = useCommonProductAttributes({
|
|
@@ -71,24 +100,63 @@ function MiniBasketItem(props: MiniBasketItemProps) {
|
|
|
71
100
|
});
|
|
72
101
|
};
|
|
73
102
|
|
|
103
|
+
const imageWidth = imageStyles?.width
|
|
104
|
+
? parseInt(String(imageStyles.width))
|
|
105
|
+
: isHighlighted
|
|
106
|
+
? 96
|
|
107
|
+
: 48;
|
|
108
|
+
const imageHeight = imageStyles?.height
|
|
109
|
+
? parseInt(String(imageStyles.height))
|
|
110
|
+
: isHighlighted
|
|
111
|
+
? 160
|
|
112
|
+
: 80;
|
|
113
|
+
|
|
74
114
|
return (
|
|
75
115
|
<li
|
|
76
|
-
style={{
|
|
77
|
-
|
|
116
|
+
style={{
|
|
117
|
+
order: isHighlighted ? '-1' : '0',
|
|
118
|
+
...itemStyles
|
|
119
|
+
}}
|
|
120
|
+
className={clsx(
|
|
121
|
+
'flex gap-3 py-4 border-b border-gray-500 relative',
|
|
122
|
+
isDesigner &&
|
|
123
|
+
selectedBlockId === 'mini-basket-item' &&
|
|
124
|
+
'ring-2 ring-blue-500 ring-inset',
|
|
125
|
+
isDesigner &&
|
|
126
|
+
'cursor-pointer hover:ring-2 hover:ring-blue-300 hover:ring-inset'
|
|
127
|
+
)}
|
|
128
|
+
onClick={(e) => isDesigner && onBlockClick?.('mini-basket-item', e)}
|
|
78
129
|
>
|
|
79
130
|
<Link
|
|
80
131
|
href={basketItem.product.absolute_url}
|
|
81
132
|
className={clsx(
|
|
82
|
-
'block shrink-0 transition-all duration-300',
|
|
83
|
-
isHighlighted ? 'w-24
|
|
133
|
+
'block shrink-0 transition-all duration-300 relative',
|
|
134
|
+
imageWidth ? `w-[${imageWidth}px] ` : isHighlighted ? 'w-24' : 'w-12',
|
|
135
|
+
imageHeight
|
|
136
|
+
? `h-[${imageHeight}px]`
|
|
137
|
+
: isHighlighted
|
|
138
|
+
? 'h-40'
|
|
139
|
+
: 'h-20',
|
|
140
|
+
isDesigner &&
|
|
141
|
+
selectedBlockId === 'mini-basket-item-image' &&
|
|
142
|
+
'ring-2 ring-blue-500 ring-inset',
|
|
143
|
+
isDesigner &&
|
|
144
|
+
'cursor-pointer hover:ring-2 hover:ring-blue-300 hover:ring-inset'
|
|
84
145
|
)}
|
|
146
|
+
onClick={(e) => {
|
|
147
|
+
if (isDesigner) {
|
|
148
|
+
e.preventDefault();
|
|
149
|
+
onBlockClick?.('mini-basket-item-image', e);
|
|
150
|
+
}
|
|
151
|
+
}}
|
|
85
152
|
>
|
|
86
153
|
<Image
|
|
87
154
|
src={basketItem.product.productimage_set?.[0]?.image ?? ''}
|
|
88
155
|
alt={basketItem.product.name}
|
|
89
|
-
width={
|
|
90
|
-
height={
|
|
156
|
+
width={imageWidth}
|
|
157
|
+
height={imageHeight}
|
|
91
158
|
className="transition-all duration-300"
|
|
159
|
+
style={imageStyles}
|
|
92
160
|
/>
|
|
93
161
|
</Link>
|
|
94
162
|
<div className="flex flex-col flex-1">
|
|
@@ -107,8 +175,22 @@ function MiniBasketItem(props: MiniBasketItemProps) {
|
|
|
107
175
|
</div>
|
|
108
176
|
<Link
|
|
109
177
|
href={basketItem.product.absolute_url}
|
|
110
|
-
className=
|
|
178
|
+
className={clsx(
|
|
179
|
+
'block relative',
|
|
180
|
+
isDesigner &&
|
|
181
|
+
selectedBlockId === 'mini-basket-item-name' &&
|
|
182
|
+
'ring-2 ring-blue-500 ring-inset',
|
|
183
|
+
isDesigner &&
|
|
184
|
+
'cursor-pointer hover:ring-2 hover:ring-blue-300 hover:ring-inset'
|
|
185
|
+
)}
|
|
111
186
|
data-testid="mini-basket-item-name"
|
|
187
|
+
style={nameStyles}
|
|
188
|
+
onClick={(e) => {
|
|
189
|
+
if (isDesigner) {
|
|
190
|
+
e.preventDefault();
|
|
191
|
+
onBlockClick?.('mini-basket-item-name', e);
|
|
192
|
+
}
|
|
193
|
+
}}
|
|
112
194
|
>
|
|
113
195
|
{basketItem.product.name}
|
|
114
196
|
{/* TODO: Get correct variants */}
|
|
@@ -116,7 +198,19 @@ function MiniBasketItem(props: MiniBasketItemProps) {
|
|
|
116
198
|
{commonProductAttributes.map((attribute, index) => (
|
|
117
199
|
<span
|
|
118
200
|
key={index}
|
|
201
|
+
className={clsx(
|
|
202
|
+
'relative',
|
|
203
|
+
isDesigner &&
|
|
204
|
+
selectedBlockId === 'mini-basket-item-attribute' &&
|
|
205
|
+
'ring-2 ring-blue-500 ring-inset',
|
|
206
|
+
isDesigner &&
|
|
207
|
+
'cursor-pointer hover:ring-2 hover:ring-blue-300 hover:ring-inset'
|
|
208
|
+
)}
|
|
119
209
|
data-testid={`mini-basket-item-${attribute.name.toLowerCase()}`}
|
|
210
|
+
style={attributeStyles}
|
|
211
|
+
onClick={(e) =>
|
|
212
|
+
isDesigner && onBlockClick?.('mini-basket-item-attribute', e)
|
|
213
|
+
}
|
|
120
214
|
>
|
|
121
215
|
{attribute.name}: {attribute.value}
|
|
122
216
|
</span>
|
|
@@ -129,16 +223,43 @@ function MiniBasketItem(props: MiniBasketItemProps) {
|
|
|
129
223
|
className="line-through"
|
|
130
224
|
/>
|
|
131
225
|
)}
|
|
132
|
-
<
|
|
226
|
+
<div
|
|
227
|
+
className={clsx(
|
|
228
|
+
'relative',
|
|
229
|
+
isDesigner &&
|
|
230
|
+
selectedBlockId === 'mini-basket-item-price' &&
|
|
231
|
+
'ring-2 ring-blue-500 ring-inset',
|
|
232
|
+
isDesigner &&
|
|
233
|
+
'cursor-pointer hover:ring-2 hover:ring-blue-300 hover:ring-inset'
|
|
234
|
+
)}
|
|
235
|
+
onClick={(e) =>
|
|
236
|
+
isDesigner && onBlockClick?.('mini-basket-item-price', e)
|
|
237
|
+
}
|
|
238
|
+
>
|
|
239
|
+
<Price value={basketItem.total_amount} style={priceStyles} />
|
|
240
|
+
</div>
|
|
133
241
|
<Button
|
|
134
242
|
appearance="ghost"
|
|
135
243
|
className={clsx(
|
|
136
|
-
'
|
|
137
|
-
isHighlighted ? 'invisible' : 'visible'
|
|
244
|
+
'transition-all duration-300 relative',
|
|
245
|
+
isHighlighted ? 'invisible' : 'visible',
|
|
246
|
+
isDesigner &&
|
|
247
|
+
selectedBlockId === 'mini-basket-item-remove-button' &&
|
|
248
|
+
'ring-2 ring-blue-500 ring-inset',
|
|
249
|
+
isDesigner &&
|
|
250
|
+
'cursor-pointer hover:ring-2 hover:ring-blue-300 hover:ring-inset'
|
|
138
251
|
)}
|
|
139
|
-
|
|
252
|
+
style={removeButtonStyles}
|
|
253
|
+
onClick={(e) => {
|
|
254
|
+
if (isDesigner) {
|
|
255
|
+
e.stopPropagation();
|
|
256
|
+
onBlockClick?.('mini-basket-item-remove-button', e);
|
|
257
|
+
} else {
|
|
258
|
+
removeItem();
|
|
259
|
+
}
|
|
260
|
+
}}
|
|
140
261
|
>
|
|
141
|
-
{t('basket.mini_basket.remove')}
|
|
262
|
+
{removeButtonContent || t('basket.mini_basket.remove')}
|
|
142
263
|
</Button>
|
|
143
264
|
</footer>
|
|
144
265
|
</div>
|
|
@@ -147,10 +268,38 @@ function MiniBasketItem(props: MiniBasketItemProps) {
|
|
|
147
268
|
}
|
|
148
269
|
|
|
149
270
|
export default function MiniBasket() {
|
|
271
|
+
const {
|
|
272
|
+
isDesigner,
|
|
273
|
+
isSectionSelected,
|
|
274
|
+
selectedBlockId,
|
|
275
|
+
getSectionStyles,
|
|
276
|
+
getSectionProperties,
|
|
277
|
+
getBlockData
|
|
278
|
+
} = useHeaderMiniBasket();
|
|
150
279
|
const { open: miniBasketOpen } = useAppSelector(
|
|
151
280
|
(state) => state.root.miniBasket
|
|
152
281
|
);
|
|
153
282
|
const dispatch = useAppDispatch();
|
|
283
|
+
|
|
284
|
+
const handleBlockClick = (blockId: string, e?: React.MouseEvent) => {
|
|
285
|
+
if (!isDesigner) return;
|
|
286
|
+
e?.stopPropagation();
|
|
287
|
+
|
|
288
|
+
if (typeof window !== 'undefined' && window.parent) {
|
|
289
|
+
window.parent.postMessage(
|
|
290
|
+
{
|
|
291
|
+
type: 'SELECT_BLOCK_FROM_PREVIEW',
|
|
292
|
+
data: {
|
|
293
|
+
placeholderId: HEADER_MINI_BASKET_PLACEHOLDER_ID,
|
|
294
|
+
sectionId: HEADER_MINI_BASKET_SECTION_ID,
|
|
295
|
+
blockId
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
'*'
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
|
|
154
303
|
const {
|
|
155
304
|
data: basket,
|
|
156
305
|
isLoading,
|
|
@@ -159,15 +308,462 @@ export default function MiniBasket() {
|
|
|
159
308
|
skip: !miniBasketOpen
|
|
160
309
|
});
|
|
161
310
|
const { data: miniBasket } = useGetMiniBasketQuery();
|
|
162
|
-
const { t } = useLocalization();
|
|
311
|
+
const { t, locale } = useLocalization();
|
|
163
312
|
const { highlightedItem } = useAppSelector((state) => state.root.miniBasket);
|
|
164
313
|
const [highlightedItemPk, setHighlightedItemPk] = useState(0);
|
|
165
314
|
const [sortedBasket, setSortedBasket] = useState([]);
|
|
315
|
+
const [isMobile, setIsMobile] = useState(false);
|
|
316
|
+
|
|
317
|
+
useEffect(() => {
|
|
318
|
+
const checkMobile = () => {
|
|
319
|
+
setIsMobile(window.innerWidth < 1024);
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
checkMobile();
|
|
323
|
+
|
|
324
|
+
window.addEventListener('resize', checkMobile);
|
|
325
|
+
return () => window.removeEventListener('resize', checkMobile);
|
|
326
|
+
}, []);
|
|
327
|
+
|
|
328
|
+
const sectionStyles = getSectionStyles();
|
|
329
|
+
const sectionProperties = getSectionProperties();
|
|
330
|
+
|
|
331
|
+
const positionProp = sectionProperties?.position;
|
|
332
|
+
const position =
|
|
333
|
+
typeof positionProp === 'object' && positionProp !== null
|
|
334
|
+
? (positionProp as { desktop?: string }).desktop || 'right'
|
|
335
|
+
: (positionProp as string) || 'right';
|
|
336
|
+
|
|
337
|
+
const headerBlock = getBlockData('mini-basket-header');
|
|
338
|
+
const footerBlock = getBlockData('mini-basket-footer');
|
|
339
|
+
const titleBlock = getBlockData('mini-basket-title');
|
|
340
|
+
const itemCountBlock = getBlockData('mini-basket-item-count');
|
|
341
|
+
const closeIconBlock = getBlockData('mini-basket-close-icon');
|
|
342
|
+
const listBlock = getBlockData('mini-basket-list');
|
|
343
|
+
const itemBlock = getBlockData('mini-basket-item');
|
|
344
|
+
const itemImageBlock = getBlockData('mini-basket-item-image');
|
|
345
|
+
const itemNameBlock = getBlockData('mini-basket-item-name');
|
|
346
|
+
const itemPriceBlock = getBlockData('mini-basket-item-price');
|
|
347
|
+
const itemRemoveButtonBlock = getBlockData('mini-basket-item-remove-button');
|
|
348
|
+
const itemAttributeBlock = getBlockData('mini-basket-item-attribute');
|
|
349
|
+
const subtotalBlock = getBlockData('mini-basket-subtotal');
|
|
350
|
+
const viewBagButtonBlock = getBlockData('mini-basket-view-bag-button');
|
|
351
|
+
const continueShoppingButtonBlock = getBlockData(
|
|
352
|
+
'mini-basket-continue-shopping-button'
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
const getBlockContent = (block: any, fallback: string): string => {
|
|
356
|
+
if (!block) return fallback;
|
|
357
|
+
|
|
358
|
+
if (block.value) {
|
|
359
|
+
if (typeof block.value === 'string') {
|
|
360
|
+
return block.value;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (typeof block.value === 'object' && block.value[locale]) {
|
|
364
|
+
return block.value[locale];
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (typeof block.value === 'object') {
|
|
368
|
+
return block.value.en || Object.values(block.value)[0] || fallback;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (block.properties?.content) {
|
|
373
|
+
return block.properties.content;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return fallback;
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
const getResponsiveValue = (
|
|
380
|
+
value: any,
|
|
381
|
+
device: 'mobile' | 'desktop' = 'desktop'
|
|
382
|
+
): string => {
|
|
383
|
+
if (typeof value === 'object' && value !== null) {
|
|
384
|
+
return String(value[device] || value.desktop || value.mobile || '');
|
|
385
|
+
}
|
|
386
|
+
return String(value || '');
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
const convertStylesToCSS = (
|
|
390
|
+
styles: Record<string, unknown> | undefined,
|
|
391
|
+
device: 'mobile' | 'desktop' = 'desktop'
|
|
392
|
+
): React.CSSProperties => {
|
|
393
|
+
if (!styles) return {};
|
|
394
|
+
|
|
395
|
+
const cssStyles: React.CSSProperties = {};
|
|
396
|
+
Object.entries(styles).forEach(([key, value]) => {
|
|
397
|
+
const cssValue = getResponsiveValue(value, device);
|
|
398
|
+
const camelKey = key.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
399
|
+
if (cssValue) {
|
|
400
|
+
(cssStyles as any)[camelKey] = cssValue;
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
return cssStyles;
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
const sectionCSSStylesMobile = convertStylesToCSS(sectionStyles, 'mobile');
|
|
407
|
+
const sectionCSSStylesDesktop = convertStylesToCSS(sectionStyles, 'desktop');
|
|
408
|
+
const headerCSSStylesMobile = convertStylesToCSS(
|
|
409
|
+
headerBlock?.styles,
|
|
410
|
+
'mobile'
|
|
411
|
+
);
|
|
412
|
+
const headerCSSStylesDesktop = convertStylesToCSS(
|
|
413
|
+
headerBlock?.styles,
|
|
414
|
+
'desktop'
|
|
415
|
+
);
|
|
416
|
+
const footerCSSStylesMobile = convertStylesToCSS(
|
|
417
|
+
footerBlock?.styles,
|
|
418
|
+
'mobile'
|
|
419
|
+
);
|
|
420
|
+
const footerCSSStylesDesktop = convertStylesToCSS(
|
|
421
|
+
footerBlock?.styles,
|
|
422
|
+
'desktop'
|
|
423
|
+
);
|
|
424
|
+
const titleCSSStylesMobile = convertStylesToCSS(titleBlock?.styles, 'mobile');
|
|
425
|
+
const titleCSSStylesDesktop = convertStylesToCSS(
|
|
426
|
+
titleBlock?.styles,
|
|
427
|
+
'desktop'
|
|
428
|
+
);
|
|
429
|
+
const itemCountCSSStylesMobile = convertStylesToCSS(
|
|
430
|
+
itemCountBlock?.styles,
|
|
431
|
+
'mobile'
|
|
432
|
+
);
|
|
433
|
+
|
|
434
|
+
const itemCountCSSStylesDesktop = convertStylesToCSS(
|
|
435
|
+
itemCountBlock?.styles,
|
|
436
|
+
'desktop'
|
|
437
|
+
);
|
|
438
|
+
|
|
439
|
+
const closeIconCSSStylesMobile = convertStylesToCSS(
|
|
440
|
+
closeIconBlock?.styles,
|
|
441
|
+
'mobile'
|
|
442
|
+
);
|
|
443
|
+
const closeIconCSSStylesDesktop = convertStylesToCSS(
|
|
444
|
+
closeIconBlock?.styles,
|
|
445
|
+
'desktop'
|
|
446
|
+
);
|
|
447
|
+
|
|
448
|
+
const listCSSStylesMobile = convertStylesToCSS(listBlock?.styles, 'mobile');
|
|
449
|
+
const listCSSStylesDesktop = convertStylesToCSS(listBlock?.styles, 'desktop');
|
|
450
|
+
const itemCSSStylesMobile = convertStylesToCSS(itemBlock?.styles, 'mobile');
|
|
451
|
+
const itemCSSStylesDesktop = convertStylesToCSS(itemBlock?.styles, 'desktop');
|
|
452
|
+
const itemImageCSSStylesMobile = convertStylesToCSS(
|
|
453
|
+
itemImageBlock?.styles,
|
|
454
|
+
'mobile'
|
|
455
|
+
);
|
|
456
|
+
const itemImageCSSStylesDesktop = convertStylesToCSS(
|
|
457
|
+
itemImageBlock?.styles,
|
|
458
|
+
'desktop'
|
|
459
|
+
);
|
|
460
|
+
const itemNameCSSStylesMobile = convertStylesToCSS(
|
|
461
|
+
itemNameBlock?.styles,
|
|
462
|
+
'mobile'
|
|
463
|
+
);
|
|
464
|
+
const itemNameCSSStylesDesktop = convertStylesToCSS(
|
|
465
|
+
itemNameBlock?.styles,
|
|
466
|
+
'desktop'
|
|
467
|
+
);
|
|
468
|
+
const itemPriceCSSStylesMobile = convertStylesToCSS(
|
|
469
|
+
itemPriceBlock?.styles,
|
|
470
|
+
'mobile'
|
|
471
|
+
);
|
|
472
|
+
const itemPriceCSSStylesDesktop = convertStylesToCSS(
|
|
473
|
+
itemPriceBlock?.styles,
|
|
474
|
+
'desktop'
|
|
475
|
+
);
|
|
476
|
+
const itemRemoveButtonCSSStylesMobile = convertStylesToCSS(
|
|
477
|
+
itemRemoveButtonBlock?.styles,
|
|
478
|
+
'mobile'
|
|
479
|
+
);
|
|
480
|
+
const itemRemoveButtonCSSStylesDesktop = convertStylesToCSS(
|
|
481
|
+
itemRemoveButtonBlock?.styles,
|
|
482
|
+
'desktop'
|
|
483
|
+
);
|
|
484
|
+
const itemAttributeCSSStylesMobile = convertStylesToCSS(
|
|
485
|
+
itemAttributeBlock?.styles,
|
|
486
|
+
'mobile'
|
|
487
|
+
);
|
|
488
|
+
const itemAttributeCSSStylesDesktop = convertStylesToCSS(
|
|
489
|
+
itemAttributeBlock?.styles,
|
|
490
|
+
'desktop'
|
|
491
|
+
);
|
|
492
|
+
const subtotalCSSStylesMobile = convertStylesToCSS(
|
|
493
|
+
subtotalBlock?.styles,
|
|
494
|
+
'mobile'
|
|
495
|
+
);
|
|
496
|
+
const subtotalCSSStylesDesktop = convertStylesToCSS(
|
|
497
|
+
subtotalBlock?.styles,
|
|
498
|
+
'desktop'
|
|
499
|
+
);
|
|
500
|
+
const viewBagButtonCSSStylesMobile = convertStylesToCSS(
|
|
501
|
+
viewBagButtonBlock?.styles,
|
|
502
|
+
'mobile'
|
|
503
|
+
);
|
|
504
|
+
const viewBagButtonCSSStylesDesktop = convertStylesToCSS(
|
|
505
|
+
viewBagButtonBlock?.styles,
|
|
506
|
+
'desktop'
|
|
507
|
+
);
|
|
508
|
+
const continueShoppingButtonCSSStylesMobile = convertStylesToCSS(
|
|
509
|
+
continueShoppingButtonBlock?.styles,
|
|
510
|
+
'mobile'
|
|
511
|
+
);
|
|
512
|
+
const continueShoppingButtonCSSStylesDesktop = convertStylesToCSS(
|
|
513
|
+
continueShoppingButtonBlock?.styles,
|
|
514
|
+
'desktop'
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
// Default styles for mini basket section (mobile)
|
|
518
|
+
const defaultSectionStylesMobile: React.CSSProperties = {
|
|
519
|
+
width: '100vw',
|
|
520
|
+
height: '100vh',
|
|
521
|
+
backgroundColor: '#ffffff',
|
|
522
|
+
borderLeftWidth: '0',
|
|
523
|
+
borderTopWidth: '0',
|
|
524
|
+
borderRightWidth: '0',
|
|
525
|
+
borderBottomWidth: '0',
|
|
526
|
+
borderStyle: 'solid',
|
|
527
|
+
padding: '20px',
|
|
528
|
+
zIndex: 50
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
// Default styles for mini basket section (desktop) based on position
|
|
532
|
+
const getPositionStyles = (): React.CSSProperties => {
|
|
533
|
+
switch (position) {
|
|
534
|
+
case 'left':
|
|
535
|
+
return {
|
|
536
|
+
position: 'absolute',
|
|
537
|
+
top: '100%',
|
|
538
|
+
left: '0',
|
|
539
|
+
right: 'auto'
|
|
540
|
+
};
|
|
541
|
+
case 'bottom':
|
|
542
|
+
return {
|
|
543
|
+
position: 'fixed',
|
|
544
|
+
bottom: '0',
|
|
545
|
+
left: '50%',
|
|
546
|
+
transform: 'translateX(-50%)',
|
|
547
|
+
top: 'auto',
|
|
548
|
+
right: 'auto',
|
|
549
|
+
width: '100%',
|
|
550
|
+
maxWidth: '600px'
|
|
551
|
+
};
|
|
552
|
+
case 'right':
|
|
553
|
+
default:
|
|
554
|
+
return {
|
|
555
|
+
position: 'absolute',
|
|
556
|
+
top: '100%',
|
|
557
|
+
right: '0',
|
|
558
|
+
left: 'auto'
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
const defaultSectionStylesDesktop: React.CSSProperties = {
|
|
564
|
+
width: '320px',
|
|
565
|
+
height: 'max-content',
|
|
566
|
+
maxHeight: '600px',
|
|
567
|
+
backgroundColor: '#ffffff',
|
|
568
|
+
borderLeftWidth: '1px',
|
|
569
|
+
borderTopWidth: '1px',
|
|
570
|
+
borderRightWidth: '2px',
|
|
571
|
+
borderBottomWidth: '2px',
|
|
572
|
+
borderColor: '#6b7280',
|
|
573
|
+
borderStyle: 'solid',
|
|
574
|
+
padding: '20px',
|
|
575
|
+
zIndex: 50,
|
|
576
|
+
...getPositionStyles()
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
// For mobile: merge mobile defaults with mobile theme styles
|
|
580
|
+
// But don't allow theme editor to override height - we need 100vh for full screen
|
|
581
|
+
const { height: _mobileHeight, ...sectionCSSStylesMobileWithoutHeight } =
|
|
582
|
+
sectionCSSStylesMobile;
|
|
583
|
+
const finalSectionStylesMobile = {
|
|
584
|
+
...defaultSectionStylesMobile,
|
|
585
|
+
...sectionCSSStylesMobileWithoutHeight
|
|
586
|
+
};
|
|
587
|
+
const finalHeaderStylesMobile = { ...headerCSSStylesMobile };
|
|
588
|
+
const finalFooterStylesMobile = { ...footerCSSStylesMobile };
|
|
589
|
+
const finalTitleStylesMobile = { ...titleCSSStylesMobile };
|
|
590
|
+
const finalItemCountStylesMobile = { ...itemCountCSSStylesMobile };
|
|
591
|
+
const finalCloseIconStylesMobile = { ...closeIconCSSStylesMobile };
|
|
592
|
+
const finalListStylesMobile = { ...listCSSStylesMobile };
|
|
593
|
+
const finalItemStylesMobile = { ...itemCSSStylesMobile };
|
|
594
|
+
const finalItemImageStylesMobile = { ...itemImageCSSStylesMobile };
|
|
595
|
+
const finalItemNameStylesMobile = { ...itemNameCSSStylesMobile };
|
|
596
|
+
const finalItemPriceStylesMobile = { ...itemPriceCSSStylesMobile };
|
|
597
|
+
const finalItemRemoveButtonStylesMobile = {
|
|
598
|
+
...itemRemoveButtonCSSStylesMobile
|
|
599
|
+
};
|
|
600
|
+
const finalItemAttributeStylesMobile = { ...itemAttributeCSSStylesMobile };
|
|
601
|
+
const finalSubtotalStylesMobile = { ...subtotalCSSStylesMobile };
|
|
602
|
+
const finalViewBagButtonStylesMobile = {
|
|
603
|
+
width: '100%',
|
|
604
|
+
display: 'flex',
|
|
605
|
+
alignItems: 'center',
|
|
606
|
+
justifyContent: 'center',
|
|
607
|
+
backgroundColor: 'var(--primary)',
|
|
608
|
+
color: 'var(--primary-foreground)',
|
|
609
|
+
borderWidth: '1px',
|
|
610
|
+
borderStyle: 'solid',
|
|
611
|
+
borderColor: 'var(--primary)',
|
|
612
|
+
height: '32px',
|
|
613
|
+
fontWeight: '600',
|
|
614
|
+
transition: 'all',
|
|
615
|
+
...viewBagButtonCSSStylesMobile
|
|
616
|
+
};
|
|
617
|
+
const finalContinueShoppingButtonStylesMobile = {
|
|
618
|
+
height: 'auto',
|
|
619
|
+
padding: '0',
|
|
620
|
+
fontWeight: '600',
|
|
621
|
+
textDecoration: 'underline',
|
|
622
|
+
alignSelf: 'center',
|
|
623
|
+
...continueShoppingButtonCSSStylesMobile
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
// For desktop: merge desktop defaults with desktop theme styles
|
|
627
|
+
// But don't allow theme editor to override height - we need max-content for dropdown
|
|
628
|
+
const { height: _desktopHeight, ...sectionCSSStylesDesktopWithoutHeight } =
|
|
629
|
+
sectionCSSStylesDesktop;
|
|
630
|
+
const finalSectionStylesDesktop = {
|
|
631
|
+
...defaultSectionStylesDesktop,
|
|
632
|
+
...sectionCSSStylesDesktopWithoutHeight
|
|
633
|
+
};
|
|
634
|
+
const finalHeaderStylesDesktop = { ...headerCSSStylesDesktop };
|
|
635
|
+
const finalFooterStylesDesktop = { ...footerCSSStylesDesktop };
|
|
636
|
+
const finalTitleStylesDesktop = { ...titleCSSStylesDesktop };
|
|
637
|
+
const finalItemCountStylesDesktop = { ...itemCountCSSStylesDesktop };
|
|
638
|
+
const finalCloseIconStylesDesktop = { ...closeIconCSSStylesDesktop };
|
|
639
|
+
const finalListStylesDesktop = { ...listCSSStylesDesktop };
|
|
640
|
+
const finalItemStylesDesktop = { ...itemCSSStylesDesktop };
|
|
641
|
+
const finalItemImageStylesDesktop = { ...itemImageCSSStylesDesktop };
|
|
642
|
+
const finalItemNameStylesDesktop = { ...itemNameCSSStylesDesktop };
|
|
643
|
+
const finalItemPriceStylesDesktop = { ...itemPriceCSSStylesDesktop };
|
|
644
|
+
const finalItemRemoveButtonStylesDesktop = {
|
|
645
|
+
...itemRemoveButtonCSSStylesDesktop
|
|
646
|
+
};
|
|
647
|
+
const finalItemAttributeStylesDesktop = { ...itemAttributeCSSStylesDesktop };
|
|
648
|
+
const finalSubtotalStylesDesktop = { ...subtotalCSSStylesDesktop };
|
|
649
|
+
const finalViewBagButtonStylesDesktop = {
|
|
650
|
+
width: '100%',
|
|
651
|
+
display: 'flex',
|
|
652
|
+
alignItems: 'center',
|
|
653
|
+
justifyContent: 'center',
|
|
654
|
+
backgroundColor: 'var(--primary)',
|
|
655
|
+
color: 'var(--primary-foreground)',
|
|
656
|
+
borderWidth: '1px',
|
|
657
|
+
borderStyle: 'solid',
|
|
658
|
+
borderColor: 'var(--primary)',
|
|
659
|
+
height: '32px',
|
|
660
|
+
fontWeight: '600',
|
|
661
|
+
transition: 'all',
|
|
662
|
+
...viewBagButtonCSSStylesDesktop
|
|
663
|
+
};
|
|
664
|
+
const finalContinueShoppingButtonStylesDesktop = {
|
|
665
|
+
height: 'auto',
|
|
666
|
+
padding: '0',
|
|
667
|
+
fontWeight: '600',
|
|
668
|
+
textDecoration: 'underline',
|
|
669
|
+
alignSelf: 'center',
|
|
670
|
+
...continueShoppingButtonCSSStylesDesktop
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
// Use appropriate styles based on viewport
|
|
674
|
+
const finalSectionStyles = isMobile
|
|
675
|
+
? finalSectionStylesMobile
|
|
676
|
+
: finalSectionStylesDesktop;
|
|
677
|
+
const finalHeaderStyles = isMobile
|
|
678
|
+
? finalHeaderStylesMobile
|
|
679
|
+
: finalHeaderStylesDesktop;
|
|
680
|
+
const finalFooterStyles = isMobile
|
|
681
|
+
? finalFooterStylesMobile
|
|
682
|
+
: finalFooterStylesDesktop;
|
|
683
|
+
const finalTitleStyles = isMobile
|
|
684
|
+
? finalTitleStylesMobile
|
|
685
|
+
: finalTitleStylesDesktop;
|
|
686
|
+
const finalItemCountStyles = isMobile
|
|
687
|
+
? finalItemCountStylesMobile
|
|
688
|
+
: finalItemCountStylesDesktop;
|
|
689
|
+
const finalCloseIconStyles = isMobile
|
|
690
|
+
? finalCloseIconStylesMobile
|
|
691
|
+
: finalCloseIconStylesDesktop;
|
|
692
|
+
const finalListStyles = isMobile
|
|
693
|
+
? finalListStylesMobile
|
|
694
|
+
: finalListStylesDesktop;
|
|
695
|
+
const finalItemStyles = isMobile
|
|
696
|
+
? finalItemStylesMobile
|
|
697
|
+
: finalItemStylesDesktop;
|
|
698
|
+
const finalItemImageStyles = isMobile
|
|
699
|
+
? finalItemImageStylesMobile
|
|
700
|
+
: finalItemImageStylesDesktop;
|
|
701
|
+
const finalItemNameStyles = isMobile
|
|
702
|
+
? finalItemNameStylesMobile
|
|
703
|
+
: finalItemNameStylesDesktop;
|
|
704
|
+
const finalItemPriceStyles = isMobile
|
|
705
|
+
? finalItemPriceStylesMobile
|
|
706
|
+
: finalItemPriceStylesDesktop;
|
|
707
|
+
const finalItemRemoveButtonStyles = isMobile
|
|
708
|
+
? finalItemRemoveButtonStylesMobile
|
|
709
|
+
: finalItemRemoveButtonStylesDesktop;
|
|
710
|
+
const finalItemAttributeStyles = isMobile
|
|
711
|
+
? finalItemAttributeStylesMobile
|
|
712
|
+
: finalItemAttributeStylesDesktop;
|
|
713
|
+
const finalSubtotalStyles = isMobile
|
|
714
|
+
? finalSubtotalStylesMobile
|
|
715
|
+
: finalSubtotalStylesDesktop;
|
|
716
|
+
const finalViewBagButtonStyles = isMobile
|
|
717
|
+
? finalViewBagButtonStylesMobile
|
|
718
|
+
: finalViewBagButtonStylesDesktop;
|
|
719
|
+
const finalContinueShoppingButtonStyles = isMobile
|
|
720
|
+
? finalContinueShoppingButtonStylesMobile
|
|
721
|
+
: finalContinueShoppingButtonStylesDesktop;
|
|
166
722
|
|
|
167
723
|
const totalQuantity = useMemo(
|
|
168
724
|
() => miniBasket?.total_quantity ?? 0,
|
|
169
725
|
[miniBasket]
|
|
170
726
|
);
|
|
727
|
+
|
|
728
|
+
const titleContent = getBlockContent(
|
|
729
|
+
titleBlock,
|
|
730
|
+
t('basket.mini_basket.my_bag')
|
|
731
|
+
);
|
|
732
|
+
const itemCountContent = getBlockContent(
|
|
733
|
+
itemCountBlock,
|
|
734
|
+
`${totalQuantity} ${t('basket.mini_basket.items')}`
|
|
735
|
+
);
|
|
736
|
+
const subtotalContent = getBlockContent(
|
|
737
|
+
subtotalBlock,
|
|
738
|
+
t('basket.mini_basket.subtotal')
|
|
739
|
+
);
|
|
740
|
+
const viewBagButtonContent = getBlockContent(
|
|
741
|
+
viewBagButtonBlock,
|
|
742
|
+
t('basket.mini_basket.view_bag')
|
|
743
|
+
);
|
|
744
|
+
const continueShoppingButtonContent = getBlockContent(
|
|
745
|
+
continueShoppingButtonBlock,
|
|
746
|
+
t('basket.mini_basket.continue_shopping')
|
|
747
|
+
);
|
|
748
|
+
const itemRemoveButtonContent = getBlockContent(
|
|
749
|
+
itemRemoveButtonBlock,
|
|
750
|
+
t('basket.mini_basket.remove')
|
|
751
|
+
);
|
|
752
|
+
|
|
753
|
+
// Get custom close icon from block properties (supports SVG)
|
|
754
|
+
const closeIconProp = closeIconBlock?.properties?.icon;
|
|
755
|
+
const closeIconValue =
|
|
756
|
+
typeof closeIconProp === 'object' && closeIconProp !== null
|
|
757
|
+
? (closeIconProp as { desktop?: string }).desktop
|
|
758
|
+
: closeIconProp;
|
|
759
|
+
const hasCustomSvgIcon =
|
|
760
|
+
closeIconValue &&
|
|
761
|
+
typeof closeIconValue === 'string' &&
|
|
762
|
+
closeIconValue.includes('<svg');
|
|
763
|
+
// Use custom icon name or default to 'close'
|
|
764
|
+
const closeIconName: string =
|
|
765
|
+
hasCustomSvgIcon || !closeIconValue ? 'close' : String(closeIconValue);
|
|
766
|
+
|
|
171
767
|
const miniBasketList = useRef(null);
|
|
172
768
|
|
|
173
769
|
useEffect(() => {
|
|
@@ -205,38 +801,151 @@ export default function MiniBasket() {
|
|
|
205
801
|
: 'opacity-0 invisible',
|
|
206
802
|
'fixed top-0 left-0 z-50 w-screen h-screen bg-black bg-opacity-80 transition-all duration-300'
|
|
207
803
|
)}
|
|
208
|
-
onClick={() =>
|
|
209
|
-
dispatch(closeMiniBasket());
|
|
210
|
-
}}
|
|
804
|
+
onClick={() => dispatch(closeMiniBasket())}
|
|
211
805
|
/>
|
|
212
806
|
<div
|
|
213
807
|
className={clsx(
|
|
808
|
+
'flex-col transition-all duration-300',
|
|
214
809
|
miniBasketOpen
|
|
215
|
-
? 'flex
|
|
216
|
-
: 'opacity-0 invisible
|
|
217
|
-
'fixed lg:absolute
|
|
810
|
+
? 'flex opacity-100 visible'
|
|
811
|
+
: 'hidden opacity-0 invisible',
|
|
812
|
+
'fixed lg:absolute',
|
|
813
|
+
'bottom-0 lg:top-full right-0',
|
|
814
|
+
'w-screen h-screen lg:w-auto',
|
|
815
|
+
isDesigner &&
|
|
816
|
+
isSectionSelected &&
|
|
817
|
+
'ring-4 ring-blue-500 ring-offset-2',
|
|
818
|
+
isDesigner &&
|
|
819
|
+
'cursor-pointer hover:ring-4 hover:ring-blue-300 hover:ring-offset-2'
|
|
218
820
|
)}
|
|
821
|
+
style={finalSectionStyles}
|
|
822
|
+
onClick={(e) => {
|
|
823
|
+
if (e.target === e.currentTarget && isDesigner) {
|
|
824
|
+
if (typeof window !== 'undefined' && window.parent) {
|
|
825
|
+
window.parent.postMessage(
|
|
826
|
+
{
|
|
827
|
+
type: 'SELECT_BLOCK_FROM_PREVIEW',
|
|
828
|
+
data: {
|
|
829
|
+
placeholderId: HEADER_MINI_BASKET_PLACEHOLDER_ID,
|
|
830
|
+
sectionId: HEADER_MINI_BASKET_SECTION_ID,
|
|
831
|
+
blockId: ''
|
|
832
|
+
}
|
|
833
|
+
},
|
|
834
|
+
'*'
|
|
835
|
+
);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}}
|
|
219
839
|
>
|
|
220
|
-
<header
|
|
221
|
-
|
|
222
|
-
|
|
840
|
+
<header
|
|
841
|
+
className={clsx(
|
|
842
|
+
'flex items-center gap-2 pb-3 border-b relative',
|
|
843
|
+
isDesigner &&
|
|
844
|
+
selectedBlockId === 'mini-basket-header' &&
|
|
845
|
+
'ring-2 ring-blue-500 ring-inset',
|
|
846
|
+
isDesigner &&
|
|
847
|
+
'cursor-pointer hover:ring-2 hover:ring-blue-300 hover:ring-inset'
|
|
848
|
+
)}
|
|
849
|
+
style={finalHeaderStyles}
|
|
850
|
+
onClick={(e) =>
|
|
851
|
+
isDesigner && handleBlockClick('mini-basket-header', e)
|
|
852
|
+
}
|
|
853
|
+
>
|
|
854
|
+
<h3
|
|
855
|
+
className={clsx(
|
|
856
|
+
'relative',
|
|
857
|
+
isDesigner &&
|
|
858
|
+
selectedBlockId === 'mini-basket-title' &&
|
|
859
|
+
'ring-2 ring-blue-500 ring-inset',
|
|
860
|
+
isDesigner &&
|
|
861
|
+
'cursor-pointer hover:ring-2 hover:ring-blue-300 hover:ring-inset'
|
|
862
|
+
)}
|
|
863
|
+
style={finalTitleStyles}
|
|
864
|
+
onClick={(e) =>
|
|
865
|
+
isDesigner && handleBlockClick('mini-basket-title', e)
|
|
866
|
+
}
|
|
867
|
+
>
|
|
868
|
+
{titleContent}
|
|
223
869
|
</h3>
|
|
224
|
-
<span
|
|
225
|
-
{
|
|
226
|
-
|
|
870
|
+
<span
|
|
871
|
+
className={clsx(
|
|
872
|
+
'relative',
|
|
873
|
+
isDesigner &&
|
|
874
|
+
selectedBlockId === 'mini-basket-item-count' &&
|
|
875
|
+
'ring-2 ring-blue-500 ring-inset',
|
|
876
|
+
isDesigner &&
|
|
877
|
+
'cursor-pointer hover:ring-2 hover:ring-blue-300 hover:ring-inset'
|
|
878
|
+
)}
|
|
879
|
+
style={finalItemCountStyles}
|
|
880
|
+
onClick={(e) =>
|
|
881
|
+
isDesigner && handleBlockClick('mini-basket-item-count', e)
|
|
882
|
+
}
|
|
883
|
+
>
|
|
884
|
+
{totalQuantity} {t('basket.mini_basket.items')}
|
|
227
885
|
</span>
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
886
|
+
{hasCustomSvgIcon ? (
|
|
887
|
+
<div
|
|
888
|
+
className={clsx(
|
|
889
|
+
'ml-auto hover:cursor-pointer flex items-center justify-center relative',
|
|
890
|
+
isDesigner &&
|
|
891
|
+
selectedBlockId === 'mini-basket-close-icon' &&
|
|
892
|
+
'ring-2 ring-blue-500 ring-inset'
|
|
893
|
+
)}
|
|
894
|
+
style={{
|
|
895
|
+
width: 16,
|
|
896
|
+
height: 16,
|
|
897
|
+
...finalCloseIconStyles
|
|
898
|
+
}}
|
|
899
|
+
dangerouslySetInnerHTML={{ __html: closeIconValue }}
|
|
900
|
+
onClick={(e) => {
|
|
901
|
+
e.stopPropagation();
|
|
902
|
+
if (isDesigner) {
|
|
903
|
+
handleBlockClick('mini-basket-close-icon', e);
|
|
904
|
+
} else {
|
|
905
|
+
dispatch(closeMiniBasket());
|
|
906
|
+
}
|
|
907
|
+
}}
|
|
908
|
+
/>
|
|
909
|
+
) : (
|
|
910
|
+
<Icon
|
|
911
|
+
name={closeIconName}
|
|
912
|
+
size={16}
|
|
913
|
+
className={clsx(
|
|
914
|
+
'ml-auto hover:cursor-pointer relative',
|
|
915
|
+
isDesigner &&
|
|
916
|
+
selectedBlockId === 'mini-basket-close-icon' &&
|
|
917
|
+
'ring-2 ring-blue-500 ring-inset'
|
|
918
|
+
)}
|
|
919
|
+
style={finalCloseIconStyles}
|
|
920
|
+
onClick={(e) => {
|
|
921
|
+
e.stopPropagation();
|
|
922
|
+
if (isDesigner) {
|
|
923
|
+
handleBlockClick('mini-basket-close-icon', e);
|
|
924
|
+
} else {
|
|
925
|
+
dispatch(closeMiniBasket());
|
|
926
|
+
}
|
|
927
|
+
}}
|
|
928
|
+
/>
|
|
929
|
+
)}
|
|
234
930
|
</header>
|
|
235
|
-
{isLoading && <LoaderSpinner />}
|
|
931
|
+
{isLoading && <LoaderSpinner />}
|
|
236
932
|
{isSuccess && (
|
|
237
933
|
<ul
|
|
238
934
|
ref={miniBasketList}
|
|
239
|
-
className=
|
|
935
|
+
className={clsx(
|
|
936
|
+
'overflow-y-auto lg:max-h-64 flex flex-col relative',
|
|
937
|
+
isDesigner &&
|
|
938
|
+
selectedBlockId === 'mini-basket-list' &&
|
|
939
|
+
'ring-2 ring-blue-500 ring-inset',
|
|
940
|
+
isDesigner &&
|
|
941
|
+
'cursor-pointer hover:ring-2 hover:ring-blue-300 hover:ring-inset'
|
|
942
|
+
)}
|
|
943
|
+
style={finalListStyles}
|
|
944
|
+
onClick={(e) => {
|
|
945
|
+
if (e.target === e.currentTarget && isDesigner) {
|
|
946
|
+
handleBlockClick('mini-basket-list', e);
|
|
947
|
+
}
|
|
948
|
+
}}
|
|
240
949
|
>
|
|
241
950
|
{sortedBasket.map((basketItem) => (
|
|
242
951
|
<MiniBasketItem
|
|
@@ -244,32 +953,98 @@ export default function MiniBasket() {
|
|
|
244
953
|
basketItem={basketItem}
|
|
245
954
|
highlightedItem={highlightedItem}
|
|
246
955
|
miniBasketListRef={miniBasketList}
|
|
956
|
+
isDesigner={isDesigner}
|
|
957
|
+
selectedBlockId={selectedBlockId}
|
|
958
|
+
onBlockClick={handleBlockClick}
|
|
959
|
+
itemStyles={finalItemStyles}
|
|
960
|
+
imageStyles={finalItemImageStyles}
|
|
961
|
+
nameStyles={finalItemNameStyles}
|
|
962
|
+
priceStyles={finalItemPriceStyles}
|
|
963
|
+
removeButtonStyles={finalItemRemoveButtonStyles}
|
|
964
|
+
removeButtonContent={itemRemoveButtonContent}
|
|
965
|
+
attributeStyles={finalItemAttributeStyles}
|
|
247
966
|
/>
|
|
248
967
|
))}
|
|
249
968
|
</ul>
|
|
250
969
|
)}
|
|
251
|
-
<footer
|
|
252
|
-
|
|
253
|
-
|
|
970
|
+
<footer
|
|
971
|
+
className={clsx(
|
|
972
|
+
'flex flex-col gap-3 mt-auto lg:mt-3 lg:flex-1 relative',
|
|
973
|
+
isDesigner &&
|
|
974
|
+
selectedBlockId === 'mini-basket-footer' &&
|
|
975
|
+
'ring-2 ring-blue-500 ring-inset',
|
|
976
|
+
isDesigner &&
|
|
977
|
+
'cursor-pointer hover:ring-2 hover:ring-blue-300 hover:ring-inset'
|
|
978
|
+
)}
|
|
979
|
+
style={finalFooterStyles}
|
|
980
|
+
onClick={(e) => {
|
|
981
|
+
if (e.target === e.currentTarget && isDesigner) {
|
|
982
|
+
handleBlockClick('mini-basket-footer', e);
|
|
983
|
+
}
|
|
984
|
+
}}
|
|
985
|
+
>
|
|
986
|
+
<div
|
|
987
|
+
className={clsx(
|
|
988
|
+
'flex self-center gap-1 text-xs font-semibold relative',
|
|
989
|
+
isDesigner &&
|
|
990
|
+
selectedBlockId === 'mini-basket-subtotal' &&
|
|
991
|
+
'ring-2 ring-blue-500 ring-inset',
|
|
992
|
+
isDesigner &&
|
|
993
|
+
'cursor-pointer hover:ring-2 hover:ring-blue-300 hover:ring-inset'
|
|
994
|
+
)}
|
|
995
|
+
style={finalSubtotalStyles}
|
|
996
|
+
onClick={(e) =>
|
|
997
|
+
isDesigner && handleBlockClick('mini-basket-subtotal', e)
|
|
998
|
+
}
|
|
999
|
+
>
|
|
1000
|
+
<span>{subtotalContent}</span>
|
|
254
1001
|
<Price value={basket?.total_amount} />
|
|
255
1002
|
</div>
|
|
256
|
-
{/* TODO: Fix link styles */}
|
|
257
1003
|
<Link
|
|
258
|
-
onClick={() => {
|
|
259
|
-
|
|
1004
|
+
onClick={(e) => {
|
|
1005
|
+
if (isDesigner) {
|
|
1006
|
+
e.preventDefault();
|
|
1007
|
+
e.stopPropagation();
|
|
1008
|
+
handleBlockClick('mini-basket-view-bag-button', e);
|
|
1009
|
+
} else {
|
|
1010
|
+
dispatch(closeMiniBasket());
|
|
1011
|
+
}
|
|
260
1012
|
}}
|
|
261
1013
|
href={ROUTES.BASKET}
|
|
262
1014
|
data-testid="mini-basket-view-bag"
|
|
263
|
-
className=
|
|
1015
|
+
className={clsx(
|
|
1016
|
+
'w-full flex items-center justify-center transition-all relative',
|
|
1017
|
+
isDesigner &&
|
|
1018
|
+
selectedBlockId === 'mini-basket-view-bag-button' &&
|
|
1019
|
+
'ring-2 ring-blue-500 ring-inset',
|
|
1020
|
+
isDesigner &&
|
|
1021
|
+
'cursor-pointer hover:ring-2 hover:ring-blue-300 hover:ring-inset'
|
|
1022
|
+
)}
|
|
1023
|
+
style={finalViewBagButtonStyles}
|
|
264
1024
|
>
|
|
265
|
-
{
|
|
1025
|
+
{viewBagButtonContent}
|
|
266
1026
|
</Link>
|
|
267
1027
|
<Link
|
|
268
1028
|
href="/"
|
|
269
|
-
className=
|
|
1029
|
+
className={clsx(
|
|
1030
|
+
'self-center relative',
|
|
1031
|
+
isDesigner &&
|
|
1032
|
+
selectedBlockId === 'mini-basket-continue-shopping-button' &&
|
|
1033
|
+
'ring-2 ring-blue-500 ring-inset',
|
|
1034
|
+
isDesigner &&
|
|
1035
|
+
'cursor-pointer hover:ring-2 hover:ring-blue-300 hover:ring-inset'
|
|
1036
|
+
)}
|
|
270
1037
|
data-testid="mini-basket-continue-shopping"
|
|
1038
|
+
style={finalContinueShoppingButtonStyles}
|
|
1039
|
+
onClick={(e) => {
|
|
1040
|
+
if (isDesigner) {
|
|
1041
|
+
e.preventDefault();
|
|
1042
|
+
e.stopPropagation();
|
|
1043
|
+
handleBlockClick('mini-basket-continue-shopping-button', e);
|
|
1044
|
+
}
|
|
1045
|
+
}}
|
|
271
1046
|
>
|
|
272
|
-
{
|
|
1047
|
+
{continueShoppingButtonContent}
|
|
273
1048
|
</Link>
|
|
274
1049
|
</footer>
|
|
275
1050
|
</div>
|