@akinon/projectzero 2.0.0-beta.20 → 2.0.0-beta.21

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.
Files changed (138) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/app-template/CHANGELOG.md +138 -0
  3. package/app-template/next.config.mjs +0 -1
  4. package/app-template/package.json +31 -30
  5. package/app-template/src/app/[pz]/[...prettyurl]/page.tsx +2 -2
  6. package/app-template/src/app/[pz]/account/layout.tsx +2 -1
  7. package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/blog/[slug]/page.tsx +4 -2
  8. package/app-template/src/app/[pz]/category/[pk]/page.tsx +11 -1
  9. package/app-template/src/app/[pz]/group-product/[pk]/page.tsx +2 -2
  10. package/app-template/src/app/[pz]/layout.tsx +3 -1
  11. package/app-template/src/app/[pz]/list/page.tsx +11 -1
  12. package/app-template/src/app/[pz]/page.tsx +13 -35
  13. package/app-template/src/app/[pz]/pages/[slug]/page.tsx +19 -0
  14. package/app-template/src/app/[pz]/product/[pk]/page.tsx +2 -2
  15. package/app-template/src/app/api/barcode-search/route.ts +1 -1
  16. package/app-template/src/app/api/cache/route.ts +1 -1
  17. package/app-template/src/app/api/image-proxy/route.ts +1 -1
  18. package/app-template/src/app/api/logout/route.ts +1 -1
  19. package/app-template/src/app/api/product-categories/route.ts +1 -1
  20. package/app-template/src/app/api/similar-product-list/route.ts +1 -1
  21. package/app-template/src/app/api/similar-products/route.ts +1 -1
  22. package/app-template/src/app/api/virtual-try-on/route.ts +1 -1
  23. package/app-template/src/app/api/web-vitals/route.ts +1 -1
  24. package/app-template/src/components/quantity-selector.tsx +16 -4
  25. package/app-template/src/components/widget-content.tsx +3 -3
  26. package/app-template/src/routes/index.ts +6 -6
  27. package/app-template/src/utils/__tests__/theme-page-context.test.ts +145 -0
  28. package/app-template/src/utils/theme-page-context.ts +309 -0
  29. package/app-template/src/views/basket/basket-item.tsx +107 -691
  30. package/app-template/src/views/basket/index.ts +0 -2
  31. package/app-template/src/views/basket/summary.tsx +75 -496
  32. package/app-template/src/views/breadcrumb.tsx +38 -13
  33. package/app-template/src/views/category/category-header.tsx +66 -289
  34. package/app-template/src/views/category/category-info.tsx +24 -173
  35. package/app-template/src/views/category/filters/index.tsx +48 -208
  36. package/app-template/src/views/category/layout.tsx +5 -7
  37. package/app-template/src/views/checkout/index.tsx +0 -5
  38. package/app-template/src/views/checkout/steps/payment/index.tsx +2 -5
  39. package/app-template/src/views/checkout/steps/payment/options/credit-card/index.tsx +1 -72
  40. package/app-template/src/views/checkout/steps/payment/payment-option-buttons.tsx +40 -171
  41. package/app-template/src/views/checkout/steps/shipping/address-box.tsx +12 -74
  42. package/app-template/src/views/checkout/steps/shipping/addresses.tsx +45 -128
  43. package/app-template/src/views/checkout/steps/shipping/shipping-options.tsx +27 -232
  44. package/app-template/src/views/checkout/summary.tsx +29 -303
  45. package/app-template/src/views/footer.tsx +13 -415
  46. package/app-template/src/views/guest-login/index.tsx +1 -1
  47. package/app-template/src/views/header/action-menu.tsx +45 -277
  48. package/app-template/src/views/header/band.tsx +21 -6
  49. package/app-template/src/views/header/index.tsx +47 -109
  50. package/app-template/src/views/header/mini-basket.tsx +45 -820
  51. package/app-template/src/views/header/navbar.tsx +111 -178
  52. package/app-template/src/views/header/search/index.tsx +32 -71
  53. package/app-template/src/views/header/search/results.tsx +65 -127
  54. package/app-template/src/views/product/accordion-wrapper.tsx +43 -135
  55. package/app-template/src/views/product/index.ts +1 -1
  56. package/app-template/src/views/product/layout.tsx +7 -2
  57. package/app-template/src/views/product/misc-buttons.tsx +25 -339
  58. package/app-template/src/views/product/product-actions.tsx +8 -137
  59. package/app-template/src/views/product/product-info.tsx +31 -69
  60. package/app-template/src/views/product/product-share.tsx +8 -11
  61. package/app-template/src/views/product/slider.tsx +79 -117
  62. package/app-template/src/views/product-item/index.tsx +46 -119
  63. package/app-template/src/widgets/footer-social.tsx +16 -47
  64. package/app-template/src/widgets/footer-subscription/index.tsx +17 -183
  65. package/dist/commands/plugins.js +23 -2
  66. package/package.json +1 -1
  67. package/app-template/src/app/[commerce]/[locale]/[currency]/pages/[slug]/page.tsx +0 -15
  68. package/app-template/src/views/basket/basket-summary-context.tsx +0 -560
  69. package/app-template/src/views/basket/designer-context.tsx +0 -617
  70. package/app-template/src/views/breadcrumb/breadcrumb-client.tsx +0 -190
  71. package/app-template/src/views/breadcrumb/breadcrumb-registrar.tsx +0 -286
  72. package/app-template/src/views/breadcrumb/constants.ts +0 -15
  73. package/app-template/src/views/breadcrumb/index.tsx +0 -127
  74. package/app-template/src/views/category/native-widget-context.tsx +0 -257
  75. package/app-template/src/views/category/product-list-registrar.tsx +0 -665
  76. package/app-template/src/views/checkout/checkout-address-registrar.tsx +0 -254
  77. package/app-template/src/views/checkout/checkout-buttons-registrar.tsx +0 -183
  78. package/app-template/src/views/checkout/checkout-delivery-method-registrar.tsx +0 -259
  79. package/app-template/src/views/checkout/checkout-payment-options-registrar.tsx +0 -253
  80. package/app-template/src/views/checkout/checkout-summary-registrar.tsx +0 -183
  81. package/app-template/src/views/checkout/constants.ts +0 -5
  82. package/app-template/src/views/checkout/steps/payment/options/masterpass-rest.tsx +0 -15
  83. package/app-template/src/views/checkout/steps/payment/options/saved-card.tsx +0 -18
  84. package/app-template/src/views/footer/footer-app-banner-context.tsx +0 -326
  85. package/app-template/src/views/footer/footer-bottom-context.tsx +0 -215
  86. package/app-template/src/views/footer/footer-bottom-wrapper.tsx +0 -74
  87. package/app-template/src/views/footer/footer-layout-constants.ts +0 -35
  88. package/app-template/src/views/footer/footer-layout-registrar.tsx +0 -342
  89. package/app-template/src/views/footer/footer-layout-switcher.tsx +0 -110
  90. package/app-template/src/views/footer/footer-menu-context.tsx +0 -211
  91. package/app-template/src/views/footer/footer-native-widgets.tsx +0 -60
  92. package/app-template/src/views/footer/footer-social-context.tsx +0 -254
  93. package/app-template/src/views/footer/footer-subscription-context.tsx +0 -210
  94. package/app-template/src/views/footer/footer-utils.ts +0 -43
  95. package/app-template/src/views/footer/footer-value-props-context.tsx +0 -326
  96. package/app-template/src/views/footer/logo-settings.ts +0 -183
  97. package/app-template/src/views/footer/native-widget-config.ts +0 -262
  98. package/app-template/src/views/footer/subscription-settings.ts +0 -122
  99. package/app-template/src/views/footer/use-footer-logo.ts +0 -162
  100. package/app-template/src/views/header/designer-context.tsx +0 -261
  101. package/app-template/src/views/header/header-announcement-registrar.tsx +0 -267
  102. package/app-template/src/views/header/header-client-wrapper.tsx +0 -496
  103. package/app-template/src/views/header/header-content.tsx +0 -1026
  104. package/app-template/src/views/header/header-currency-registrar.tsx +0 -348
  105. package/app-template/src/views/header/header-icons-context.tsx +0 -262
  106. package/app-template/src/views/header/header-language-registrar.tsx +0 -348
  107. package/app-template/src/views/header/header-layout-context.tsx +0 -143
  108. package/app-template/src/views/header/header-layout-registrar.tsx +0 -658
  109. package/app-template/src/views/header/header-logo-context.tsx +0 -228
  110. package/app-template/src/views/header/header-logo.tsx +0 -118
  111. package/app-template/src/views/header/header-mini-basket-context.tsx +0 -524
  112. package/app-template/src/views/header/header-search-registrar.tsx +0 -511
  113. package/app-template/src/views/header/header-text-slider-registrar.tsx +0 -382
  114. package/app-template/src/views/header/inline-search.tsx +0 -262
  115. package/app-template/src/views/header/navbar-menu-context.tsx +0 -219
  116. package/app-template/src/views/header/search/search-input.tsx +0 -61
  117. package/app-template/src/views/header/server-settings-parser.ts +0 -1105
  118. package/app-template/src/views/header/use-header-icons.ts +0 -241
  119. package/app-template/src/views/header/use-header-logo.ts +0 -213
  120. package/app-template/src/views/header/use-navbar-menu.ts +0 -179
  121. package/app-template/src/views/product/accordion-section.tsx +0 -61
  122. package/app-template/src/views/product/custom-button-group.tsx +0 -69
  123. package/app-template/src/views/product/favorites-button-section.tsx +0 -69
  124. package/app-template/src/views/product/find-in-store-section.tsx +0 -60
  125. package/app-template/src/views/product/product-info-section.tsx +0 -140
  126. package/app-template/src/views/product/quantity-section.tsx +0 -73
  127. package/app-template/src/views/product/sale-tag.tsx +0 -10
  128. package/app-template/src/views/product/share-section.tsx +0 -357
  129. package/app-template/src/views/product/variants-section.tsx +0 -126
  130. package/app-template/src/views/product-detail/constants.ts +0 -272
  131. package/app-template/src/views/product-detail/index.ts +0 -10
  132. package/app-template/src/views/product-detail/product-detail-registrar.tsx +0 -616
  133. package/app-template/src/widgets/footer-app-banner.tsx +0 -444
  134. package/app-template/src/widgets/footer-bottom.tsx +0 -127
  135. package/app-template/src/widgets/footer-menu-compact.tsx +0 -238
  136. package/app-template/src/widgets/footer-menu-two.tsx +0 -298
  137. package/app-template/src/widgets/footer-social-client.tsx +0 -251
  138. package/app-template/src/widgets/footer-value-props.tsx +0 -201
@@ -16,8 +16,6 @@ import { Link, LoaderSpinner } from '@akinon/next/components';
16
16
  import { ROUTES } from '@theme/routes';
17
17
  import { useRouter } from '@akinon/next/hooks';
18
18
  import { RootState } from '@theme/redux/store';
19
- import { NativeWidgetProvider, useNativeWidget } from './native-widget-context';
20
- import { useProductList } from './product-list-registrar';
21
19
 
22
20
  interface ListPageProps {
23
21
  data: GetCategoryResponse;
@@ -34,7 +32,7 @@ export default function ListPage(props: ListPageProps) {
34
32
  const router = useRouter();
35
33
 
36
34
  const layoutSize = useMemo(
37
- () => searchParams.get('layout') ?? '4',
35
+ () => Number(searchParams.get('layout') ?? 3),
38
36
  [searchParams]
39
37
  );
40
38
 
@@ -45,9 +43,9 @@ export default function ListPage(props: ListPageProps) {
45
43
 
46
44
  const itemDimensions = useMemo(() => {
47
45
  switch (layoutSize) {
48
- case '2':
46
+ case 2:
49
47
  return { width: 510, height: 765 };
50
- case '3':
48
+ case 3:
51
49
  default:
52
50
  return { width: 340, height: 510 };
53
51
  }
@@ -60,7 +58,7 @@ export default function ListPage(props: ListPageProps) {
60
58
  router.push(newUrl.pathname + newUrl.search, undefined);
61
59
  }
62
60
  // eslint-disable-next-line react-hooks/exhaustive-deps
63
- }, [searchParams, data?.products, page]);
61
+ }, [searchParams, data.products, page]);
64
62
 
65
63
  const { t } = useLocalization();
66
64
 
@@ -69,109 +67,32 @@ export default function ListPage(props: ListPageProps) {
69
67
  // eslint-disable-next-line react-hooks/exhaustive-deps
70
68
  }, [data.facets]);
71
69
 
72
- return (
73
- <NativeWidgetProvider>
74
- <ListPageContent data={data} />
75
- </NativeWidgetProvider>
76
- );
77
- }
78
-
79
- function ListPageContent({ data }: ListPageProps) {
80
- const dispatch = useAppDispatch();
81
- const isMenuOpen = useAppSelector(
82
- (state: RootState) => state.category.isMenuOpen
83
- );
84
- const {
85
- isDesigner,
86
- filterProperties: registrarProps,
87
- productsStyles: registrarProductsStyles,
88
- paginationProperties: registrarPaginationProps,
89
- paginationStyles: registrarPaginationStyles
90
- } = useProductList();
91
- const {
92
- filterProperties: widgetProps,
93
- productsStyles: widgetProductsStyles,
94
- paginationProperties: widgetPaginationProps,
95
- paginationStyles: widgetPaginationStyles
96
- } = useNativeWidget();
97
-
98
- // Use registrar properties in designer mode, widget properties otherwise
99
- const filterProperties = isDesigner ? registrarProps : widgetProps;
100
- const productsStyles = isDesigner
101
- ? registrarProductsStyles
102
- : widgetProductsStyles;
103
- const paginationProperties = isDesigner
104
- ? { ...widgetPaginationProps, ...registrarPaginationProps }
105
- : widgetPaginationProps;
106
- const paginationStyles = isDesigner
107
- ? { ...widgetPaginationStyles, ...registrarPaginationStyles }
108
- : widgetPaginationStyles;
109
- const { t } = useLocalization();
110
-
111
- const searchParams = useSearchParams();
112
-
113
- const layoutSize = useMemo(
114
- () => searchParams.get('layout') ?? '4',
115
- [searchParams]
116
- );
117
-
118
- const page = useMemo(
119
- () => Number(searchParams.get('page') ?? 1),
120
- [searchParams]
121
- );
122
-
123
- const itemDimensions = useMemo(() => {
124
- switch (layoutSize) {
125
- case '2':
126
- return { width: 510, height: 765 };
127
- case '3':
128
- default:
129
- return { width: 340, height: 510 };
130
- }
131
- }, [layoutSize]);
132
-
133
- // Get layout from widget properties
134
- const layout = (filterProperties.layout as string) || 'top';
135
-
136
70
  return (
137
71
  <>
138
- <div className="container px-4 mx-auto lg:px-0">
139
- <div
140
- className={clsx(
141
- 'grid',
142
- layout === 'sidebar' && 'lg:grid-cols-[280px_1fr] lg:gap-8'
143
- )}
144
- >
145
- {layout === 'sidebar' && (
146
- <>
147
- <Filters
148
- isMenuOpen={isMenuOpen}
149
- totalCount={data.pagination?.total_count}
150
- setIsMenuOpen={(open) => dispatch(setMenuOpen(open))}
151
- sortOptions={data.sorters}
152
- />
153
- <div
154
- onClick={() => dispatch(setMenuOpen(false))}
155
- className={clsx(
156
- 'transition-opacity duration-300 ease-linear lg:hidden',
157
- isMenuOpen
158
- ? 'fixed bg-black bg-opacity-60 top-16 inset-x-0 bottom-0 z-10 opacity-100 pointer-events-auto'
159
- : 'opacity-0 pointer-events-none'
160
- )}
161
- ></div>
162
- </>
163
- )}
72
+ <div className="container px-4 mx-auto lg:px-0 lg:my-4">
73
+ <div className="grid grid-cols-[19rem_1fr]">
74
+ <Filters
75
+ isMenuOpen={isMenuOpen}
76
+ setIsMenuOpen={(open) => dispatch(setMenuOpen(open))}
77
+ />
164
78
  <div
79
+ onClick={() => dispatch(setMenuOpen(false))}
165
80
  className={clsx(
166
- 'flex flex-col items-center lg:items-stretch',
167
- layout !== 'sidebar' && 'col-span-2 lg:col-span-1'
81
+ 'transition-opacity duration-300 ease-linear lg:hidden',
82
+ isMenuOpen
83
+ ? 'fixed bg-black bg-opacity-60 inset-0 z-10 opacity-100'
84
+ : 'opacity-0'
168
85
  )}
169
- >
86
+ ></div>
87
+ <div className="flex flex-col items-center lg:items-stretch col-span-2 lg:col-span-1">
170
88
  <CategoryHeader
171
89
  totalCount={data.pagination?.total_count}
172
90
  setMenuStatus={() => dispatch(setMenuOpen(true))}
173
91
  sortOptions={data.sorters}
174
92
  />
93
+ <div className="hidden lg:block">
94
+ <CategoryActiveFilters />
95
+ </div>
175
96
 
176
97
  {data.products?.length === 0 && page === 1 && (
177
98
  <div className="text-center bg-gray-200 px-5 py-20">
@@ -185,25 +106,11 @@ function ListPageContent({ data }: ListPageProps) {
185
106
  {data.products?.length === 0 && page > 1 && <LoaderSpinner />}
186
107
 
187
108
  <div
188
- className={clsx('grid grid-cols-2 md:grid-cols-3', {
189
- 'lg:grid-cols-2': layoutSize === '2',
190
- 'lg:grid-cols-3': layoutSize === '3',
191
- 'lg:grid-cols-4': layoutSize === '4',
192
- 'lg:grid-cols-6': layoutSize === '6'
109
+ className={clsx('grid gap-x-4 gap-y-12 grid-cols-2', {
110
+ 'md:grid-cols-3': layoutSize === 3,
111
+ 'lg:grid-cols-2': layoutSize === 2,
112
+ 'lg:grid-cols-3': layoutSize === 3
193
113
  })}
194
- style={{
195
- gap: `${(productsStyles['gap-y'] as string) || '48px'} ${
196
- (productsStyles['gap-x'] as string) || '16px'
197
- }`,
198
- paddingTop: (productsStyles['padding-top'] as string) || '0px',
199
- paddingBottom:
200
- (productsStyles['padding-bottom'] as string) || '0px',
201
- paddingLeft:
202
- (productsStyles['padding-left'] as string) || '0px',
203
- paddingRight:
204
- (productsStyles['padding-right'] as string) || '0px'
205
- }}
206
- data-section-id="products-section"
207
114
  >
208
115
  {data?.products?.map((product, index) => (
209
116
  <ProductItem
@@ -221,62 +128,6 @@ function ListPageContent({ data }: ListPageProps) {
221
128
  limit={data.pagination.page_size}
222
129
  currentPage={data.pagination.current_page}
223
130
  numberOfPages={data.pagination.num_pages}
224
- type={
225
- (paginationProperties.type as 'list' | 'more' | 'infinite') ||
226
- 'list'
227
- }
228
- customStyles={{
229
- marginTop:
230
- (paginationStyles['margin-top'] as string) || '32px',
231
- marginBottom:
232
- (paginationStyles['margin-bottom'] as string) || '16px',
233
- pageFontSize:
234
- (paginationStyles['page-font-size'] as string) || '14px',
235
- pageColor:
236
- (paginationStyles['page-color'] as string) || '#9ca3af',
237
- pageActiveColor:
238
- (paginationStyles['page-active-color'] as string) ||
239
- '#1a1a1a',
240
- pageActiveFontWeight:
241
- (paginationStyles['page-active-font-weight'] as string) ||
242
- '600',
243
- pageGap: (paginationStyles['page-gap'] as string) || '8px',
244
- pageBgColor:
245
- (paginationStyles['page-bg-color'] as string) ||
246
- 'transparent',
247
- pageActiveBgColor:
248
- (paginationStyles['page-active-bg-color'] as string) ||
249
- 'transparent',
250
- pagePaddingX:
251
- (paginationStyles['page-padding-x'] as string) || '8px',
252
- pagePaddingY:
253
- (paginationStyles['page-padding-y'] as string) || '4px',
254
- pageBorderRadius:
255
- (paginationStyles['page-border-radius'] as string) || '0px',
256
- pageBorderWidth:
257
- (paginationStyles['page-border-width'] as string) || '0px',
258
- pageBorderColor:
259
- (paginationStyles['page-border-color'] as string) ||
260
- '#e5e7eb',
261
- pageActiveBorderColor:
262
- (paginationStyles['page-active-border-color'] as string) ||
263
- '#1a1a1a',
264
- arrowColor:
265
- (paginationStyles['arrow-color'] as string) || '#1a1a1a',
266
- buttonBgColor:
267
- (paginationStyles['button-bg-color'] as string) ||
268
- '#000000',
269
- buttonTextColor:
270
- (paginationStyles['button-text-color'] as string) ||
271
- '#ffffff',
272
- buttonBorderRadius:
273
- (paginationStyles['button-border-radius'] as string) ||
274
- '4px',
275
- buttonPaddingX:
276
- (paginationStyles['button-padding-x'] as string) || '20px',
277
- buttonPaddingY:
278
- (paginationStyles['button-padding-y'] as string) || '12px'
279
- }}
280
131
  />
281
132
  )}
282
133
  </div>
@@ -1,56 +1,27 @@
1
1
  'use client';
2
2
 
3
3
  import clsx from 'clsx';
4
- import { Button, Icon, Select } from '@theme/components';
5
- import { useRouter, useLocalization } from '@akinon/next/hooks';
4
+ import { Button, Icon } from '@theme/components';
5
+ import { useLocalization } from '@akinon/next/hooks';
6
6
  import { useAppDispatch, useAppSelector } from '@akinon/next/redux/hooks';
7
7
  import { resetSelectedFacets } from '@theme/redux/reducers/category';
8
8
  import CategoryActiveFilters from '@theme/views/category/category-active-filters';
9
- import { useMemo, useTransition, useState, CSSProperties } from 'react';
9
+ import { useMemo, useTransition } from 'react';
10
10
  import { FilterItem } from './filter-item';
11
- import { SortOption } from '@akinon/next/types';
12
- import { usePathname, useSearchParams } from 'next/navigation';
13
- import { useProductList } from '../product-list-registrar';
14
- import { useNativeWidget } from '../native-widget-context';
15
11
 
16
12
  interface Props {
17
13
  isMenuOpen: boolean;
18
14
  setIsMenuOpen: (isMenuOpen: boolean) => void;
19
- totalCount?: number;
20
- sortOptions: SortOption[];
21
15
  }
22
16
 
23
17
  export const Filters = (props: Props) => {
24
18
  const facets = useAppSelector((state) => state.category.facets);
25
19
  const dispatch = useAppDispatch();
26
20
  const { t } = useLocalization();
27
- const { isMenuOpen, setIsMenuOpen, totalCount, sortOptions } = props;
28
- const [openDropdown, setOpenDropdown] = useState<string | null>(null);
21
+ const { isMenuOpen, setIsMenuOpen } = props;
29
22
 
30
23
  const [isPending, startTransition] = useTransition();
31
24
 
32
- const router = useRouter();
33
- const searchParams = useSearchParams();
34
- const pathname = usePathname();
35
-
36
- // Get styles and properties from both contexts
37
- const {
38
- isDesigner,
39
- filterStyles: registrarStyles,
40
- filterProperties: registrarProps
41
- } = useProductList();
42
- const { filterStyles: widgetStyles, filterProperties: widgetProps } =
43
- useNativeWidget();
44
-
45
- // Use registrar data in designer mode, widget data otherwise
46
- const filterStyles = isDesigner ? registrarStyles : widgetStyles;
47
-
48
- // Merge properties - registrar props override widget props for live updates
49
- const filterProperties = {
50
- ...widgetProps,
51
- ...registrarProps
52
- };
53
-
54
25
  const haveFilter = useMemo(() => {
55
26
  return facets?.some((facet) =>
56
27
  facet?.data?.choices?.some((choice) => choice.is_selected)
@@ -61,181 +32,50 @@ export const Filters = (props: Props) => {
61
32
  dispatch(resetSelectedFacets());
62
33
  };
63
34
 
64
- const handleSelectFilter = ({
65
- key,
66
- value
67
- }: {
68
- key: string;
69
- value: string;
70
- }) => {
71
- const urlSearchParams = new URLSearchParams(searchParams.toString());
72
-
73
- urlSearchParams.set(key, value);
74
-
75
- router.push(pathname + '?' + urlSearchParams.toString());
76
- };
77
-
78
- // Get layout from properties
79
- const layout = (filterProperties.layout as string) || 'top';
80
- const containerStyles = filterStyles as CSSProperties;
81
-
82
- // Parse item properties (they come as strings like '14px' from Theme Editor)
83
- const itemPaddingY =
84
- typeof filterProperties['item-padding-y'] === 'number'
85
- ? filterProperties['item-padding-y']
86
- : typeof filterProperties['item-padding-y'] === 'string'
87
- ? parseInt(filterProperties['item-padding-y'], 10)
88
- : 6;
89
- const itemPaddingX =
90
- typeof filterProperties['item-padding-x'] === 'number'
91
- ? filterProperties['item-padding-x']
92
- : typeof filterProperties['item-padding-x'] === 'string'
93
- ? parseInt(filterProperties['item-padding-x'], 10)
94
- : 0;
95
- const itemMarginBottom =
96
- typeof filterProperties['item-margin-bottom'] === 'number'
97
- ? filterProperties['item-margin-bottom']
98
- : typeof filterProperties['item-margin-bottom'] === 'string'
99
- ? parseInt(filterProperties['item-margin-bottom'], 10)
100
- : 0;
101
-
102
- // Sidebar layout (desktop + mobile)
103
- if (layout === 'sidebar') {
104
- return (
105
- <>
106
- {/* Mobile overlay backdrop */}
107
- {isMenuOpen && (
108
- <div
109
- className="fixed inset-0 bg-black/80 z-40 lg:hidden transition-opacity duration-300"
110
- onClick={() => setIsMenuOpen(false)}
35
+ return (
36
+ <div
37
+ className={clsx(
38
+ 'w-9/10 fixed left-0 top-0 bottom-0 bg-white z-20 p-6 transition-all ease-in duration-300 lg:static lg:block lg:mr-16 lg:text-sm lg:p-0 lg:pt-4',
39
+ isMenuOpen
40
+ ? 'flex flex-col opacity-100 overflow-auto'
41
+ : 'opacity-0 invisible absolute -translate-x-full lg:opacity-100 lg:visible lg:translate-x-0'
42
+ )}
43
+ >
44
+ <div className="flex justify-between mb-6 lg:hidden">
45
+ <h3 className="text-2xl">{t('category.filters.title')}</h3>
46
+ <Icon name="close" size={22} onClick={() => setIsMenuOpen(false)} />
47
+ </div>
48
+ <div className="flex justify-between items-center mb-6 lg:hidden">
49
+ <span className="text-sm">1 {t('category.filters.results')}</span>
50
+ <span>{t('category.filters.ready_to_wear')}</span>
51
+ </div>
52
+
53
+ {facets?.map((facet) => {
54
+ return (
55
+ <FilterItem
56
+ key={facet.key}
57
+ facet={facet}
58
+ isPending={isPending}
59
+ startTransition={startTransition}
111
60
  />
112
- )}
113
-
114
- {/* Mobile slide-in menu */}
115
- <div
116
- className={clsx(
117
- 'w-11/12 fixed left-0 top-0 bottom-0 bg-white z-50 transition-all ease-in duration-300 lg:hidden',
118
- isMenuOpen
119
- ? 'flex flex-col opacity-100 overflow-auto'
120
- : 'opacity-0 invisible absolute -translate-x-full'
121
- )}
122
- style={containerStyles}
123
- data-section-id="filters-section"
124
- >
125
- <div className="relative flex items-center justify-center mb-6 border-b border-black-650 pt-2 pb-3">
126
- <div className="flex flex-col items-center text-center gap-1 text-black-750">
127
- <h3 className="text-sm">{t('category.filters.mobile_title')}</h3>
128
- <span className="text-[10px]">
129
- {totalCount} {t('category.header.results')}
130
- </span>
131
- </div>
132
- <Button
133
- type="button"
134
- appearance="ghost"
135
- aria-label="Close Filter Menu"
136
- onClick={() => setIsMenuOpen(false)}
137
- className="absolute right-4 p-0 text-black bg-transparent hover:bg-transparent hover:text-black"
138
- >
139
- <Icon name="close" size={16} />
140
- </Button>
141
- </div>
142
-
143
- <div className="px-4">
144
- {facets?.map((facet) => {
145
- return (
146
- <FilterItem
147
- key={facet.key}
148
- facet={facet}
149
- isPending={isPending}
150
- startTransition={startTransition}
151
- itemPaddingY={itemPaddingY}
152
- itemPaddingX={itemPaddingX}
153
- itemMarginBottom={itemMarginBottom}
154
- />
155
- );
156
- })}
157
- </div>
158
-
159
- <div className="px-4 flex items-center justify-between text-black-750 text-sm">
160
- {t('category.header.sort_by')}:
161
- <Select
162
- options={sortOptions}
163
- value={sortOptions?.find(({ is_selected }) => is_selected)?.value}
164
- data-testid="list-sorter"
165
- className="border-0 text-black-750 text-sm"
166
- onChange={(e) => {
167
- handleSelectFilter({
168
- key: 'sorter',
169
- value: e.currentTarget.value
170
- });
171
- }}
172
- borderless={false}
173
- />
174
- </div>
175
-
176
- <div className="p-8">
177
- <CategoryActiveFilters />
178
- </div>
179
-
180
- {haveFilter && (
181
- <div className="px-4">
182
- <Button
183
- onClick={handleResetFilter}
184
- appearance="filled"
185
- className="w-full mt-4"
186
- data-section-id="filters-section"
187
- >
188
- {t('category.filters.clear_all')}
189
- </Button>
190
- </div>
191
- )}
61
+ );
62
+ })}
63
+
64
+ <div className="lg:hidden">
65
+ <CategoryActiveFilters />
66
+ </div>
67
+
68
+ {haveFilter && (
69
+ <div className="lg:hidden">
70
+ <Button
71
+ onClick={handleResetFilter}
72
+ appearance="outlined"
73
+ className="w-full mt-4 lg:hidden"
74
+ >
75
+ {t('category.filters.clear_all')}
76
+ </Button>
192
77
  </div>
193
-
194
- {/* Desktop sidebar */}
195
- <aside
196
- className="hidden lg:block lg:col-span-1"
197
- style={containerStyles}
198
- data-section-id="filters-section"
199
- >
200
- <div className="sticky top-24">
201
- <h3 className="text-lg font-medium mb-4">
202
- {t('category.filters.title')}
203
- </h3>
204
-
205
- <div>
206
- {facets?.map((facet) => {
207
- return (
208
- <FilterItem
209
- key={facet.key}
210
- facet={facet}
211
- isPending={isPending}
212
- startTransition={startTransition}
213
- itemPaddingY={itemPaddingY}
214
- itemPaddingX={itemPaddingX}
215
- itemMarginBottom={itemMarginBottom}
216
- />
217
- );
218
- })}
219
- </div>
220
-
221
- {haveFilter && (
222
- <div className="mt-6">
223
- <Button
224
- onClick={handleResetFilter}
225
- appearance="outlined"
226
- className="w-full"
227
- data-section-id="filters-section"
228
- >
229
- {t('category.filters.clear_all')}
230
- </Button>
231
- </div>
232
- )}
233
- </div>
234
- </aside>
235
- </>
236
- );
237
- }
238
-
239
- // Top layout - return null, handled in category-header
240
- return null;
78
+ )}
79
+ </div>
80
+ );
241
81
  };
@@ -1,10 +1,8 @@
1
1
  import clsx from 'clsx';
2
2
  import { BreadcrumbResultType, GetCategoryResponse } from '@akinon/next/types';
3
- import ThemePlaceholder from '@akinon/next/components/theme-editor/theme-placeholder';
4
3
  import Breadcrumb from '@theme/views/breadcrumb';
5
4
  import { CategoryBanner } from '@theme/views/category/category-banner';
6
5
  import ListPage from '@theme/views/category/category-info';
7
- import ProductListRegistrar from '@theme/views/category/product-list-registrar';
8
6
 
9
7
  export default async function Layout({
10
8
  data,
@@ -14,10 +12,10 @@ export default async function Layout({
14
12
  data: GetCategoryResponse;
15
13
  children?: React.ReactNode;
16
14
  breadcrumbData?: BreadcrumbResultType[];
15
+ pageContext?: Record<string, unknown>;
17
16
  }) {
18
17
  return (
19
- <ProductListRegistrar>
20
- <ThemePlaceholder slug="list-page-body-new" />
18
+ <>
21
19
  <div
22
20
  className={clsx(
23
21
  data?.category?.attributes?.category_banner
@@ -28,16 +26,16 @@ export default async function Layout({
28
26
  {children}
29
27
  <div
30
28
  className={clsx(
31
- 'my-10 lg:my-16',
29
+ 'my-4 lg:mt-7',
32
30
  data?.category?.attributes?.category_banner &&
33
31
  'lg:absolute lg:inset-x-0 z-10 container lg:my-4 mx-auto'
34
32
  )}
35
33
  >
36
34
  <Breadcrumb breadcrumbList={breadcrumbData} />
37
35
  </div>
38
- <CategoryBanner {...data?.category?.attributes?.banner} />
36
+ <CategoryBanner {...data?.category?.attributes?.category_banner} />
39
37
  </div>
40
38
  <ListPage data={data} />
41
- </ProductListRegistrar>
39
+ </>
42
40
  );
43
41
  }
@@ -1,8 +1,3 @@
1
1
  export * from './step-button';
2
2
  export * from './step-list';
3
3
  export * from './summary';
4
- export * from './checkout-address-registrar';
5
- export * from './checkout-delivery-method-registrar';
6
- export * from './checkout-payment-options-registrar';
7
- export * from './checkout-summary-registrar';
8
- export * from './checkout-buttons-registrar';
@@ -4,7 +4,6 @@ import { CheckoutPaymentOption } from '@akinon/next/types';
4
4
  import clsx from 'clsx';
5
5
  import { RootState } from '@theme/redux/store';
6
6
  import PaymentOptionButtons from './payment-option-buttons';
7
- import { CheckoutPaymentOptionsRegistrar } from '@theme/views/checkout/checkout-payment-options-registrar';
8
7
 
9
8
  export const PaymentOptionViews: Array<CheckoutPaymentOption> = [];
10
9
 
@@ -19,10 +18,8 @@ const PaymentStep = () => {
19
18
  'pointer-events-none opacity-30': isPaymentStepBusy
20
19
  })}
21
20
  >
22
- <div className="w-full mt-4 md:border md:border-gray-400 md:-mb-px md:z-10 md:mt-0 md:border-b-0 order-2 md:order-none">
23
- <CheckoutPaymentOptionsRegistrar>
24
- <PaymentOptionButtons />
25
- </CheckoutPaymentOptionsRegistrar>
21
+ <div className="w-full mt-4 flex justify-start border border-gray-400 -mb-px z-10 md:mt-0 md:border-r-0 md:border-b-0 md:w-auto order-2 md:order-none overflow-x-auto">
22
+ <PaymentOptionButtons />
26
23
  </div>
27
24
  <div className="w-full border border-solid border-gray-400 bg-white">
28
25
  <SelectedPaymentOptionView />