@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
@@ -1,69 +0,0 @@
1
- 'use client';
2
-
3
- import { Icon, Button } from '@theme/components';
4
-
5
- type CustomButtonGroupProps = {
6
- carouselState?: {
7
- currentSlide: number;
8
- totalItems: number;
9
- };
10
- previous?: () => void;
11
- next?: () => void;
12
- goToSlide?: (slide: number) => void;
13
- };
14
-
15
- export default function CustomButtonGroup({
16
- carouselState,
17
- previous,
18
- next
19
- }: CustomButtonGroupProps) {
20
- const currentSlide = carouselState?.currentSlide ?? 0;
21
- const totalItems = carouselState?.totalItems ?? 0;
22
-
23
- if (!totalItems) return null;
24
-
25
- const isFirstSlide = currentSlide === 0;
26
- const isLastSlide = currentSlide >= totalItems - 1;
27
-
28
- const handlePrevClick = () => {
29
- if (isFirstSlide) return;
30
- previous?.();
31
- };
32
-
33
- const handleNextClick = () => {
34
- if (isLastSlide) return;
35
- next?.();
36
- };
37
-
38
- return (
39
- <div className="relative mt-3 w-full">
40
- <div className="flex items-center justify-center gap-2 text-[13px] font-medium text-gray-650">
41
- <Button
42
- type="button"
43
- aria-label="Previous image"
44
- aria-disabled={isFirstSlide}
45
- disabled={isFirstSlide}
46
- onClick={handlePrevClick}
47
- className="bg-transparent text-primary border-none"
48
- >
49
- <Icon name="chevron-start" size={12} />
50
- </Button>
51
-
52
- <span>
53
- {currentSlide + 1}/{totalItems}
54
- </span>
55
-
56
- <Button
57
- type="button"
58
- aria-label="Next image"
59
- aria-disabled={isLastSlide}
60
- disabled={isLastSlide}
61
- onClick={handleNextClick}
62
- className="bg-transparent text-primary border-none"
63
- >
64
- <Icon name="chevron-end" size={12} className="text-gray-900" />
65
- </Button>
66
- </div>
67
- </div>
68
- );
69
- }
@@ -1,69 +0,0 @@
1
- 'use client';
2
-
3
- /**
4
- * Favorites Button Section Wrapper
5
- *
6
- * Wraps favorites button with Theme Editor styling support.
7
- * Applies CSS variables for customization via Theme Editor.
8
- */
9
-
10
- import { PropsWithChildren, CSSProperties, useMemo } from 'react';
11
- import clsx from 'clsx';
12
- import {
13
- useProductDetail,
14
- FAVORITES_BUTTON_SECTION_ID
15
- } from '@theme/views/product-detail';
16
-
17
- export default function FavoritesButtonSection({
18
- children
19
- }: PropsWithChildren) {
20
- const { isDesigner, selectedSectionId, favoritesButtonStyles } =
21
- useProductDetail();
22
-
23
- // Check if this section is selected in designer mode
24
- const isSelected =
25
- isDesigner && selectedSectionId === FAVORITES_BUTTON_SECTION_ID;
26
-
27
- // Build CSS variables from favoritesButtonStyles
28
- const cssVariables = useMemo((): CSSProperties => {
29
- if (!favoritesButtonStyles) return {};
30
-
31
- const vars: Record<string, string> = {};
32
- Object.entries(favoritesButtonStyles).forEach(([key, value]) => {
33
- if (value) {
34
- vars[`--favorites-button-${key}`] = value;
35
- }
36
- });
37
- return vars as CSSProperties;
38
- }, [favoritesButtonStyles]);
39
-
40
- const handleClick = (e: React.MouseEvent) => {
41
- if (isDesigner) {
42
- e.stopPropagation();
43
- window.parent?.postMessage(
44
- {
45
- type: 'SELECT_SECTION',
46
- data: {
47
- placeholderId: 'product-detail',
48
- sectionId: FAVORITES_BUTTON_SECTION_ID
49
- }
50
- },
51
- '*'
52
- );
53
- }
54
- };
55
-
56
- return (
57
- <div
58
- className={clsx(
59
- 'favorites-button-section',
60
- isDesigner && 'cursor-pointer',
61
- isSelected && 'ring-2 ring-blue-500 ring-offset-2'
62
- )}
63
- style={cssVariables}
64
- onClick={handleClick}
65
- >
66
- {children}
67
- </div>
68
- );
69
- }
@@ -1,60 +0,0 @@
1
- 'use client';
2
-
3
- import React, { CSSProperties, useMemo } from 'react';
4
- import { useDesignerFeatures } from '@akinon/next/components/theme-editor/hooks/use-designer-features';
5
- import {
6
- useProductDetail,
7
- PRODUCT_DETAIL_PLACEHOLDER_ID,
8
- FIND_IN_STORE_SECTION_ID
9
- } from '@theme/views/product-detail';
10
-
11
- interface FindInStoreSectionProps {
12
- children: React.ReactNode;
13
- }
14
-
15
- export default function FindInStoreSection({
16
- children
17
- }: FindInStoreSectionProps) {
18
- const { isDesigner, selectedSectionId, findInStoreStyles } =
19
- useProductDetail();
20
-
21
- const { handleClick } = useDesignerFeatures({
22
- sectionId: FIND_IN_STORE_SECTION_ID,
23
- placeholderId: PRODUCT_DETAIL_PLACEHOLDER_ID,
24
- blockId: '',
25
- isDesigner
26
- });
27
-
28
- const isSelected = selectedSectionId === FIND_IN_STORE_SECTION_ID;
29
-
30
- const cssVariables = useMemo((): CSSProperties => {
31
- if (!findInStoreStyles) return {};
32
-
33
- const vars: Record<string, string> = {};
34
- Object.entries(findInStoreStyles).forEach(([key, value]) => {
35
- if (value) {
36
- vars[`--find-in-store-${key}`] = value;
37
- }
38
- });
39
- return vars as CSSProperties;
40
- }, [findInStoreStyles]);
41
-
42
- if (!isDesigner) {
43
- return <>{children}</>;
44
- }
45
-
46
- return (
47
- <div
48
- onClick={handleClick}
49
- style={{
50
- ...cssVariables,
51
- cursor: 'pointer',
52
- outline: isSelected ? '2px solid #3b82f6' : 'none',
53
- outlineOffset: '2px'
54
- }}
55
- data-section-id={FIND_IN_STORE_SECTION_ID}
56
- >
57
- {children}
58
- </div>
59
- );
60
- }
@@ -1,140 +0,0 @@
1
- 'use client';
2
-
3
- import React from 'react';
4
- import { Product } from '@akinon/next/types';
5
- import { Price } from '@theme/components';
6
- import {
7
- useProductDetail,
8
- PRODUCT_INFO_SECTION_ID
9
- } from '@theme/views/product-detail';
10
- import clsx from 'clsx';
11
-
12
- interface ProductInfoSectionProps {
13
- product: Product;
14
- }
15
-
16
- export const ProductInfoSection: React.FC<ProductInfoSectionProps> = ({
17
- product
18
- }) => {
19
- const { isDesigner, selectedSectionId, productInfoStyles } =
20
- useProductDetail();
21
-
22
- const isSelected = selectedSectionId === PRODUCT_INFO_SECTION_ID;
23
-
24
- // Handle designer click for section selection
25
- const handleDesignerClick = () => {
26
- if (isDesigner) {
27
- window.parent?.postMessage(
28
- {
29
- type: 'SELECT_SECTION',
30
- data: {
31
- placeholderId: 'product-detail',
32
- sectionId: PRODUCT_INFO_SECTION_ID
33
- }
34
- },
35
- '*'
36
- );
37
- }
38
- };
39
-
40
- const infoStyles: Record<string, string> = {};
41
-
42
- // Product name styles
43
- if (productInfoStyles['name-font-size'])
44
- infoStyles['--product-name-font-size'] =
45
- productInfoStyles['name-font-size'];
46
- if (productInfoStyles['name-font-weight'])
47
- infoStyles['--product-name-font-weight'] =
48
- productInfoStyles['name-font-weight'];
49
- if (productInfoStyles['name-color'])
50
- infoStyles['--product-name-color'] = productInfoStyles['name-color'];
51
- if (productInfoStyles['name-line-height'])
52
- infoStyles['--product-name-line-height'] =
53
- productInfoStyles['name-line-height'];
54
-
55
- // Price styles
56
- if (productInfoStyles['price-font-size'])
57
- infoStyles['--product-price-font-size'] =
58
- productInfoStyles['price-font-size'];
59
- if (productInfoStyles['price-font-weight'])
60
- infoStyles['--product-price-font-weight'] =
61
- productInfoStyles['price-font-weight'];
62
- if (productInfoStyles['price-color'])
63
- infoStyles['--product-price-color'] = productInfoStyles['price-color'];
64
-
65
- // Retail price styles
66
- if (productInfoStyles['retail-price-font-size'])
67
- infoStyles['--product-retail-price-font-size'] =
68
- productInfoStyles['retail-price-font-size'];
69
- if (productInfoStyles['retail-price-font-weight'])
70
- infoStyles['--product-retail-price-font-weight'] =
71
- productInfoStyles['retail-price-font-weight'];
72
- if (productInfoStyles['retail-price-color'])
73
- infoStyles['--product-retail-price-color'] =
74
- productInfoStyles['retail-price-color'];
75
-
76
- // Description styles
77
- if (productInfoStyles['description-font-size'])
78
- infoStyles['--product-description-font-size'] =
79
- productInfoStyles['description-font-size'];
80
- if (productInfoStyles['description-font-weight'])
81
- infoStyles['--product-description-font-weight'] =
82
- productInfoStyles['description-font-weight'];
83
- if (productInfoStyles['description-color'])
84
- infoStyles['--product-description-color'] =
85
- productInfoStyles['description-color'];
86
- if (productInfoStyles['description-line-height'])
87
- infoStyles['--product-description-line-height'] =
88
- productInfoStyles['description-line-height'];
89
-
90
- return (
91
- <div
92
- style={infoStyles}
93
- className={clsx('relative', {
94
- 'ring-2 ring-blue-500 ring-offset-2': isDesigner && isSelected
95
- })}
96
- onClick={handleDesignerClick}
97
- >
98
- {/* Product Name */}
99
- <h1
100
- className="text-3xl text-black-750 mb-4"
101
- style={{
102
- fontSize: 'var(--product-name-font-size, 24px)',
103
- fontWeight: 'var(--product-name-font-weight, 600)',
104
- color: 'var(--product-name-color, #1f2937)',
105
- lineHeight: 'var(--product-name-line-height, 1.2)'
106
- }}
107
- data-testid="product-name"
108
- >
109
- {product.name}
110
- </h1>
111
-
112
- {/* Price */}
113
- <div
114
- className="text-black-750 mb-4"
115
- style={{
116
- fontSize: 'var(--product-price-font-size, 28px)',
117
- fontWeight: 'var(--product-price-font-weight, 700)',
118
- color: 'var(--product-price-color, #030712)'
119
- }}
120
- >
121
- <Price value={product.price} data-testid="price" />
122
- </div>
123
-
124
- {/* Description */}
125
- {product.attributes?.description && (
126
- <p
127
- className="text-black-750 tracking-[0.64px] mb-4"
128
- style={{
129
- fontSize: 'var(--product-description-font-size, 14px)',
130
- fontWeight: 'var(--product-description-font-weight, 400)',
131
- color: 'var(--product-description-color, #6b7280)',
132
- lineHeight: 'var(--product-description-line-height, 1.6)'
133
- }}
134
- >
135
- {product.attributes.description}
136
- </p>
137
- )}
138
- </div>
139
- );
140
- };
@@ -1,73 +0,0 @@
1
- 'use client';
2
-
3
- import { useLocalization } from '@akinon/next/hooks';
4
- import { QuantitySelector } from '@theme/components';
5
- import {
6
- useProductDetail,
7
- QUANTITY_SECTION_ID
8
- } from '@theme/views/product-detail';
9
- import clsx from 'clsx';
10
-
11
- interface QuantitySectionProps {
12
- quantity: number;
13
- onChange: (quantity: number) => void;
14
- disabled?: boolean;
15
- min?: number;
16
- max?: number;
17
- }
18
-
19
- /**
20
- * QuantitySection Component
21
- *
22
- * Wraps QuantitySelector with Theme Editor integration.
23
- * Allows customization of display type (buttons/dropdown) and styles.
24
- */
25
- export function QuantitySection({
26
- quantity,
27
- onChange,
28
- disabled = false,
29
- min = 1,
30
- max = 999
31
- }: QuantitySectionProps) {
32
- const { t } = useLocalization();
33
- const { isDesigner, selectedSectionId, quantityStyles, quantityProperties } =
34
- useProductDetail();
35
-
36
- const isSelected = selectedSectionId === QUANTITY_SECTION_ID;
37
-
38
- // Handle designer click for section selection
39
- const handleDesignerClick = () => {
40
- if (isDesigner) {
41
- window.parent?.postMessage(
42
- {
43
- type: 'SELECT_SECTION',
44
- data: {
45
- placeholderId: 'product-detail',
46
- sectionId: QUANTITY_SECTION_ID
47
- }
48
- },
49
- '*'
50
- );
51
- }
52
- };
53
-
54
- return (
55
- <div className="flex flex-col gap-2.5 mb-4">
56
- <span className="text-[13px] text-black-750 tracking-[0.39px]">
57
- {t('product.quantity')}
58
- </span>
59
- <QuantitySelector
60
- quantity={quantity}
61
- onChange={onChange}
62
- disabled={disabled}
63
- min={min}
64
- max={max}
65
- displayType={quantityProperties.displayType}
66
- maxDropdownOptions={quantityProperties.maxDropdownOptions}
67
- styles={quantityStyles}
68
- isSelected={isSelected}
69
- onDesignerClick={isDesigner ? handleDesignerClick : undefined}
70
- />
71
- </div>
72
- );
73
- }
@@ -1,10 +0,0 @@
1
- import { useLocalization } from '@akinon/next/hooks';
2
-
3
- export function SaleTag() {
4
- const { t } = useLocalization();
5
- return (
6
- <span className="inline-flex items-center px-3 py-1 rounded-full bg-[#014D4E] text-white text-[13px] tracking-[0.39px]">
7
- {t('common.sale')}
8
- </span>
9
- );
10
- }