@gfed-medusa/sf-lib-products 1.8.1 → 1.9.0

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 (41) hide show
  1. package/dist/components/behavior-tracker/index.d.ts +12 -0
  2. package/dist/components/behavior-tracker/index.d.ts.map +1 -0
  3. package/dist/components/behavior-tracker/index.js +149 -0
  4. package/dist/components/behavior-tracker/index.js.map +1 -0
  5. package/dist/components/product-actions/index.js +3 -3
  6. package/dist/components/product-actions/index.js.map +1 -1
  7. package/dist/components/product-actions/mobile-actions.js +7 -7
  8. package/dist/components/product-actions/mobile-actions.js.map +1 -1
  9. package/dist/components/product-actions/option-select.js +1 -1
  10. package/dist/components/product-onboarding-cta/index.d.ts +2 -2
  11. package/dist/components/product-price/index.d.ts +2 -2
  12. package/dist/components/product-tabs/accordion.js +1 -1
  13. package/dist/components/product-tabs/index.d.ts +2 -2
  14. package/dist/components/refinement-list/index.d.ts +2 -2
  15. package/dist/components/refinement-list/index.d.ts.map +1 -1
  16. package/dist/components/refinement-list/index.js +1 -1
  17. package/dist/components/refinement-list/sort-products/index.d.ts +2 -2
  18. package/dist/components/refinement-list/sort-products/index.d.ts.map +1 -1
  19. package/dist/components/related-products/index.d.ts +2 -2
  20. package/dist/components/related-products/index.d.ts.map +1 -1
  21. package/dist/components/skeleton-product-grid/index.d.ts +2 -2
  22. package/dist/components/skeleton-product-grid/index.d.ts.map +1 -1
  23. package/dist/components/skeleton-product-preview/index.d.ts +2 -2
  24. package/dist/components/skeleton-related-products/index.d.ts +2 -2
  25. package/dist/components/skeleton-related-products/index.d.ts.map +1 -1
  26. package/dist/lib/gql/fragments/product.d.ts +16 -16
  27. package/dist/lib/gql/mutations/cart.d.ts +10 -10
  28. package/dist/lib/gql/queries/cart.d.ts +2 -2
  29. package/dist/lib/gql/queries/cart.d.ts.map +1 -1
  30. package/dist/lib/gql/queries/product.d.ts +13 -13
  31. package/dist/templates/paginated-products/client.d.ts +2 -2
  32. package/dist/templates/paginated-products/client.js +2 -2
  33. package/dist/templates/paginated-products/index.d.ts +2 -2
  34. package/dist/templates/product-actions-wrapper/index.d.ts +2 -2
  35. package/dist/templates/product-template/index.d.ts.map +1 -1
  36. package/dist/templates/product-template/index.js +4 -2
  37. package/dist/templates/product-template/index.js.map +1 -1
  38. package/dist/templates/store-template/index.d.ts +2 -2
  39. package/dist/templates/store-template/index.d.ts.map +1 -1
  40. package/dist/templates/store-template/index.js +1 -1
  41. package/package.json +6 -4
@@ -0,0 +1,12 @@
1
+ import { Product } from "../../types/graphql.js";
2
+
3
+ //#region src/components/behavior-tracker/index.d.ts
4
+ interface BehaviorTrackerProps {
5
+ product: Product;
6
+ }
7
+ declare function BehaviorTracker({
8
+ product
9
+ }: BehaviorTrackerProps): null;
10
+ //#endregion
11
+ export { BehaviorTracker, BehaviorTracker as default, BehaviorTrackerProps };
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/behavior-tracker/index.tsx"],"sourcesContent":[],"mappings":";;;UAkJiB,oBAAA;WACN;AADX;AAIgB,iBAAA,eAAA,CAAkB;EAAA;AAA+B,CAApB,EAAA,oBAAoB,CAAA,EAAA,IAAA"}
@@ -0,0 +1,149 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useRef } from "react";
4
+ import Cookies from "js-cookie";
5
+ import { PERSONALIZATION_CONFIG, getSegmentIdFromCollection } from "@gfed-medusa/sf-lib-common/lib/personalization/config";
6
+ import { useStorefrontContext } from "@gfed-medusa/sf-lib-common/lib/data/context";
7
+
8
+ //#region src/components/behavior-tracker/index.tsx
9
+ const PDP_HESITATION_MS = PERSONALIZATION_CONFIG.pdpHesitationMs;
10
+ const HIGH_SCROLL_THRESHOLD = PERSONALIZATION_CONFIG.highScrollThreshold;
11
+ const PRICE_THRESHOLD_USD = PERSONALIZATION_CONFIG.priceThresholdUsd;
12
+ const SIGNAL_COOKIE = "_jg_segment";
13
+ const cookieOptions = {
14
+ path: "/",
15
+ sameSite: "none",
16
+ secure: true,
17
+ domain: ".justgood.win"
18
+ };
19
+ function getScrollPercentage() {
20
+ const scrollTop = window.scrollY;
21
+ const docHeight = document.documentElement.scrollHeight - window.innerHeight;
22
+ return docHeight > 0 ? scrollTop / docHeight : 0;
23
+ }
24
+ function getCheapestVariantPrice(product) {
25
+ const variants = product.variants;
26
+ if (!variants || variants.length === 0) return null;
27
+ let cheapest = null;
28
+ for (const variant of variants) {
29
+ const priceObj = variant.price;
30
+ if (priceObj && typeof priceObj.amount === "number") {
31
+ if (cheapest === null || priceObj.amount < cheapest) cheapest = priceObj.amount;
32
+ }
33
+ }
34
+ return cheapest;
35
+ }
36
+ function throttle(fn, limit) {
37
+ let lastCall = 0;
38
+ return ((...args) => {
39
+ const now = Date.now();
40
+ if (now - lastCall >= limit) {
41
+ lastCall = now;
42
+ fn(...args);
43
+ }
44
+ });
45
+ }
46
+ function getSegmentData() {
47
+ const value = Cookies.get(SIGNAL_COOKIE);
48
+ if (!value) return {};
49
+ try {
50
+ return JSON.parse(decodeURIComponent(value));
51
+ } catch {
52
+ return {};
53
+ }
54
+ }
55
+ function emitSignal(type, payload) {
56
+ const data = getSegmentData();
57
+ if (!data.signals || typeof data.signals !== "object") data.signals = {};
58
+ data.signals[type] = payload ?? true;
59
+ Cookies.set(SIGNAL_COOKIE, encodeURIComponent(JSON.stringify(data)), {
60
+ ...cookieOptions,
61
+ expires: 7
62
+ });
63
+ }
64
+ const REPEAT_CATEGORY_THRESHOLD = 3;
65
+ function trackRepeatedCategoryView(segment) {
66
+ try {
67
+ let data = getSegmentData();
68
+ if (Object.keys(data).length === 0) data = { signals: {} };
69
+ if (!data.signals || typeof data.signals !== "object") data.signals = {};
70
+ const categoryCounts = data.signals["repeated-category-view"] ?? {};
71
+ const newCount = (categoryCounts[segment] ?? 0) + 1;
72
+ categoryCounts[segment] = newCount;
73
+ data.signals["repeated-category-view"] = categoryCounts;
74
+ if (newCount >= REPEAT_CATEGORY_THRESHOLD) emitSignal("repeated-category-view", {
75
+ segment,
76
+ count: newCount
77
+ });
78
+ Cookies.set(SIGNAL_COOKIE, encodeURIComponent(JSON.stringify(data)), {
79
+ ...cookieOptions,
80
+ expires: 7
81
+ });
82
+ } catch {}
83
+ }
84
+ function addHistoryToCookie(segment) {
85
+ try {
86
+ let data = getSegmentData();
87
+ if (Object.keys(data).length === 0) data = { history: [] };
88
+ if (!data.history || !Array.isArray(data.history)) data.history = [];
89
+ const history = [...data.history, segment].slice(-PERSONALIZATION_CONFIG.historyMaxLength);
90
+ data.history = history;
91
+ Cookies.set(SIGNAL_COOKIE, encodeURIComponent(JSON.stringify(data)), {
92
+ ...cookieOptions,
93
+ expires: 7
94
+ });
95
+ } catch {}
96
+ }
97
+ function BehaviorTracker({ product }) {
98
+ const { cartId } = useStorefrontContext();
99
+ const hesitationTimeoutRef = useRef(null);
100
+ const scrollHandlerRef = useRef(null);
101
+ const scrollTrackedRef = useRef(false);
102
+ useRef(false);
103
+ useEffect(() => {
104
+ if (!product?.id) return;
105
+ const collectionHandle = product.collection?.handle;
106
+ const segment = getSegmentIdFromCollection(collectionHandle);
107
+ if (segment) {
108
+ addHistoryToCookie(segment);
109
+ trackRepeatedCategoryView(segment);
110
+ }
111
+ const productPrice = getCheapestVariantPrice(product);
112
+ const hasCart = Boolean(cartId);
113
+ if (productPrice && productPrice >= PRICE_THRESHOLD_USD && !hasCart) hesitationTimeoutRef.current = setTimeout(() => {
114
+ emitSignal("pdp-hesitation", {
115
+ productId: product.id,
116
+ price: productPrice
117
+ });
118
+ }, PDP_HESITATION_MS);
119
+ const handleScroll = throttle(() => {
120
+ if (scrollTrackedRef.current) return;
121
+ if (getScrollPercentage() >= HIGH_SCROLL_THRESHOLD && !hasCart) {
122
+ scrollTrackedRef.current = true;
123
+ emitSignal("high-scroll-no-action", {
124
+ productId: product.id,
125
+ scrollDepth: HIGH_SCROLL_THRESHOLD
126
+ });
127
+ }
128
+ }, 500);
129
+ scrollHandlerRef.current = handleScroll;
130
+ window.addEventListener("scroll", handleScroll, { passive: true });
131
+ return () => {
132
+ if (hesitationTimeoutRef.current !== null) {
133
+ clearTimeout(hesitationTimeoutRef.current);
134
+ hesitationTimeoutRef.current = null;
135
+ }
136
+ if (scrollHandlerRef.current !== null) {
137
+ window.removeEventListener("scroll", scrollHandlerRef.current);
138
+ scrollHandlerRef.current = null;
139
+ }
140
+ scrollTrackedRef.current = false;
141
+ };
142
+ }, [product, cartId]);
143
+ return null;
144
+ }
145
+ var behavior_tracker_default = BehaviorTracker;
146
+
147
+ //#endregion
148
+ export { BehaviorTracker, behavior_tracker_default as default };
149
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["cookieOptions: Cookies.CookieAttributes","cheapest: number | null"],"sources":["../../../src/components/behavior-tracker/index.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useRef } from 'react';\nimport Cookies from 'js-cookie';\n\nimport {\n PERSONALIZATION_CONFIG,\n getSegmentIdFromCollection,\n} from '@gfed-medusa/sf-lib-common/lib/personalization/config';\nimport { useStorefrontContext } from '@gfed-medusa/sf-lib-common/lib/data/context';\nimport { Product } from '@/types/graphql';\n\nconst PDP_HESITATION_MS = PERSONALIZATION_CONFIG.pdpHesitationMs;\nconst HIGH_SCROLL_THRESHOLD = PERSONALIZATION_CONFIG.highScrollThreshold;\nconst PRICE_THRESHOLD_USD = PERSONALIZATION_CONFIG.priceThresholdUsd;\n\nconst SIGNAL_COOKIE = '_jg_segment';\nconst isProd = process.env.NODE_ENV === 'production';\n\nconst cookieOptions: Cookies.CookieAttributes = isProd\n ? { path: '/', sameSite: 'none', secure: true, domain: '.justgood.win' }\n : { path: '/', sameSite: 'lax' };\n\nfunction getScrollPercentage(): number {\n const scrollTop = window.scrollY;\n const docHeight =\n document.documentElement.scrollHeight - window.innerHeight;\n return docHeight > 0 ? scrollTop / docHeight : 0;\n}\n\nfunction getCheapestVariantPrice(product: Product): number | null {\n const variants = product.variants;\n if (!variants || variants.length === 0) return null;\n\n let cheapest: number | null = null;\n\n for (const variant of variants) {\n const priceObj = variant.price;\n if (priceObj && typeof priceObj.amount === 'number') {\n if (cheapest === null || priceObj.amount < cheapest) {\n cheapest = priceObj.amount;\n }\n }\n }\n\n return cheapest;\n}\n\nfunction throttle<T extends (...args: unknown[]) => void>(\n fn: T,\n limit: number\n): T {\n let lastCall = 0;\n return ((...args: unknown[]) => {\n const now = Date.now();\n if (now - lastCall >= limit) {\n lastCall = now;\n fn(...args);\n }\n }) as T;\n}\n\nfunction getSegmentData(): Record<string, unknown> {\n const value = Cookies.get(SIGNAL_COOKIE);\n if (!value) return {};\n try {\n return JSON.parse(decodeURIComponent(value));\n } catch {\n return {};\n }\n}\n\nfunction emitSignal(type: string, payload?: unknown) {\n const data = getSegmentData();\n if (!data.signals || typeof data.signals !== 'object') {\n data.signals = {};\n }\n\n (data.signals as Record<string, unknown>)[type] = payload ?? true;\n\n Cookies.set(\n SIGNAL_COOKIE,\n encodeURIComponent(JSON.stringify(data)),\n { ...cookieOptions, expires: 7 }\n );\n}\n\nconst REPEAT_CATEGORY_THRESHOLD = 3;\n\nfunction trackRepeatedCategoryView(segment: string) {\n try {\n let data = getSegmentData();\n if (Object.keys(data).length === 0) {\n data = { signals: {} };\n }\n\n if (!data.signals || typeof data.signals !== 'object') {\n data.signals = {};\n }\n\n const categoryCounts = (data.signals as Record<string, unknown>)['repeated-category-view'] as Record<string, number> ?? {};\n const currentCount = categoryCounts[segment] ?? 0;\n const newCount = currentCount + 1;\n\n categoryCounts[segment] = newCount;\n (data.signals as Record<string, unknown>)['repeated-category-view'] = categoryCounts;\n\n if (newCount >= REPEAT_CATEGORY_THRESHOLD) {\n emitSignal('repeated-category-view', { segment, count: newCount });\n }\n\n Cookies.set(\n SIGNAL_COOKIE,\n encodeURIComponent(JSON.stringify(data)),\n { ...cookieOptions, expires: 7 }\n );\n } catch {\n // Ignore\n }\n}\n\nfunction addHistoryToCookie(segment: string): void {\n try {\n let data = getSegmentData();\n if (Object.keys(data).length === 0) {\n data = { history: [] };\n }\n\n if (!data.history || !Array.isArray(data.history)) {\n data.history = [];\n }\n\n const history = [...(data.history as string[]), segment].slice(\n -PERSONALIZATION_CONFIG.historyMaxLength\n );\n data.history = history;\n\n Cookies.set(\n SIGNAL_COOKIE,\n encodeURIComponent(JSON.stringify(data)),\n { ...cookieOptions, expires: 7 }\n );\n } catch {\n }\n}\n\nexport interface BehaviorTrackerProps {\n product: Product;\n}\n\nexport function BehaviorTracker({ product }: BehaviorTrackerProps) {\n const { cartId } = useStorefrontContext();\n const hesitationTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(\n null\n );\n const scrollHandlerRef = useRef<(() => void) | null>(null);\n const scrollTrackedRef = useRef(false);\n const historyTrackedRef = useRef(false);\n\n useEffect(() => {\n if (!product?.id) return;\n\n const collectionHandle = product.collection?.handle;\n const segment = getSegmentIdFromCollection(collectionHandle);\n\n if (segment) {\n addHistoryToCookie(segment);\n trackRepeatedCategoryView(segment);\n }\n\n const productPrice = getCheapestVariantPrice(product);\n const hasCart = Boolean(cartId);\n\n if (productPrice && productPrice >= PRICE_THRESHOLD_USD && !hasCart) {\n hesitationTimeoutRef.current = setTimeout(() => {\n emitSignal('pdp-hesitation', {\n productId: product.id,\n price: productPrice,\n });\n }, PDP_HESITATION_MS);\n }\n\n const handleScroll = throttle(() => {\n if (scrollTrackedRef.current) return;\n if (getScrollPercentage() >= HIGH_SCROLL_THRESHOLD && !hasCart) {\n scrollTrackedRef.current = true;\n emitSignal('high-scroll-no-action', {\n productId: product.id,\n scrollDepth: HIGH_SCROLL_THRESHOLD,\n });\n }\n }, 500);\n\n scrollHandlerRef.current = handleScroll;\n window.addEventListener('scroll', handleScroll, { passive: true });\n\n return () => {\n if (hesitationTimeoutRef.current !== null) {\n clearTimeout(hesitationTimeoutRef.current);\n hesitationTimeoutRef.current = null;\n }\n if (scrollHandlerRef.current !== null) {\n window.removeEventListener('scroll', scrollHandlerRef.current);\n scrollHandlerRef.current = null;\n }\n scrollTrackedRef.current = false;\n };\n }, [product, cartId]);\n\n return null;\n}\n\nexport default BehaviorTracker;"],"mappings":"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"}
@@ -6,9 +6,9 @@ import { useIntersection } from "../../lib/hooks/use-intersection.js";
6
6
  import { useProductPrice } from "../../lib/hooks/use-product-price.js";
7
7
  import { mergeProductPricing } from "../../lib/utils/merge-product-pricing.js";
8
8
  import mobile_actions_default from "./mobile-actions.js";
9
- import { Button } from "@medusajs/ui";
10
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
9
  import { useEffect, useMemo, useRef, useState } from "react";
10
+ import { Button } from "@medusajs/ui";
11
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
12
12
  import { useParams } from "next/navigation";
13
13
  import { isEqual } from "lodash";
14
14
  import { ErrorMessage } from "@gfed-medusa/sf-lib-common/components/error-message";
@@ -92,7 +92,7 @@ function ProductActions({ product, regionId, disabled, enableMobileActions = tru
92
92
  setStatus(AddToCartStatus.ERROR);
93
93
  }
94
94
  };
95
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", {
95
+ return /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsxs("div", {
96
96
  className: "flex flex-col gap-y-2",
97
97
  ref: actionsRef,
98
98
  children: [
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["OptionSelect","MobileActions"],"sources":["../../../src/components/product-actions/index.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useMemo, useRef, useState } from 'react';\n\nimport { useParams } from 'next/navigation';\n\nimport { isEqual } from 'lodash';\n\nimport { ErrorMessage } from '@gfed-medusa/sf-lib-common/components/error-message';\nimport { WebComponent } from '@gfed-medusa/sf-lib-common/components/web-component';\nimport { mutateCart } from '@gfed-medusa/sf-lib-common/lib/hooks/use-cart';\nimport { Divider } from '@gfed-medusa/sf-lib-ui/components/divider';\nimport { HttpTypes } from '@medusajs/types';\nimport { Button } from '@medusajs/ui';\n\nimport OptionSelect from '@/components/product-actions/option-select';\nimport { addToCart } from '@/lib/data/cart';\nimport { useIntersection } from '@/lib/hooks/use-intersection';\nimport { useProductPrice } from '@/lib/hooks/use-product-price';\nimport { mergeProductPricing } from '@/lib/utils/merge-product-pricing';\nimport { ProductActionsProduct } from '@/types';\nimport { ProductVariant } from '@/types/graphql';\n\nimport MobileActions from './mobile-actions';\n\nexport type ProductActionsProps = {\n product: ProductActionsProduct;\n regionId?: string;\n disabled?: boolean;\n enableMobileActions?: boolean;\n};\n\nenum AddToCartStatus {\n IDLE = 'idle',\n ADDING = 'adding',\n SUCCESS = 'success',\n ERROR = 'error',\n}\n\nconst optionsAsKeymap = (\n variantOptions:\n | HttpTypes.StoreProductVariant['options']\n | ProductVariant['options']\n | null\n | undefined\n) => {\n return variantOptions?.reduce((acc: Record<string, string>, varopt: any) => {\n acc[varopt.optionId] = varopt.value;\n return acc;\n }, {});\n};\n\nexport default function ProductActions({\n product,\n regionId,\n disabled,\n enableMobileActions = true,\n}: ProductActionsProps) {\n const [options, setOptions] = useState<Record<string, string | undefined>>(\n {}\n );\n const [status, setStatus] = useState<AddToCartStatus>(AddToCartStatus.IDLE);\n const countryCode = useParams().countryCode as string;\n const { product: pricingProduct } = useProductPrice(product.id, regionId);\n const pricedProduct = useMemo(\n () => mergeProductPricing(product, pricingProduct),\n [product, pricingProduct]\n );\n\n // If there is only 1 variant, preselect the options\n useEffect(() => {\n if (pricedProduct?.variants && pricedProduct.variants.length === 1) {\n const variantOptions = optionsAsKeymap(\n pricedProduct.variants[0]?.options || null\n );\n setOptions(variantOptions ?? {});\n }\n }, [pricedProduct.variants]);\n\n const selectedVariant = useMemo(() => {\n if (!pricedProduct.variants || pricedProduct.variants.length === 0) {\n return;\n }\n\n return pricedProduct.variants.find((v) => {\n const variantOptions = optionsAsKeymap(v.options);\n return isEqual(variantOptions, options);\n });\n }, [pricedProduct.variants, options]);\n\n // update the options when a variant is selected\n const setOptionValue = (optionId: string, value: string) => {\n setOptions((prev) => ({\n ...prev,\n [optionId]: value,\n }));\n };\n\n //check if the selected options produce a valid variant\n const isValidVariant = useMemo(() => {\n return pricedProduct.variants?.some((v) => {\n const variantOptions = optionsAsKeymap(v.options);\n return isEqual(variantOptions, options);\n });\n }, [pricedProduct.variants, options]);\n\n const stockStatus = useMemo(() => {\n if (!selectedVariant) {\n return 'unknown' as const;\n }\n\n if (!selectedVariant.manageInventory) {\n return 'in_stock' as const;\n }\n\n if (selectedVariant.allowBackorder) {\n return 'in_stock' as const;\n }\n\n const qty = selectedVariant.inventoryQuantity;\n\n if (typeof qty !== 'number') {\n return 'in_stock' as const;\n }\n\n return qty > 0 ? ('in_stock' as const) : ('out_of_stock' as const);\n }, [selectedVariant]);\n\n const inStock = useMemo(() => {\n // If we don't manage inventory, we can always add to cart\n if (selectedVariant && !selectedVariant.manageInventory) {\n return true;\n }\n\n // If we allow back orders on the variant, we can add to cart\n if (selectedVariant?.allowBackorder) {\n return true;\n }\n\n if (selectedVariant?.manageInventory) {\n const qty = selectedVariant.inventoryQuantity;\n if (typeof qty === 'number') {\n return qty > 0;\n }\n // If we don't have a numeric quantity, don't block add-to-cart\n return true;\n }\n\n // Otherwise, we can't add to cart\n return false;\n }, [selectedVariant]);\n\n const actionsRef = useRef<HTMLDivElement>(null);\n\n const inView = useIntersection(actionsRef, '0px');\n\n // add the selected variant to the cart\n const handleAddToCart = async () => {\n if (!selectedVariant?.id) return null;\n\n setStatus(AddToCartStatus.ADDING);\n\n try {\n await addToCart({\n variantId: selectedVariant.id,\n quantity: 1,\n countryCode,\n });\n\n mutateCart();\n\n setStatus(AddToCartStatus.SUCCESS);\n } catch (error) {\n console.log(error);\n setStatus(AddToCartStatus.ERROR);\n }\n };\n\n return (\n <>\n <div className=\"flex flex-col gap-y-2\" ref={actionsRef}>\n <div>\n {(product.variants?.length ?? 0) > 1 && (\n <div className=\"flex flex-col gap-y-4\">\n {(product.options || []).map((option) => {\n return (\n <div key={option.id}>\n <OptionSelect\n option={option}\n current={options[option.id]}\n updateOption={setOptionValue}\n title={option.title ?? ''}\n data-testid=\"product-options\"\n disabled={!!disabled || status === AddToCartStatus.ADDING}\n />\n </div>\n );\n })}\n <Divider />\n </div>\n )}\n </div>\n\n <WebComponent\n tag=\"mfe-product-price\"\n data-props={JSON.stringify({\n selectedVariantId: selectedVariant?.id ?? '',\n })}\n />\n\n {status === AddToCartStatus.ERROR && (\n <ErrorMessage error=\"Failed adding product to cart. Please try again.\" />\n )}\n {status === AddToCartStatus.SUCCESS && (\n <div className=\"text-small-regular pt-2 text-green-700\">\n Successfully added product to cart\n </div>\n )}\n <Button\n onClick={handleAddToCart}\n disabled={\n !inStock ||\n !selectedVariant ||\n !!disabled ||\n status === AddToCartStatus.ADDING ||\n !isValidVariant\n }\n variant=\"primary\"\n className=\"h-10 w-full\"\n isLoading={status === AddToCartStatus.ADDING}\n data-testid=\"add-product-button\"\n >\n {!selectedVariant\n ? 'Add to cart'\n : !inStock || !isValidVariant\n ? 'Out of stock'\n : 'Add to cart'}\n </Button>\n {enableMobileActions && (\n <MobileActions\n product={pricedProduct}\n variant={selectedVariant}\n options={options}\n updateOptions={setOptionValue}\n stockStatus={stockStatus}\n handleAddToCart={handleAddToCart}\n isAdding={status === AddToCartStatus.ADDING}\n show={!inView}\n optionsDisabled={!!disabled || status === AddToCartStatus.ADDING}\n />\n )}\n </div>\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAgCA,IAAK,8DAAL;AACE;AACA;AACA;AACA;;EAJG;AAOL,MAAM,mBACJ,mBAKG;AACH,QAAO,gBAAgB,QAAQ,KAA6B,WAAgB;AAC1E,MAAI,OAAO,YAAY,OAAO;AAC9B,SAAO;IACN,EAAE,CAAC;;AAGR,SAAwB,eAAe,EACrC,SACA,UACA,UACA,sBAAsB,QACA;CACtB,MAAM,CAAC,SAAS,cAAc,SAC5B,EAAE,CACH;CACD,MAAM,CAAC,QAAQ,aAAa,SAA0B,gBAAgB,KAAK;CAC3E,MAAM,cAAc,WAAW,CAAC;CAChC,MAAM,EAAE,SAAS,mBAAmB,gBAAgB,QAAQ,IAAI,SAAS;CACzE,MAAM,gBAAgB,cACd,oBAAoB,SAAS,eAAe,EAClD,CAAC,SAAS,eAAe,CAC1B;AAGD,iBAAgB;AACd,MAAI,eAAe,YAAY,cAAc,SAAS,WAAW,EAI/D,YAHuB,gBACrB,cAAc,SAAS,IAAI,WAAW,KACvC,IAC4B,EAAE,CAAC;IAEjC,CAAC,cAAc,SAAS,CAAC;CAE5B,MAAM,kBAAkB,cAAc;AACpC,MAAI,CAAC,cAAc,YAAY,cAAc,SAAS,WAAW,EAC/D;AAGF,SAAO,cAAc,SAAS,MAAM,MAAM;AAExC,UAAO,QADgB,gBAAgB,EAAE,QAAQ,EAClB,QAAQ;IACvC;IACD,CAAC,cAAc,UAAU,QAAQ,CAAC;CAGrC,MAAM,kBAAkB,UAAkB,UAAkB;AAC1D,cAAY,UAAU;GACpB,GAAG;IACF,WAAW;GACb,EAAE;;CAIL,MAAM,iBAAiB,cAAc;AACnC,SAAO,cAAc,UAAU,MAAM,MAAM;AAEzC,UAAO,QADgB,gBAAgB,EAAE,QAAQ,EAClB,QAAQ;IACvC;IACD,CAAC,cAAc,UAAU,QAAQ,CAAC;CAErC,MAAM,cAAc,cAAc;AAChC,MAAI,CAAC,gBACH,QAAO;AAGT,MAAI,CAAC,gBAAgB,gBACnB,QAAO;AAGT,MAAI,gBAAgB,eAClB,QAAO;EAGT,MAAM,MAAM,gBAAgB;AAE5B,MAAI,OAAO,QAAQ,SACjB,QAAO;AAGT,SAAO,MAAM,IAAK,aAAwB;IACzC,CAAC,gBAAgB,CAAC;CAErB,MAAM,UAAU,cAAc;AAE5B,MAAI,mBAAmB,CAAC,gBAAgB,gBACtC,QAAO;AAIT,MAAI,iBAAiB,eACnB,QAAO;AAGT,MAAI,iBAAiB,iBAAiB;GACpC,MAAM,MAAM,gBAAgB;AAC5B,OAAI,OAAO,QAAQ,SACjB,QAAO,MAAM;AAGf,UAAO;;AAIT,SAAO;IACN,CAAC,gBAAgB,CAAC;CAErB,MAAM,aAAa,OAAuB,KAAK;CAE/C,MAAM,SAAS,gBAAgB,YAAY,MAAM;CAGjD,MAAM,kBAAkB,YAAY;AAClC,MAAI,CAAC,iBAAiB,GAAI,QAAO;AAEjC,YAAU,gBAAgB,OAAO;AAEjC,MAAI;AACF,SAAM,UAAU;IACd,WAAW,gBAAgB;IAC3B,UAAU;IACV;IACD,CAAC;AAEF,eAAY;AAEZ,aAAU,gBAAgB,QAAQ;WAC3B,OAAO;AACd,WAAQ,IAAI,MAAM;AAClB,aAAU,gBAAgB,MAAM;;;AAIpC,QACE,0CACE,qBAAC;EAAI,WAAU;EAAwB,KAAK;;GAC1C,oBAAC,oBACG,QAAQ,UAAU,UAAU,KAAK,KACjC,qBAAC;IAAI,WAAU;gBACX,QAAQ,WAAW,EAAE,EAAE,KAAK,WAAW;AACvC,YACE,oBAAC,mBACC,oBAACA;MACS;MACR,SAAS,QAAQ,OAAO;MACxB,cAAc;MACd,OAAO,OAAO,SAAS;MACvB,eAAY;MACZ,UAAU,CAAC,CAAC,YAAY,WAAW,gBAAgB;OACnD,IARM,OAAO,GASX;MAER,EACF,oBAAC,YAAU;KACP,GAEJ;GAEN,oBAAC;IACC,KAAI;IACJ,cAAY,KAAK,UAAU,EACzB,mBAAmB,iBAAiB,MAAM,IAC3C,CAAC;KACF;GAED,WAAW,gBAAgB,SAC1B,oBAAC,gBAAa,OAAM,qDAAqD;GAE1E,WAAW,gBAAgB,WAC1B,oBAAC;IAAI,WAAU;cAAyC;KAElD;GAER,oBAAC;IACC,SAAS;IACT,UACE,CAAC,WACD,CAAC,mBACD,CAAC,CAAC,YACF,WAAW,gBAAgB,UAC3B,CAAC;IAEH,SAAQ;IACR,WAAU;IACV,WAAW,WAAW,gBAAgB;IACtC,eAAY;cAEX,CAAC,kBACE,gBACA,CAAC,WAAW,CAAC,iBACX,iBACA;KACC;GACR,uBACC,oBAACC;IACC,SAAS;IACT,SAAS;IACA;IACT,eAAe;IACF;IACI;IACjB,UAAU,WAAW,gBAAgB;IACrC,MAAM,CAAC;IACP,iBAAiB,CAAC,CAAC,YAAY,WAAW,gBAAgB;KAC1D;;GAEA,GACL"}
1
+ {"version":3,"file":"index.js","names":["OptionSelect","MobileActions"],"sources":["../../../src/components/product-actions/index.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useMemo, useRef, useState } from 'react';\n\nimport { useParams } from 'next/navigation';\n\nimport { isEqual } from 'lodash';\n\nimport { ErrorMessage } from '@gfed-medusa/sf-lib-common/components/error-message';\nimport { WebComponent } from '@gfed-medusa/sf-lib-common/components/web-component';\nimport { mutateCart } from '@gfed-medusa/sf-lib-common/lib/hooks/use-cart';\nimport { Divider } from '@gfed-medusa/sf-lib-ui/components/divider';\nimport { HttpTypes } from '@medusajs/types';\nimport { Button } from '@medusajs/ui';\n\nimport OptionSelect from '@/components/product-actions/option-select';\nimport { addToCart } from '@/lib/data/cart';\nimport { useIntersection } from '@/lib/hooks/use-intersection';\nimport { useProductPrice } from '@/lib/hooks/use-product-price';\nimport { mergeProductPricing } from '@/lib/utils/merge-product-pricing';\nimport { ProductActionsProduct } from '@/types';\nimport { ProductVariant } from '@/types/graphql';\n\nimport MobileActions from './mobile-actions';\n\nexport type ProductActionsProps = {\n product: ProductActionsProduct;\n regionId?: string;\n disabled?: boolean;\n enableMobileActions?: boolean;\n};\n\nenum AddToCartStatus {\n IDLE = 'idle',\n ADDING = 'adding',\n SUCCESS = 'success',\n ERROR = 'error',\n}\n\nconst optionsAsKeymap = (\n variantOptions:\n | HttpTypes.StoreProductVariant['options']\n | ProductVariant['options']\n | null\n | undefined\n) => {\n return variantOptions?.reduce((acc: Record<string, string>, varopt: any) => {\n acc[varopt.optionId] = varopt.value;\n return acc;\n }, {});\n};\n\nexport default function ProductActions({\n product,\n regionId,\n disabled,\n enableMobileActions = true,\n}: ProductActionsProps) {\n const [options, setOptions] = useState<Record<string, string | undefined>>(\n {}\n );\n const [status, setStatus] = useState<AddToCartStatus>(AddToCartStatus.IDLE);\n const countryCode = useParams().countryCode as string;\n const { product: pricingProduct } = useProductPrice(product.id, regionId);\n const pricedProduct = useMemo(\n () => mergeProductPricing(product, pricingProduct),\n [product, pricingProduct]\n );\n\n // If there is only 1 variant, preselect the options\n useEffect(() => {\n if (pricedProduct?.variants && pricedProduct.variants.length === 1) {\n const variantOptions = optionsAsKeymap(\n pricedProduct.variants[0]?.options || null\n );\n setOptions(variantOptions ?? {});\n }\n }, [pricedProduct.variants]);\n\n const selectedVariant = useMemo(() => {\n if (!pricedProduct.variants || pricedProduct.variants.length === 0) {\n return;\n }\n\n return pricedProduct.variants.find((v) => {\n const variantOptions = optionsAsKeymap(v.options);\n return isEqual(variantOptions, options);\n });\n }, [pricedProduct.variants, options]);\n\n // update the options when a variant is selected\n const setOptionValue = (optionId: string, value: string) => {\n setOptions((prev) => ({\n ...prev,\n [optionId]: value,\n }));\n };\n\n //check if the selected options produce a valid variant\n const isValidVariant = useMemo(() => {\n return pricedProduct.variants?.some((v) => {\n const variantOptions = optionsAsKeymap(v.options);\n return isEqual(variantOptions, options);\n });\n }, [pricedProduct.variants, options]);\n\n const stockStatus = useMemo(() => {\n if (!selectedVariant) {\n return 'unknown' as const;\n }\n\n if (!selectedVariant.manageInventory) {\n return 'in_stock' as const;\n }\n\n if (selectedVariant.allowBackorder) {\n return 'in_stock' as const;\n }\n\n const qty = selectedVariant.inventoryQuantity;\n\n if (typeof qty !== 'number') {\n return 'in_stock' as const;\n }\n\n return qty > 0 ? ('in_stock' as const) : ('out_of_stock' as const);\n }, [selectedVariant]);\n\n const inStock = useMemo(() => {\n // If we don't manage inventory, we can always add to cart\n if (selectedVariant && !selectedVariant.manageInventory) {\n return true;\n }\n\n // If we allow back orders on the variant, we can add to cart\n if (selectedVariant?.allowBackorder) {\n return true;\n }\n\n if (selectedVariant?.manageInventory) {\n const qty = selectedVariant.inventoryQuantity;\n if (typeof qty === 'number') {\n return qty > 0;\n }\n // If we don't have a numeric quantity, don't block add-to-cart\n return true;\n }\n\n // Otherwise, we can't add to cart\n return false;\n }, [selectedVariant]);\n\n const actionsRef = useRef<HTMLDivElement>(null);\n\n const inView = useIntersection(actionsRef, '0px');\n\n // add the selected variant to the cart\n const handleAddToCart = async () => {\n if (!selectedVariant?.id) return null;\n\n setStatus(AddToCartStatus.ADDING);\n\n try {\n await addToCart({\n variantId: selectedVariant.id,\n quantity: 1,\n countryCode,\n });\n\n mutateCart();\n\n setStatus(AddToCartStatus.SUCCESS);\n } catch (error) {\n console.log(error);\n setStatus(AddToCartStatus.ERROR);\n }\n };\n\n return (\n <>\n <div className=\"flex flex-col gap-y-2\" ref={actionsRef}>\n <div>\n {(product.variants?.length ?? 0) > 1 && (\n <div className=\"flex flex-col gap-y-4\">\n {(product.options || []).map((option) => {\n return (\n <div key={option.id}>\n <OptionSelect\n option={option}\n current={options[option.id]}\n updateOption={setOptionValue}\n title={option.title ?? ''}\n data-testid=\"product-options\"\n disabled={!!disabled || status === AddToCartStatus.ADDING}\n />\n </div>\n );\n })}\n <Divider />\n </div>\n )}\n </div>\n\n <WebComponent\n tag=\"mfe-product-price\"\n data-props={JSON.stringify({\n selectedVariantId: selectedVariant?.id ?? '',\n })}\n />\n\n {status === AddToCartStatus.ERROR && (\n <ErrorMessage error=\"Failed adding product to cart. Please try again.\" />\n )}\n {status === AddToCartStatus.SUCCESS && (\n <div className=\"text-small-regular pt-2 text-green-700\">\n Successfully added product to cart\n </div>\n )}\n <Button\n onClick={handleAddToCart}\n disabled={\n !inStock ||\n !selectedVariant ||\n !!disabled ||\n status === AddToCartStatus.ADDING ||\n !isValidVariant\n }\n variant=\"primary\"\n className=\"h-10 w-full\"\n isLoading={status === AddToCartStatus.ADDING}\n data-testid=\"add-product-button\"\n >\n {!selectedVariant\n ? 'Add to cart'\n : !inStock || !isValidVariant\n ? 'Out of stock'\n : 'Add to cart'}\n </Button>\n {enableMobileActions && (\n <MobileActions\n product={pricedProduct}\n variant={selectedVariant}\n options={options}\n updateOptions={setOptionValue}\n stockStatus={stockStatus}\n handleAddToCart={handleAddToCart}\n isAdding={status === AddToCartStatus.ADDING}\n show={!inView}\n optionsDisabled={!!disabled || status === AddToCartStatus.ADDING}\n />\n )}\n </div>\n </>\n );\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import option_select_default from "./option-select.js";
2
2
  import { isSimpleProduct } from "../../lib/utils/product.js";
3
+ import React, { Fragment } from "react";
3
4
  import { Button, clx } from "@medusajs/ui";
4
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
- import React, { Fragment as Fragment$1 } from "react";
5
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
6
  import { isEqual } from "lodash";
7
7
  import { WebComponent } from "@gfed-medusa/sf-lib-common/components/web-component";
8
8
  import useToggleState from "@gfed-medusa/sf-lib-common/lib/hooks/use-toggle-state";
@@ -29,10 +29,10 @@ const MobileActions = ({ product, variant, options, updateOptions, stockStatus,
29
29
  };
30
30
  if ((product.variants ?? []).some((productVariant) => isEqual(optionsAsKeymap(productVariant.options), nextOptions))) close();
31
31
  };
32
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
32
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
33
33
  className: clx("fixed inset-x-0 bottom-0 z-40 lg:hidden", { "pointer-events-none": !show }),
34
34
  children: /* @__PURE__ */ jsx(Transition, {
35
- as: Fragment$1,
35
+ as: Fragment,
36
36
  show,
37
37
  enter: "ease-in-out duration-300",
38
38
  enterFrom: "opacity-0",
@@ -78,13 +78,13 @@ const MobileActions = ({ product, variant, options, updateOptions, stockStatus,
78
78
  }), /* @__PURE__ */ jsx(Transition, {
79
79
  appear: true,
80
80
  show: state,
81
- as: Fragment$1,
81
+ as: Fragment,
82
82
  children: /* @__PURE__ */ jsxs(Dialog, {
83
83
  as: "div",
84
84
  className: "relative z-[100]",
85
85
  onClose: close,
86
86
  children: [/* @__PURE__ */ jsx(Transition.Child, {
87
- as: Fragment$1,
87
+ as: Fragment,
88
88
  enter: "ease-out duration-300",
89
89
  enterFrom: "opacity-0",
90
90
  enterTo: "opacity-100",
@@ -97,7 +97,7 @@ const MobileActions = ({ product, variant, options, updateOptions, stockStatus,
97
97
  children: /* @__PURE__ */ jsx("div", {
98
98
  className: "flex h-full min-h-full items-center justify-center text-center",
99
99
  children: /* @__PURE__ */ jsx(Transition.Child, {
100
- as: Fragment$1,
100
+ as: Fragment,
101
101
  enter: "ease-out duration-300",
102
102
  enterFrom: "opacity-0",
103
103
  enterTo: "opacity-100",
@@ -1 +1 @@
1
- {"version":3,"file":"mobile-actions.js","names":["MobileActions: React.FC<MobileActionsProps>","Fragment","OptionSelect"],"sources":["../../../src/components/product-actions/mobile-actions.tsx"],"sourcesContent":["import React, { Fragment } from 'react';\n\nimport { isEqual } from 'lodash';\n\nimport { WebComponent } from '@gfed-medusa/sf-lib-common/components/web-component';\nimport useToggleState from '@gfed-medusa/sf-lib-common/lib/hooks/use-toggle-state';\nimport { ChevronDown } from '@gfed-medusa/sf-lib-ui/icons/chevron-down';\nimport { X } from '@gfed-medusa/sf-lib-ui/icons/x';\nimport { Dialog, Transition } from '@headlessui/react';\nimport { Button, clx } from '@medusajs/ui';\n\nimport { isSimpleProduct } from '@/lib/utils/product';\nimport { ProductActionsProduct } from '@/types';\nimport { ProductVariant } from '@/types/graphql';\n\nimport OptionSelect from './option-select';\n\ntype MobileActionsProps = {\n product: ProductActionsProduct;\n variant?: ProductVariant;\n options: Record<string, string | undefined>;\n updateOptions: (title: string, value: string) => void;\n stockStatus?: 'unknown' | 'in_stock' | 'out_of_stock';\n handleAddToCart: () => void;\n isAdding?: boolean;\n show: boolean;\n optionsDisabled: boolean;\n};\n\nconst optionsAsKeymap = (\n variantOptions: ProductVariant['options'] | null | undefined\n) => {\n return variantOptions?.reduce<Record<string, string>>((acc, varopt) => {\n if (!varopt) {\n return acc;\n }\n\n acc[varopt.optionId] = varopt.value;\n\n return acc;\n }, {});\n};\n\nconst MobileActions: React.FC<MobileActionsProps> = ({\n product,\n variant,\n options,\n updateOptions,\n stockStatus,\n handleAddToCart,\n isAdding,\n show,\n optionsDisabled,\n}) => {\n const { state, open, close } = useToggleState();\n\n const isSimple = isSimpleProduct(product);\n const handleUpdateOption = (optionId: string, value: string) => {\n updateOptions(optionId, value);\n\n const nextOptions = {\n ...options,\n [optionId]: value,\n };\n\n const hasMatchingVariant = (product.variants ?? []).some((productVariant) =>\n isEqual(optionsAsKeymap(productVariant.options), nextOptions)\n );\n\n if (hasMatchingVariant) {\n close();\n }\n };\n\n return (\n <>\n <div\n className={clx('fixed inset-x-0 bottom-0 z-40 lg:hidden', {\n 'pointer-events-none': !show,\n })}\n >\n <Transition\n as={Fragment}\n show={show}\n enter=\"ease-in-out duration-300\"\n enterFrom=\"opacity-0\"\n enterTo=\"opacity-100\"\n leave=\"ease-in duration-300\"\n leaveFrom=\"opacity-100\"\n leaveTo=\"opacity-0\"\n >\n <div\n className=\"text-large-regular flex h-full w-full flex-col items-center justify-center gap-y-3 border-t border-gray-200 bg-white p-4\"\n data-testid=\"mobile-actions\"\n >\n <div className=\"flex w-full items-start justify-between gap-x-4\">\n <span className=\"flex-1 text-left\" data-testid=\"mobile-title\">\n {product.title}\n </span>\n <WebComponent\n tag=\"mfe-product-price\"\n data-props={JSON.stringify({\n selectedVariantId: variant?.id ?? '',\n })}\n />\n </div>\n <div\n className={clx('grid w-full grid-cols-2 gap-x-4', {\n '!grid-cols-1': isSimple,\n })}\n >\n {!isSimple && (\n <Button\n onClick={open}\n variant=\"secondary\"\n className=\"w-full\"\n data-testid=\"mobile-actions-button\"\n >\n <div className=\"flex w-full items-center justify-between\">\n <span>\n {variant\n ? Object.values(options).join(' / ')\n : 'Select Size'}\n </span>\n <ChevronDown />\n </div>\n </Button>\n )}\n <Button\n onClick={handleAddToCart}\n disabled={!variant || stockStatus === 'out_of_stock'}\n className=\"w-full\"\n isLoading={isAdding}\n data-testid=\"mobile-cart-button\"\n >\n {stockStatus === 'out_of_stock'\n ? 'Out of stock'\n : 'Add to cart'}\n </Button>\n </div>\n </div>\n </Transition>\n </div>\n <Transition appear show={state} as={Fragment}>\n <Dialog as=\"div\" className=\"relative z-[100]\" onClose={close}>\n <Transition.Child\n as={Fragment}\n enter=\"ease-out duration-300\"\n enterFrom=\"opacity-0\"\n enterTo=\"opacity-100\"\n leave=\"ease-in duration-200\"\n leaveFrom=\"opacity-100\"\n leaveTo=\"opacity-0\"\n >\n <div className=\"fixed inset-0 h-screen bg-black/20 backdrop-blur-sm\" />\n </Transition.Child>\n\n <div className=\"fixed inset-x-0 bottom-0\">\n <div className=\"flex h-full min-h-full items-center justify-center text-center\">\n <Transition.Child\n as={Fragment}\n enter=\"ease-out duration-300\"\n enterFrom=\"opacity-0\"\n enterTo=\"opacity-100\"\n leave=\"ease-in duration-200\"\n leaveFrom=\"opacity-100\"\n leaveTo=\"opacity-0\"\n >\n <Dialog.Panel\n className=\"pointer-events-none flex w-full transform flex-col gap-y-3 text-left\"\n data-testid=\"mobile-actions-modal\"\n >\n <div className=\"flex w-full justify-end pr-6\">\n <button\n onClick={close}\n className=\"text-ui-fg-base pointer-events-auto flex h-12 w-12 items-center justify-center rounded-full bg-white\"\n data-testid=\"close-modal-button\"\n >\n <X />\n </button>\n </div>\n <div className=\"pointer-events-auto bg-white px-6 py-12\">\n {(product.variants?.length ?? 0) > 1 && (\n <div className=\"flex flex-col gap-y-6\">\n {(product.options || []).map((option) => {\n return (\n <div key={option.id}>\n <OptionSelect\n option={option}\n current={options[option.id]}\n updateOption={handleUpdateOption}\n title={option.title ?? ''}\n disabled={optionsDisabled}\n />\n </div>\n );\n })}\n </div>\n )}\n </div>\n </Dialog.Panel>\n </Transition.Child>\n </div>\n </div>\n </Dialog>\n </Transition>\n </>\n );\n};\n\nexport default MobileActions;\n"],"mappings":";;;;;;;;;;;;;AA6BA,MAAM,mBACJ,mBACG;AACH,QAAO,gBAAgB,QAAgC,KAAK,WAAW;AACrE,MAAI,CAAC,OACH,QAAO;AAGT,MAAI,OAAO,YAAY,OAAO;AAE9B,SAAO;IACN,EAAE,CAAC;;AAGR,MAAMA,iBAA+C,EACnD,SACA,SACA,SACA,eACA,aACA,iBACA,UACA,MACA,sBACI;CACJ,MAAM,EAAE,OAAO,MAAM,UAAU,gBAAgB;CAE/C,MAAM,WAAW,gBAAgB,QAAQ;CACzC,MAAM,sBAAsB,UAAkB,UAAkB;AAC9D,gBAAc,UAAU,MAAM;EAE9B,MAAM,cAAc;GAClB,GAAG;IACF,WAAW;GACb;AAMD,OAJ4B,QAAQ,YAAY,EAAE,EAAE,MAAM,mBACxD,QAAQ,gBAAgB,eAAe,QAAQ,EAAE,YAAY,CAC9D,CAGC,QAAO;;AAIX,QACE,4CACE,oBAAC;EACC,WAAW,IAAI,2CAA2C,EACxD,uBAAuB,CAAC,MACzB,CAAC;YAEF,oBAAC;GACC,IAAIC;GACE;GACN,OAAM;GACN,WAAU;GACV,SAAQ;GACR,OAAM;GACN,WAAU;GACV,SAAQ;aAER,qBAAC;IACC,WAAU;IACV,eAAY;eAEZ,qBAAC;KAAI,WAAU;gBACb,oBAAC;MAAK,WAAU;MAAmB,eAAY;gBAC5C,QAAQ;OACJ,EACP,oBAAC;MACC,KAAI;MACJ,cAAY,KAAK,UAAU,EACzB,mBAAmB,SAAS,MAAM,IACnC,CAAC;OACF;MACE,EACN,qBAAC;KACC,WAAW,IAAI,mCAAmC,EAChD,gBAAgB,UACjB,CAAC;gBAED,CAAC,YACA,oBAAC;MACC,SAAS;MACT,SAAQ;MACR,WAAU;MACV,eAAY;gBAEZ,qBAAC;OAAI,WAAU;kBACb,oBAAC,oBACE,UACG,OAAO,OAAO,QAAQ,CAAC,KAAK,MAAM,GAClC,gBACC,EACP,oBAAC,gBAAc;QACX;OACC,EAEX,oBAAC;MACC,SAAS;MACT,UAAU,CAAC,WAAW,gBAAgB;MACtC,WAAU;MACV,WAAW;MACX,eAAY;gBAEX,gBAAgB,iBACb,iBACA;OACG;MACL;KACF;IACK;GACT,EACN,oBAAC;EAAW;EAAO,MAAM;EAAO,IAAIA;YAClC,qBAAC;GAAO,IAAG;GAAM,WAAU;GAAmB,SAAS;cACrD,oBAAC,WAAW;IACV,IAAIA;IACJ,OAAM;IACN,WAAU;IACV,SAAQ;IACR,OAAM;IACN,WAAU;IACV,SAAQ;cAER,oBAAC,SAAI,WAAU,wDAAwD;KACtD,EAEnB,oBAAC;IAAI,WAAU;cACb,oBAAC;KAAI,WAAU;eACb,oBAAC,WAAW;MACV,IAAIA;MACJ,OAAM;MACN,WAAU;MACV,SAAQ;MACR,OAAM;MACN,WAAU;MACV,SAAQ;gBAER,qBAAC,OAAO;OACN,WAAU;OACV,eAAY;kBAEZ,oBAAC;QAAI,WAAU;kBACb,oBAAC;SACC,SAAS;SACT,WAAU;SACV,eAAY;mBAEZ,oBAAC,MAAI;UACE;SACL,EACN,oBAAC;QAAI,WAAU;mBACX,QAAQ,UAAU,UAAU,KAAK,KACjC,oBAAC;SAAI,WAAU;oBACX,QAAQ,WAAW,EAAE,EAAE,KAAK,WAAW;AACvC,iBACE,oBAAC,mBACC,oBAACC;WACS;WACR,SAAS,QAAQ,OAAO;WACxB,cAAc;WACd,OAAO,OAAO,SAAS;WACvB,UAAU;YACV,IAPM,OAAO,GAQX;WAER;UACE;SAEJ;QACO;OACE;MACf;KACF;IACC;GACE,IACZ;;AAIP,6BAAe"}
1
+ {"version":3,"file":"mobile-actions.js","names":["MobileActions: React.FC<MobileActionsProps>","OptionSelect"],"sources":["../../../src/components/product-actions/mobile-actions.tsx"],"sourcesContent":["import React, { Fragment } from 'react';\n\nimport { isEqual } from 'lodash';\n\nimport { WebComponent } from '@gfed-medusa/sf-lib-common/components/web-component';\nimport useToggleState from '@gfed-medusa/sf-lib-common/lib/hooks/use-toggle-state';\nimport { ChevronDown } from '@gfed-medusa/sf-lib-ui/icons/chevron-down';\nimport { X } from '@gfed-medusa/sf-lib-ui/icons/x';\nimport { Dialog, Transition } from '@headlessui/react';\nimport { Button, clx } from '@medusajs/ui';\n\nimport { isSimpleProduct } from '@/lib/utils/product';\nimport { ProductActionsProduct } from '@/types';\nimport { ProductVariant } from '@/types/graphql';\n\nimport OptionSelect from './option-select';\n\ntype MobileActionsProps = {\n product: ProductActionsProduct;\n variant?: ProductVariant;\n options: Record<string, string | undefined>;\n updateOptions: (title: string, value: string) => void;\n stockStatus?: 'unknown' | 'in_stock' | 'out_of_stock';\n handleAddToCart: () => void;\n isAdding?: boolean;\n show: boolean;\n optionsDisabled: boolean;\n};\n\nconst optionsAsKeymap = (\n variantOptions: ProductVariant['options'] | null | undefined\n) => {\n return variantOptions?.reduce<Record<string, string>>((acc, varopt) => {\n if (!varopt) {\n return acc;\n }\n\n acc[varopt.optionId] = varopt.value;\n\n return acc;\n }, {});\n};\n\nconst MobileActions: React.FC<MobileActionsProps> = ({\n product,\n variant,\n options,\n updateOptions,\n stockStatus,\n handleAddToCart,\n isAdding,\n show,\n optionsDisabled,\n}) => {\n const { state, open, close } = useToggleState();\n\n const isSimple = isSimpleProduct(product);\n const handleUpdateOption = (optionId: string, value: string) => {\n updateOptions(optionId, value);\n\n const nextOptions = {\n ...options,\n [optionId]: value,\n };\n\n const hasMatchingVariant = (product.variants ?? []).some((productVariant) =>\n isEqual(optionsAsKeymap(productVariant.options), nextOptions)\n );\n\n if (hasMatchingVariant) {\n close();\n }\n };\n\n return (\n <>\n <div\n className={clx('fixed inset-x-0 bottom-0 z-40 lg:hidden', {\n 'pointer-events-none': !show,\n })}\n >\n <Transition\n as={Fragment}\n show={show}\n enter=\"ease-in-out duration-300\"\n enterFrom=\"opacity-0\"\n enterTo=\"opacity-100\"\n leave=\"ease-in duration-300\"\n leaveFrom=\"opacity-100\"\n leaveTo=\"opacity-0\"\n >\n <div\n className=\"text-large-regular flex h-full w-full flex-col items-center justify-center gap-y-3 border-t border-gray-200 bg-white p-4\"\n data-testid=\"mobile-actions\"\n >\n <div className=\"flex w-full items-start justify-between gap-x-4\">\n <span className=\"flex-1 text-left\" data-testid=\"mobile-title\">\n {product.title}\n </span>\n <WebComponent\n tag=\"mfe-product-price\"\n data-props={JSON.stringify({\n selectedVariantId: variant?.id ?? '',\n })}\n />\n </div>\n <div\n className={clx('grid w-full grid-cols-2 gap-x-4', {\n '!grid-cols-1': isSimple,\n })}\n >\n {!isSimple && (\n <Button\n onClick={open}\n variant=\"secondary\"\n className=\"w-full\"\n data-testid=\"mobile-actions-button\"\n >\n <div className=\"flex w-full items-center justify-between\">\n <span>\n {variant\n ? Object.values(options).join(' / ')\n : 'Select Size'}\n </span>\n <ChevronDown />\n </div>\n </Button>\n )}\n <Button\n onClick={handleAddToCart}\n disabled={!variant || stockStatus === 'out_of_stock'}\n className=\"w-full\"\n isLoading={isAdding}\n data-testid=\"mobile-cart-button\"\n >\n {stockStatus === 'out_of_stock'\n ? 'Out of stock'\n : 'Add to cart'}\n </Button>\n </div>\n </div>\n </Transition>\n </div>\n <Transition appear show={state} as={Fragment}>\n <Dialog as=\"div\" className=\"relative z-[100]\" onClose={close}>\n <Transition.Child\n as={Fragment}\n enter=\"ease-out duration-300\"\n enterFrom=\"opacity-0\"\n enterTo=\"opacity-100\"\n leave=\"ease-in duration-200\"\n leaveFrom=\"opacity-100\"\n leaveTo=\"opacity-0\"\n >\n <div className=\"fixed inset-0 h-screen bg-black/20 backdrop-blur-sm\" />\n </Transition.Child>\n\n <div className=\"fixed inset-x-0 bottom-0\">\n <div className=\"flex h-full min-h-full items-center justify-center text-center\">\n <Transition.Child\n as={Fragment}\n enter=\"ease-out duration-300\"\n enterFrom=\"opacity-0\"\n enterTo=\"opacity-100\"\n leave=\"ease-in duration-200\"\n leaveFrom=\"opacity-100\"\n leaveTo=\"opacity-0\"\n >\n <Dialog.Panel\n className=\"pointer-events-none flex w-full transform flex-col gap-y-3 text-left\"\n data-testid=\"mobile-actions-modal\"\n >\n <div className=\"flex w-full justify-end pr-6\">\n <button\n onClick={close}\n className=\"text-ui-fg-base pointer-events-auto flex h-12 w-12 items-center justify-center rounded-full bg-white\"\n data-testid=\"close-modal-button\"\n >\n <X />\n </button>\n </div>\n <div className=\"pointer-events-auto bg-white px-6 py-12\">\n {(product.variants?.length ?? 0) > 1 && (\n <div className=\"flex flex-col gap-y-6\">\n {(product.options || []).map((option) => {\n return (\n <div key={option.id}>\n <OptionSelect\n option={option}\n current={options[option.id]}\n updateOption={handleUpdateOption}\n title={option.title ?? ''}\n disabled={optionsDisabled}\n />\n </div>\n );\n })}\n </div>\n )}\n </div>\n </Dialog.Panel>\n </Transition.Child>\n </div>\n </div>\n </Dialog>\n </Transition>\n </>\n );\n};\n\nexport default MobileActions;\n"],"mappings":";;;;;;;;;;;;;AA6BA,MAAM,mBACJ,mBACG;AACH,QAAO,gBAAgB,QAAgC,KAAK,WAAW;AACrE,MAAI,CAAC,OACH,QAAO;AAGT,MAAI,OAAO,YAAY,OAAO;AAE9B,SAAO;IACN,EAAE,CAAC;;AAGR,MAAMA,iBAA+C,EACnD,SACA,SACA,SACA,eACA,aACA,iBACA,UACA,MACA,sBACI;CACJ,MAAM,EAAE,OAAO,MAAM,UAAU,gBAAgB;CAE/C,MAAM,WAAW,gBAAgB,QAAQ;CACzC,MAAM,sBAAsB,UAAkB,UAAkB;AAC9D,gBAAc,UAAU,MAAM;EAE9B,MAAM,cAAc;GAClB,GAAG;IACF,WAAW;GACb;AAMD,OAJ4B,QAAQ,YAAY,EAAE,EAAE,MAAM,mBACxD,QAAQ,gBAAgB,eAAe,QAAQ,EAAE,YAAY,CAC9D,CAGC,QAAO;;AAIX,QACE,8CACE,oBAAC;EACC,WAAW,IAAI,2CAA2C,EACxD,uBAAuB,CAAC,MACzB,CAAC;YAEF,oBAAC;GACC,IAAI;GACE;GACN,OAAM;GACN,WAAU;GACV,SAAQ;GACR,OAAM;GACN,WAAU;GACV,SAAQ;aAER,qBAAC;IACC,WAAU;IACV,eAAY;eAEZ,qBAAC;KAAI,WAAU;gBACb,oBAAC;MAAK,WAAU;MAAmB,eAAY;gBAC5C,QAAQ;OACJ,EACP,oBAAC;MACC,KAAI;MACJ,cAAY,KAAK,UAAU,EACzB,mBAAmB,SAAS,MAAM,IACnC,CAAC;OACF;MACE,EACN,qBAAC;KACC,WAAW,IAAI,mCAAmC,EAChD,gBAAgB,UACjB,CAAC;gBAED,CAAC,YACA,oBAAC;MACC,SAAS;MACT,SAAQ;MACR,WAAU;MACV,eAAY;gBAEZ,qBAAC;OAAI,WAAU;kBACb,oBAAC,oBACE,UACG,OAAO,OAAO,QAAQ,CAAC,KAAK,MAAM,GAClC,gBACC,EACP,oBAAC,gBAAc;QACX;OACC,EAEX,oBAAC;MACC,SAAS;MACT,UAAU,CAAC,WAAW,gBAAgB;MACtC,WAAU;MACV,WAAW;MACX,eAAY;gBAEX,gBAAgB,iBACb,iBACA;OACG;MACL;KACF;IACK;GACT,EACN,oBAAC;EAAW;EAAO,MAAM;EAAO,IAAI;YAClC,qBAAC;GAAO,IAAG;GAAM,WAAU;GAAmB,SAAS;cACrD,oBAAC,WAAW;IACV,IAAI;IACJ,OAAM;IACN,WAAU;IACV,SAAQ;IACR,OAAM;IACN,WAAU;IACV,SAAQ;cAER,oBAAC,SAAI,WAAU,wDAAwD;KACtD,EAEnB,oBAAC;IAAI,WAAU;cACb,oBAAC;KAAI,WAAU;eACb,oBAAC,WAAW;MACV,IAAI;MACJ,OAAM;MACN,WAAU;MACV,SAAQ;MACR,OAAM;MACN,WAAU;MACV,SAAQ;gBAER,qBAAC,OAAO;OACN,WAAU;OACV,eAAY;kBAEZ,oBAAC;QAAI,WAAU;kBACb,oBAAC;SACC,SAAS;SACT,WAAU;SACV,eAAY;mBAEZ,oBAAC,MAAI;UACE;SACL,EACN,oBAAC;QAAI,WAAU;mBACX,QAAQ,UAAU,UAAU,KAAK,KACjC,oBAAC;SAAI,WAAU;oBACX,QAAQ,WAAW,EAAE,EAAE,KAAK,WAAW;AACvC,iBACE,oBAAC,mBACC,oBAACC;WACS;WACR,SAAS,QAAQ,OAAO;WACxB,cAAc;WACd,OAAO,OAAO,SAAS;WACvB,UAAU;YACV,IAPM,OAAO,GAQX;WAER;UACE;SAEJ;QACO;OACE;MACf;KACF;IACC;GACE,IACZ;;AAIP,6BAAe"}
@@ -1,6 +1,6 @@
1
+ import React from "react";
1
2
  import { clx } from "@medusajs/ui";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import React from "react";
4
4
 
5
5
  //#region src/components/product-actions/option-select.tsx
6
6
  const OptionSelect = ({ option, current, updateOption, title, "data-testid": dataTestId, disabled }) => {
@@ -1,7 +1,7 @@
1
- import * as react_jsx_runtime4 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime5 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/product-onboarding-cta/index.d.ts
4
- declare function ProductOnboardingCta(): Promise<react_jsx_runtime4.JSX.Element | null>;
4
+ declare function ProductOnboardingCta(): Promise<react_jsx_runtime5.JSX.Element | null>;
5
5
  //#endregion
6
6
  export { ProductOnboardingCta as default };
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import { ProductVariant } from "../../types/graphql.js";
2
2
  import { ProductActionsProduct } from "../../types/index.js";
3
- import * as react_jsx_runtime3 from "react/jsx-runtime";
3
+ import * as react_jsx_runtime7 from "react/jsx-runtime";
4
4
 
5
5
  //#region src/components/product-price/index.d.ts
6
6
  declare function ProductPrice({
@@ -9,7 +9,7 @@ declare function ProductPrice({
9
9
  }: {
10
10
  product: ProductActionsProduct;
11
11
  variant?: ProductVariant;
12
- }): react_jsx_runtime3.JSX.Element;
12
+ }): react_jsx_runtime7.JSX.Element;
13
13
  //#endregion
14
14
  export { ProductPrice as default };
15
15
  //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,6 @@
1
+ import React from "react";
1
2
  import { Text, clx } from "@medusajs/ui";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import React from "react";
4
4
  import * as AccordionPrimitive from "@radix-ui/react-accordion";
5
5
 
6
6
  //#region src/components/product-tabs/accordion.tsx
@@ -1,5 +1,5 @@
1
1
  import { Product } from "../../types/graphql.js";
2
- import * as react_jsx_runtime5 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime9 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/components/product-tabs/index.d.ts
5
5
  type ProductTabsProps = {
@@ -7,7 +7,7 @@ type ProductTabsProps = {
7
7
  };
8
8
  declare const ProductTabs: ({
9
9
  product
10
- }: ProductTabsProps) => react_jsx_runtime5.JSX.Element;
10
+ }: ProductTabsProps) => react_jsx_runtime9.JSX.Element;
11
11
  //#endregion
12
12
  export { ProductTabs as default };
13
13
  //# sourceMappingURL=index.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { SortOptions } from "./sort-products/index.js";
2
- import * as react_jsx_runtime7 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime10 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/components/refinement-list/index.d.ts
5
5
  type RefinementListProps = {
@@ -12,7 +12,7 @@ declare const RefinementList: ({
12
12
  sortBy,
13
13
  "data-testid": dataTestId,
14
14
  className
15
- }: RefinementListProps) => react_jsx_runtime7.JSX.Element;
15
+ }: RefinementListProps) => react_jsx_runtime10.JSX.Element;
16
16
  //#endregion
17
17
  export { RefinementList as default };
18
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/refinement-list/index.tsx"],"sourcesContent":[],"mappings":";;;;KAUK,mBAAA;UACK;;EADL,aAAA,CAAA,EAAA,MAAmB;EAOlB,SAAA,CAAA,EAAA,MA8CL;CA9CuB;cAAlB,cAAkB,EAAA,CAAA;EAAA,MAAA;EAAA,aAAA,EAAA,UAAA;EAAA;AAAA,CAAA,EAIrB,mBAJqB,EAAA,GAIF,kBAAA,CAAA,GAAA,CAAA,OAJE"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/refinement-list/index.tsx"],"sourcesContent":[],"mappings":";;;;KAUK,mBAAA;UACK;;EADL,aAAA,CAAA,EAAA,MAAmB;EAOlB,SAAA,CAAA,EAAA,MA8CL;CA9CuB;cAAlB,cAAkB,EAAA,CAAA;EAAA,MAAA;EAAA,aAAA,EAAA,UAAA;EAAA;AAAA,CAAA,EAIrB,mBAJqB,EAAA,GAIF,mBAAA,CAAA,GAAA,CAAA,OAJE"}
@@ -1,9 +1,9 @@
1
1
  'use client';
2
2
 
3
3
  import sort_products_default from "./sort-products/index.js";
4
+ import { useCallback } from "react";
4
5
  import { clx } from "@medusajs/ui";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
- import { useCallback } from "react";
7
7
  import { usePathname, useRouter, useSearchParams } from "next/navigation";
8
8
 
9
9
  //#region src/components/refinement-list/index.tsx
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime14 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime4 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/refinement-list/sort-products/index.d.ts
4
4
  type SortOptions = 'price_asc' | 'price_desc' | 'created_at';
@@ -13,7 +13,7 @@ declare const SortProducts: ({
13
13
  sortBy,
14
14
  setQueryParams,
15
15
  variant
16
- }: SortProductsProps) => react_jsx_runtime14.JSX.Element;
16
+ }: SortProductsProps) => react_jsx_runtime4.JSX.Element;
17
17
  //#endregion
18
18
  export { SortOptions, SortProducts as default };
19
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/components/refinement-list/sort-products/index.tsx"],"sourcesContent":[],"mappings":";;;KAKY,WAAA;KAEP,iBAAA;UACK;EAHE,cAAW,EAAA,CAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAIiB,WAJjB,EAAA,GAAA,IAAA;EAElB,OAAA,CAAA,EAAA,OAAA,GAAiB,UAAA;EAsBhB,aAAA,CAAA,EAwCL,MAAA;CAxCqB;cAAhB,YAAgB,EAAA,CAAA;EAAA,aAAA,EAAA,UAAA;EAAA,MAAA;EAAA,cAAA;EAAA;AAAA,CAAA,EAKnB,iBALmB,EAAA,GAKF,mBAAA,CAAA,GAAA,CAAA,OALE"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/components/refinement-list/sort-products/index.tsx"],"sourcesContent":[],"mappings":";;;KAKY,WAAA;KAEP,iBAAA;UACK;EAHE,cAAW,EAAA,CAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAIiB,WAJjB,EAAA,GAAA,IAAA;EAElB,OAAA,CAAA,EAAA,OAAA,GAAiB,UAAA;EAsBhB,aAAA,CAAA,EAwCL,MAAA;CAxCqB;cAAhB,YAAgB,EAAA,CAAA;EAAA,aAAA,EAAA,UAAA;EAAA,MAAA;EAAA,cAAA;EAAA;AAAA,CAAA,EAKnB,iBALmB,EAAA,GAKF,kBAAA,CAAA,GAAA,CAAA,OALE"}
@@ -1,5 +1,5 @@
1
1
  import { Product } from "../../types/graphql.js";
2
- import * as react_jsx_runtime6 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime11 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/components/related-products/index.d.ts
5
5
  type RelatedProductsProps = {
@@ -9,7 +9,7 @@ type RelatedProductsProps = {
9
9
  declare function RelatedProducts({
10
10
  product,
11
11
  countryCode
12
- }: RelatedProductsProps): Promise<react_jsx_runtime6.JSX.Element | null>;
12
+ }: RelatedProductsProps): Promise<react_jsx_runtime11.JSX.Element | null>;
13
13
  //#endregion
14
14
  export { RelatedProducts as default };
15
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/related-products/index.tsx"],"sourcesContent":[],"mappings":";;;;KASK,oBAAA;WACM;;AAHc,CAAA;AAOK,iBAAA,eAAA,CAAe;EAAA,OAAA;EAAA;AAAA,CAAA,EAG1C,oBAH0C,CAAA,EAGtB,OAHsB,CAGtB,kBAAA,CAAA,GAAA,CAAA,OAAA,GAHsB,IAAA,CAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/related-products/index.tsx"],"sourcesContent":[],"mappings":";;;;KASK,oBAAA;WACM;;AAHc,CAAA;AAOK,iBAAA,eAAA,CAAe;EAAA,OAAA;EAAA;AAAA,CAAA,EAG1C,oBAH0C,CAAA,EAGtB,OAHsB,CAGtB,mBAAA,CAAA,GAAA,CAAA,OAAA,GAHsB,IAAA,CAAA"}
@@ -1,11 +1,11 @@
1
- import * as react_jsx_runtime8 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime15 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/skeleton-product-grid/index.d.ts
4
4
  declare const SkeletonProductGrid: ({
5
5
  numberOfProducts
6
6
  }: {
7
7
  numberOfProducts?: number;
8
- }) => react_jsx_runtime8.JSX.Element;
8
+ }) => react_jsx_runtime15.JSX.Element;
9
9
  //#endregion
10
10
  export { SkeletonProductGrid as default };
11
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/skeleton-product-grid/index.tsx"],"sourcesContent":[],"mappings":";;;cAGM;;;;MAIL,kBAAA,CAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/skeleton-product-grid/index.tsx"],"sourcesContent":[],"mappings":";;;cAGM;;;;MAIL,mBAAA,CAAA,GAAA,CAAA"}
@@ -1,7 +1,7 @@
1
- import * as react_jsx_runtime9 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime6 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/skeleton-product-preview/index.d.ts
4
- declare const SkeletonProductPreview: () => react_jsx_runtime9.JSX.Element;
4
+ declare const SkeletonProductPreview: () => react_jsx_runtime6.JSX.Element;
5
5
  //#endregion
6
6
  export { SkeletonProductPreview as default };
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1,7 +1,7 @@
1
- import * as react_jsx_runtime10 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime8 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/skeleton-related-products/index.d.ts
4
- declare const SkeletonRelatedProducts: () => react_jsx_runtime10.JSX.Element;
4
+ declare const SkeletonRelatedProducts: () => react_jsx_runtime8.JSX.Element;
5
5
  //#endregion
6
6
  export { SkeletonRelatedProducts as default };
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/skeleton-related-products/index.tsx"],"sourcesContent":[],"mappings":";;;cAGM,+BAAuB,mBAAA,CAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/skeleton-related-products/index.tsx"],"sourcesContent":[],"mappings":";;;cAGM,+BAAuB,kBAAA,CAAA,GAAA,CAAA"}
@@ -1,21 +1,21 @@
1
- import * as _apollo_client17 from "@apollo/client";
1
+ import * as _apollo_client29 from "@apollo/client";
2
2
 
3
3
  //#region src/lib/gql/fragments/product.d.ts
4
- declare const PRODUCT_IMAGE_FRAGMENT: _apollo_client17.DocumentNode;
5
- declare const PRODUCT_TAG_FRAGMENT: _apollo_client17.DocumentNode;
6
- declare const PRODUCT_OPTION_FRAGMENT: _apollo_client17.DocumentNode;
7
- declare const PRICE_FRAGMENT: _apollo_client17.DocumentNode;
8
- declare const PRODUCT_VARIANT_CONTENT_FRAGMENT: _apollo_client17.DocumentNode;
9
- declare const PRODUCT_VARIANT_PRICING_FRAGMENT: _apollo_client17.DocumentNode;
10
- declare const PRODUCT_VARIANT_FRAGMENT: _apollo_client17.DocumentNode;
11
- declare const PRODUCT_CATEGORY_FRAGMENT: _apollo_client17.DocumentNode;
12
- declare const PRODUCT_COLLECTION_FRAGMENT: _apollo_client17.DocumentNode;
13
- declare const PRODUCT_CONTENT_FRAGMENT: _apollo_client17.DocumentNode;
14
- declare const PRODUCT_FRAGMENT: _apollo_client17.DocumentNode;
15
- declare const PRODUCT_PREVIEW_FRAGMENT: _apollo_client17.DocumentNode;
16
- declare const COLLECTION_PRODUCTS_FRAGMENT: _apollo_client17.DocumentNode;
17
- declare const PRODUCT_HIT_FRAGMENT: _apollo_client17.DocumentNode;
18
- declare const BROWSE_PRODUCT_HIT_FRAGMENT: _apollo_client17.DocumentNode;
4
+ declare const PRODUCT_IMAGE_FRAGMENT: _apollo_client29.DocumentNode;
5
+ declare const PRODUCT_TAG_FRAGMENT: _apollo_client29.DocumentNode;
6
+ declare const PRODUCT_OPTION_FRAGMENT: _apollo_client29.DocumentNode;
7
+ declare const PRICE_FRAGMENT: _apollo_client29.DocumentNode;
8
+ declare const PRODUCT_VARIANT_CONTENT_FRAGMENT: _apollo_client29.DocumentNode;
9
+ declare const PRODUCT_VARIANT_PRICING_FRAGMENT: _apollo_client29.DocumentNode;
10
+ declare const PRODUCT_VARIANT_FRAGMENT: _apollo_client29.DocumentNode;
11
+ declare const PRODUCT_CATEGORY_FRAGMENT: _apollo_client29.DocumentNode;
12
+ declare const PRODUCT_COLLECTION_FRAGMENT: _apollo_client29.DocumentNode;
13
+ declare const PRODUCT_CONTENT_FRAGMENT: _apollo_client29.DocumentNode;
14
+ declare const PRODUCT_FRAGMENT: _apollo_client29.DocumentNode;
15
+ declare const PRODUCT_PREVIEW_FRAGMENT: _apollo_client29.DocumentNode;
16
+ declare const COLLECTION_PRODUCTS_FRAGMENT: _apollo_client29.DocumentNode;
17
+ declare const PRODUCT_HIT_FRAGMENT: _apollo_client29.DocumentNode;
18
+ declare const BROWSE_PRODUCT_HIT_FRAGMENT: _apollo_client29.DocumentNode;
19
19
  //#endregion
20
20
  export { BROWSE_PRODUCT_HIT_FRAGMENT, COLLECTION_PRODUCTS_FRAGMENT, PRICE_FRAGMENT, PRODUCT_CATEGORY_FRAGMENT, PRODUCT_COLLECTION_FRAGMENT, PRODUCT_CONTENT_FRAGMENT, PRODUCT_FRAGMENT, PRODUCT_HIT_FRAGMENT, PRODUCT_IMAGE_FRAGMENT, PRODUCT_OPTION_FRAGMENT, PRODUCT_PREVIEW_FRAGMENT, PRODUCT_TAG_FRAGMENT, PRODUCT_VARIANT_CONTENT_FRAGMENT, PRODUCT_VARIANT_FRAGMENT, PRODUCT_VARIANT_PRICING_FRAGMENT };
21
21
  //# sourceMappingURL=product.d.ts.map
@@ -1,15 +1,15 @@
1
- import * as _apollo_client7 from "@apollo/client";
1
+ import * as _apollo_client8 from "@apollo/client";
2
2
 
3
3
  //#region src/lib/gql/mutations/cart.d.ts
4
- declare const CREATE_CART_MUTATION: _apollo_client7.DocumentNode;
5
- declare const UPDATE_CART_MUTATION: _apollo_client7.DocumentNode;
6
- declare const CREATE_LINE_ITEM_MUTATION: _apollo_client7.DocumentNode;
7
- declare const UPDATE_LINE_ITEM_MUTATION: _apollo_client7.DocumentNode;
8
- declare const DELETE_LINE_ITEM_MUTATION: _apollo_client7.DocumentNode;
9
- declare const ADD_SHIPPING_METHOD_MUTATION: _apollo_client7.DocumentNode;
10
- declare const COMPLETE_CART_MUTATION: _apollo_client7.DocumentNode;
11
- declare const TRANSFER_CART_MUTATION: _apollo_client7.DocumentNode;
12
- declare const APPLY_PROMOTIONS_MUTATION: _apollo_client7.DocumentNode;
4
+ declare const CREATE_CART_MUTATION: _apollo_client8.DocumentNode;
5
+ declare const UPDATE_CART_MUTATION: _apollo_client8.DocumentNode;
6
+ declare const CREATE_LINE_ITEM_MUTATION: _apollo_client8.DocumentNode;
7
+ declare const UPDATE_LINE_ITEM_MUTATION: _apollo_client8.DocumentNode;
8
+ declare const DELETE_LINE_ITEM_MUTATION: _apollo_client8.DocumentNode;
9
+ declare const ADD_SHIPPING_METHOD_MUTATION: _apollo_client8.DocumentNode;
10
+ declare const COMPLETE_CART_MUTATION: _apollo_client8.DocumentNode;
11
+ declare const TRANSFER_CART_MUTATION: _apollo_client8.DocumentNode;
12
+ declare const APPLY_PROMOTIONS_MUTATION: _apollo_client8.DocumentNode;
13
13
  //#endregion
14
14
  export { ADD_SHIPPING_METHOD_MUTATION, APPLY_PROMOTIONS_MUTATION, COMPLETE_CART_MUTATION, CREATE_CART_MUTATION, CREATE_LINE_ITEM_MUTATION, DELETE_LINE_ITEM_MUTATION, TRANSFER_CART_MUTATION, UPDATE_CART_MUTATION, UPDATE_LINE_ITEM_MUTATION };
15
15
  //# sourceMappingURL=cart.d.ts.map
@@ -1,7 +1,7 @@
1
- import * as _apollo_client16 from "@apollo/client";
1
+ import * as _apollo_client7 from "@apollo/client";
2
2
 
3
3
  //#region src/lib/gql/queries/cart.d.ts
4
- declare const GET_CART_QUERY: _apollo_client16.DocumentNode;
4
+ declare const GET_CART_QUERY: _apollo_client7.DocumentNode;
5
5
  //#endregion
6
6
  export { GET_CART_QUERY };
7
7
  //# sourceMappingURL=cart.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cart.d.ts","names":[],"sources":["../../../../src/lib/gql/queries/cart.ts"],"sourcesContent":[],"mappings":";;;cAIa,gBAOZ,gBAAA,CAP0B"}
1
+ {"version":3,"file":"cart.d.ts","names":[],"sources":["../../../../src/lib/gql/queries/cart.ts"],"sourcesContent":[],"mappings":";;;cAIa,gBAOZ,eAAA,CAP0B"}
@@ -1,18 +1,18 @@
1
- import * as _apollo_client32 from "@apollo/client";
1
+ import * as _apollo_client17 from "@apollo/client";
2
2
 
3
3
  //#region src/lib/gql/queries/product.d.ts
4
- declare const GET_PRODUCTS_QUERY: _apollo_client32.DocumentNode;
5
- declare const GET_PRODUCTS_PREVIEW_QUERY: _apollo_client32.DocumentNode;
6
- declare const GET_PRODUCT_QUERY: _apollo_client32.DocumentNode;
7
- declare const GET_PRODUCT_CONTENT_BY_HANDLE_QUERY: _apollo_client32.DocumentNode;
8
- declare const GET_PRODUCT_PRICING_QUERY: _apollo_client32.DocumentNode;
9
- declare const GET_PRODUCT_CATEGORIES_QUERY: _apollo_client32.DocumentNode;
10
- declare const GET_PRODUCT_CATEGORY_QUERY: _apollo_client32.DocumentNode;
11
- declare const GET_COLLECTIONS_QUERY: _apollo_client32.DocumentNode;
12
- declare const GET_COLLECTIONS_SUMMARY_QUERY: _apollo_client32.DocumentNode;
13
- declare const GET_COLLECTION_QUERY: _apollo_client32.DocumentNode;
14
- declare const SEARCH_SUGGESTIONS_QUERY: _apollo_client32.DocumentNode;
15
- declare const BROWSE_PRODUCTS_QUERY: _apollo_client32.DocumentNode;
4
+ declare const GET_PRODUCTS_QUERY: _apollo_client17.DocumentNode;
5
+ declare const GET_PRODUCTS_PREVIEW_QUERY: _apollo_client17.DocumentNode;
6
+ declare const GET_PRODUCT_QUERY: _apollo_client17.DocumentNode;
7
+ declare const GET_PRODUCT_CONTENT_BY_HANDLE_QUERY: _apollo_client17.DocumentNode;
8
+ declare const GET_PRODUCT_PRICING_QUERY: _apollo_client17.DocumentNode;
9
+ declare const GET_PRODUCT_CATEGORIES_QUERY: _apollo_client17.DocumentNode;
10
+ declare const GET_PRODUCT_CATEGORY_QUERY: _apollo_client17.DocumentNode;
11
+ declare const GET_COLLECTIONS_QUERY: _apollo_client17.DocumentNode;
12
+ declare const GET_COLLECTIONS_SUMMARY_QUERY: _apollo_client17.DocumentNode;
13
+ declare const GET_COLLECTION_QUERY: _apollo_client17.DocumentNode;
14
+ declare const SEARCH_SUGGESTIONS_QUERY: _apollo_client17.DocumentNode;
15
+ declare const BROWSE_PRODUCTS_QUERY: _apollo_client17.DocumentNode;
16
16
  //#endregion
17
17
  export { BROWSE_PRODUCTS_QUERY, GET_COLLECTIONS_QUERY, GET_COLLECTIONS_SUMMARY_QUERY, GET_COLLECTION_QUERY, GET_PRODUCTS_PREVIEW_QUERY, GET_PRODUCTS_QUERY, GET_PRODUCT_CATEGORIES_QUERY, GET_PRODUCT_CATEGORY_QUERY, GET_PRODUCT_CONTENT_BY_HANDLE_QUERY, GET_PRODUCT_PRICING_QUERY, GET_PRODUCT_QUERY, SEARCH_SUGGESTIONS_QUERY };
18
18
  //# sourceMappingURL=product.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import { BrowseProductHitFragment } from "../../types/graphql.js";
2
2
  import { SortOptions } from "../../components/refinement-list/sort-products/index.js";
3
- import * as react_jsx_runtime11 from "react/jsx-runtime";
3
+ import * as react_jsx_runtime12 from "react/jsx-runtime";
4
4
 
5
5
  //#region src/templates/paginated-products/client.d.ts
6
6
  type PaginatedProductsClientProps = {
@@ -24,7 +24,7 @@ declare function PaginatedProductsClient({
24
24
  categoryId,
25
25
  productsIds,
26
26
  countryCode
27
- }: PaginatedProductsClientProps): react_jsx_runtime11.JSX.Element;
27
+ }: PaginatedProductsClientProps): react_jsx_runtime12.JSX.Element;
28
28
  //#endregion
29
29
  export { PaginatedProductsClient as default };
30
30
  //# sourceMappingURL=client.d.ts.map
@@ -3,8 +3,8 @@
3
3
  import { BrowseProductPreview } from "../../components/browse-product-preview/index.js";
4
4
  import { Pagination } from "../../components/pagination/index.js";
5
5
  import skeleton_product_grid_default from "../../components/skeleton-product-grid/index.js";
6
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
6
  import { useEffect, useRef, useState } from "react";
7
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
8
 
9
9
  //#region src/templates/paginated-products/client.tsx
10
10
  const LCP_CANDIDATE_COUNT = 4;
@@ -169,7 +169,7 @@ function PaginatedProductsClient({ initialProducts, initialTotalItems, initialTa
169
169
  sortBy,
170
170
  totalPages
171
171
  ]);
172
- return /* @__PURE__ */ jsxs(Fragment, { children: [
172
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
173
173
  /* @__PURE__ */ jsx("ul", {
174
174
  className: "grid w-full grid-cols-[repeat(auto-fit,_minmax(min(100%,_max(10rem,_calc((100%_-_4.5rem)_/_4))),_1fr))] gap-x-6 gap-y-8",
175
175
  "data-testid": "products-list",
@@ -1,5 +1,5 @@
1
1
  import { SortOptions } from "../../components/refinement-list/sort-products/index.js";
2
- import * as react_jsx_runtime12 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime13 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/templates/paginated-products/index.d.ts
5
5
  declare function PaginatedProducts({
@@ -16,7 +16,7 @@ declare function PaginatedProducts({
16
16
  categoryId?: string;
17
17
  productsIds?: string[];
18
18
  countryCode: string;
19
- }): Promise<react_jsx_runtime12.JSX.Element>;
19
+ }): Promise<react_jsx_runtime13.JSX.Element>;
20
20
  //#endregion
21
21
  export { PaginatedProducts as default };
22
22
  //# sourceMappingURL=index.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { ProductActionsProduct } from "../../types/index.js";
2
- import * as react_jsx_runtime15 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime14 from "react/jsx-runtime";
3
3
  import { Region } from "@gfed-medusa/sf-lib-common/types/graphql";
4
4
 
5
5
  //#region src/templates/product-actions-wrapper/index.d.ts
@@ -12,7 +12,7 @@ declare function ProductActionsWrapper({
12
12
  }: {
13
13
  product: ProductActionsProduct;
14
14
  region: Region;
15
- }): Promise<react_jsx_runtime15.JSX.Element>;
15
+ }): Promise<react_jsx_runtime14.JSX.Element>;
16
16
  //#endregion
17
17
  export { ProductActionsWrapper as default };
18
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/templates/product-template/index.tsx"],"sourcesContent":[],"mappings":";;;;;KAeK,oBAAA;YACO;EADP,MAAA,EAEK,MAFL;EACO,WAAA,EAAA,MAAA;EACF,WAAA,CAAA,EAEM,KAAA,CAAM,SAFZ;CAEM;cAGV,eAHyB,EAGR,KAAA,CAAM,EAHE,CAGC,oBAHD,CAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/templates/product-template/index.tsx"],"sourcesContent":[],"mappings":";;;;;KAgBK,oBAAA;YACO;EADP,MAAA,EAEK,MAFL;EACO,WAAA,EAAA,MAAA;EACF,WAAA,CAAA,EAEM,KAAA,CAAM,SAFZ;CAEM;cAGV,eAHyB,EAGR,KAAA,CAAM,EAHE,CAGC,oBAHD,CAAA"}
@@ -1,3 +1,4 @@
1
+ import behavior_tracker_default from "../../components/behavior-tracker/index.js";
1
2
  import image_gallery_default from "../../components/image-gallery/index.js";
2
3
  import ProductActions from "../../components/product-actions/index.js";
3
4
  import product_onboarding_cta_default from "../../components/product-onboarding-cta/index.js";
@@ -5,14 +6,15 @@ import product_tabs_default from "../../components/product-tabs/index.js";
5
6
  import RelatedProducts from "../../components/related-products/index.js";
6
7
  import skeleton_related_products_default from "../../components/skeleton-related-products/index.js";
7
8
  import product_info_default from "../product-info/index.js";
8
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
9
  import React, { Suspense } from "react";
10
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
11
  import { notFound } from "next/navigation";
11
12
 
12
13
  //#region src/templates/product-template/index.tsx
13
14
  const ProductTemplate = ({ product, region, countryCode, breadcrumbs }) => {
14
15
  if (!product || !product.id) return notFound();
15
- return /* @__PURE__ */ jsxs(Fragment, { children: [
16
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
17
+ /* @__PURE__ */ jsx(behavior_tracker_default, { product }),
16
18
  breadcrumbs && /* @__PURE__ */ jsx("div", {
17
19
  className: "content-container my-8",
18
20
  children: breadcrumbs
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["ProductTemplate: React.FC<ProductTemplateProps>","ProductInfo","ProductTabs","ImageGallery","ProductOnboardingCta","SkeletonRelatedProducts"],"sources":["../../../src/templates/product-template/index.tsx"],"sourcesContent":["import React, { Suspense } from 'react';\n\nimport { notFound } from 'next/navigation';\n\nimport { Region } from '@gfed-medusa/sf-lib-common/types/graphql';\n\nimport ImageGallery from '@/components/image-gallery';\nimport ProductActions from '@/components/product-actions';\nimport ProductOnboardingCta from '@/components/product-onboarding-cta';\nimport ProductTabs from '@/components/product-tabs';\nimport RelatedProducts from '@/components/related-products';\nimport SkeletonRelatedProducts from '@/components/skeleton-related-products';\nimport ProductInfo from '@/templates/product-info';\nimport { Product } from '@/types/graphql';\n\ntype ProductTemplateProps = {\n product?: Product | null;\n region: Region;\n countryCode: string;\n breadcrumbs?: React.ReactNode;\n};\n\nconst ProductTemplate: React.FC<ProductTemplateProps> = ({\n product,\n region,\n countryCode,\n breadcrumbs,\n}) => {\n if (!product || !product.id) {\n return notFound();\n }\n\n return (\n <>\n {breadcrumbs && (\n <div className=\"content-container my-8\">{breadcrumbs}</div>\n )}\n <div\n className=\"content-container small:flex-row small:items-start relative flex flex-col py-6\"\n data-testid=\"product-container\"\n >\n <div className=\"small:sticky small:top-48 small:max-w-[300px] small:py-0 flex w-full flex-col gap-y-6 py-8\">\n <ProductInfo product={product} />\n <ProductTabs product={product} />\n </div>\n <div className=\"relative block w-full\">\n <ImageGallery images={product?.images || []} />\n </div>\n <div className=\"small:sticky small:top-48 small:max-w-[300px] small:py-0 flex w-full flex-col gap-y-12 py-8\">\n <ProductOnboardingCta />\n <ProductActions product={product} regionId={region.id} />\n </div>\n </div>\n <div\n className=\"content-container small:my-32 my-16\"\n data-testid=\"related-products-container\"\n >\n <Suspense fallback={<SkeletonRelatedProducts />}>\n <RelatedProducts product={product} countryCode={countryCode} />\n </Suspense>\n </div>\n </>\n );\n};\n\nexport default ProductTemplate;\n"],"mappings":";;;;;;;;;;;;AAsBA,MAAMA,mBAAmD,EACvD,SACA,QACA,aACA,kBACI;AACJ,KAAI,CAAC,WAAW,CAAC,QAAQ,GACvB,QAAO,UAAU;AAGnB,QACE;EACG,eACC,oBAAC;GAAI,WAAU;aAA0B;IAAkB;EAE7D,qBAAC;GACC,WAAU;GACV,eAAY;;IAEZ,qBAAC;KAAI,WAAU;gBACb,oBAACC,wBAAqB,UAAW,EACjC,oBAACC,wBAAqB,UAAW;MAC7B;IACN,oBAAC;KAAI,WAAU;eACb,oBAACC,yBAAa,QAAQ,SAAS,UAAU,EAAE,GAAI;MAC3C;IACN,qBAAC;KAAI,WAAU;gBACb,oBAACC,mCAAuB,EACxB,oBAAC;MAAwB;MAAS,UAAU,OAAO;OAAM;MACrD;;IACF;EACN,oBAAC;GACC,WAAU;GACV,eAAY;aAEZ,oBAAC;IAAS,UAAU,oBAACC,sCAA0B;cAC7C,oBAAC;KAAyB;KAAsB;MAAe;KACtD;IACP;KACL;;AAIP,+BAAe"}
1
+ {"version":3,"file":"index.js","names":["ProductTemplate: React.FC<ProductTemplateProps>","BehaviorTracker","ProductInfo","ProductTabs","ImageGallery","ProductOnboardingCta","SkeletonRelatedProducts"],"sources":["../../../src/templates/product-template/index.tsx"],"sourcesContent":["import React, { Suspense } from 'react';\n\nimport { notFound } from 'next/navigation';\n\nimport { Region } from '@gfed-medusa/sf-lib-common/types/graphql';\n\nimport BehaviorTracker from '@/components/behavior-tracker';\nimport ImageGallery from '@/components/image-gallery';\nimport ProductActions from '@/components/product-actions';\nimport ProductOnboardingCta from '@/components/product-onboarding-cta';\nimport ProductTabs from '@/components/product-tabs';\nimport RelatedProducts from '@/components/related-products';\nimport SkeletonRelatedProducts from '@/components/skeleton-related-products';\nimport ProductInfo from '@/templates/product-info';\nimport { Product } from '@/types/graphql';\n\ntype ProductTemplateProps = {\n product?: Product | null;\n region: Region;\n countryCode: string;\n breadcrumbs?: React.ReactNode;\n};\n\nconst ProductTemplate: React.FC<ProductTemplateProps> = ({\n product,\n region,\n countryCode,\n breadcrumbs,\n}) => {\n if (!product || !product.id) {\n return notFound();\n }\n\n return (\n <>\n <BehaviorTracker product={product} />\n {breadcrumbs && (\n <div className=\"content-container my-8\">{breadcrumbs}</div>\n )}\n <div\n className=\"content-container small:flex-row small:items-start relative flex flex-col py-6\"\n data-testid=\"product-container\"\n >\n <div className=\"small:sticky small:top-48 small:max-w-[300px] small:py-0 flex w-full flex-col gap-y-6 py-8\">\n <ProductInfo product={product} />\n <ProductTabs product={product} />\n </div>\n <div className=\"relative block w-full\">\n <ImageGallery images={product?.images || []} />\n </div>\n <div className=\"small:sticky small:top-48 small:max-w-[300px] small:py-0 flex w-full flex-col gap-y-12 py-8\">\n <ProductOnboardingCta />\n <ProductActions product={product} regionId={region.id} />\n </div>\n </div>\n <div\n className=\"content-container small:my-32 my-16\"\n data-testid=\"related-products-container\"\n >\n <Suspense fallback={<SkeletonRelatedProducts />}>\n <RelatedProducts product={product} countryCode={countryCode} />\n </Suspense>\n </div>\n </>\n );\n};\n\nexport default ProductTemplate;\n"],"mappings":";;;;;;;;;;;;;AAuBA,MAAMA,mBAAmD,EACvD,SACA,QACA,aACA,kBACI;AACJ,KAAI,CAAC,WAAW,CAAC,QAAQ,GACvB,QAAO,UAAU;AAGnB,QACE;EACE,oBAACC,4BAAyB,UAAW;EACpC,eACC,oBAAC;GAAI,WAAU;aAA0B;IAAkB;EAE7D,qBAAC;GACC,WAAU;GACV,eAAY;;IAEZ,qBAAC;KAAI,WAAU;gBACb,oBAACC,wBAAqB,UAAW,EACjC,oBAACC,wBAAqB,UAAW;MAC7B;IACN,oBAAC;KAAI,WAAU;eACb,oBAACC,yBAAa,QAAQ,SAAS,UAAU,EAAE,GAAI;MAC3C;IACN,qBAAC;KAAI,WAAU;gBACb,oBAACC,mCAAuB,EACxB,oBAAC;MAAwB;MAAS,UAAU,OAAO;OAAM;MACrD;;IACF;EACN,oBAAC;GACC,WAAU;GACV,eAAY;aAEZ,oBAAC;IAAS,UAAU,oBAACC,sCAA0B;cAC7C,oBAAC;KAAyB;KAAsB;MAAe;KACtD;IACP;KACL;;AAIP,+BAAe"}
@@ -1,5 +1,5 @@
1
1
  import { SortOptions } from "../../components/refinement-list/sort-products/index.js";
2
- import * as react_jsx_runtime13 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime3 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/templates/store-template/index.d.ts
5
5
  declare const StoreTemplate: ({
@@ -10,7 +10,7 @@ declare const StoreTemplate: ({
10
10
  sortBy?: SortOptions;
11
11
  page?: string;
12
12
  countryCode: string;
13
- }) => react_jsx_runtime13.JSX.Element;
13
+ }) => react_jsx_runtime3.JSX.Element;
14
14
  //#endregion
15
15
  export { StoreTemplate as default };
16
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/templates/store-template/index.tsx"],"sourcesContent":[],"mappings":";;;;cAQM;;;;;WAKK;;EALL,WAAA,EAAA,MAoCL;CApCsB,EAAA,GAQtB,mBAAA,CAAA,GAAA,CAAA,OARsB"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/templates/store-template/index.tsx"],"sourcesContent":[],"mappings":";;;;cAQM;;;;;WAKK;;EALL,WAAA,EAAA,MAoCL;CApCsB,EAAA,GAQtB,kBAAA,CAAA,GAAA,CAAA,OARsB"}
@@ -1,8 +1,8 @@
1
1
  import refinement_list_default from "../../components/refinement-list/index.js";
2
2
  import skeleton_product_grid_default from "../../components/skeleton-product-grid/index.js";
3
3
  import PaginatedProducts from "../paginated-products/index.js";
4
- import { jsx, jsxs } from "react/jsx-runtime";
5
4
  import { Suspense } from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
6
 
7
7
  //#region src/templates/store-template/index.tsx
8
8
  const StoreTemplate = ({ sortBy, page, countryCode }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gfed-medusa/sf-lib-products",
3
- "version": "1.8.1",
3
+ "version": "1.9.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",
@@ -51,7 +51,7 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "@apollo/client": "^4.0.9",
54
- "@gfed-medusa/sf-lib-common": "^3.5.1",
54
+ "@gfed-medusa/sf-lib-common": "^3.7.0",
55
55
  "@gfed-medusa/sf-lib-ui": "^1.2.4",
56
56
  "@headlessui/react": "^2.2.9",
57
57
  "@medusajs/icons": "^2.12.1",
@@ -60,6 +60,7 @@
60
60
  "@radix-ui/react-accordion": "^1.2.1",
61
61
  "algoliasearch": "^5.49.1",
62
62
  "isomorphic-dompurify": "^2.34.0",
63
+ "js-cookie": "^3.0.5",
63
64
  "lodash": "^4.17.21",
64
65
  "next": "^15.3.8",
65
66
  "react": "^19.2.0",
@@ -73,6 +74,7 @@
73
74
  "@graphql-codegen/typescript": "^5.0.0",
74
75
  "@graphql-codegen/typescript-operations": "^5.0.0",
75
76
  "@graphql-typed-document-node/core": "^3.2.0",
77
+ "@types/js-cookie": "^3.0.6",
76
78
  "@types/lodash": "^4.14.202",
77
79
  "@types/node": "^20",
78
80
  "@types/react": "^19",
@@ -82,10 +84,10 @@
82
84
  "eslint-config-next": "16.0.6",
83
85
  "tsdown": "^0.17.2",
84
86
  "typescript": "^5",
85
- "@packages/eslint-config": "0.0.0",
86
87
  "@packages/jest-config": "0.0.0",
88
+ "@packages/typescript-config": "0.0.0",
87
89
  "@packages/prettier-config": "0.0.0",
88
- "@packages/typescript-config": "0.0.0"
90
+ "@packages/eslint-config": "0.0.0"
89
91
  },
90
92
  "scripts": {
91
93
  "build": "tsdown --env.NODE_ENV=production",