@gfed-medusa/sf-lib-common 3.3.3 → 3.3.5
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.
- package/dist/components/breadcrumbs/index.js +6 -2
- package/dist/components/breadcrumbs/index.js.map +1 -1
- package/dist/components/cart-mismatch-banner/index.d.ts +2 -2
- package/dist/components/cart-mismatch-banner/index.d.ts.map +1 -1
- package/dist/components/cart-mismatch-banner/index.js +11 -2
- package/dist/components/cart-mismatch-banner/index.js.map +1 -1
- package/dist/components/country-select/index.js +3 -1
- package/dist/components/country-select/index.js.map +1 -1
- package/dist/components/delete-button/index.d.ts +2 -2
- package/dist/components/error-message/index.d.ts +2 -2
- package/dist/components/error-message/index.js +3 -1
- package/dist/components/error-message/index.js.map +1 -1
- package/dist/components/free-shipping-price-nudge/index.d.ts +2 -2
- package/dist/components/free-shipping-price-nudge/index.js +64 -47
- package/dist/components/free-shipping-price-nudge/index.js.map +1 -1
- package/dist/components/interactive-link/index.d.ts +9 -6
- package/dist/components/interactive-link/index.d.ts.map +1 -1
- package/dist/components/interactive-link/index.js +6 -6
- package/dist/components/interactive-link/index.js.map +1 -1
- package/dist/components/line-item-options/index.d.ts +2 -2
- package/dist/components/line-item-price/index.d.ts +2 -2
- package/dist/components/localized-client-link/index.d.ts +2 -2
- package/dist/components/localized-client-link/index.js +10 -6
- package/dist/components/localized-client-link/index.js.map +1 -1
- package/dist/components/modal/index.d.ts +2 -2
- package/dist/components/preview-price/index.d.ts +2 -2
- package/dist/components/preview-price/index.js +3 -1
- package/dist/components/preview-price/index.js.map +1 -1
- package/dist/components/product-card/index.d.ts +2 -2
- package/dist/components/product-card/index.d.ts.map +1 -1
- package/dist/components/product-card/index.js +3 -3
- package/dist/components/product-card/index.js.map +1 -1
- package/dist/components/product-preview/index.d.ts +7 -3
- package/dist/components/product-preview/index.d.ts.map +1 -1
- package/dist/components/product-preview/index.js +4 -2
- package/dist/components/product-preview/index.js.map +1 -1
- package/dist/components/submit-button/index.d.ts +2 -2
- package/dist/components/thumbnail/index.d.ts +2 -0
- package/dist/components/thumbnail/index.d.ts.map +1 -1
- package/dist/components/thumbnail/index.js +7 -3
- package/dist/components/thumbnail/index.js.map +1 -1
- package/dist/lib/config/medusa.js +3 -2
- package/dist/lib/config/medusa.js.map +1 -1
- package/dist/lib/context/apollo-context.d.ts +2 -2
- package/dist/lib/context/apollo-context.d.ts.map +1 -1
- package/dist/lib/context/apollo-context.js +2 -1
- package/dist/lib/context/apollo-context.js.map +1 -1
- package/dist/lib/context/modal-context.d.ts +2 -2
- package/dist/lib/context/modal-context.d.ts.map +1 -1
- package/dist/lib/context/modal-context.js +3 -1
- package/dist/lib/context/modal-context.js.map +1 -1
- package/dist/lib/data/cart.js +35 -17
- package/dist/lib/data/cart.js.map +1 -1
- package/dist/lib/data/categories.js +2 -1
- package/dist/lib/data/categories.js.map +1 -1
- package/dist/lib/data/client-actions.js +7 -2
- package/dist/lib/data/client-actions.js.map +1 -1
- package/dist/lib/data/collections.js +7 -4
- package/dist/lib/data/collections.js.map +1 -1
- package/dist/lib/data/context.d.ts +2 -2
- package/dist/lib/data/context.js +3 -1
- package/dist/lib/data/context.js.map +1 -1
- package/dist/lib/data/cookies-actions.d.ts.map +1 -1
- package/dist/lib/data/cookies-actions.js +20 -10
- package/dist/lib/data/cookies-actions.js.map +1 -1
- package/dist/lib/data/cookies-utils.js +9 -3
- package/dist/lib/data/cookies-utils.js.map +1 -1
- package/dist/lib/data/customer.js +19 -10
- package/dist/lib/data/customer.js.map +1 -1
- package/dist/lib/data/footer.js +2 -1
- package/dist/lib/data/footer.js.map +1 -1
- package/dist/lib/data/orders.js +3 -2
- package/dist/lib/data/orders.js.map +1 -1
- package/dist/lib/data/regions.js +9 -6
- package/dist/lib/data/regions.js.map +1 -1
- package/dist/lib/globals/expose-globals.js +1 -1
- package/dist/lib/gql/apollo-client.js +12 -7
- package/dist/lib/gql/apollo-client.js.map +1 -1
- package/dist/lib/gql/fragments/cart.d.ts +9 -9
- package/dist/lib/gql/fragments/customer.d.ts +3 -3
- package/dist/lib/gql/fragments/product.d.ts +9 -10
- package/dist/lib/gql/fragments/product.d.ts.map +1 -1
- package/dist/lib/gql/fragments/product.js +1 -10
- package/dist/lib/gql/fragments/product.js.map +1 -1
- package/dist/lib/gql/mutations/cart.d.ts +6 -6
- package/dist/lib/gql/queries/cart.d.ts +2 -2
- package/dist/lib/gql/queries/cart.d.ts.map +1 -1
- package/dist/lib/gql/queries/collections.d.ts +3 -3
- package/dist/lib/gql/queries/collections.d.ts.map +1 -1
- package/dist/lib/gql/queries/customer.d.ts +2 -2
- package/dist/lib/gql/queries/customer.d.ts.map +1 -1
- package/dist/lib/gql/queries/footer.d.ts +3 -3
- package/dist/lib/gql/queries/order.d.ts +4 -4
- package/dist/lib/gql/queries/order.d.ts.map +1 -1
- package/dist/lib/gql/queries/order.js +1 -0
- package/dist/lib/gql/queries/order.js.map +1 -1
- package/dist/lib/gql/queries/product.d.ts +3 -4
- package/dist/lib/gql/queries/product.d.ts.map +1 -1
- package/dist/lib/gql/queries/product.js +2 -12
- package/dist/lib/gql/queries/product.js.map +1 -1
- package/dist/lib/gql/queries/regions.d.ts +3 -3
- package/dist/lib/gql/queries/shipping.d.ts +3 -3
- package/dist/lib/hooks/use-apollo.d.ts +2 -2
- package/dist/lib/hooks/use-apollo.js +2 -1
- package/dist/lib/hooks/use-apollo.js.map +1 -1
- package/dist/lib/hooks/use-cart.js +3 -1
- package/dist/lib/hooks/use-cart.js.map +1 -1
- package/dist/lib/hooks/use-customer.js +3 -1
- package/dist/lib/hooks/use-customer.js.map +1 -1
- package/dist/lib/utils/data-types.js +1 -1
- package/dist/lib/utils/data-types.js.map +1 -1
- package/dist/lib/utils/get-percentage-diff.js +3 -1
- package/dist/lib/utils/get-percentage-diff.js.map +1 -1
- package/dist/lib/utils/get-product-price.js +15 -5
- package/dist/lib/utils/get-product-price.js.map +1 -1
- package/dist/lib/utils/imagekit.d.ts +0 -4
- package/dist/lib/utils/imagekit.d.ts.map +1 -1
- package/dist/lib/utils/imagekit.js +5 -8
- package/dist/lib/utils/imagekit.js.map +1 -1
- package/dist/lib/utils/medusa-error.js +5 -2
- package/dist/lib/utils/medusa-error.js.map +1 -1
- package/dist/types/graphql.d.ts +1 -54
- package/dist/types/graphql.d.ts.map +1 -1
- package/dist/types/graphql.js +1 -203
- package/dist/types/graphql.js.map +1 -1
- package/package.json +4 -4
- package/dist/lib/data/search.d.ts +0 -9
- package/dist/lib/data/search.d.ts.map +0 -1
- package/dist/lib/data/search.js +0 -23
- package/dist/lib/data/search.js.map +0 -1
- package/dist/lib/hooks/use-search.d.ts +0 -22
- package/dist/lib/hooks/use-search.d.ts.map +0 -1
- package/dist/lib/hooks/use-search.js +0 -69
- package/dist/lib/hooks/use-search.js.map +0 -1
|
@@ -22,11 +22,15 @@ const createBreadcrumbItems = (segments) => [{
|
|
|
22
22
|
const isLocaleCode = (segment) => /^[a-zA-Z]{2}(-[a-zA-Z]{2})?$/.test(segment);
|
|
23
23
|
const getPathSegments = (pathname) => {
|
|
24
24
|
const segments = pathname.split("/").filter(Boolean);
|
|
25
|
-
if (segments.length > 0 && isLocaleCode(segments[0] ?? ""))
|
|
25
|
+
if (segments.length > 0 && isLocaleCode(segments[0] ?? "")) {
|
|
26
|
+
segments.shift();
|
|
27
|
+
}
|
|
26
28
|
return segments;
|
|
27
29
|
};
|
|
28
30
|
function Breadcrumbs({ iconClassName, iconSize, separatorIcon }) {
|
|
29
|
-
const
|
|
31
|
+
const pathname = usePathname();
|
|
32
|
+
const pathSegments = getPathSegments(pathname);
|
|
33
|
+
const breadcrumbItems = createBreadcrumbItems(pathSegments);
|
|
30
34
|
const SeparatorIcon = separatorIcon ? SEPARATOR_ICONS[separatorIcon] : null;
|
|
31
35
|
return /* @__PURE__ */ jsx(Breadcrumb, {
|
|
32
36
|
className: "mt-3",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["SEPARATOR_ICONS: Record<\n string,\n React.ComponentType<{ size?: number; className?: string }>\n>","segments: string[]"],"sources":["../../../src/components/breadcrumbs/index.tsx"],"sourcesContent":["'use client';\n\nimport { Fragment } from 'react';\n\nimport { usePathname } from 'next/navigation';\n\nimport { SlashIcon, Tally1 } from 'lucide-react';\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@gfed-medusa/sf-lib-ui/components/breadcrumb';\n\nconst SEPARATOR_ICONS: Record<\n string,\n React.ComponentType<{ size?: number; className?: string }>\n> = {\n verticalLine: Tally1,\n slash: SlashIcon,\n};\n\ninterface BreadcrumbsProps {\n separatorIcon?: keyof typeof SEPARATOR_ICONS;\n iconSize?: number;\n iconClassName?: string;\n}\n\nconst formatSegmentLabel = (segment: string): string =>\n segment.charAt(0).toUpperCase() + segment.slice(1).replace(/-/g, ' ');\n\nconst createBreadcrumbItems = (segments: string[]) => [\n { label: 'Home', href: '/' },\n ...segments.map((segment, index) => ({\n href: '/' + segments.slice(0, index + 1).join('/'),\n label: formatSegmentLabel(segment),\n })),\n];\n\n// Helper function to check if a string is a locale code (e.g., 'en', 'en-US')\nconst isLocaleCode = (segment: string): boolean =>\n /^[a-zA-Z]{2}(-[a-zA-Z]{2})?$/.test(segment);\n\nconst getPathSegments = (pathname: string): string[] => {\n const segments: string[] = pathname.split('/').filter(Boolean);\n\n if (segments.length > 0 && isLocaleCode(segments[0] ?? '')) {\n segments.shift();\n }\n\n return segments;\n};\n\nfunction Breadcrumbs({\n iconClassName,\n iconSize,\n separatorIcon,\n}: BreadcrumbsProps) {\n const pathname = usePathname();\n const pathSegments = getPathSegments(pathname);\n const breadcrumbItems = createBreadcrumbItems(pathSegments);\n const SeparatorIcon = separatorIcon ? SEPARATOR_ICONS[separatorIcon] : null;\n\n return (\n <Breadcrumb className=\"mt-3\">\n <BreadcrumbList className=\"lg:gap-6\">\n {breadcrumbItems.map((item, index) => {\n const isLast = index === breadcrumbItems.length - 1;\n\n return (\n <Fragment key={item.href}>\n <BreadcrumbItem className=\"text-sm\">\n {isLast ? (\n <BreadcrumbPage>{item.label}</BreadcrumbPage>\n ) : (\n <BreadcrumbLink href={item.href}>{item.label}</BreadcrumbLink>\n )}\n </BreadcrumbItem>\n {!isLast && (\n <BreadcrumbSeparator>\n {SeparatorIcon && (\n <SeparatorIcon size={iconSize} className={iconClassName} />\n )}\n </BreadcrumbSeparator>\n )}\n </Fragment>\n );\n })}\n </BreadcrumbList>\n </Breadcrumb>\n );\n}\n\nexport { Breadcrumbs };\n"],"mappings":";;;;;;;;;AAiBA,MAAMA,kBAGF;CACF,cAAc;CACd,OAAO;CACR;AAQD,MAAM,sBAAsB,YAC1B,QAAQ,OAAO,EAAE,CAAC,aAAa,GAAG,QAAQ,MAAM,EAAE,CAAC,QAAQ,MAAM,IAAI;AAEvE,MAAM,yBAAyB,aAAuB,CACpD;CAAE,OAAO;CAAQ,MAAM;CAAK,EAC5B,GAAG,SAAS,KAAK,SAAS,WAAW;CACnC,MAAM,MAAM,SAAS,MAAM,GAAG,QAAQ,EAAE,CAAC,KAAK,IAAI;CAClD,OAAO,mBAAmB,QAAQ;CACnC,EAAE,CACJ;AAGD,MAAM,gBAAgB,YACpB,+BAA+B,KAAK,QAAQ;AAE9C,MAAM,mBAAmB,aAA+B;CACtD,MAAMC,WAAqB,SAAS,MAAM,IAAI,CAAC,OAAO,QAAQ;AAE9D,KAAI,SAAS,SAAS,KAAK,aAAa,SAAS,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"index.js","names":["SEPARATOR_ICONS: Record<\n string,\n React.ComponentType<{ size?: number; className?: string }>\n>","segments: string[]"],"sources":["../../../src/components/breadcrumbs/index.tsx"],"sourcesContent":["'use client';\n\nimport { Fragment } from 'react';\n\nimport { usePathname } from 'next/navigation';\n\nimport { SlashIcon, Tally1 } from 'lucide-react';\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@gfed-medusa/sf-lib-ui/components/breadcrumb';\n\nconst SEPARATOR_ICONS: Record<\n string,\n React.ComponentType<{ size?: number; className?: string }>\n> = {\n verticalLine: Tally1,\n slash: SlashIcon,\n};\n\ninterface BreadcrumbsProps {\n separatorIcon?: keyof typeof SEPARATOR_ICONS;\n iconSize?: number;\n iconClassName?: string;\n}\n\nconst formatSegmentLabel = (segment: string): string =>\n segment.charAt(0).toUpperCase() + segment.slice(1).replace(/-/g, ' ');\n\nconst createBreadcrumbItems = (segments: string[]) => [\n { label: 'Home', href: '/' },\n ...segments.map((segment, index) => ({\n href: '/' + segments.slice(0, index + 1).join('/'),\n label: formatSegmentLabel(segment),\n })),\n];\n\n// Helper function to check if a string is a locale code (e.g., 'en', 'en-US')\nconst isLocaleCode = (segment: string): boolean =>\n /^[a-zA-Z]{2}(-[a-zA-Z]{2})?$/.test(segment);\n\nconst getPathSegments = (pathname: string): string[] => {\n const segments: string[] = pathname.split('/').filter(Boolean);\n\n if (segments.length > 0 && isLocaleCode(segments[0] ?? '')) {\n segments.shift();\n }\n\n return segments;\n};\n\nfunction Breadcrumbs({\n iconClassName,\n iconSize,\n separatorIcon,\n}: BreadcrumbsProps) {\n const pathname = usePathname();\n const pathSegments = getPathSegments(pathname);\n const breadcrumbItems = createBreadcrumbItems(pathSegments);\n const SeparatorIcon = separatorIcon ? SEPARATOR_ICONS[separatorIcon] : null;\n\n return (\n <Breadcrumb className=\"mt-3\">\n <BreadcrumbList className=\"lg:gap-6\">\n {breadcrumbItems.map((item, index) => {\n const isLast = index === breadcrumbItems.length - 1;\n\n return (\n <Fragment key={item.href}>\n <BreadcrumbItem className=\"text-sm\">\n {isLast ? (\n <BreadcrumbPage>{item.label}</BreadcrumbPage>\n ) : (\n <BreadcrumbLink href={item.href}>{item.label}</BreadcrumbLink>\n )}\n </BreadcrumbItem>\n {!isLast && (\n <BreadcrumbSeparator>\n {SeparatorIcon && (\n <SeparatorIcon size={iconSize} className={iconClassName} />\n )}\n </BreadcrumbSeparator>\n )}\n </Fragment>\n );\n })}\n </BreadcrumbList>\n </Breadcrumb>\n );\n}\n\nexport { Breadcrumbs };\n"],"mappings":";;;;;;;;;AAiBA,MAAMA,kBAGF;CACF,cAAc;CACd,OAAO;CACR;AAQD,MAAM,sBAAsB,YAC1B,QAAQ,OAAO,EAAE,CAAC,aAAa,GAAG,QAAQ,MAAM,EAAE,CAAC,QAAQ,MAAM,IAAI;AAEvE,MAAM,yBAAyB,aAAuB,CACpD;CAAE,OAAO;CAAQ,MAAM;CAAK,EAC5B,GAAG,SAAS,KAAK,SAAS,WAAW;CACnC,MAAM,MAAM,SAAS,MAAM,GAAG,QAAQ,EAAE,CAAC,KAAK,IAAI;CAClD,OAAO,mBAAmB,QAAQ;CACnC,EAAE,CACJ;AAGD,MAAM,gBAAgB,YACpB,+BAA+B,KAAK,QAAQ;AAE9C,MAAM,mBAAmB,aAA+B;CACtD,MAAMC,WAAqB,SAAS,MAAM,IAAI,CAAC,OAAO,QAAQ;AAE9D,KAAI,SAAS,SAAS,KAAK,aAAa,SAAS,MAAM,GAAG,EAAE;AAC1D,WAAS,OAAO;;AAGlB,QAAO;;AAGT,SAAS,YAAY,EACnB,eACA,UACA,iBACmB;CACnB,MAAM,WAAW,aAAa;CAC9B,MAAM,eAAe,gBAAgB,SAAS;CAC9C,MAAM,kBAAkB,sBAAsB,aAAa;CAC3D,MAAM,gBAAgB,gBAAgB,gBAAgB,iBAAiB;AAEvE,QACE,oBAAC;EAAW,WAAU;YACpB,oBAAC;GAAe,WAAU;aACvB,gBAAgB,KAAK,MAAM,UAAU;IACpC,MAAM,SAAS,UAAU,gBAAgB,SAAS;AAElD,WACE,qBAAC,uBACC,oBAAC;KAAe,WAAU;eACvB,SACC,oBAAC,4BAAgB,KAAK,QAAuB,GAE7C,oBAAC;MAAe,MAAM,KAAK;gBAAO,KAAK;OAAuB;MAEjD,EAChB,CAAC,UACA,oBAAC,iCACE,iBACC,oBAAC;KAAc,MAAM;KAAU,WAAW;MAAiB,GAEzC,KAbX,KAAK,KAeT;KAEb;IACa;GACN"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Cart, Customer } from "../../types/graphql.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime11 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/cart-mismatch-banner/index.d.ts
|
|
5
5
|
declare function CartMismatchBanner(props: {
|
|
6
6
|
customer: Customer;
|
|
7
7
|
cart: Cart;
|
|
8
|
-
}):
|
|
8
|
+
}): react_jsx_runtime11.JSX.Element | undefined;
|
|
9
9
|
//#endregion
|
|
10
10
|
export { CartMismatchBanner };
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/cart-mismatch-banner/index.tsx"],"sourcesContent":[],"mappings":";;;;iBAYS,kBAAA;YAAsC;EAAtC,IAAA,EAAsD,IAAtD;CAAsC,CAAA,EAAsB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/cart-mismatch-banner/index.tsx"],"sourcesContent":[],"mappings":";;;;iBAYS,kBAAA;YAAsC;EAAtC,IAAA,EAAsD,IAAtD;CAAsC,CAAA,EAAsB,mBAAA,CAAA,GAAA,CAAA,OAAA,GAAtB,SAAA"}
|
|
@@ -12,13 +12,22 @@ function CartMismatchBanner(props) {
|
|
|
12
12
|
const { customer, cart } = props;
|
|
13
13
|
const [isPending, setIsPending] = useState(false);
|
|
14
14
|
const [actionText, setActionText] = useState("Run transfer again");
|
|
15
|
+
const [transferComplete, setTransferComplete] = useState(false);
|
|
15
16
|
const ctx = useStorefrontContext();
|
|
16
|
-
if (!customer || !!cart.customerId)
|
|
17
|
+
if (!customer || !!cart.customerId || transferComplete) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
17
20
|
const handleSubmit = async () => {
|
|
18
21
|
try {
|
|
19
22
|
setIsPending(true);
|
|
20
23
|
setActionText("Transferring..");
|
|
21
|
-
await transferCart(ctx);
|
|
24
|
+
const result = await transferCart(ctx);
|
|
25
|
+
setIsPending(false);
|
|
26
|
+
if (result?.customerId) {
|
|
27
|
+
setTransferComplete(true);
|
|
28
|
+
} else {
|
|
29
|
+
setActionText("Run transfer again");
|
|
30
|
+
}
|
|
22
31
|
} catch {
|
|
23
32
|
setActionText("Run transfer again");
|
|
24
33
|
setIsPending(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/cart-mismatch-banner/index.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\n\nimport { ExclamationCircleSolid } from '@medusajs/icons';\nimport { Button } from '@medusajs/ui';\n\nimport { useStorefrontContext } from '@/lib/data/context';\nimport { transferCart } from '@/lib/data/customer';\nimport { Customer } from '@/types/graphql';\nimport { Cart } from '@/types/graphql';\n\nfunction CartMismatchBanner(props: { customer: Customer; cart: Cart }) {\n const { customer, cart } = props;\n const [isPending, setIsPending] = useState(false);\n const [actionText, setActionText] = useState('Run transfer again');\n const ctx = useStorefrontContext();\n\n if (!customer || !!cart.customerId) {\n return;\n }\n\n const handleSubmit = async () => {\n try {\n setIsPending(true);\n setActionText('Transferring..');\n\n await transferCart(ctx);\n } catch {\n setActionText('Run transfer again');\n setIsPending(false);\n }\n };\n\n return (\n <div className=\"small:gap-2 small:p-4 mt-2 flex items-center justify-center gap-1 bg-orange-300 p-2 text-center text-sm text-orange-800\">\n <div className=\"small:flex-row small:gap-2 flex flex-col items-center gap-1\">\n <span className=\"flex items-center gap-1\">\n <ExclamationCircleSolid className=\"inline\" />\n Something went wrong when we tried to transfer your cart\n </span>\n\n <span>·</span>\n\n <Button\n variant=\"transparent\"\n className=\"bg-transparent p-0 text-orange-950 hover:bg-transparent focus:bg-transparent active:bg-transparent disabled:text-orange-500\"\n size=\"base\"\n disabled={isPending}\n onClick={handleSubmit}\n >\n {actionText}\n </Button>\n </div>\n </div>\n );\n}\n\nexport { CartMismatchBanner };\n"],"mappings":";;;;;;;;;;AAYA,SAAS,mBAAmB,OAA2C;CACrE,MAAM,EAAE,UAAU,SAAS;CAC3B,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;CACjD,MAAM,CAAC,YAAY,iBAAiB,SAAS,qBAAqB;CAClE,MAAM,MAAM,sBAAsB;AAElC,KAAI,CAAC,YAAY,CAAC,CAAC,KAAK,
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/cart-mismatch-banner/index.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\n\nimport { ExclamationCircleSolid } from '@medusajs/icons';\nimport { Button } from '@medusajs/ui';\n\nimport { useStorefrontContext } from '@/lib/data/context';\nimport { transferCart } from '@/lib/data/customer';\nimport { Customer } from '@/types/graphql';\nimport { Cart } from '@/types/graphql';\n\nfunction CartMismatchBanner(props: { customer: Customer; cart: Cart }) {\n const { customer, cart } = props;\n const [isPending, setIsPending] = useState(false);\n const [actionText, setActionText] = useState('Run transfer again');\n const [transferComplete, setTransferComplete] = useState(false);\n const ctx = useStorefrontContext();\n\n if (!customer || !!cart.customerId || transferComplete) {\n return;\n }\n\n const handleSubmit = async () => {\n try {\n setIsPending(true);\n setActionText('Transferring..');\n\n const result = await transferCart(ctx);\n\n setIsPending(false);\n if (result?.customerId) {\n setTransferComplete(true);\n } else {\n setActionText('Run transfer again');\n }\n } catch {\n setActionText('Run transfer again');\n setIsPending(false);\n }\n };\n\n return (\n <div className=\"small:gap-2 small:p-4 mt-2 flex items-center justify-center gap-1 bg-orange-300 p-2 text-center text-sm text-orange-800\">\n <div className=\"small:flex-row small:gap-2 flex flex-col items-center gap-1\">\n <span className=\"flex items-center gap-1\">\n <ExclamationCircleSolid className=\"inline\" />\n Something went wrong when we tried to transfer your cart\n </span>\n\n <span>·</span>\n\n <Button\n variant=\"transparent\"\n className=\"bg-transparent p-0 text-orange-950 hover:bg-transparent focus:bg-transparent active:bg-transparent disabled:text-orange-500\"\n size=\"base\"\n disabled={isPending}\n onClick={handleSubmit}\n >\n {actionText}\n </Button>\n </div>\n </div>\n );\n}\n\nexport { CartMismatchBanner };\n"],"mappings":";;;;;;;;;;AAYA,SAAS,mBAAmB,OAA2C;CACrE,MAAM,EAAE,UAAU,SAAS;CAC3B,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;CACjD,MAAM,CAAC,YAAY,iBAAiB,SAAS,qBAAqB;CAClE,MAAM,CAAC,kBAAkB,uBAAuB,SAAS,MAAM;CAC/D,MAAM,MAAM,sBAAsB;AAElC,KAAI,CAAC,YAAY,CAAC,CAAC,KAAK,cAAc,kBAAkB;AACtD;;CAGF,MAAM,eAAe,YAAY;AAC/B,MAAI;AACF,gBAAa,KAAK;AAClB,iBAAc,iBAAiB;GAE/B,MAAM,SAAS,MAAM,aAAa,IAAI;AAEtC,gBAAa,MAAM;AACnB,OAAI,QAAQ,YAAY;AACtB,wBAAoB,KAAK;UACpB;AACL,kBAAc,qBAAqB;;UAE/B;AACN,iBAAc,qBAAqB;AACnC,gBAAa,MAAM;;;AAIvB,QACE,oBAAC;EAAI,WAAU;YACb,qBAAC;GAAI,WAAU;;IACb,qBAAC;KAAK,WAAU;gBACd,oBAAC,0BAAuB,WAAU,WAAW;MAExC;IAEP,oBAAC,oBAAK,MAAQ;IAEd,oBAAC;KACC,SAAQ;KACR,WAAU;KACV,MAAK;KACL,UAAU;KACV,SAAS;eAER;MACM;;IACL;GACF"}
|
|
@@ -7,7 +7,9 @@ const CountrySelect = React.forwardRef(({ placeholder = "Country", region, defau
|
|
|
7
7
|
const innerRef = useRef(null);
|
|
8
8
|
useImperativeHandle(ref, () => innerRef.current);
|
|
9
9
|
const countryOptions = useMemo(() => {
|
|
10
|
-
if (!region)
|
|
10
|
+
if (!region) {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
11
13
|
return region.countries?.map((country) => ({
|
|
12
14
|
value: country?.iso2,
|
|
13
15
|
label: country?.displayName
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/country-select/index.tsx"],"sourcesContent":["import React, { useImperativeHandle, useMemo, useRef } from 'react';\n\nimport NativeSelect, {\n NativeSelectProps,\n} from '@gfed-medusa/sf-lib-ui/components/native-select';\n\nimport { Region } from '@/types/graphql';\n\nconst CountrySelect = React.forwardRef<\n HTMLSelectElement,\n NativeSelectProps & {\n region?: Region | null;\n }\n>(({ placeholder = 'Country', region, defaultValue, ...props }, ref) => {\n const innerRef = useRef<HTMLSelectElement>(null);\n\n useImperativeHandle<HTMLSelectElement | null, HTMLSelectElement | null>(\n ref,\n () => innerRef.current\n );\n\n const countryOptions = useMemo(() => {\n if (!region) {\n return [];\n }\n\n return region.countries?.map((country) => ({\n value: country?.iso2,\n label: country?.displayName,\n }));\n }, [region]);\n\n return (\n <NativeSelect\n ref={innerRef}\n placeholder={placeholder}\n defaultValue={defaultValue}\n {...props}\n >\n {countryOptions?.map(({ value, label }, index) => (\n <option key={index} value={value ?? ''}>\n {label}\n </option>\n ))}\n </NativeSelect>\n );\n});\n\nCountrySelect.displayName = 'CountrySelect';\n\nexport { CountrySelect };\n"],"mappings":";;;;;AAQA,MAAM,gBAAgB,MAAM,YAKzB,EAAE,cAAc,WAAW,QAAQ,cAAc,GAAG,SAAS,QAAQ;CACtE,MAAM,WAAW,OAA0B,KAAK;AAEhD,qBACE,WACM,SAAS,QAChB;CAED,MAAM,iBAAiB,cAAc;AACnC,MAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/country-select/index.tsx"],"sourcesContent":["import React, { useImperativeHandle, useMemo, useRef } from 'react';\n\nimport NativeSelect, {\n NativeSelectProps,\n} from '@gfed-medusa/sf-lib-ui/components/native-select';\n\nimport { Region } from '@/types/graphql';\n\nconst CountrySelect = React.forwardRef<\n HTMLSelectElement,\n NativeSelectProps & {\n region?: Region | null;\n }\n>(({ placeholder = 'Country', region, defaultValue, ...props }, ref) => {\n const innerRef = useRef<HTMLSelectElement>(null);\n\n useImperativeHandle<HTMLSelectElement | null, HTMLSelectElement | null>(\n ref,\n () => innerRef.current\n );\n\n const countryOptions = useMemo(() => {\n if (!region) {\n return [];\n }\n\n return region.countries?.map((country) => ({\n value: country?.iso2,\n label: country?.displayName,\n }));\n }, [region]);\n\n return (\n <NativeSelect\n ref={innerRef}\n placeholder={placeholder}\n defaultValue={defaultValue}\n {...props}\n >\n {countryOptions?.map(({ value, label }, index) => (\n <option key={index} value={value ?? ''}>\n {label}\n </option>\n ))}\n </NativeSelect>\n );\n});\n\nCountrySelect.displayName = 'CountrySelect';\n\nexport { CountrySelect };\n"],"mappings":";;;;;AAQA,MAAM,gBAAgB,MAAM,YAKzB,EAAE,cAAc,WAAW,QAAQ,cAAc,GAAG,SAAS,QAAQ;CACtE,MAAM,WAAW,OAA0B,KAAK;AAEhD,qBACE,WACM,SAAS,QAChB;CAED,MAAM,iBAAiB,cAAc;AACnC,MAAI,CAAC,QAAQ;AACX,UAAO,EAAE;;AAGX,SAAO,OAAO,WAAW,KAAK,aAAa;GACzC,OAAO,SAAS;GAChB,OAAO,SAAS;GACjB,EAAE;IACF,CAAC,OAAO,CAAC;AAEZ,QACE,oBAAC;EACC,KAAK;EACQ;EACC;EACd,GAAI;YAEH,gBAAgB,KAAK,EAAE,OAAO,SAAS,UACtC,oBAAC;GAAmB,OAAO,SAAS;aACjC;KADU,MAEJ,CACT;GACW;EAEjB;AAEF,cAAc,cAAc"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime7 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/components/delete-button/index.d.ts
|
|
4
4
|
declare const DeleteButton: ({
|
|
@@ -9,7 +9,7 @@ declare const DeleteButton: ({
|
|
|
9
9
|
id: string;
|
|
10
10
|
children?: React.ReactNode;
|
|
11
11
|
className?: string;
|
|
12
|
-
}) =>
|
|
12
|
+
}) => react_jsx_runtime7.JSX.Element;
|
|
13
13
|
//#endregion
|
|
14
14
|
export { DeleteButton };
|
|
15
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime12 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/components/error-message/index.d.ts
|
|
4
4
|
declare const ErrorMessage: ({
|
|
@@ -7,7 +7,7 @@ declare const ErrorMessage: ({
|
|
|
7
7
|
}: {
|
|
8
8
|
error?: string | null;
|
|
9
9
|
"data-testid"?: string;
|
|
10
|
-
}) =>
|
|
10
|
+
}) => react_jsx_runtime12.JSX.Element | null;
|
|
11
11
|
//#endregion
|
|
12
12
|
export { ErrorMessage };
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -2,7 +2,9 @@ import { jsx } from "react/jsx-runtime";
|
|
|
2
2
|
|
|
3
3
|
//#region src/components/error-message/index.tsx
|
|
4
4
|
const ErrorMessage = ({ error, "data-testid": dataTestid }) => {
|
|
5
|
-
if (!error)
|
|
5
|
+
if (!error) {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
6
8
|
return /* @__PURE__ */ jsx("div", {
|
|
7
9
|
className: "text-small-regular pt-2 text-rose-600",
|
|
8
10
|
"data-testid": dataTestid,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/error-message/index.tsx"],"sourcesContent":["const ErrorMessage = ({\n error,\n 'data-testid': dataTestid,\n}: {\n error?: string | null;\n 'data-testid'?: string;\n}) => {\n if (!error) {\n return null;\n }\n\n return (\n <div\n className=\"text-small-regular pt-2 text-rose-600\"\n data-testid={dataTestid}\n >\n <span>{error}</span>\n </div>\n );\n};\n\nexport { ErrorMessage };\n"],"mappings":";;;AAAA,MAAM,gBAAgB,EACpB,OACA,eAAe,iBAIX;AACJ,KAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/error-message/index.tsx"],"sourcesContent":["const ErrorMessage = ({\n error,\n 'data-testid': dataTestid,\n}: {\n error?: string | null;\n 'data-testid'?: string;\n}) => {\n if (!error) {\n return null;\n }\n\n return (\n <div\n className=\"text-small-regular pt-2 text-rose-600\"\n data-testid={dataTestid}\n >\n <span>{error}</span>\n </div>\n );\n};\n\nexport { ErrorMessage };\n"],"mappings":";;;AAAA,MAAM,gBAAgB,EACpB,OACA,eAAe,iBAIX;AACJ,KAAI,CAAC,OAAO;AACV,SAAO;;AAGT,QACE,oBAAC;EACC,WAAU;EACV,eAAa;YAEb,oBAAC,oBAAM,QAAa;GAChB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Cart, ShippingOption } from "../../types/graphql.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/free-shipping-price-nudge/index.d.ts
|
|
5
5
|
declare function ShippingPriceNudge({
|
|
@@ -10,7 +10,7 @@ declare function ShippingPriceNudge({
|
|
|
10
10
|
variant?: 'popup' | 'inline';
|
|
11
11
|
cart: Cart;
|
|
12
12
|
shippingOptions: ShippingOption[];
|
|
13
|
-
}):
|
|
13
|
+
}): react_jsx_runtime0.JSX.Element | undefined;
|
|
14
14
|
//#endregion
|
|
15
15
|
export { ShippingPriceNudge };
|
|
16
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -12,47 +12,59 @@ const computeTarget = (cart, price) => {
|
|
|
12
12
|
const priceRule = (price.priceRules || []).find((pr) => pr?.attribute === "item_total");
|
|
13
13
|
const currentAmount = cart.itemTotal;
|
|
14
14
|
const targetAmount = parseFloat(priceRule.value);
|
|
15
|
-
if (priceRule.operator === "gt")
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
15
|
+
if (priceRule.operator === "gt") {
|
|
16
|
+
return {
|
|
17
|
+
current_amount: currentAmount,
|
|
18
|
+
target_amount: targetAmount,
|
|
19
|
+
target_reached: currentAmount > targetAmount,
|
|
20
|
+
target_remaining: currentAmount > targetAmount ? 0 : targetAmount + 1 - currentAmount,
|
|
21
|
+
remaining_percentage: currentAmount / targetAmount * 100
|
|
22
|
+
};
|
|
23
|
+
} else if (priceRule.operator === "gte") {
|
|
24
|
+
return {
|
|
25
|
+
current_amount: currentAmount,
|
|
26
|
+
target_amount: targetAmount,
|
|
27
|
+
target_reached: currentAmount > targetAmount,
|
|
28
|
+
target_remaining: currentAmount > targetAmount ? 0 : targetAmount - currentAmount,
|
|
29
|
+
remaining_percentage: currentAmount / targetAmount * 100
|
|
30
|
+
};
|
|
31
|
+
} else if (priceRule.operator === "lt") {
|
|
32
|
+
return {
|
|
33
|
+
current_amount: currentAmount,
|
|
34
|
+
target_amount: targetAmount,
|
|
35
|
+
target_reached: targetAmount > currentAmount,
|
|
36
|
+
target_remaining: targetAmount > currentAmount ? 0 : currentAmount + 1 - targetAmount,
|
|
37
|
+
remaining_percentage: currentAmount / targetAmount * 100
|
|
38
|
+
};
|
|
39
|
+
} else if (priceRule.operator === "lte") {
|
|
40
|
+
return {
|
|
41
|
+
current_amount: currentAmount,
|
|
42
|
+
target_amount: targetAmount,
|
|
43
|
+
target_reached: targetAmount > currentAmount,
|
|
44
|
+
target_remaining: targetAmount > currentAmount ? 0 : currentAmount - targetAmount,
|
|
45
|
+
remaining_percentage: currentAmount / targetAmount * 100
|
|
46
|
+
};
|
|
47
|
+
} else {
|
|
48
|
+
return {
|
|
49
|
+
current_amount: currentAmount,
|
|
50
|
+
target_amount: targetAmount,
|
|
51
|
+
target_reached: currentAmount === targetAmount,
|
|
52
|
+
target_remaining: targetAmount > currentAmount ? 0 : targetAmount - currentAmount,
|
|
53
|
+
remaining_percentage: currentAmount / targetAmount * 100
|
|
54
|
+
};
|
|
55
|
+
}
|
|
50
56
|
};
|
|
51
57
|
function ShippingPriceNudge({ variant = "inline", cart, shippingOptions }) {
|
|
52
|
-
if (!cart || !shippingOptions?.length)
|
|
58
|
+
if (!cart || !shippingOptions?.length) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
53
61
|
const freeShippingPrice = shippingOptions.map((shippingOption) => {
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+
const calculatedPrice = shippingOption.calculatedPrice;
|
|
63
|
+
if (!calculatedPrice) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const validCurrencyPrices = (shippingOption.prices ?? []).filter((price) => price !== null && price !== undefined && price.currencyCode === cart.currencyCode && (price.priceRules || []).some((priceRule) => priceRule?.attribute === "item_total"));
|
|
67
|
+
return validCurrencyPrices.map((price) => {
|
|
56
68
|
return {
|
|
57
69
|
...price,
|
|
58
70
|
shipping_option_id: shippingOption.id,
|
|
@@ -60,15 +72,20 @@ function ShippingPriceNudge({ variant = "inline", cart, shippingOptions }) {
|
|
|
60
72
|
};
|
|
61
73
|
});
|
|
62
74
|
}).flat(1).filter(Boolean).find((price) => price?.amount === 0);
|
|
63
|
-
if (!freeShippingPrice)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
75
|
+
if (!freeShippingPrice) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (variant === "popup") {
|
|
79
|
+
return /* @__PURE__ */ jsx(FreeShippingPopup, {
|
|
80
|
+
cart,
|
|
81
|
+
price: freeShippingPrice
|
|
82
|
+
});
|
|
83
|
+
} else {
|
|
84
|
+
return /* @__PURE__ */ jsx(FreeShippingInline, {
|
|
85
|
+
cart,
|
|
86
|
+
price: freeShippingPrice
|
|
87
|
+
});
|
|
88
|
+
}
|
|
72
89
|
}
|
|
73
90
|
function FreeShippingInline({ cart, price }) {
|
|
74
91
|
return /* @__PURE__ */ jsx("div", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/free-shipping-price-nudge/index.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\n\nimport { CheckCircleSolid, XMark } from '@medusajs/icons';\nimport { Button, clx } from '@medusajs/ui';\n\nimport { convertToLocale } from '@/lib/utils/money';\nimport { Cart, ShippingOption, ShippingOptionPrice } from '@/types/graphql';\nimport { StoreFreeShippingPrice } from '@/types/prices';\n\nimport { LocalizedClientLink } from '../localized-client-link';\n\nconst computeTarget = (cart: Cart, price: ShippingOptionPrice) => {\n const priceRule = (price.priceRules || []).find(\n (pr) => pr?.attribute === 'item_total'\n )!;\n\n const currentAmount = cart.itemTotal;\n const targetAmount = parseFloat(priceRule.value);\n\n if (priceRule.operator === 'gt') {\n return {\n current_amount: currentAmount,\n target_amount: targetAmount,\n target_reached: currentAmount > targetAmount,\n target_remaining:\n currentAmount > targetAmount ? 0 : targetAmount + 1 - currentAmount,\n remaining_percentage: (currentAmount / targetAmount) * 100,\n };\n } else if (priceRule.operator === 'gte') {\n return {\n current_amount: currentAmount,\n target_amount: targetAmount,\n target_reached: currentAmount > targetAmount,\n target_remaining:\n currentAmount > targetAmount ? 0 : targetAmount - currentAmount,\n remaining_percentage: (currentAmount / targetAmount) * 100,\n };\n } else if (priceRule.operator === 'lt') {\n return {\n current_amount: currentAmount,\n target_amount: targetAmount,\n target_reached: targetAmount > currentAmount,\n target_remaining:\n targetAmount > currentAmount ? 0 : currentAmount + 1 - targetAmount,\n remaining_percentage: (currentAmount / targetAmount) * 100,\n };\n } else if (priceRule.operator === 'lte') {\n return {\n current_amount: currentAmount,\n target_amount: targetAmount,\n target_reached: targetAmount > currentAmount,\n target_remaining:\n targetAmount > currentAmount ? 0 : currentAmount - targetAmount,\n remaining_percentage: (currentAmount / targetAmount) * 100,\n };\n } else {\n return {\n current_amount: currentAmount,\n target_amount: targetAmount,\n target_reached: currentAmount === targetAmount,\n target_remaining:\n targetAmount > currentAmount ? 0 : targetAmount - currentAmount,\n remaining_percentage: (currentAmount / targetAmount) * 100,\n };\n }\n};\n\nfunction ShippingPriceNudge({\n variant = 'inline',\n cart,\n shippingOptions,\n}: {\n variant?: 'popup' | 'inline';\n cart: Cart;\n shippingOptions: ShippingOption[];\n}) {\n if (!cart || !shippingOptions?.length) {\n return;\n }\n\n // Check if any shipping options have a conditional price based on item_total\n const freeShippingPrice = shippingOptions\n .map((shippingOption) => {\n const calculatedPrice = shippingOption.calculatedPrice;\n\n if (!calculatedPrice) {\n return;\n }\n\n // Get all prices that are:\n // 1. Currency code is same as the cart's\n // 2. Have a rule that is set on item_total\n const validCurrencyPrices = (shippingOption.prices ?? []).filter(\n (price): price is NonNullable<typeof price> =>\n price !== null &&\n price !== undefined &&\n price.currencyCode === cart.currencyCode &&\n (price.priceRules || []).some(\n (priceRule) => priceRule?.attribute === 'item_total'\n )\n );\n\n return validCurrencyPrices.map((price) => {\n return {\n ...price,\n shipping_option_id: shippingOption.id,\n ...computeTarget(cart, price),\n };\n });\n })\n .flat(1)\n .filter(Boolean)\n // We focus here entirely on free shipping, but this can be edited to handle multiple layers\n // of reduced shipping prices.\n .find((price) => price?.amount === 0);\n\n if (!freeShippingPrice) {\n return;\n }\n\n if (variant === 'popup') {\n return <FreeShippingPopup cart={cart} price={freeShippingPrice} />;\n } else {\n return <FreeShippingInline cart={cart} price={freeShippingPrice} />;\n }\n}\n\nfunction FreeShippingInline({\n cart,\n price,\n}: {\n cart: Cart;\n price: StoreFreeShippingPrice;\n}) {\n return (\n <div className=\"rounded-lg border bg-neutral-100 p-2\">\n <div className=\"space-y-1.5\">\n <div className=\"flex justify-between text-xs text-neutral-600\">\n <div>\n {price.target_reached ? (\n <div className=\"flex items-center gap-1.5\">\n <CheckCircleSolid className=\"inline-block text-green-500\" />{' '}\n Free Shipping unlocked!\n </div>\n ) : (\n `Unlock Free Shipping`\n )}\n </div>\n\n <div\n className={clx('visible', {\n 'invisible opacity-0': price.target_reached,\n })}\n >\n Only{' '}\n <span className=\"text-neutral-950\">\n {convertToLocale({\n amount: price.target_remaining,\n currency_code: cart.currencyCode,\n })}\n </span>{' '}\n away\n </div>\n </div>\n <div className=\"flex justify-between gap-1\">\n <div\n className={clx(\n 'h-1 max-w-full rounded-full bg-gradient-to-r from-zinc-400 to-zinc-500 duration-500 ease-in-out',\n {\n 'from-green-400 to-green-500': price.target_reached,\n }\n )}\n style={{ width: `${price.remaining_percentage}%` }}\n ></div>\n <div className=\"h-1 w-fit flex-grow rounded-full bg-neutral-300\"></div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction FreeShippingPopup({\n cart,\n price,\n}: {\n cart: Cart;\n price: StoreFreeShippingPrice;\n}) {\n const [isClosed, setIsClosed] = useState(false);\n\n return (\n <div\n className={clx(\n 'fixed bottom-5 right-5 z-10 flex flex-col items-end gap-2 transition-all duration-500 ease-in-out',\n {\n 'invisible opacity-0 delay-1000': price.target_reached,\n 'invisible opacity-0': isClosed,\n 'visible opacity-100': !price.target_reached && !isClosed,\n }\n )}\n >\n <div>\n <Button\n className=\"rounded-full border-none bg-neutral-900 p-2 text-[15px] shadow-none outline-none\"\n onClick={() => setIsClosed(true)}\n >\n <XMark />\n </Button>\n </div>\n\n <div className=\"w-[400px] rounded-lg bg-black p-6 text-white\">\n <div className=\"pb-4\">\n <div className=\"space-y-3\">\n <div className=\"flex justify-between text-[15px] text-neutral-400\">\n <div>\n {price.target_reached ? (\n <div className=\"flex items-center gap-1.5\">\n <CheckCircleSolid className=\"inline-block text-green-500\" />{' '}\n Free Shipping unlocked!\n </div>\n ) : (\n `Unlock Free Shipping`\n )}\n </div>\n\n <div\n className={clx('visible', {\n 'invisible opacity-0': price.target_reached,\n })}\n >\n Only{' '}\n <span className=\"text-white\">\n {convertToLocale({\n amount: price.target_remaining,\n currency_code: cart.currencyCode,\n })}\n </span>{' '}\n away\n </div>\n </div>\n <div className=\"flex justify-between gap-1\">\n <div\n className={clx(\n 'h-1.5 max-w-full rounded-full bg-gradient-to-r from-zinc-400 to-zinc-500 duration-500 ease-in-out',\n {\n 'from-green-400 to-green-500': price.target_reached,\n }\n )}\n style={{ width: `${price.remaining_percentage}%` }}\n ></div>\n <div className=\"h-1.5 w-fit flex-grow rounded-full bg-zinc-600\"></div>\n </div>\n </div>\n </div>\n\n <div className=\"flex gap-3\">\n <LocalizedClientLink\n className=\"rounded-2xl border-[1px] border-white bg-transparent px-4 py-2.5 text-[15px] shadow-none outline-none\"\n href=\"/cart\"\n >\n View cart\n </LocalizedClientLink>\n\n <LocalizedClientLink\n className=\"flex-grow rounded-2xl border-[1px] border-white bg-white px-4 py-2.5 text-center text-[15px] text-neutral-950 shadow-none outline-none\"\n href=\"/store\"\n >\n View products\n </LocalizedClientLink>\n </div>\n </div>\n </div>\n );\n}\n\nexport { ShippingPriceNudge };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/free-shipping-price-nudge/index.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\n\nimport { CheckCircleSolid, XMark } from '@medusajs/icons';\nimport { Button, clx } from '@medusajs/ui';\n\nimport { convertToLocale } from '@/lib/utils/money';\nimport { Cart, ShippingOption, ShippingOptionPrice } from '@/types/graphql';\nimport { StoreFreeShippingPrice } from '@/types/prices';\n\nimport { LocalizedClientLink } from '../localized-client-link';\n\nconst computeTarget = (cart: Cart, price: ShippingOptionPrice) => {\n const priceRule = (price.priceRules || []).find(\n (pr) => pr?.attribute === 'item_total'\n )!;\n\n const currentAmount = cart.itemTotal;\n const targetAmount = parseFloat(priceRule.value);\n\n if (priceRule.operator === 'gt') {\n return {\n current_amount: currentAmount,\n target_amount: targetAmount,\n target_reached: currentAmount > targetAmount,\n target_remaining:\n currentAmount > targetAmount ? 0 : targetAmount + 1 - currentAmount,\n remaining_percentage: (currentAmount / targetAmount) * 100,\n };\n } else if (priceRule.operator === 'gte') {\n return {\n current_amount: currentAmount,\n target_amount: targetAmount,\n target_reached: currentAmount > targetAmount,\n target_remaining:\n currentAmount > targetAmount ? 0 : targetAmount - currentAmount,\n remaining_percentage: (currentAmount / targetAmount) * 100,\n };\n } else if (priceRule.operator === 'lt') {\n return {\n current_amount: currentAmount,\n target_amount: targetAmount,\n target_reached: targetAmount > currentAmount,\n target_remaining:\n targetAmount > currentAmount ? 0 : currentAmount + 1 - targetAmount,\n remaining_percentage: (currentAmount / targetAmount) * 100,\n };\n } else if (priceRule.operator === 'lte') {\n return {\n current_amount: currentAmount,\n target_amount: targetAmount,\n target_reached: targetAmount > currentAmount,\n target_remaining:\n targetAmount > currentAmount ? 0 : currentAmount - targetAmount,\n remaining_percentage: (currentAmount / targetAmount) * 100,\n };\n } else {\n return {\n current_amount: currentAmount,\n target_amount: targetAmount,\n target_reached: currentAmount === targetAmount,\n target_remaining:\n targetAmount > currentAmount ? 0 : targetAmount - currentAmount,\n remaining_percentage: (currentAmount / targetAmount) * 100,\n };\n }\n};\n\nfunction ShippingPriceNudge({\n variant = 'inline',\n cart,\n shippingOptions,\n}: {\n variant?: 'popup' | 'inline';\n cart: Cart;\n shippingOptions: ShippingOption[];\n}) {\n if (!cart || !shippingOptions?.length) {\n return;\n }\n\n // Check if any shipping options have a conditional price based on item_total\n const freeShippingPrice = shippingOptions\n .map((shippingOption) => {\n const calculatedPrice = shippingOption.calculatedPrice;\n\n if (!calculatedPrice) {\n return;\n }\n\n // Get all prices that are:\n // 1. Currency code is same as the cart's\n // 2. Have a rule that is set on item_total\n const validCurrencyPrices = (shippingOption.prices ?? []).filter(\n (price): price is NonNullable<typeof price> =>\n price !== null &&\n price !== undefined &&\n price.currencyCode === cart.currencyCode &&\n (price.priceRules || []).some(\n (priceRule) => priceRule?.attribute === 'item_total'\n )\n );\n\n return validCurrencyPrices.map((price) => {\n return {\n ...price,\n shipping_option_id: shippingOption.id,\n ...computeTarget(cart, price),\n };\n });\n })\n .flat(1)\n .filter(Boolean)\n // We focus here entirely on free shipping, but this can be edited to handle multiple layers\n // of reduced shipping prices.\n .find((price) => price?.amount === 0);\n\n if (!freeShippingPrice) {\n return;\n }\n\n if (variant === 'popup') {\n return <FreeShippingPopup cart={cart} price={freeShippingPrice} />;\n } else {\n return <FreeShippingInline cart={cart} price={freeShippingPrice} />;\n }\n}\n\nfunction FreeShippingInline({\n cart,\n price,\n}: {\n cart: Cart;\n price: StoreFreeShippingPrice;\n}) {\n return (\n <div className=\"rounded-lg border bg-neutral-100 p-2\">\n <div className=\"space-y-1.5\">\n <div className=\"flex justify-between text-xs text-neutral-600\">\n <div>\n {price.target_reached ? (\n <div className=\"flex items-center gap-1.5\">\n <CheckCircleSolid className=\"inline-block text-green-500\" />{' '}\n Free Shipping unlocked!\n </div>\n ) : (\n `Unlock Free Shipping`\n )}\n </div>\n\n <div\n className={clx('visible', {\n 'invisible opacity-0': price.target_reached,\n })}\n >\n Only{' '}\n <span className=\"text-neutral-950\">\n {convertToLocale({\n amount: price.target_remaining,\n currency_code: cart.currencyCode,\n })}\n </span>{' '}\n away\n </div>\n </div>\n <div className=\"flex justify-between gap-1\">\n <div\n className={clx(\n 'h-1 max-w-full rounded-full bg-gradient-to-r from-zinc-400 to-zinc-500 duration-500 ease-in-out',\n {\n 'from-green-400 to-green-500': price.target_reached,\n }\n )}\n style={{ width: `${price.remaining_percentage}%` }}\n ></div>\n <div className=\"h-1 w-fit flex-grow rounded-full bg-neutral-300\"></div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction FreeShippingPopup({\n cart,\n price,\n}: {\n cart: Cart;\n price: StoreFreeShippingPrice;\n}) {\n const [isClosed, setIsClosed] = useState(false);\n\n return (\n <div\n className={clx(\n 'fixed bottom-5 right-5 z-10 flex flex-col items-end gap-2 transition-all duration-500 ease-in-out',\n {\n 'invisible opacity-0 delay-1000': price.target_reached,\n 'invisible opacity-0': isClosed,\n 'visible opacity-100': !price.target_reached && !isClosed,\n }\n )}\n >\n <div>\n <Button\n className=\"rounded-full border-none bg-neutral-900 p-2 text-[15px] shadow-none outline-none\"\n onClick={() => setIsClosed(true)}\n >\n <XMark />\n </Button>\n </div>\n\n <div className=\"w-[400px] rounded-lg bg-black p-6 text-white\">\n <div className=\"pb-4\">\n <div className=\"space-y-3\">\n <div className=\"flex justify-between text-[15px] text-neutral-400\">\n <div>\n {price.target_reached ? (\n <div className=\"flex items-center gap-1.5\">\n <CheckCircleSolid className=\"inline-block text-green-500\" />{' '}\n Free Shipping unlocked!\n </div>\n ) : (\n `Unlock Free Shipping`\n )}\n </div>\n\n <div\n className={clx('visible', {\n 'invisible opacity-0': price.target_reached,\n })}\n >\n Only{' '}\n <span className=\"text-white\">\n {convertToLocale({\n amount: price.target_remaining,\n currency_code: cart.currencyCode,\n })}\n </span>{' '}\n away\n </div>\n </div>\n <div className=\"flex justify-between gap-1\">\n <div\n className={clx(\n 'h-1.5 max-w-full rounded-full bg-gradient-to-r from-zinc-400 to-zinc-500 duration-500 ease-in-out',\n {\n 'from-green-400 to-green-500': price.target_reached,\n }\n )}\n style={{ width: `${price.remaining_percentage}%` }}\n ></div>\n <div className=\"h-1.5 w-fit flex-grow rounded-full bg-zinc-600\"></div>\n </div>\n </div>\n </div>\n\n <div className=\"flex gap-3\">\n <LocalizedClientLink\n className=\"rounded-2xl border-[1px] border-white bg-transparent px-4 py-2.5 text-[15px] shadow-none outline-none\"\n href=\"/cart\"\n >\n View cart\n </LocalizedClientLink>\n\n <LocalizedClientLink\n className=\"flex-grow rounded-2xl border-[1px] border-white bg-white px-4 py-2.5 text-center text-[15px] text-neutral-950 shadow-none outline-none\"\n href=\"/store\"\n >\n View products\n </LocalizedClientLink>\n </div>\n </div>\n </div>\n );\n}\n\nexport { ShippingPriceNudge };\n"],"mappings":"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"}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { LocalizedClientLink } from "../localized-client-link/index.js";
|
|
2
|
+
import * as react_jsx_runtime1 from "react/jsx-runtime";
|
|
2
3
|
|
|
3
4
|
//#region src/components/interactive-link/index.d.ts
|
|
4
|
-
type InteractiveLinkProps = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
onClick?: () => void;
|
|
5
|
+
type InteractiveLinkProps = React.ComponentPropsWithoutRef<typeof LocalizedClientLink> & {
|
|
6
|
+
textClassName?: string;
|
|
7
|
+
iconClassName?: string;
|
|
8
8
|
};
|
|
9
9
|
declare const InteractiveLink: ({
|
|
10
10
|
href,
|
|
11
11
|
children,
|
|
12
12
|
onClick,
|
|
13
|
+
className,
|
|
14
|
+
textClassName,
|
|
15
|
+
iconClassName,
|
|
13
16
|
...props
|
|
14
|
-
}: InteractiveLinkProps) =>
|
|
17
|
+
}: InteractiveLinkProps) => react_jsx_runtime1.JSX.Element;
|
|
15
18
|
//#endregion
|
|
16
19
|
export { InteractiveLink };
|
|
17
20
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/interactive-link/index.tsx"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/interactive-link/index.tsx"],"sourcesContent":[],"mappings":";;;;KAKK,oBAAA,GAAuB,KAAA,CAAM,gCACzB;;;AAHsD,CAAA;AAEL,cAOpD,eA0BL,EAAA,CAAA;EAAA,IAAA;EAAA,QAAA;EAAA,OAAA;EAAA,SAAA;EAAA,aAAA;EAAA,aAAA;EAAA,GAAA;AAAA,CAAA,EAlBE,oBAkBF,EAAA,GAlBsB,kBAAA,CAAA,GAAA,CAAA,OAkBtB"}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { LocalizedClientLink } from "../localized-client-link/index.js";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { ArrowUpRightMini } from "@medusajs/icons";
|
|
4
|
-
import { Text } from "@medusajs/ui";
|
|
4
|
+
import { Text, clx } from "@medusajs/ui";
|
|
5
5
|
|
|
6
6
|
//#region src/components/interactive-link/index.tsx
|
|
7
|
-
const InteractiveLink = ({ href, children, onClick, ...props }) => {
|
|
7
|
+
const InteractiveLink = ({ href, children, onClick, className, textClassName, iconClassName, ...props }) => {
|
|
8
8
|
return /* @__PURE__ */ jsxs(LocalizedClientLink, {
|
|
9
|
-
className: "group flex items-center gap-x-1",
|
|
9
|
+
className: clx("text-ui-fg-interactive group flex items-center gap-x-1", className),
|
|
10
10
|
href,
|
|
11
11
|
onClick,
|
|
12
12
|
...props,
|
|
13
13
|
children: [/* @__PURE__ */ jsx(Text, {
|
|
14
|
-
className: "text-
|
|
14
|
+
className: clx("text-current", textClassName),
|
|
15
15
|
children
|
|
16
16
|
}), /* @__PURE__ */ jsx(ArrowUpRightMini, {
|
|
17
|
-
className: "duration-150 ease-in-out group-hover:rotate-45",
|
|
18
|
-
color: "
|
|
17
|
+
className: clx("duration-150 ease-in-out group-hover:rotate-45", iconClassName),
|
|
18
|
+
color: "currentColor"
|
|
19
19
|
})]
|
|
20
20
|
});
|
|
21
21
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/interactive-link/index.tsx"],"sourcesContent":["import { ArrowUpRightMini } from '@medusajs/icons';\nimport { Text } from '@medusajs/ui';\n\nimport { LocalizedClientLink } from '../localized-client-link';\n\ntype InteractiveLinkProps =
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/interactive-link/index.tsx"],"sourcesContent":["import { ArrowUpRightMini } from '@medusajs/icons';\nimport { Text, clx } from '@medusajs/ui';\n\nimport { LocalizedClientLink } from '../localized-client-link';\n\ntype InteractiveLinkProps = React.ComponentPropsWithoutRef<\n typeof LocalizedClientLink\n> & {\n textClassName?: string;\n iconClassName?: string;\n};\n\nconst InteractiveLink = ({\n href,\n children,\n onClick,\n className,\n textClassName,\n iconClassName,\n ...props\n}: InteractiveLinkProps) => {\n return (\n <LocalizedClientLink\n className={clx('text-ui-fg-interactive group flex items-center gap-x-1', className)}\n href={href}\n onClick={onClick}\n {...props}\n >\n <Text className={clx('text-current', textClassName)}>{children}</Text>\n <ArrowUpRightMini\n className={clx(\n 'duration-150 ease-in-out group-hover:rotate-45',\n iconClassName\n )}\n color=\"currentColor\"\n />\n </LocalizedClientLink>\n );\n};\n\nexport { InteractiveLink };\n"],"mappings":";;;;;;AAYA,MAAM,mBAAmB,EACvB,MACA,UACA,SACA,WACA,eACA,eACA,GAAG,YACuB;AAC1B,QACE,qBAAC;EACC,WAAW,IAAI,0DAA0D,UAAU;EAC7E;EACG;EACT,GAAI;aAEJ,oBAAC;GAAK,WAAW,IAAI,gBAAgB,cAAc;GAAG;IAAgB,EACtE,oBAAC;GACC,WAAW,IACT,kDACA,cACD;GACD,OAAM;IACN;GACkB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Maybe, ProductVariant } from "../../types/graphql.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime2 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/line-item-options/index.d.ts
|
|
5
5
|
type LineItemOptionsProps = {
|
|
@@ -11,7 +11,7 @@ declare const LineItemOptions: ({
|
|
|
11
11
|
variant,
|
|
12
12
|
"data-testid": dataTestid,
|
|
13
13
|
"data-value": dataValue
|
|
14
|
-
}: LineItemOptionsProps) =>
|
|
14
|
+
}: LineItemOptionsProps) => react_jsx_runtime2.JSX.Element;
|
|
15
15
|
//#endregion
|
|
16
16
|
export { LineItemOptions };
|
|
17
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LineItem } from "../../types/graphql.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime14 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/line-item-price/index.d.ts
|
|
5
5
|
type LineItemPriceProps = {
|
|
@@ -11,7 +11,7 @@ declare const LineItemPrice: ({
|
|
|
11
11
|
item,
|
|
12
12
|
style,
|
|
13
13
|
currencyCode
|
|
14
|
-
}: LineItemPriceProps) =>
|
|
14
|
+
}: LineItemPriceProps) => react_jsx_runtime14.JSX.Element;
|
|
15
15
|
//#endregion
|
|
16
16
|
export { LineItemPrice };
|
|
17
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AnchorHTMLAttributes, DetailedHTMLProps } from "react";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime3 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/localized-client-link/index.d.ts
|
|
5
5
|
type LocalizedClientLinkProps = DetailedHTMLProps<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement> & {
|
|
@@ -10,7 +10,7 @@ declare const LocalizedClientLink: ({
|
|
|
10
10
|
href,
|
|
11
11
|
locale,
|
|
12
12
|
...props
|
|
13
|
-
}: LocalizedClientLinkProps) =>
|
|
13
|
+
}: LocalizedClientLinkProps) => react_jsx_runtime3.JSX.Element;
|
|
14
14
|
//#endregion
|
|
15
15
|
export { LocalizedClientLink };
|
|
16
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -12,7 +12,9 @@ const LocalizedClientLink = ({ children, href, locale, ...props }) => {
|
|
|
12
12
|
}, []);
|
|
13
13
|
const getLocaleFromPathname = (pathname$1) => {
|
|
14
14
|
const pathLocale = pathname$1.split("/")[1];
|
|
15
|
-
if (pathLocale && LOCALE_REGEX.test(pathLocale))
|
|
15
|
+
if (pathLocale && LOCALE_REGEX.test(pathLocale)) {
|
|
16
|
+
return pathLocale;
|
|
17
|
+
}
|
|
16
18
|
return "dk";
|
|
17
19
|
};
|
|
18
20
|
const activeLocale = locale || getLocaleFromPathname(pathname);
|
|
@@ -20,11 +22,13 @@ const LocalizedClientLink = ({ children, href, locale, ...props }) => {
|
|
|
20
22
|
if (!href$1) return "";
|
|
21
23
|
return href$1.startsWith("/") ? href$1 : `/${href$1}`;
|
|
22
24
|
};
|
|
23
|
-
if (href?.startsWith("http") || href?.startsWith("//"))
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
if (href?.startsWith("http") || href?.startsWith("//")) {
|
|
26
|
+
return /* @__PURE__ */ jsx("a", {
|
|
27
|
+
href,
|
|
28
|
+
...props,
|
|
29
|
+
children
|
|
30
|
+
});
|
|
31
|
+
}
|
|
28
32
|
return /* @__PURE__ */ jsx("a", {
|
|
29
33
|
href: `/${activeLocale}${normalizeHref(href)}`,
|
|
30
34
|
suppressHydrationWarning: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["pathname","href"],"sources":["../../../src/components/localized-client-link/index.tsx"],"sourcesContent":["'use client';\n\nimport {\n AnchorHTMLAttributes,\n DetailedHTMLProps,\n useEffect,\n useState,\n} from 'react';\n\nconst LOCALE_REGEX = /^[a-z]{2}(?:-[A-Z]{2})?$/;\n\ntype LocalizedClientLinkProps = DetailedHTMLProps<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n HTMLAnchorElement\n> & {\n locale?: string;\n};\n\nconst LocalizedClientLink = ({\n children,\n href,\n locale,\n ...props\n}: LocalizedClientLinkProps) => {\n const [pathname, setPathname] = useState('');\n\n useEffect(() => {\n setPathname(window.location.pathname);\n }, []);\n\n const getLocaleFromPathname = (pathname: string): string => {\n const pathLocale = pathname.split('/')[1];\n if (pathLocale && LOCALE_REGEX.test(pathLocale)) {\n return pathLocale;\n }\n return 'dk';\n };\n\n const activeLocale = locale || getLocaleFromPathname(pathname);\n\n const normalizeHref = (href?: string) => {\n if (!href) return '';\n return href.startsWith('/') ? href : `/${href}`;\n };\n\n if (href?.startsWith('http') || href?.startsWith('//')) {\n return (\n <a href={href} {...props}>\n {children}\n </a>\n );\n }\n\n return (\n <a\n href={`/${activeLocale}${normalizeHref(href)}`}\n suppressHydrationWarning\n {...props}\n >\n {children}\n </a>\n );\n};\n\nexport { LocalizedClientLink };\n"],"mappings":";;;;;;AASA,MAAM,eAAe;AASrB,MAAM,uBAAuB,EAC3B,UACA,MACA,QACA,GAAG,YAC2B;CAC9B,MAAM,CAAC,UAAU,eAAe,SAAS,GAAG;AAE5C,iBAAgB;AACd,cAAY,OAAO,SAAS,SAAS;IACpC,EAAE,CAAC;CAEN,MAAM,yBAAyB,eAA6B;EAC1D,MAAM,aAAaA,WAAS,MAAM,IAAI,CAAC;AACvC,MAAI,cAAc,aAAa,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"index.js","names":["pathname","href"],"sources":["../../../src/components/localized-client-link/index.tsx"],"sourcesContent":["'use client';\n\nimport {\n AnchorHTMLAttributes,\n DetailedHTMLProps,\n useEffect,\n useState,\n} from 'react';\n\nconst LOCALE_REGEX = /^[a-z]{2}(?:-[A-Z]{2})?$/;\n\ntype LocalizedClientLinkProps = DetailedHTMLProps<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n HTMLAnchorElement\n> & {\n locale?: string;\n};\n\nconst LocalizedClientLink = ({\n children,\n href,\n locale,\n ...props\n}: LocalizedClientLinkProps) => {\n const [pathname, setPathname] = useState('');\n\n useEffect(() => {\n setPathname(window.location.pathname);\n }, []);\n\n const getLocaleFromPathname = (pathname: string): string => {\n const pathLocale = pathname.split('/')[1];\n if (pathLocale && LOCALE_REGEX.test(pathLocale)) {\n return pathLocale;\n }\n return 'dk';\n };\n\n const activeLocale = locale || getLocaleFromPathname(pathname);\n\n const normalizeHref = (href?: string) => {\n if (!href) return '';\n return href.startsWith('/') ? href : `/${href}`;\n };\n\n if (href?.startsWith('http') || href?.startsWith('//')) {\n return (\n <a href={href} {...props}>\n {children}\n </a>\n );\n }\n\n return (\n <a\n href={`/${activeLocale}${normalizeHref(href)}`}\n suppressHydrationWarning\n {...props}\n >\n {children}\n </a>\n );\n};\n\nexport { LocalizedClientLink };\n"],"mappings":";;;;;;AASA,MAAM,eAAe;AASrB,MAAM,uBAAuB,EAC3B,UACA,MACA,QACA,GAAG,YAC2B;CAC9B,MAAM,CAAC,UAAU,eAAe,SAAS,GAAG;AAE5C,iBAAgB;AACd,cAAY,OAAO,SAAS,SAAS;IACpC,EAAE,CAAC;CAEN,MAAM,yBAAyB,eAA6B;EAC1D,MAAM,aAAaA,WAAS,MAAM,IAAI,CAAC;AACvC,MAAI,cAAc,aAAa,KAAK,WAAW,EAAE;AAC/C,UAAO;;AAET,SAAO;;CAGT,MAAM,eAAe,UAAU,sBAAsB,SAAS;CAE9D,MAAM,iBAAiB,WAAkB;AACvC,MAAI,CAACC,OAAM,QAAO;AAClB,SAAOA,OAAK,WAAW,IAAI,GAAGA,SAAO,IAAIA;;AAG3C,KAAI,MAAM,WAAW,OAAO,IAAI,MAAM,WAAW,KAAK,EAAE;AACtD,SACE,oBAAC;GAAQ;GAAM,GAAI;GAChB;IACC;;AAIR,QACE,oBAAC;EACC,MAAM,IAAI,eAAe,cAAc,KAAK;EAC5C;EACA,GAAI;EAEH;GACC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime4 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/modal/index.d.ts
|
|
5
5
|
type ModalProps = {
|
|
@@ -20,7 +20,7 @@ declare const Modal: {
|
|
|
20
20
|
children,
|
|
21
21
|
"data-testid": dataTestId,
|
|
22
22
|
"aria-label": ariaLabel
|
|
23
|
-
}: ModalProps):
|
|
23
|
+
}: ModalProps): react_jsx_runtime4.JSX.Element;
|
|
24
24
|
Title: React.FC<{
|
|
25
25
|
children: React.ReactNode;
|
|
26
26
|
}>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { VariantPrice } from "../../types/prices.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime5 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/preview-price/index.d.ts
|
|
5
5
|
declare function PreviewPrice({
|
|
6
6
|
price
|
|
7
7
|
}: {
|
|
8
8
|
price: VariantPrice;
|
|
9
|
-
}):
|
|
9
|
+
}): react_jsx_runtime5.JSX.Element | null;
|
|
10
10
|
//#endregion
|
|
11
11
|
export { PreviewPrice };
|
|
12
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -3,7 +3,9 @@ import { Text, clx } from "@medusajs/ui";
|
|
|
3
3
|
|
|
4
4
|
//#region src/components/preview-price/index.tsx
|
|
5
5
|
function PreviewPrice({ price }) {
|
|
6
|
-
if (!price)
|
|
6
|
+
if (!price) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
7
9
|
return /* @__PURE__ */ jsxs(Fragment, { children: [price.price_type === "sale" && /* @__PURE__ */ jsx(Text, {
|
|
8
10
|
className: "text-ui-fg-muted line-through",
|
|
9
11
|
"data-testid": "original-price",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/preview-price/index.tsx"],"sourcesContent":["import { Text, clx } from '@medusajs/ui';\n\nimport { VariantPrice } from '@/types/prices';\n\nfunction PreviewPrice({ price }: { price: VariantPrice }) {\n if (!price) {\n return null;\n }\n\n return (\n <>\n {price.price_type === 'sale' && (\n <Text\n className=\"text-ui-fg-muted line-through\"\n data-testid=\"original-price\"\n >\n {price.original_price}\n </Text>\n )}\n <Text\n className={clx('text-ui-fg-muted', {\n 'text-ui-fg-interactive': price.price_type === 'sale',\n })}\n data-testid=\"price\"\n >\n {price.calculated_price}\n </Text>\n </>\n );\n}\n\nexport { PreviewPrice };\n"],"mappings":";;;;AAIA,SAAS,aAAa,EAAE,SAAkC;AACxD,KAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/preview-price/index.tsx"],"sourcesContent":["import { Text, clx } from '@medusajs/ui';\n\nimport { VariantPrice } from '@/types/prices';\n\nfunction PreviewPrice({ price }: { price: VariantPrice }) {\n if (!price) {\n return null;\n }\n\n return (\n <>\n {price.price_type === 'sale' && (\n <Text\n className=\"text-ui-fg-muted line-through\"\n data-testid=\"original-price\"\n >\n {price.original_price}\n </Text>\n )}\n <Text\n className={clx('text-ui-fg-muted', {\n 'text-ui-fg-interactive': price.price_type === 'sale',\n })}\n data-testid=\"price\"\n >\n {price.calculated_price}\n </Text>\n </>\n );\n}\n\nexport { PreviewPrice };\n"],"mappings":";;;;AAIA,SAAS,aAAa,EAAE,SAAkC;AACxD,KAAI,CAAC,OAAO;AACV,SAAO;;AAGT,QACE,4CACG,MAAM,eAAe,UACpB,oBAAC;EACC,WAAU;EACV,eAAY;YAEX,MAAM;GACF,EAET,oBAAC;EACC,WAAW,IAAI,oBAAoB,EACjC,0BAA0B,MAAM,eAAe,QAChD,CAAC;EACF,eAAY;YAEX,MAAM;GACF,IACN"}
|