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

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 (140) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/app-template/CHANGELOG.md +170 -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/codemods/migrate-auth-v5/index.js +339 -0
  66. package/codemods/migrate-auth-v5/transform.js +86 -0
  67. package/dist/commands/plugins.js +23 -2
  68. package/package.json +1 -1
  69. package/app-template/src/app/[commerce]/[locale]/[currency]/pages/[slug]/page.tsx +0 -15
  70. package/app-template/src/views/basket/basket-summary-context.tsx +0 -560
  71. package/app-template/src/views/basket/designer-context.tsx +0 -617
  72. package/app-template/src/views/breadcrumb/breadcrumb-client.tsx +0 -190
  73. package/app-template/src/views/breadcrumb/breadcrumb-registrar.tsx +0 -286
  74. package/app-template/src/views/breadcrumb/constants.ts +0 -15
  75. package/app-template/src/views/breadcrumb/index.tsx +0 -127
  76. package/app-template/src/views/category/native-widget-context.tsx +0 -257
  77. package/app-template/src/views/category/product-list-registrar.tsx +0 -665
  78. package/app-template/src/views/checkout/checkout-address-registrar.tsx +0 -254
  79. package/app-template/src/views/checkout/checkout-buttons-registrar.tsx +0 -183
  80. package/app-template/src/views/checkout/checkout-delivery-method-registrar.tsx +0 -259
  81. package/app-template/src/views/checkout/checkout-payment-options-registrar.tsx +0 -253
  82. package/app-template/src/views/checkout/checkout-summary-registrar.tsx +0 -183
  83. package/app-template/src/views/checkout/constants.ts +0 -5
  84. package/app-template/src/views/checkout/steps/payment/options/masterpass-rest.tsx +0 -15
  85. package/app-template/src/views/checkout/steps/payment/options/saved-card.tsx +0 -18
  86. package/app-template/src/views/footer/footer-app-banner-context.tsx +0 -326
  87. package/app-template/src/views/footer/footer-bottom-context.tsx +0 -215
  88. package/app-template/src/views/footer/footer-bottom-wrapper.tsx +0 -74
  89. package/app-template/src/views/footer/footer-layout-constants.ts +0 -35
  90. package/app-template/src/views/footer/footer-layout-registrar.tsx +0 -342
  91. package/app-template/src/views/footer/footer-layout-switcher.tsx +0 -110
  92. package/app-template/src/views/footer/footer-menu-context.tsx +0 -211
  93. package/app-template/src/views/footer/footer-native-widgets.tsx +0 -60
  94. package/app-template/src/views/footer/footer-social-context.tsx +0 -254
  95. package/app-template/src/views/footer/footer-subscription-context.tsx +0 -210
  96. package/app-template/src/views/footer/footer-utils.ts +0 -43
  97. package/app-template/src/views/footer/footer-value-props-context.tsx +0 -326
  98. package/app-template/src/views/footer/logo-settings.ts +0 -183
  99. package/app-template/src/views/footer/native-widget-config.ts +0 -262
  100. package/app-template/src/views/footer/subscription-settings.ts +0 -122
  101. package/app-template/src/views/footer/use-footer-logo.ts +0 -162
  102. package/app-template/src/views/header/designer-context.tsx +0 -261
  103. package/app-template/src/views/header/header-announcement-registrar.tsx +0 -267
  104. package/app-template/src/views/header/header-client-wrapper.tsx +0 -496
  105. package/app-template/src/views/header/header-content.tsx +0 -1026
  106. package/app-template/src/views/header/header-currency-registrar.tsx +0 -348
  107. package/app-template/src/views/header/header-icons-context.tsx +0 -262
  108. package/app-template/src/views/header/header-language-registrar.tsx +0 -348
  109. package/app-template/src/views/header/header-layout-context.tsx +0 -143
  110. package/app-template/src/views/header/header-layout-registrar.tsx +0 -658
  111. package/app-template/src/views/header/header-logo-context.tsx +0 -228
  112. package/app-template/src/views/header/header-logo.tsx +0 -118
  113. package/app-template/src/views/header/header-mini-basket-context.tsx +0 -524
  114. package/app-template/src/views/header/header-search-registrar.tsx +0 -511
  115. package/app-template/src/views/header/header-text-slider-registrar.tsx +0 -382
  116. package/app-template/src/views/header/inline-search.tsx +0 -262
  117. package/app-template/src/views/header/navbar-menu-context.tsx +0 -219
  118. package/app-template/src/views/header/search/search-input.tsx +0 -61
  119. package/app-template/src/views/header/server-settings-parser.ts +0 -1105
  120. package/app-template/src/views/header/use-header-icons.ts +0 -241
  121. package/app-template/src/views/header/use-header-logo.ts +0 -213
  122. package/app-template/src/views/header/use-navbar-menu.ts +0 -179
  123. package/app-template/src/views/product/accordion-section.tsx +0 -61
  124. package/app-template/src/views/product/custom-button-group.tsx +0 -69
  125. package/app-template/src/views/product/favorites-button-section.tsx +0 -69
  126. package/app-template/src/views/product/find-in-store-section.tsx +0 -60
  127. package/app-template/src/views/product/product-info-section.tsx +0 -140
  128. package/app-template/src/views/product/quantity-section.tsx +0 -73
  129. package/app-template/src/views/product/sale-tag.tsx +0 -10
  130. package/app-template/src/views/product/share-section.tsx +0 -357
  131. package/app-template/src/views/product/variants-section.tsx +0 -126
  132. package/app-template/src/views/product-detail/constants.ts +0 -272
  133. package/app-template/src/views/product-detail/index.ts +0 -10
  134. package/app-template/src/views/product-detail/product-detail-registrar.tsx +0 -616
  135. package/app-template/src/widgets/footer-app-banner.tsx +0 -444
  136. package/app-template/src/widgets/footer-bottom.tsx +0 -127
  137. package/app-template/src/widgets/footer-menu-compact.tsx +0 -238
  138. package/app-template/src/widgets/footer-menu-two.tsx +0 -298
  139. package/app-template/src/widgets/footer-social-client.tsx +0 -251
  140. 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 />