@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
@@ -1,13 +1,38 @@
1
- /**
2
- * Breadcrumb Component
3
- *
4
- * Re-exports the Breadcrumb component from the breadcrumb folder.
5
- * This file is kept for backwards compatibility with existing imports.
6
- */
7
- export { default } from './breadcrumb/index';
8
- export type { BreadcrumbProps } from './breadcrumb/index';
9
- export {
10
- BreadcrumbRegistrar,
11
- useBreadcrumb,
12
- BreadcrumbClient
13
- } from './breadcrumb/index';
1
+ 'use client';
2
+
3
+ import { Fragment } from 'react';
4
+ import { Icon, Link } from '@theme/components';
5
+ import { ROUTES } from '@theme/routes';
6
+ import { useLocalization } from '@akinon/next/hooks';
7
+ import { BreadcrumbResultType } from '@akinon/next/types';
8
+ import { capitalize } from '@akinon/next/utils';
9
+
10
+ export interface BreadcrumbProps {
11
+ breadcrumbList?: BreadcrumbResultType[];
12
+ }
13
+
14
+ export default function Breadcrumb(props: BreadcrumbProps) {
15
+ const { t, locale } = useLocalization();
16
+ const { breadcrumbList = [] } = props;
17
+
18
+ const list = [
19
+ { url: ROUTES.HOME, text: t('common.breadcrumb.homepage') },
20
+ ...breadcrumbList.map((breadcrumb) => ({
21
+ url: breadcrumb.url,
22
+ text: breadcrumb.label
23
+ }))
24
+ ];
25
+
26
+ return (
27
+ <div className="flex items-center gap-3 text-xs leading-4 text-gray-950">
28
+ {list.map((item, index) => (
29
+ <Fragment key={index}>
30
+ <Link href={item.url}>
31
+ {capitalize(item.text.toLocaleLowerCase(locale))}
32
+ </Link>
33
+ {index !== list.length - 1 && <Icon name="chevron-end" size={8} />}
34
+ </Fragment>
35
+ ))}
36
+ </div>
37
+ );
38
+ }
@@ -1,17 +1,13 @@
1
1
  'use client';
2
2
 
3
- import React, { useMemo, useState, useTransition, CSSProperties } from 'react';
3
+ import React, { useMemo } from 'react';
4
4
  import { usePathname, useSearchParams } from 'next/navigation';
5
5
  import clsx from 'clsx';
6
6
 
7
7
  import { Button, Icon, Select, Link } from '@theme/components';
8
8
  import { SortOption } from '@akinon/next/types';
9
- import { useAppSelector } from '@akinon/next/redux/hooks';
10
- import { FilterItem } from './filters/filter-item';
11
9
 
12
10
  import { useRouter, useLocalization } from '@akinon/next/hooks';
13
- import { useProductList } from './product-list-registrar';
14
- import { useNativeWidget } from './native-widget-context';
15
11
 
16
12
  interface Props {
17
13
  totalCount: number;
@@ -32,76 +28,16 @@ export const CategoryHeader = (props: Props) => {
32
28
  ];
33
29
  const { totalCount, setMenuStatus, sortOptions } = props;
34
30
  const router = useRouter();
35
- const facets = useAppSelector((state) => state.category.facets);
36
- const [openDropdown, setOpenDropdown] = useState<string | null>(null);
37
- const [isPending, startTransition] = useTransition();
38
31
 
39
32
  const searchParams = useSearchParams();
40
33
  const pathname = usePathname();
41
34
 
42
- // Get styles and properties from both contexts
43
- const {
44
- isDesigner,
45
- filterStyles: registrarStyles,
46
- filterProperties: registrarProps,
47
- productsProperties: registrarProductsProps
48
- } = useProductList();
49
- const {
50
- filterStyles: widgetStyles,
51
- filterProperties: widgetProps,
52
- productsProperties: widgetProductsProps
53
- } = useNativeWidget();
54
-
55
- // Use registrar data in designer mode, widget data otherwise
56
- const filterStyles = isDesigner ? registrarStyles : widgetStyles;
57
-
58
- // Merge properties - registrar props override widget props for live updates
59
- const filterProperties = {
60
- ...widgetProps,
61
- ...registrarProps
62
- };
63
-
64
- const layout = (filterProperties.layout as string) || 'top';
65
- const containerStyles = filterStyles as CSSProperties;
66
-
67
- // Get products properties - merge widget and registrar
68
- const productsProperties = {
69
- ...widgetProductsProps,
70
- ...registrarProductsProps
71
- };
72
- const showLayoutButtons = productsProperties['show-layout-buttons'] !== false;
73
- const availableLayouts = productsProperties['available-layouts'] || [
74
- '2',
75
- '3',
76
- '4'
77
- ];
78
-
79
- // Parse item properties
80
- const itemPaddingY =
81
- typeof filterProperties['item-padding-y'] === 'number'
82
- ? filterProperties['item-padding-y']
83
- : typeof filterProperties['item-padding-y'] === 'string'
84
- ? parseInt(filterProperties['item-padding-y'], 10)
85
- : 6;
86
- const itemPaddingX =
87
- typeof filterProperties['item-padding-x'] === 'number'
88
- ? filterProperties['item-padding-x']
89
- : typeof filterProperties['item-padding-x'] === 'string'
90
- ? parseInt(filterProperties['item-padding-x'], 10)
91
- : 0;
92
- const itemMarginBottom =
93
- typeof filterProperties['item-margin-bottom'] === 'number'
94
- ? filterProperties['item-margin-bottom']
95
- : typeof filterProperties['item-margin-bottom'] === 'string'
96
- ? parseInt(filterProperties['item-margin-bottom'], 10)
97
- : 0;
98
-
99
35
  const pageSize = useMemo(
100
36
  () => searchParams.get('page_size') ?? 48,
101
37
  [searchParams]
102
38
  );
103
39
  const layoutSize = useMemo(
104
- () => searchParams.get('layout') ?? '3',
40
+ () => searchParams.get('layout') ?? 3,
105
41
  [searchParams]
106
42
  );
107
43
 
@@ -119,241 +55,82 @@ export const CategoryHeader = (props: Props) => {
119
55
  router.push(pathname + '?' + urlSearchParams.toString());
120
56
  };
121
57
 
122
- const facetButtonStyles = {
123
- paddingTop: `${itemPaddingY}px`,
124
- paddingBottom: `${itemPaddingY}px`,
125
- paddingLeft: `${itemPaddingX}px`,
126
- paddingRight: `${itemPaddingX}px`,
127
- marginRight: `${itemMarginBottom}px`
128
- };
129
-
130
58
  return (
131
- <div className="w-full flex flex-col gap-4 text-gray-950 text-sm">
132
- {layout === 'top' && (
133
- <div
134
- className="hidden lg:flex items-center gap-6 text-sm"
135
- style={containerStyles}
136
- data-section-id="filters-section"
137
- >
138
- <span className="text-black-750 text-sm">
139
- {t('category.filters.title')}:
140
- </span>
141
- {facets?.map((facet) => (
142
- <div key={facet.key} className="relative" style={facetButtonStyles}>
143
- <Button
144
- onClick={() =>
145
- setOpenDropdown(openDropdown === facet.key ? null : facet.key)
146
- }
147
- appearance="ghost"
148
- className="flex items-center gap-2 p-0 text-sm text-black-750 hover:bg-transparent hover:text-black-750"
149
- >
150
- <span>{facet.name}</span>
151
- <Icon
152
- name="chevron-down"
153
- size={16}
154
- className={clsx(
155
- 'transition-transform',
156
- openDropdown === facet.key && 'rotate-180'
157
- )}
158
- />
159
- </Button>
160
- {openDropdown === facet.key && (
161
- <>
162
- <div
163
- className="fixed inset-0 z-10"
164
- onClick={() => setOpenDropdown(null)}
165
- />
166
- <div className="absolute top-full left-0 mt-2 w-64 bg-white border border-gray-200 rounded shadow-lg z-20 max-h-96 overflow-y-auto">
167
- <FilterItem
168
- facet={facet}
169
- isPending={isPending}
170
- startTransition={startTransition}
171
- isDropdown
172
- itemPaddingY={itemPaddingY}
173
- itemPaddingX={itemPaddingX}
174
- itemMarginBottom={itemMarginBottom}
175
- />
176
- </div>
177
- </>
178
- )}
179
- </div>
180
- ))}
181
- <div className="ml-auto flex items-center gap-2 text-black-750 text-sm">
182
- <span>{t('category.header.sort_by')}:</span>
183
- <Select
184
- options={sortOptions}
185
- value={sortOptions?.find(({ is_selected }) => is_selected)?.value}
186
- data-testid="list-sorter"
187
- onChange={(e) => {
188
- handleSelectFilter({
189
- key: 'sorter',
190
- value: e.currentTarget.value
191
- });
192
- }}
193
- className="text-black-750 text-sm border-0"
194
- borderless={false}
195
- />
196
- {showLayoutButtons && availableLayouts.length > 0 && (
197
- <div className="flex items-center gap-2">
198
- {availableLayouts.map((cols) => (
199
- <Button
200
- key={cols}
201
- onClick={() =>
202
- handleSelectFilter({
203
- key: 'layout',
204
- value: cols
205
- })
206
- }
207
- appearance="ghost"
208
- className={clsx(
209
- 'p-2 hover:bg-gray-100',
210
- layoutSize === cols && 'bg-gray-200'
211
- )}
212
- data-section-id="products-section"
213
- >
214
- <svg
215
- width="20"
216
- height="20"
217
- viewBox="0 0 20 20"
218
- fill="none"
219
- xmlns="http://www.w3.org/2000/svg"
220
- >
221
- {Array.from({ length: parseInt(cols) }).map((_, i) => {
222
- const colWidth = 20 / parseInt(cols);
223
- const gap = 2;
224
- const rectWidth = colWidth - gap;
225
- return (
226
- <g key={i}>
227
- <rect
228
- x={i * colWidth}
229
- y="0"
230
- width={rectWidth}
231
- height="8"
232
- fill="currentColor"
233
- />
234
- <rect
235
- x={i * colWidth}
236
- y="10"
237
- width={rectWidth}
238
- height="8"
239
- fill="currentColor"
240
- />
241
- </g>
242
- );
243
- })}
244
- </svg>
245
- </Button>
246
- ))}
247
- </div>
248
- )}
249
- <span>
250
- <span data-testid="list-count">{totalCount}</span>{' '}
251
- {t('category.header.results')}
252
- </span>
253
- </div>
254
- </div>
255
- )}
59
+ <div className="flex flex-col gap-4 mb-4 text-gray-950 text-sm">
60
+ <div className="flex items-center">
61
+ <span className="hidden lg:block">
62
+ <span data-testid="list-count">{totalCount}</span>{' '}
63
+ {t('category.header.results')}
64
+ </span>
256
65
 
257
- {/* Sidebar layout - show sorting and product count */}
258
- {layout === 'sidebar' && (
259
- <div
260
- className="hidden lg:flex items-center justify-between"
261
- style={containerStyles}
262
- data-section-id="filters-section"
263
- >
264
- <div className="flex items-center gap-2 text-black-750 text-sm">
265
- <span>{t('category.header.sort_by')}:</span>
266
- <Select
267
- options={sortOptions}
268
- value={sortOptions?.find(({ is_selected }) => is_selected)?.value}
269
- data-testid="list-sorter"
270
- onChange={(e) => {
66
+ <div className="hidden lg:flex gap-5 ml-auto mr-7 px-5 py-2 border border-gray-100">
67
+ <span> {t('category.header.view')}</span>
68
+ {PAGE_SIZE.map(({ label, value }) => (
69
+ <a
70
+ key={value}
71
+ onClick={() => {
271
72
  handleSelectFilter({
272
- key: 'sorter',
273
- value: e.currentTarget.value
73
+ key: 'page_size',
74
+ value: String(value)
274
75
  });
275
76
  }}
276
- className="text-black-750 text-sm border-0"
277
- borderless={false}
278
- />
279
- </div>
280
- <span className="text-black-750 text-sm">
281
- <span data-testid="list-count">{totalCount}</span>{' '}
282
- {t('category.header.results')}
283
- </span>
284
- {showLayoutButtons && availableLayouts.length > 0 && (
285
- <div className="flex items-center gap-2">
286
- {availableLayouts.map((cols) => (
287
- <Button
288
- key={cols}
289
- onClick={() =>
290
- handleSelectFilter({
291
- key: 'layout',
292
- value: cols
293
- })
77
+ className={clsx('cursor-pointer', {
78
+ 'text-black font-semibold': Number(pageSize) === value
79
+ })}
80
+ >
81
+ {label}
82
+ </a>
83
+ ))}
84
+ <div className="flex items-center gap-2 pl-5 border-l border-gray-400">
85
+ {LAYOUTS.map(({ icon, value }) => (
86
+ <a
87
+ key={value}
88
+ onClick={() => {
89
+ handleSelectFilter({
90
+ key: 'layout',
91
+ value: String(value)
92
+ });
93
+ }}
94
+ className="cursor-pointer"
95
+ >
96
+ <Icon
97
+ key={value}
98
+ name={icon}
99
+ size={16}
100
+ className={
101
+ Number(layoutSize) === value
102
+ ? 'text-black'
103
+ : 'text-gray-500'
294
104
  }
295
- appearance="ghost"
296
- className={clsx(
297
- 'p-2 hover:bg-gray-100',
298
- layoutSize === cols && 'bg-gray-200'
299
- )}
300
- data-section-id="products-section"
301
- >
302
- <svg
303
- width="20"
304
- height="20"
305
- viewBox="0 0 20 20"
306
- fill="none"
307
- xmlns="http://www.w3.org/2000/svg"
308
- >
309
- {Array.from({ length: parseInt(cols) }).map((_, i) => {
310
- const colWidth = 20 / parseInt(cols);
311
- const gap = 2;
312
- const rectWidth = colWidth - gap;
313
- return (
314
- <g key={i}>
315
- <rect
316
- x={i * colWidth}
317
- y="0"
318
- width={rectWidth}
319
- height="8"
320
- fill="currentColor"
321
- />
322
- <rect
323
- x={i * colWidth}
324
- y="10"
325
- width={rectWidth}
326
- height="8"
327
- fill="currentColor"
328
- />
329
- </g>
330
- );
331
- })}
332
- </svg>
333
- </Button>
334
- ))}
335
- </div>
336
- )}
105
+ />
106
+ </a>
107
+ ))}
108
+ </div>
337
109
  </div>
338
- )}
339
-
340
- <div className="flex items-center w-full justify-between lg:hidden">
341
110
  <Button
342
- className="relative p-0 hover:bg-transparent hover:text-black"
111
+ className="relative border-gray-100 text-left mr-5 bg-white text-primary-100 w-40 lg:hidden lg:mr-0"
343
112
  onClick={() => setMenuStatus()}
344
- appearance="ghost"
345
113
  data-testid="list-filter"
346
114
  >
347
- <Icon name="filter-and-sort" size={20} />
348
- <span className="lg:hidden text-sm">
349
- {t('category.filters.mobile_title')}
350
- </span>
351
- <span className="hidden lg:block">{t('category.filters.title')}</span>
115
+ {t('category.filters.title')}
116
+ <Icon
117
+ name="chevron-down"
118
+ size={10}
119
+ className="absolute right-1 top-1/2 transform -translate-y-1/2"
120
+ />
352
121
  </Button>
353
- <span>
354
- <span data-testid="list-count">{totalCount}</span>{' '}
355
- {t('category.header.results')}
356
- </span>
122
+ <Select
123
+ options={sortOptions}
124
+ value={sortOptions?.find(({ is_selected }) => is_selected)?.value}
125
+ data-testid="list-sorter"
126
+ onChange={(e) => {
127
+ handleSelectFilter({
128
+ key: 'sorter',
129
+ value: e.currentTarget.value
130
+ });
131
+ }}
132
+ borderless={false}
133
+ />
357
134
  </div>
358
135
  {totalCount === 0 && (
359
136
  <div className="h-40 flex items-center justify-center flex-col bg-gray-200 p-4">