@rebuy/rebuy-hydrogen 3.0.0-beta.1 → 3.0.0-beta.10

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 (143) hide show
  1. package/README.md +0 -2
  2. package/dist/components/AddToCartBtn/AddToCartBtn.d.ts +3 -0
  3. package/dist/components/AddToCartBtn/AddToCartBtn.d.ts.map +1 -0
  4. package/dist/components/AddToCartBtn/HydrogenAddToCartBtn.d.ts +3 -0
  5. package/dist/components/AddToCartBtn/HydrogenAddToCartBtn.d.ts.map +1 -0
  6. package/dist/components/AddToCartBtn/HydrogenReactAddToCartBtn.d.ts +3 -0
  7. package/dist/components/AddToCartBtn/HydrogenReactAddToCartBtn.d.ts.map +1 -0
  8. package/dist/components/AddToCartBtn/index.d.ts +2 -0
  9. package/dist/components/AddToCartBtn/index.d.ts.map +1 -0
  10. package/{src/components/AddToCartBtn/types.ts → dist/components/AddToCartBtn/types.d.ts} +1 -2
  11. package/dist/components/AddToCartBtn/types.d.ts.map +1 -0
  12. package/dist/components/ProductCard/ProductCard.d.ts +3 -0
  13. package/dist/components/ProductCard/ProductCard.d.ts.map +1 -0
  14. package/dist/components/ProductCard/index.d.ts +2 -0
  15. package/dist/components/ProductCard/index.d.ts.map +1 -0
  16. package/{src/components/ProductCard/types.ts → dist/components/ProductCard/types.d.ts} +2 -2
  17. package/dist/components/ProductCard/types.d.ts.map +1 -0
  18. package/dist/components/ProductPrice/ProductPrice.d.ts +5 -0
  19. package/dist/components/ProductPrice/ProductPrice.d.ts.map +1 -0
  20. package/dist/components/ProductPrice/index.d.ts +2 -0
  21. package/dist/components/ProductPrice/index.d.ts.map +1 -0
  22. package/dist/components/Title/Title.d.ts +3 -0
  23. package/dist/components/Title/Title.d.ts.map +1 -0
  24. package/dist/components/Title/index.d.ts +2 -0
  25. package/dist/components/Title/index.d.ts.map +1 -0
  26. package/{src/components/Title/types.ts → dist/components/Title/types.d.ts} +1 -1
  27. package/dist/components/Title/types.d.ts.map +1 -0
  28. package/dist/components/VariantSelect/VariantSelect.d.ts +3 -0
  29. package/dist/components/VariantSelect/VariantSelect.d.ts.map +1 -0
  30. package/dist/components/VariantSelect/index.d.ts +2 -0
  31. package/dist/components/VariantSelect/index.d.ts.map +1 -0
  32. package/{src/components/VariantSelect/types.ts → dist/components/VariantSelect/types.d.ts} +1 -1
  33. package/dist/components/VariantSelect/types.d.ts.map +1 -0
  34. package/{src/context/RebuyContext.tsx → dist/context/RebuyContext.d.ts} +2 -5
  35. package/dist/context/RebuyContext.d.ts.map +1 -0
  36. package/dist/hooks/titleLevel.d.ts +3 -0
  37. package/dist/hooks/titleLevel.d.ts.map +1 -0
  38. package/dist/index.css +296 -0
  39. package/dist/index.css.map +7 -0
  40. package/{src/index.ts → dist/index.d.ts} +1 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +1967 -0
  43. package/dist/index.js.map +7 -0
  44. package/dist/index.mjs +1935 -0
  45. package/dist/index.mjs.map +7 -0
  46. package/dist/providers/RebuyHydrogenContextProvider.d.ts +3 -0
  47. package/dist/providers/RebuyHydrogenContextProvider.d.ts.map +1 -0
  48. package/dist/providers/RebuyHydrogenReactContextProvider.d.ts +3 -0
  49. package/dist/providers/RebuyHydrogenReactContextProvider.d.ts.map +1 -0
  50. package/{src/providers/types.ts → dist/providers/types.d.ts} +12 -16
  51. package/dist/providers/types.d.ts.map +1 -0
  52. package/dist/queries/cart.queries.d.ts +5 -0
  53. package/dist/queries/cart.queries.d.ts.map +1 -0
  54. package/dist/types/common.d.ts +9 -0
  55. package/dist/types/common.d.ts.map +1 -0
  56. package/{src/types/rebuyCustom.ts → dist/types/rebuyCustom.d.ts} +12 -35
  57. package/dist/types/rebuyCustom.d.ts.map +1 -0
  58. package/{src/types/rebuySmartCart.ts → dist/types/rebuySmartCart.d.ts} +1 -5
  59. package/dist/types/rebuySmartCart.d.ts.map +1 -0
  60. package/dist/types/shopify.d.ts +85 -0
  61. package/dist/types/shopify.d.ts.map +1 -0
  62. package/{src/types/widgets.ts → dist/types/widgets.d.ts} +2 -9
  63. package/dist/types/widgets.d.ts.map +1 -0
  64. package/dist/utils/convertToRebuyProduct.d.ts +156 -0
  65. package/dist/utils/convertToRebuyProduct.d.ts.map +1 -0
  66. package/dist/utils/createContextParameters.d.ts +3 -0
  67. package/dist/utils/createContextParameters.d.ts.map +1 -0
  68. package/dist/utils/getEncodedAttributes.d.ts +3 -0
  69. package/dist/utils/getEncodedAttributes.d.ts.map +1 -0
  70. package/dist/utils/getRebuyConfig.d.ts +3 -0
  71. package/dist/utils/getRebuyConfig.d.ts.map +1 -0
  72. package/dist/widgetContainer/RebuyWidgetContainer.d.ts +8 -0
  73. package/dist/widgetContainer/RebuyWidgetContainer.d.ts.map +1 -0
  74. package/dist/widgets/RebuyCompleteTheLook/RebuyCompleteTheLook.d.ts +3 -0
  75. package/dist/widgets/RebuyCompleteTheLook/RebuyCompleteTheLook.d.ts.map +1 -0
  76. package/{src/widgets/RebuyCompleteTheLook/index.ts → dist/widgets/RebuyCompleteTheLook/index.d.ts} +1 -0
  77. package/dist/widgets/RebuyCompleteTheLook/index.d.ts.map +1 -0
  78. package/{src/widgets/RebuyCompleteTheLook/types.ts → dist/widgets/RebuyCompleteTheLook/types.d.ts} +1 -1
  79. package/dist/widgets/RebuyCompleteTheLook/types.d.ts.map +1 -0
  80. package/dist/widgets/RebuyDynamicBundleProducts/BundleImages.d.ts +5 -0
  81. package/dist/widgets/RebuyDynamicBundleProducts/BundleImages.d.ts.map +1 -0
  82. package/dist/widgets/RebuyDynamicBundleProducts/BundlePrice.d.ts +5 -0
  83. package/dist/widgets/RebuyDynamicBundleProducts/BundlePrice.d.ts.map +1 -0
  84. package/dist/widgets/RebuyDynamicBundleProducts/BundleSelection.d.ts +3 -0
  85. package/dist/widgets/RebuyDynamicBundleProducts/BundleSelection.d.ts.map +1 -0
  86. package/dist/widgets/RebuyDynamicBundleProducts/RebuyDynamicBundleProducts.d.ts +3 -0
  87. package/dist/widgets/RebuyDynamicBundleProducts/RebuyDynamicBundleProducts.d.ts.map +1 -0
  88. package/dist/widgets/RebuyDynamicBundleProducts/Select.d.ts +3 -0
  89. package/dist/widgets/RebuyDynamicBundleProducts/Select.d.ts.map +1 -0
  90. package/{src/widgets/RebuyDynamicBundleProducts/index.ts → dist/widgets/RebuyDynamicBundleProducts/index.d.ts} +1 -0
  91. package/dist/widgets/RebuyDynamicBundleProducts/index.d.ts.map +1 -0
  92. package/{src/widgets/RebuyDynamicBundleProducts/types.ts → dist/widgets/RebuyDynamicBundleProducts/types.d.ts} +1 -5
  93. package/dist/widgets/RebuyDynamicBundleProducts/types.d.ts.map +1 -0
  94. package/dist/widgets/RebuyProductAddOns/RebuyProductAddOnCard.d.ts +3 -0
  95. package/dist/widgets/RebuyProductAddOns/RebuyProductAddOnCard.d.ts.map +1 -0
  96. package/dist/widgets/RebuyProductAddOns/RebuyProductAddOns.d.ts +3 -0
  97. package/dist/widgets/RebuyProductAddOns/RebuyProductAddOns.d.ts.map +1 -0
  98. package/{src/widgets/RebuyProductAddOns/index.ts → dist/widgets/RebuyProductAddOns/index.d.ts} +1 -0
  99. package/dist/widgets/RebuyProductAddOns/index.d.ts.map +1 -0
  100. package/{src/widgets/RebuyProductAddOns/types.ts → dist/widgets/RebuyProductAddOns/types.d.ts} +2 -7
  101. package/dist/widgets/RebuyProductAddOns/types.d.ts.map +1 -0
  102. package/dist/widgets/RebuyProductRecommendations/RebuyProductRecommendations.d.ts +3 -0
  103. package/dist/widgets/RebuyProductRecommendations/RebuyProductRecommendations.d.ts.map +1 -0
  104. package/{src/widgets/RebuyProductRecommendations/index.ts → dist/widgets/RebuyProductRecommendations/index.d.ts} +1 -0
  105. package/dist/widgets/RebuyProductRecommendations/index.d.ts.map +1 -0
  106. package/{src/widgets/RebuyProductRecommendations/types.ts → dist/widgets/RebuyProductRecommendations/types.d.ts} +1 -1
  107. package/dist/widgets/RebuyProductRecommendations/types.d.ts.map +1 -0
  108. package/package.json +48 -36
  109. package/src/components/AddToCartBtn/AddToCartBtn.tsx +0 -45
  110. package/src/components/AddToCartBtn/HydrogenAddToCartBtn.tsx +0 -43
  111. package/src/components/AddToCartBtn/HydrogenReactAddToCartBtn.tsx +0 -35
  112. package/src/components/AddToCartBtn/index.ts +0 -1
  113. package/src/components/ProductCard/ProductCard.tsx +0 -70
  114. package/src/components/ProductCard/index.ts +0 -1
  115. package/src/components/ProductPrice/ProductPrice.tsx +0 -49
  116. package/src/components/ProductPrice/index.ts +0 -1
  117. package/src/components/Title/Title.tsx +0 -20
  118. package/src/components/Title/index.ts +0 -1
  119. package/src/components/VariantSelect/VariantSelect.tsx +0 -45
  120. package/src/components/VariantSelect/index.ts +0 -1
  121. package/src/hooks/titleLevel.tsx +0 -42
  122. package/src/providers/RebuyHydrogenContextProvider.tsx +0 -112
  123. package/src/providers/RebuyHydrogenReactContextProvider.tsx +0 -192
  124. package/src/queries/cart.queries.ts +0 -467
  125. package/src/types/common.ts +0 -8
  126. package/src/types/css.d.ts +0 -11
  127. package/src/types/env.d.ts +0 -12
  128. package/src/types/rebuy.d.ts +0 -31
  129. package/src/types/shopify.ts +0 -142
  130. package/src/utils/convertToRebuyProduct.tsx +0 -319
  131. package/src/utils/createContextParameters.ts +0 -142
  132. package/src/utils/getEncodedAttributes.ts +0 -11
  133. package/src/utils/getRebuyConfig.ts +0 -31
  134. package/src/widgetContainer/RebuyWidgetContainer.tsx +0 -183
  135. package/src/widgets/RebuyCompleteTheLook/RebuyCompleteTheLook.tsx +0 -50
  136. package/src/widgets/RebuyDynamicBundleProducts/BundleImages.tsx +0 -62
  137. package/src/widgets/RebuyDynamicBundleProducts/BundlePrice.tsx +0 -93
  138. package/src/widgets/RebuyDynamicBundleProducts/BundleSelection.tsx +0 -65
  139. package/src/widgets/RebuyDynamicBundleProducts/RebuyDynamicBundleProducts.tsx +0 -118
  140. package/src/widgets/RebuyDynamicBundleProducts/Select.tsx +0 -41
  141. package/src/widgets/RebuyProductAddOns/RebuyProductAddOnCard.tsx +0 -66
  142. package/src/widgets/RebuyProductAddOns/RebuyProductAddOns.tsx +0 -218
  143. package/src/widgets/RebuyProductRecommendations/RebuyProductRecommendations.tsx +0 -50
@@ -1,183 +0,0 @@
1
- import { RebuyClient } from '@rebuy/rebuy';
2
- import * as Utilities from '@rebuy/rebuy/utilities';
3
- import { flattenConnection } from '@shopify/hydrogen';
4
- import React, {
5
- ComponentType,
6
- useContext,
7
- useEffect,
8
- useMemo,
9
- useState,
10
- } from 'react';
11
-
12
- import type {
13
- RebuyProduct,
14
- RebuyWidgetContainerProps,
15
- RebuyWidgetMetadata,
16
- } from '~/types/rebuyCustom';
17
-
18
- import { RebuyContext } from '~/context/RebuyContext';
19
-
20
- type RebuyWidgetContainerComponent = {
21
- (props: RebuyWidgetContainerProps): JSX.Element;
22
- } & ComponentType<RebuyWidgetContainerProps>;
23
-
24
- const RebuyWidgetContainerBase = ({
25
- children,
26
- ...props
27
- }: RebuyWidgetContainerProps) => {
28
- const {
29
- collection,
30
- collectionId,
31
- dataSource,
32
- limit,
33
- options,
34
- product,
35
- productId,
36
- variant,
37
- variantId,
38
- } = props;
39
-
40
- const contextParameters = useContext(RebuyContext);
41
-
42
- const [Rebuy, setRebuy] = useState<RebuyClient | null>(null);
43
- const [initialized, setInitialized] = useState(false);
44
- const shopifyProductId = product?.id ?? productId ?? null;
45
- const shopifyVariantId = variant?.id ?? variantId ?? null;
46
- const shopifyCollectionId = collection?.id ?? collectionId ?? null;
47
- const [products, setProducts] = useState<RebuyProduct[]>([]);
48
- const [metadata, setMetadata] = useState<RebuyWidgetMetadata>();
49
-
50
- const REBUY_API_KEY = import.meta.env.PUBLIC_REBUY_API_KEY;
51
-
52
- // Initialize Rebuy API client
53
- useEffect(() => {
54
- if (!Rebuy) {
55
- const client = new RebuyClient(REBUY_API_KEY);
56
- client.setContextParameters(
57
- contextParameters as Record<string, unknown> // TODO: fix this type when @rebuy/rebuy is moved to typescript
58
- );
59
-
60
- if (options) {
61
- client.setDefaultParameters(options as Record<string, unknown>); // TODO: fix this type when @rebuy/rebuy is moved to typescript
62
- }
63
-
64
- setRebuy(client);
65
- setInitialized(true);
66
- }
67
- }, [REBUY_API_KEY, Rebuy, contextParameters, options]);
68
-
69
- useEffect(() => {
70
- if (!Rebuy) return;
71
-
72
- Rebuy.setContextParameters(
73
- contextParameters as Record<string, unknown> // TODO: fix this type when @rebuy/rebuy is moved to typescript
74
- );
75
- }, [Rebuy, contextParameters]);
76
-
77
- // Memoize request object on prop changes (e.g. product)
78
- const request = useMemo(() => {
79
- const request = {
80
- endpoint: dataSource || '/api/v1/products/recommended',
81
- params: {} as Record<string, string | number>, // Keeping this object generic to allow for custom endpoints
82
- };
83
-
84
- if (shopifyProductId) {
85
- request.params.shopify_product_ids = Utilities.getIdFromGraphUrl(
86
- shopifyProductId,
87
- 'Product'
88
- );
89
- }
90
-
91
- if (shopifyProductId) {
92
- request.params.shopify_product_ids = Utilities.getIdFromGraphUrl(
93
- shopifyProductId,
94
- 'Product'
95
- );
96
- }
97
-
98
- if (shopifyVariantId) {
99
- request.params.shopify_variant_ids = Utilities.getIdFromGraphUrl(
100
- shopifyVariantId,
101
- 'ProductVariant'
102
- );
103
- }
104
-
105
- if (shopifyCollectionId) {
106
- request.params.shopify_collection_ids = Utilities.getIdFromGraphUrl(
107
- shopifyCollectionId,
108
- 'Collection'
109
- );
110
- }
111
-
112
- if (limit) {
113
- request.params.limit = limit;
114
- }
115
-
116
- return request;
117
- }, [
118
- dataSource,
119
- shopifyProductId,
120
- shopifyVariantId,
121
- shopifyCollectionId,
122
- limit,
123
- ]);
124
-
125
- // Update product recommendations on cart or request change
126
- useEffect(() => {
127
- let isMounted = true;
128
- if (!Rebuy || !initialized) return;
129
-
130
- const fetchData = async () => {
131
- const { data, metadata } = (await Rebuy.getStorefrontData(
132
- request.endpoint,
133
- request.params
134
- )) as {
135
- data: RebuyProduct[];
136
- metadata: RebuyWidgetMetadata;
137
- };
138
-
139
- // Set state only if mounted
140
- if (isMounted) {
141
- setProducts(
142
- Array.isArray(data)
143
- ? data.map((product) => ({
144
- ...product,
145
- variants: {
146
- nodes: product.variants
147
- ? flattenConnection(product.variants)
148
- : [],
149
- },
150
- }))
151
- : []
152
- );
153
- setMetadata(metadata);
154
- }
155
- };
156
-
157
- fetchData();
158
- // Unmounted?
159
- return () => {
160
- isMounted = false;
161
- };
162
- }, [Rebuy, initialized, request]);
163
-
164
- const childrenWithProps = (props: RebuyWidgetContainerProps) =>
165
- React.Children.map(children, (child) =>
166
- React.isValidElement(child)
167
- ? React.cloneElement(child, props)
168
- : child
169
- );
170
-
171
- const childProps = {
172
- ...props,
173
- isHydrogenReact: contextParameters?.contextParameters?.isHydrogenReact,
174
- key: product?.id,
175
- metadata,
176
- products,
177
- };
178
-
179
- return childrenWithProps(childProps);
180
- };
181
-
182
- export const RebuyWidgetContainer =
183
- RebuyWidgetContainerBase as RebuyWidgetContainerComponent;
@@ -1,50 +0,0 @@
1
- import styles from '~/widgets/RebuyCompleteTheLook/RebuyCompleteTheLook.module.css';
2
-
3
- import type { RebuyCompleteTheLookProps } from './types';
4
-
5
- import { ProductCard } from '~/components/ProductCard';
6
- import { Title } from '~/components/Title';
7
- import { getTitleLevel } from '~/hooks/titleLevel';
8
-
9
- // Component implementation
10
- export const RebuyCompleteTheLook = (props: RebuyCompleteTheLookProps) => {
11
- const {
12
- addToCartBtnText = 'Add to cart',
13
- addToCartCallback,
14
- customTitle = `These pair with ${props.product?.title}`,
15
- customTitleLevel = 'h2',
16
- customTitleStyle,
17
- products = [],
18
- } = props;
19
-
20
- if (products.length === 0) {
21
- console.log('RebuyCompleteTheLook: No products found');
22
- return null;
23
- }
24
-
25
- return (
26
- <section className={styles.container}>
27
- <Title
28
- level={getTitleLevel(customTitleLevel)}
29
- style={customTitleStyle}
30
- text={customTitle}
31
- />
32
- <ul className={styles.productGrid}>
33
- {products.map((product) => (
34
- <li className={styles.productItem} key={product.id}>
35
- <ProductCard
36
- addToCartBtnText={addToCartBtnText}
37
- addToCartCallback={addToCartCallback}
38
- isHydrogenReact={props.isHydrogenReact}
39
- product={product}
40
- productCardTitleLevel={getTitleLevel(
41
- customTitleLevel,
42
- true
43
- )}
44
- />
45
- </li>
46
- ))}
47
- </ul>
48
- </section>
49
- );
50
- };
@@ -1,62 +0,0 @@
1
- import { Link } from '@remix-run/react';
2
- import { Image } from '@shopify/hydrogen';
3
- import { Fragment } from 'react';
4
-
5
- import styles from '~/widgets/RebuyDynamicBundleProducts/RebuyDynamicBundleProducts.module.css';
6
-
7
- import type { BundleProduct } from '~/widgets/RebuyDynamicBundleProducts/types';
8
-
9
- export const BundleImages = ({ products }: { products: BundleProduct[] }) => {
10
- const selected = products.filter((product) => product.selected);
11
-
12
- return (
13
- <ul className={styles.bundleImages}>
14
- {products.map((product, index) => {
15
- const image = product.selectedVariant?.image;
16
- const productImage = image ? (
17
- <Image
18
- alt={image.altText || `Picture of ${product.title}`}
19
- className={styles.bundleImage}
20
- data={image}
21
- height={80}
22
- title={product.title}
23
- width={80}
24
- />
25
- ) : (
26
- // No image defined
27
- product.title
28
- );
29
- // Hide delimiter for first selected item
30
- const showDelimiter = selected[0]?.id !== product.id;
31
-
32
- return (
33
- <Fragment key={product.id + '-BundleImages-' + index}>
34
- {product.selected && (
35
- <>
36
- {showDelimiter && (
37
- <li className={styles.bundleImageDelimiter}>
38
- <span>+</span>
39
- </li>
40
- )}
41
- <li className="flex items-center">
42
- {product.default ? (
43
- // Already on product page
44
- productImage
45
- ) : (
46
- // Link to product
47
- <Link
48
- title={product.title}
49
- to={`/products/${product.handle}`}
50
- >
51
- {productImage}
52
- </Link>
53
- )}
54
- </li>
55
- </>
56
- )}
57
- </Fragment>
58
- );
59
- })}
60
- </ul>
61
- );
62
- };
@@ -1,93 +0,0 @@
1
- import { Money } from '@shopify/hydrogen';
2
-
3
- import styles from './RebuyDynamicBundleProducts.module.css';
4
-
5
- import type {
6
- CurrencyCode,
7
- MoneyV2,
8
- } from '@shopify/hydrogen-react/storefront-api-types';
9
- import type { BundleProduct } from '~/widgets/RebuyDynamicBundleProducts/types';
10
-
11
- export const BundlePrice = ({ products }: { products: BundleProduct[] }) => {
12
- const isDisabled =
13
- products.filter((product) => product.selected).length < 1;
14
-
15
- const totalBundlePrice = () => {
16
- let total = 0;
17
- let currencyCode = 'USD' as CurrencyCode;
18
-
19
- for (const product of products) {
20
- if (product.selected && product.selectedVariant) {
21
- const { priceV2: price } = product.selectedVariant;
22
-
23
- total += Number(price?.amount);
24
- currencyCode = (price?.currencyCode || 'USD') as CurrencyCode;
25
- }
26
- }
27
-
28
- return {
29
- amount: String(total),
30
- currencyCode,
31
- };
32
- };
33
-
34
- const totalBundleCompareAtPrice = () => {
35
- let compareAtTotal = 0;
36
- let currencyCode = 'USD' as CurrencyCode;
37
-
38
- for (const product of products) {
39
- if (product.selected && product.selectedVariant) {
40
- const { compareAtPriceV2: compareAtPrice, priceV2: price } =
41
- product.selectedVariant;
42
-
43
- currencyCode = (price?.currencyCode || 'USD') as CurrencyCode;
44
- compareAtTotal += Number((compareAtPrice || price)?.amount);
45
- }
46
- }
47
-
48
- return {
49
- amount: String(compareAtTotal),
50
- currencyCode,
51
- };
52
- };
53
- const isDiscounted = (
54
- price: { amount: string; currencyCode: string } | null,
55
- compareAtPrice: { amount: string; currencyCode: string } | null
56
- ) => Number(compareAtPrice?.amount) > Number(price?.amount);
57
-
58
- const price = totalBundlePrice();
59
- const compareAtPrice = totalBundleCompareAtPrice();
60
-
61
- const CompareAtPrice = ({
62
- data: compareAtPrice,
63
- }: {
64
- data: MoneyV2 | null;
65
- }) => {
66
- return (
67
- compareAtPrice && (
68
- <Money
69
- as="span"
70
- className={styles.compareAtPrice}
71
- data={compareAtPrice}
72
- withoutTrailingZeros
73
- />
74
- )
75
- );
76
- };
77
-
78
- return (
79
- products.length > 0 && (
80
- <div className="flex items-center flex-col">
81
- {!isDisabled && (
82
- <p className="flex items-center gap-2 mb-2">
83
- <span>Total Price:</span>
84
- <Money as="span" data={price} withoutTrailingZeros />
85
- {isDiscounted(price, compareAtPrice) && (
86
- <CompareAtPrice data={compareAtPrice} />
87
- )}
88
- </p>
89
- )}
90
- </div>
91
- )
92
- );
93
- };
@@ -1,65 +0,0 @@
1
- import styles from '~/widgets/RebuyDynamicBundleProducts/RebuyDynamicBundleProducts.module.css';
2
-
3
- import type { BundleSelectionProps } from '~/widgets/RebuyDynamicBundleProducts/types';
4
-
5
- import { RebuyProductPrice } from '~/components/ProductPrice';
6
- import { Select } from '~/widgets/RebuyDynamicBundleProducts/Select';
7
-
8
- export const BundleSelection = ({
9
- onSelectVariant,
10
- onToggleBundleItem,
11
- products,
12
- }: BundleSelectionProps) => {
13
- return (
14
- <ul>
15
- {products.map((product, index) => {
16
- const { availableForSale } = product.selectedVariant;
17
- const isOutOfStock = !availableForSale;
18
-
19
- return (
20
- <li
21
- className={`${styles.bundleItemRowContainer} ${
22
- !product.selected && styles.unselected
23
- }`}
24
- key={product.id + '-BundleSelection' + index}
25
- >
26
- <div className={styles.bundleItemRow}>
27
- <input
28
- checked={product.selected && availableForSale}
29
- className="mt-1 rounded-sm accent-black cursor-pointer"
30
- disabled={isOutOfStock}
31
- id={`${product.id}-toggle`}
32
- onChange={() => onToggleBundleItem(product)}
33
- type="checkbox"
34
- value={product.id}
35
- />
36
- <div className={styles.bundleItemInput}>
37
- <label
38
- className={styles.bundleItemLabel}
39
- htmlFor={`${product.id}-toggle`}
40
- >
41
- {isOutOfStock && <b>SOLD OUT</b>}
42
- {product.default && <b>This item:</b>}
43
- {product.title}
44
-
45
- <RebuyProductPrice
46
- selectedVariant={
47
- product.selectedVariant
48
- }
49
- />
50
- </label>
51
-
52
- {product.variants.nodes.length > 1 && (
53
- <Select
54
- onSelectVariant={onSelectVariant}
55
- product={product}
56
- />
57
- )}
58
- </div>
59
- </div>
60
- </li>
61
- );
62
- })}
63
- </ul>
64
- );
65
- };
@@ -1,118 +0,0 @@
1
- import { useCallback, useEffect, useState } from 'react';
2
-
3
- import { BundlePrice } from './BundlePrice';
4
-
5
- import styles from './RebuyDynamicBundleProducts.module.css';
6
-
7
- import type {
8
- BundleProduct,
9
- RebuyDynamicBundleProductsProps,
10
- } from '~/widgets/RebuyDynamicBundleProducts/types';
11
-
12
- import { AddToCartBtn } from '~/components/AddToCartBtn';
13
- import { Title } from '~/components/Title';
14
- import { getTitleLevel } from '~/hooks/titleLevel';
15
- import { convertToRebuyProduct } from '~/utils/convertToRebuyProduct';
16
- import { BundleImages } from '~/widgets/RebuyDynamicBundleProducts/BundleImages';
17
- import { BundleSelection } from '~/widgets/RebuyDynamicBundleProducts/BundleSelection';
18
-
19
- export const RebuyDynamicBundleProducts = (
20
- props: RebuyDynamicBundleProductsProps
21
- ) => {
22
- const {
23
- addToCartBtnText = 'Add to cart',
24
- addToCartCallback,
25
- customTitle = `These pair with ${props.product?.title}`,
26
- customTitleLevel = 'h2',
27
- customTitleStyle,
28
- isHydrogenReact,
29
- product,
30
- products = [],
31
- } = props;
32
- const [bundleProducts, setBundleProducts] = useState<BundleProduct[]>([]);
33
-
34
- // Initializiation
35
- useEffect(() => {
36
- const mainProduct: BundleProduct = convertToRebuyProduct(
37
- isHydrogenReact || false,
38
- product
39
- );
40
-
41
- const formattedProducts = products.map((product) => {
42
- return {
43
- ...product,
44
- selected: true,
45
- selectedVariant: product.variants.nodes[0],
46
- };
47
- });
48
-
49
- setBundleProducts([mainProduct, ...formattedProducts]);
50
- }, [product, products, isHydrogenReact]);
51
-
52
- const onToggleBundleItem = useCallback(
53
- (product: BundleProduct) => {
54
- product.selected = !product.selected;
55
-
56
- setBundleProducts([...bundleProducts]);
57
- },
58
- [bundleProducts]
59
- );
60
-
61
- const onSelectVariant = useCallback(
62
- (product: BundleProduct, variant_id: string) => {
63
- const variant = product.variants.nodes.find(
64
- ({ id }) => id === variant_id
65
- );
66
-
67
- if (variant) {
68
- product.selectedVariant = variant;
69
- product.selected = variant.availableForSale || false;
70
-
71
- setBundleProducts([...bundleProducts]);
72
- }
73
- },
74
- [bundleProducts]
75
- );
76
-
77
- if (products.length === 0) {
78
- console.log('RebuyDynamicBundleProducts: No products found');
79
- return null;
80
- }
81
-
82
- return (
83
- <section className={styles.container}>
84
- <Title
85
- level={getTitleLevel(customTitleLevel)}
86
- style={customTitleStyle}
87
- text={customTitle}
88
- />
89
- <div className={styles.bundleContainer}>
90
- <BundleImages products={bundleProducts} />
91
- <BundlePrice products={bundleProducts} />
92
-
93
- <div className={styles.addCartBtnContainer}>
94
- <AddToCartBtn
95
- addToCartBtnText={addToCartBtnText}
96
- addToCartCallback={addToCartCallback}
97
- disabled={
98
- bundleProducts.filter((product) => product.selected)
99
- .length === 0
100
- }
101
- isHydrogenReact={isHydrogenReact}
102
- selectedVariants={bundleProducts
103
- .filter((product) => product.selected)
104
- .map((product) => {
105
- return product.selectedVariant;
106
- })}
107
- />
108
- </div>
109
-
110
- <BundleSelection
111
- onSelectVariant={onSelectVariant}
112
- onToggleBundleItem={onToggleBundleItem}
113
- products={bundleProducts}
114
- />
115
- </div>
116
- </section>
117
- );
118
- };
@@ -1,41 +0,0 @@
1
- import styles from '~/widgets/RebuyDynamicBundleProducts/RebuyDynamicBundleProducts.module.css';
2
-
3
- import type {
4
- BundleProduct,
5
- BundleSelectProps,
6
- } from '~/widgets/RebuyDynamicBundleProducts/types';
7
-
8
- export const Select = ({ onSelectVariant, product }: BundleSelectProps) => {
9
- const getOptionsLabel = (product: BundleProduct) => {
10
- const options = product.variants.nodes[0].selectedOptions;
11
- const optionsFromKeys = options ? Object.keys(options[0]) : [];
12
- const optionsFromValues = options
13
- ? options.map((option) => option.name)
14
- : [];
15
- const useValues = optionsFromKeys.every((key) =>
16
- ['name', 'value'].includes(key)
17
- );
18
-
19
- // Return delimited label for available option(s) e.g. Color / Size, Scent, etc
20
- return (useValues ? optionsFromValues : optionsFromKeys).join(' / ');
21
- };
22
-
23
- return (
24
- product && (
25
- <select
26
- aria-label="select variant"
27
- className={styles.select}
28
- onChange={(e) => onSelectVariant(product, e.target.value)}
29
- value={product.selectedVariant.id}
30
- >
31
- <optgroup label={getOptionsLabel(product)}>
32
- {product.variants.nodes.map(({ id, title }) => (
33
- <option key={id + '-BundleVariant'} value={id}>
34
- {title}
35
- </option>
36
- ))}
37
- </optgroup>
38
- </select>
39
- )
40
- );
41
- };
@@ -1,66 +0,0 @@
1
- import { Link } from '@remix-run/react';
2
- import { Image } from '@shopify/hydrogen';
3
-
4
- import styles from './RebuyProductAddOns.module.css';
5
-
6
- import type { RebuyProductAddOnCardProps } from './types';
7
-
8
- import { RebuyProductPrice } from '~/components/ProductPrice';
9
- import { Title } from '~/components/Title';
10
-
11
- export const RebuyProductAddOnCard = ({
12
- handleChange,
13
- learnMoreText,
14
- outOfStockText,
15
- product,
16
- titleLevel,
17
- }: RebuyProductAddOnCardProps) => {
18
- const { availableForSale, image } = product.selectedVariant || {};
19
-
20
- return (
21
- <label className={styles.addOnCard} htmlFor={product.id}>
22
- <div className={styles.addOnCardContent}>
23
- <input
24
- checked={Boolean(product.selected)}
25
- className={styles.addOnCardInput}
26
- disabled={!product.variants.nodes[0].availableForSale}
27
- id={product.id}
28
- name={product.title}
29
- onChange={(event) => handleChange(event, product)}
30
- type="checkbox"
31
- value=""
32
- />
33
- <div className={styles.addOnCardContentImage}>
34
- {image && (
35
- <Image
36
- alt={image.altText || `Picture of ${product.title}`}
37
- data={image}
38
- height={150}
39
- width={300}
40
- />
41
- )}
42
- </div>
43
-
44
- <div className={styles.addOnCardTextContent}>
45
- {!availableForSale && (
46
- <p className={styles.addOnCardOutOfStock}>
47
- {outOfStockText}
48
- </p>
49
- )}
50
-
51
- <Title level={titleLevel} text={product.title} />
52
-
53
- <RebuyProductPrice
54
- selectedVariant={product.selectedVariant}
55
- />
56
- <Link
57
- className={styles.addOnCardLearnMore}
58
- to={`/products/${product.handle}`}
59
- >
60
- {learnMoreText}
61
- </Link>
62
- </div>
63
- </div>
64
- </label>
65
- );
66
- };