@tapcart/mobile-components 0.7.59 → 0.7.61

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.
@@ -0,0 +1,10 @@
1
+ type Customer = {
2
+ isAuthenticated: boolean;
3
+ };
4
+ type UseCustomerProps = {};
5
+ type UseCustomerReturn = {
6
+ customer: Customer;
7
+ };
8
+ export declare const useCustomer: (props: UseCustomerProps | null) => UseCustomerReturn;
9
+ export {};
10
+ //# sourceMappingURL=use-customer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-customer.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-customer.ts"],"names":[],"mappings":"AAWA,KAAK,QAAQ,GAAG;IACd,eAAe,EAAE,OAAO,CAAA;CACzB,CAAA;AAGD,KAAK,gBAAgB,GAAG,EAAE,CAAA;AAE1B,KAAK,iBAAiB,GAAG;IACvB,QAAQ,EAAE,QAAQ,CAAA;CACnB,CAAA;AAED,eAAO,MAAM,WAAW,UACf,gBAAgB,GAAG,IAAI,KAC7B,iBAuBF,CAAA"}
@@ -0,0 +1,24 @@
1
+ "use client";
2
+ import { useState, useEffect } from "react";
3
+ // @ts-ignore -- webbridge-react is not typed (yet)
4
+ import { useActions } from "@tapcart/webbridge-react";
5
+ export const useCustomer = (props) => {
6
+ const [isAuthenticated, setIsAuthenticated] = useState(false);
7
+ const [customer, setCustomer] = useState({});
8
+ const actions = useActions();
9
+ // verify customer
10
+ useEffect(() => {
11
+ try {
12
+ // webbridge method to get customerIdentity
13
+ actions.getCustomerIdentity(null, {
14
+ onSuccess: (user) => setIsAuthenticated(!!(user === null || user === void 0 ? void 0 : user.email)),
15
+ });
16
+ }
17
+ catch (e) {
18
+ console.log("unable to get customer identity ", e);
19
+ }
20
+ }, [actions]);
21
+ return {
22
+ customer: Object.assign({ isAuthenticated }, customer),
23
+ };
24
+ };
@@ -1,4 +1,4 @@
1
- import { Product } from "app-studio-types";
1
+ import { Money, Product, DiscountApplicationTargetType } from "app-studio-types";
2
2
  type UseMockCartParams = {
3
3
  apiUrl: string;
4
4
  appId: string;
@@ -15,8 +15,10 @@ export declare const useMockCart: ({ apiUrl, appId, enabled, limit, }: UseMockCa
15
15
  error: any;
16
16
  isLoading: boolean;
17
17
  cart: {
18
+ calculatedData: import("../../lib/cart.util").CalculatedData;
18
19
  subtotal: number;
19
20
  items: {
21
+ id: string;
20
22
  discounts: {
21
23
  amount: number;
22
24
  code: string;
@@ -39,7 +41,7 @@ export declare const useMockCart: ({ apiUrl, appId, enabled, limit, }: UseMockCa
39
41
  value: string;
40
42
  optionValue: import("app-studio-types").ProductOptionValue;
41
43
  }[];
42
- price: import("app-studio-types").Money;
44
+ price: Money;
43
45
  available: boolean;
44
46
  image?: import("app-studio-types").Image | undefined;
45
47
  createdAt: string;
@@ -58,16 +60,10 @@ export declare const useMockCart: ({ apiUrl, appId, enabled, limit, }: UseMockCa
58
60
  };
59
61
  };
60
62
  sellingPlanAllocation: {
61
- priceAdjustments: {
62
- perDeliveryPrice: {
63
- amount: number;
64
- currencyCode: string;
65
- };
66
- price: {
67
- amount: number;
68
- currencyCode: string;
69
- };
70
- };
63
+ priceAdjustments: [{
64
+ perDeliveryPrice: Money;
65
+ price: Money;
66
+ }];
71
67
  sellingPlan: {
72
68
  id: string;
73
69
  name: string;
@@ -76,12 +72,64 @@ export declare const useMockCart: ({ apiUrl, appId, enabled, limit, }: UseMockCa
76
72
  } | undefined;
77
73
  }[];
78
74
  discountAllocations: {
79
- targetType: string;
75
+ targetType: DiscountApplicationTargetType;
80
76
  discountedAmount: {
81
77
  amount: string;
78
+ currencyCode: string;
82
79
  };
83
80
  code: string;
84
81
  }[];
82
+ delivery: {
83
+ addresses: {
84
+ selected: boolean;
85
+ oneTimeUse: boolean;
86
+ id: string;
87
+ address: {
88
+ address1: string;
89
+ city: string;
90
+ countryCode: string;
91
+ };
92
+ }[];
93
+ };
94
+ deliveryGroups: {
95
+ id: string;
96
+ deliveryOptions: {
97
+ code: string;
98
+ handle: string;
99
+ title: string;
100
+ deliveryMethodType: string;
101
+ description: string;
102
+ estimatedCost: {
103
+ amount: string;
104
+ currencyCode: string;
105
+ };
106
+ }[];
107
+ selectedDeliveryOption: {
108
+ code: string;
109
+ handle: string;
110
+ title: string;
111
+ deliveryMethodType: string;
112
+ description: string;
113
+ estimatedCost: {
114
+ amount: string;
115
+ currencyCode: string;
116
+ };
117
+ };
118
+ }[];
119
+ cost: {
120
+ subtotalAmount: {
121
+ amount: string;
122
+ currencyCode: string;
123
+ };
124
+ totalAmount: {
125
+ amount: string;
126
+ currencyCode: string;
127
+ };
128
+ totalTaxAmount: {
129
+ amount: string;
130
+ currencyCode: string;
131
+ };
132
+ };
85
133
  attributes: {
86
134
  key: string;
87
135
  value: string;
@@ -95,6 +143,15 @@ export declare const useMockCart: ({ apiUrl, appId, enabled, limit, }: UseMockCa
95
143
  lastCharacters: string;
96
144
  amountUsed: {
97
145
  amount: string;
146
+ currencyCode: string;
147
+ };
148
+ balance: {
149
+ amount: string;
150
+ currencyCode: string;
151
+ };
152
+ presentmentAmountUsed: {
153
+ amount: string;
154
+ currencyCode: string;
98
155
  };
99
156
  }[];
100
157
  };
@@ -1 +1 @@
1
- {"version":3,"file":"use-mock-cart.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-mock-cart.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAyH1C,KAAK,iBAAiB,GAAG;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,eAAO,MAAM,WAAW,uCAKrB,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BnB,CAAA"}
1
+ {"version":3,"file":"use-mock-cart.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-mock-cart.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAA;AAsLhF,KAAK,iBAAiB,GAAG;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,eAAO,MAAM,WAAW,uCAKrB,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sCAzGc,KAAK;2BAChB,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0I3B,CAAA"}
@@ -1,6 +1,8 @@
1
1
  "use client";
2
+ import { getCalculatedCartData } from "../../lib/cart.util";
2
3
  import { getIdFromGid } from "../../lib/utils";
3
4
  import { useProducts } from "./use-products";
5
+ import { DiscountApplicationTargetType } from "app-studio-types";
4
6
  const cartMock = {
5
7
  attributes: [{ key: "tapcart_id", value: "123" }],
6
8
  currency: "USD",
@@ -11,8 +13,8 @@ const cartMock = {
11
13
  subtotal: 0,
12
14
  discountAllocations: [
13
15
  {
14
- targetType: "SHIPPING_LINE",
15
- discountedAmount: { amount: "10.00" },
16
+ targetType: DiscountApplicationTargetType.ShippingLine,
17
+ discountedAmount: { amount: "10.00", currencyCode: "USD" },
16
18
  code: "FREE_SHIPPING",
17
19
  },
18
20
  ],
@@ -20,7 +22,9 @@ const cartMock = {
20
22
  {
21
23
  id: "gid://shopify/GiftCard/1",
22
24
  lastCharacters: "1234",
23
- amountUsed: { amount: "10.00" },
25
+ amountUsed: { amount: "10.00", currencyCode: "USD" },
26
+ balance: { amount: "40.00", currencyCode: "USD" },
27
+ presentmentAmountUsed: { amount: "10.00", currencyCode: "USD" },
24
28
  },
25
29
  ],
26
30
  };
@@ -55,16 +59,18 @@ const transformCart = ({ products, cartOrigin = cartMock, }) => {
55
59
  }
56
60
  const sellingPlanAllocation = i === 0
57
61
  ? {
58
- priceAdjustments: {
59
- perDeliveryPrice: {
60
- amount: price,
61
- currencyCode: "USD",
62
+ priceAdjustments: [
63
+ {
64
+ perDeliveryPrice: {
65
+ amount: price,
66
+ currencyCode: "USD",
67
+ },
68
+ price: {
69
+ amount: price,
70
+ currencyCode: "USD",
71
+ },
62
72
  },
63
- price: {
64
- amount: price,
65
- currencyCode: "USD",
66
- },
67
- },
73
+ ],
68
74
  sellingPlan: {
69
75
  id: "gid://shopify/SellingPlan/123",
70
76
  name: "Delivery every 30 Days",
@@ -73,6 +79,7 @@ const transformCart = ({ products, cartOrigin = cartMock, }) => {
73
79
  }
74
80
  : undefined;
75
81
  return {
82
+ id: `item-${i}`,
76
83
  discounts,
77
84
  productId,
78
85
  quantity: 1,
@@ -84,15 +91,62 @@ const transformCart = ({ products, cartOrigin = cartMock, }) => {
84
91
  };
85
92
  });
86
93
  const orderLevelDiscount = {
87
- targetType: "LINE_ITEM",
88
- discountedAmount: { amount: (subtotal / 10).toString() },
94
+ targetType: DiscountApplicationTargetType.LineItem,
95
+ discountedAmount: {
96
+ amount: (subtotal / 10).toString(),
97
+ currencyCode: "USD",
98
+ },
89
99
  code: "10_OFF_ORDER",
90
100
  };
101
+ const delivery = {
102
+ addresses: [
103
+ {
104
+ selected: true,
105
+ oneTimeUse: false,
106
+ id: "mock-delivery-address-id",
107
+ address: {
108
+ address1: "123 Mock St",
109
+ city: "Mock City",
110
+ countryCode: "US",
111
+ },
112
+ },
113
+ ],
114
+ };
115
+ const deliveryGroups = [
116
+ {
117
+ id: "mock-delivery-group-id",
118
+ deliveryOptions: [
119
+ {
120
+ code: "mock-code",
121
+ handle: "mock-handle",
122
+ title: "Mock Delivery Option",
123
+ deliveryMethodType: "standard",
124
+ description: "Mock delivery description",
125
+ estimatedCost: { amount: "5.00", currencyCode: "USD" },
126
+ },
127
+ ],
128
+ selectedDeliveryOption: {
129
+ code: "mock-code",
130
+ handle: "mock-handle",
131
+ title: "Mock Delivery Option",
132
+ deliveryMethodType: "standard",
133
+ description: "Mock delivery description",
134
+ estimatedCost: { amount: "5.00", currencyCode: "USD" },
135
+ },
136
+ },
137
+ ];
138
+ const cost = {
139
+ subtotalAmount: { amount: subtotal.toString(), currencyCode: "USD" },
140
+ totalAmount: { amount: (subtotal + 5).toString(), currencyCode: "USD" },
141
+ totalTaxAmount: { amount: "0.00", currencyCode: "USD" },
142
+ };
91
143
  return Object.assign(Object.assign({}, cartOrigin), { subtotal,
92
144
  items, discountAllocations: [
93
145
  ...cartOrigin.discountAllocations,
94
146
  orderLevelDiscount,
95
- ] });
147
+ ], delivery,
148
+ deliveryGroups,
149
+ cost });
96
150
  };
97
151
  export const useMockCart = ({ apiUrl, appId, enabled = true, limit = 1, }) => {
98
152
  const { products, error: productsError, isLoading: productsLoading, } = useProducts({
@@ -116,6 +170,6 @@ export const useMockCart = ({ apiUrl, appId, enabled = true, limit = 1, }) => {
116
170
  return {
117
171
  error: productsError,
118
172
  isLoading: productsLoading,
119
- cart,
173
+ cart: Object.assign(Object.assign({}, cart), { calculatedData: getCalculatedCartData(cart) }),
120
174
  };
121
175
  };
@@ -1,8 +1,8 @@
1
- import React from "react"
1
+ import React from "react";
2
2
  declare const useTap: (tapThreshold?: number) => {
3
- onTap: (handler: (event: any) => void) => (event: any) => void
4
- isPressed: boolean
5
- ref: React.MutableRefObject<null>
6
- }
7
- export { useTap }
8
- //# sourceMappingURL=use-tap.d.ts.map
3
+ onTap: (handler: (event: any) => void) => (event: any) => void;
4
+ isPressed: boolean;
5
+ ref: React.MutableRefObject<null>;
6
+ };
7
+ export { useTap };
8
+ //# sourceMappingURL=use-tap.d.ts.map
@@ -1,100 +1,100 @@
1
- "use client"
2
- import { useState, useEffect, useCallback, useRef } from "react"
1
+ "use client";
2
+ import { useState, useEffect, useCallback, useRef } from "react";
3
3
  // Shared manager for all instances of the hook
4
4
  const tapManager = (() => {
5
- const elements = new Map()
6
- let isListening = false
7
- const startListening = () => {
8
- if (isListening) return
9
- const handleTouchStart = (e) => {
10
- const touch = e.touches[0]
11
- elements.forEach((data, el) => {
12
- if (el.contains(touch.target)) {
13
- data.touchStarted = true
14
- data.touchMoved = false
15
- data.startPosition = { x: touch.clientX, y: touch.clientY }
16
- // Don't set isPressed here, wait to determine if it's a tap or drag
17
- }
18
- })
19
- }
20
- const handleTouchMove = (e) => {
21
- const touch = e.touches[0]
22
- elements.forEach((data, el) => {
23
- if (data.touchStarted) {
24
- const deltaX = Math.abs(touch.clientX - data.startPosition.x)
25
- const deltaY = Math.abs(touch.clientY - data.startPosition.y)
26
- if (deltaX > data.tapThreshold || deltaY > data.tapThreshold) {
27
- data.touchMoved = true
28
- data.setIsPressed(false)
29
- }
30
- }
31
- })
32
- }
33
- const handleTouchEnd = () => {
34
- elements.forEach((data) => {
35
- if (data.touchStarted) {
36
- data.touchStarted = false
37
- if (!data.touchMoved) {
38
- // It's a tap, set isPressed briefly
39
- data.setIsPressed(true)
40
- setTimeout(() => data.setIsPressed(false), 100)
41
- }
42
- }
43
- })
44
- }
45
- document.addEventListener("touchstart", (e) => handleTouchStart(e), {
46
- passive: true,
47
- })
48
- document.addEventListener("touchmove", (e) => handleTouchMove(e), {
49
- passive: true,
50
- })
51
- document.addEventListener("touchend", () => handleTouchEnd(), {
52
- passive: true,
53
- })
54
- isListening = true
55
- }
56
- return {
57
- register: (el, data) => {
58
- elements.set(el, data)
59
- startListening()
60
- },
61
- unregister: (el) => {
62
- elements.delete(el)
63
- },
64
- elements,
65
- }
66
- })()
5
+ const elements = new Map();
6
+ let isListening = false;
7
+ const startListening = () => {
8
+ if (isListening)
9
+ return;
10
+ const handleTouchStart = (e) => {
11
+ const touch = e.touches[0];
12
+ elements.forEach((data, el) => {
13
+ if (el.contains(touch.target)) {
14
+ data.touchStarted = true;
15
+ data.touchMoved = false;
16
+ data.startPosition = { x: touch.clientX, y: touch.clientY };
17
+ // Don't set isPressed here, wait to determine if it's a tap or drag
18
+ }
19
+ });
20
+ };
21
+ const handleTouchMove = (e) => {
22
+ const touch = e.touches[0];
23
+ elements.forEach((data, el) => {
24
+ if (data.touchStarted) {
25
+ const deltaX = Math.abs(touch.clientX - data.startPosition.x);
26
+ const deltaY = Math.abs(touch.clientY - data.startPosition.y);
27
+ if (deltaX > data.tapThreshold || deltaY > data.tapThreshold) {
28
+ data.touchMoved = true;
29
+ data.setIsPressed(false);
30
+ }
31
+ }
32
+ });
33
+ };
34
+ const handleTouchEnd = () => {
35
+ elements.forEach((data) => {
36
+ if (data.touchStarted) {
37
+ data.touchStarted = false;
38
+ if (!data.touchMoved) {
39
+ // It's a tap, set isPressed briefly
40
+ data.setIsPressed(true);
41
+ setTimeout(() => data.setIsPressed(false), 100);
42
+ }
43
+ }
44
+ });
45
+ };
46
+ document.addEventListener("touchstart", (e) => handleTouchStart(e), { passive: true });
47
+ document.addEventListener("touchmove", (e) => handleTouchMove(e), { passive: true });
48
+ document.addEventListener("touchend", () => handleTouchEnd(), {
49
+ passive: true,
50
+ });
51
+ isListening = true;
52
+ };
53
+ return {
54
+ register: (el, data) => {
55
+ elements.set(el, data);
56
+ startListening();
57
+ },
58
+ unregister: (el) => {
59
+ elements.delete(el);
60
+ },
61
+ elements,
62
+ };
63
+ })();
67
64
  const useTap = (tapThreshold = 10) => {
68
- const [isPressed, setIsPressed] = useState(false)
69
- const elementRef = useRef(null)
70
- useEffect(() => {
71
- const element = elementRef.current
72
- if (!element) return
73
- const data = {
74
- touchStarted: false,
75
- touchMoved: false,
76
- startPosition: { x: 0, y: 0 },
77
- setIsPressed,
78
- tapThreshold,
79
- }
80
- tapManager.register(element, data)
81
- return () => {
82
- tapManager.unregister(element)
83
- }
84
- }, [tapThreshold])
85
- const onTap = useCallback((handler) => {
86
- return (event) => {
87
- const data = tapManager.elements.get(elementRef.current)
88
- if (!data) return
89
- if (event.type === "touchend" && !data.touchMoved) {
90
- handler(event)
91
- } else if (event.type === "click" && !data.touchStarted) {
92
- handler(event)
93
- setIsPressed(true)
94
- setTimeout(() => setIsPressed(false), 100)
95
- }
96
- }
97
- }, [])
98
- return { onTap, isPressed, ref: elementRef }
99
- }
100
- export { useTap }
65
+ const [isPressed, setIsPressed] = useState(false);
66
+ const elementRef = useRef(null);
67
+ useEffect(() => {
68
+ const element = elementRef.current;
69
+ if (!element)
70
+ return;
71
+ const data = {
72
+ touchStarted: false,
73
+ touchMoved: false,
74
+ startPosition: { x: 0, y: 0 },
75
+ setIsPressed,
76
+ tapThreshold,
77
+ };
78
+ tapManager.register(element, data);
79
+ return () => {
80
+ tapManager.unregister(element);
81
+ };
82
+ }, [tapThreshold]);
83
+ const onTap = useCallback((handler) => {
84
+ return (event) => {
85
+ const data = tapManager.elements.get(elementRef.current);
86
+ if (!data)
87
+ return;
88
+ if (event.type === "touchend" && !data.touchMoved) {
89
+ handler(event);
90
+ }
91
+ else if (event.type === "click" && !data.touchStarted) {
92
+ handler(event);
93
+ setIsPressed(true);
94
+ setTimeout(() => setIsPressed(false), 100);
95
+ }
96
+ };
97
+ }, []);
98
+ return { onTap, isPressed, ref: elementRef };
99
+ };
100
+ export { useTap };
@@ -17,13 +17,20 @@ export interface ApplePayButtonProps extends React.ButtonHTMLAttributes<HTMLButt
17
17
  supportedNetworks?: string[];
18
18
  buttonType?: ApplePayButtonType;
19
19
  buttonStyle?: ApplePayButtonStyle;
20
+ applePayButtonStyle?: {
21
+ width?: string | undefined;
22
+ height?: string | undefined;
23
+ borderRadius?: string | undefined;
24
+ padding?: string | undefined;
25
+ boxSizing?: string | undefined;
26
+ } | undefined;
20
27
  onPaymentAuthorized?: (paymentData: ApplePayJS.ApplePayPayment) => Promise<boolean>;
21
28
  onShippingContactSelected?: (shippingContact: ApplePayJS.ApplePayPaymentContact) => Promise<ApplePayJS.ApplePayShippingMethodUpdate>;
22
29
  onShippingMethodSelected?: (shippingMethod: ApplePayJS.ApplePayShippingMethod) => Promise<ApplePayJS.ApplePayShippingMethodUpdate>;
23
30
  onPaymentCancelled?: (event?: ApplePayJS.Event) => void;
24
31
  }
25
32
  declare const ApplePayButton: {
26
- ({ displayName, amount, requiredBillingContactFields, requiredShippingContactFields, startSessionURL, startSessionCacheBypass, appId, domainName, countryCode, currencyCode, merchantCapabilities, supportedNetworks, buttonType, buttonStyle, onPaymentAuthorized, onShippingContactSelected, onShippingMethodSelected, onPaymentCancelled, }: ApplePayButtonProps): import("react/jsx-runtime").JSX.Element;
33
+ ({ displayName, amount, requiredBillingContactFields, requiredShippingContactFields, startSessionURL, startSessionCacheBypass, appId, domainName, countryCode, currencyCode, merchantCapabilities, supportedNetworks, buttonType, buttonStyle, applePayButtonStyle, onPaymentAuthorized, onShippingContactSelected, onShippingMethodSelected, onPaymentCancelled, }: ApplePayButtonProps): import("react/jsx-runtime").JSX.Element;
27
34
  displayName: string;
28
35
  };
29
36
  export { ApplePayButton };
@@ -1 +1 @@
1
- {"version":3,"file":"apple-pay-button.d.ts","sourceRoot":"","sources":["../../../components/ui/apple-pay-button.tsx"],"names":[],"mappings":";AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,MAAM,MAAM,kBAAkB,GAC1B,OAAO,GACP,WAAW,GACX,MAAM,GACN,KAAK,GACL,WAAW,GACX,UAAU,GACV,YAAY,GACZ,QAAQ,GACR,OAAO,GACP,KAAK,GACL,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,WAAW,GACX,SAAS,GACT,KAAK,GACL,QAAQ,CAAA;AAEZ,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,OAAO,GAAG,eAAe,CAAA;AAErE,MAAM,WAAW,mBACf,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IACrD,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,4BAA4B,CAAC,EAAE,UAAU,CAAC,oBAAoB,EAAE,CAAA;IAChE,6BAA6B,CAAC,EAAE,UAAU,CAAC,oBAAoB,EAAE,CAAA;IACjE,eAAe,EAAE,MAAM,CAAA;IACvB,uBAAuB,EAAE,OAAO,CAAA;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,oBAAoB,CAAC,EAAE,UAAU,CAAC,0BAA0B,EAAE,CAAA;IAC9D,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,UAAU,CAAC,EAAE,kBAAkB,CAAA;IAC/B,WAAW,CAAC,EAAE,mBAAmB,CAAA;IACjC,mBAAmB,CAAC,EAAE,CACpB,WAAW,EAAE,UAAU,CAAC,eAAe,KACpC,OAAO,CAAC,OAAO,CAAC,CAAA;IACrB,yBAAyB,CAAC,EAAE,CAC1B,eAAe,EAAE,UAAU,CAAC,sBAAsB,KAC/C,OAAO,CAAC,UAAU,CAAC,4BAA4B,CAAC,CAAA;IACrD,wBAAwB,CAAC,EAAE,CACzB,cAAc,EAAE,UAAU,CAAC,sBAAsB,KAC9C,OAAO,CAAC,UAAU,CAAC,4BAA4B,CAAC,CAAA;IACrD,kBAAkB,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,KAAK,KAAK,IAAI,CAAA;CACxD;AAED,QAAA,MAAM,cAAc;oVAmBjB,mBAAmB;;CAyKrB,CAAA;AAID,OAAO,EAAE,cAAc,EAAE,CAAA"}
1
+ {"version":3,"file":"apple-pay-button.d.ts","sourceRoot":"","sources":["../../../components/ui/apple-pay-button.tsx"],"names":[],"mappings":";AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,MAAM,MAAM,kBAAkB,GAC1B,OAAO,GACP,WAAW,GACX,MAAM,GACN,KAAK,GACL,WAAW,GACX,UAAU,GACV,YAAY,GACZ,QAAQ,GACR,OAAO,GACP,KAAK,GACL,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,WAAW,GACX,SAAS,GACT,KAAK,GACL,QAAQ,CAAA;AAEZ,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,OAAO,GAAG,eAAe,CAAA;AAErE,MAAM,WAAW,mBACf,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IACrD,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,4BAA4B,CAAC,EAAE,UAAU,CAAC,oBAAoB,EAAE,CAAA;IAChE,6BAA6B,CAAC,EAAE,UAAU,CAAC,oBAAoB,EAAE,CAAA;IACjE,eAAe,EAAE,MAAM,CAAA;IACvB,uBAAuB,EAAE,OAAO,CAAA;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,oBAAoB,CAAC,EAAE,UAAU,CAAC,0BAA0B,EAAE,CAAA;IAC9D,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,UAAU,CAAC,EAAE,kBAAkB,CAAA;IAC/B,WAAW,CAAC,EAAE,mBAAmB,CAAA;IACjC,mBAAmB,CAAC,EAChB;QACE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAC3B,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QACjC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAC/B,GACD,SAAS,CAAA;IACb,mBAAmB,CAAC,EAAE,CACpB,WAAW,EAAE,UAAU,CAAC,eAAe,KACpC,OAAO,CAAC,OAAO,CAAC,CAAA;IACrB,yBAAyB,CAAC,EAAE,CAC1B,eAAe,EAAE,UAAU,CAAC,sBAAsB,KAC/C,OAAO,CAAC,UAAU,CAAC,4BAA4B,CAAC,CAAA;IACrD,wBAAwB,CAAC,EAAE,CACzB,cAAc,EAAE,UAAU,CAAC,sBAAsB,KAC9C,OAAO,CAAC,UAAU,CAAC,4BAA4B,CAAC,CAAA;IACrD,kBAAkB,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,KAAK,KAAK,IAAI,CAAA;CACxD;AAED,QAAA,MAAM,cAAc;yWAoBjB,mBAAmB;;CAsKrB,CAAA;AAID,OAAO,EAAE,cAAc,EAAE,CAAA"}
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  import { jsx as _jsx } from "react/jsx-runtime";
12
12
  import ApplePayButtonComponent from "apple-pay-button";
13
- const ApplePayButton = ({ displayName, amount, requiredBillingContactFields = ["name", "postalAddress", "phone", "email"], requiredShippingContactFields = ["name", "postalAddress", "phone", "email"], startSessionURL, startSessionCacheBypass = false, appId, domainName, countryCode = "US", currencyCode = "USD", merchantCapabilities = ["supports3DS"], supportedNetworks = ["visa", "masterCard", "amex", "discover"], buttonType = "plain", buttonStyle = "white-outline", onPaymentAuthorized, onShippingContactSelected, onShippingMethodSelected, onPaymentCancelled, }) => {
13
+ const ApplePayButton = ({ displayName, amount, requiredBillingContactFields = ["name", "postalAddress", "phone", "email"], requiredShippingContactFields = ["name", "postalAddress", "phone", "email"], startSessionURL, startSessionCacheBypass = false, appId, domainName, countryCode = "US", currencyCode = "USD", merchantCapabilities = ["supports3DS"], supportedNetworks = ["visa", "masterCard", "amex", "discover"], buttonType = "plain", buttonStyle = "white-outline", applePayButtonStyle, onPaymentAuthorized, onShippingContactSelected, onShippingMethodSelected, onPaymentCancelled, }) => {
14
14
  const onClick = () => {
15
15
  const applePayRequest = {
16
16
  countryCode,
@@ -127,10 +127,7 @@ const ApplePayButton = ({ displayName, amount, requiredBillingContactFields = ["
127
127
  console.log("Session Cancelled.", event);
128
128
  };
129
129
  };
130
- return (_jsx(ApplePayButtonComponent, { onClick: onClick, style: {
131
- height: "48px",
132
- borderRadius: "4px",
133
- }, type: buttonType, buttonStyle: buttonStyle }));
130
+ return (_jsx(ApplePayButtonComponent, { onClick: onClick, style: applePayButtonStyle, type: buttonType, buttonStyle: buttonStyle }));
134
131
  };
135
132
  ApplePayButton.displayName = "ApplePayButton";
136
133
  export { ApplePayButton };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { cn, cva, getColor, getBackgroundAndPaddingStyle, getBorderStyle, getBorderSidesStyle, getTextStyle, getVerticalAlignmentStyle, getBackgroundAndSpacingStyle, getIdFromGid, productGidFromId, variantGidFromId, getPaddingStyle, getMarginStyle, getVerticalAlignment, mapFlexToAlignment, formatRelativeTime, stringRatioToInt, getOverlayStyle, throttleFunction, getDestinationHandler, getProductGidsFromIds, createCollectionImageMap, isFavoriteIntegrationEnabled, getSpaceBetween, getGridSpacing, pluralize, getInputPlaceholderTextProps, } from "./lib/utils";
2
+ export * from "./lib/cart.util";
2
3
  export * from "./components/contexts/translation-context";
3
4
  export * from "./components/hooks/use-collection";
4
5
  export * from "./components/hooks/use-infinite-scroll";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,EAAE,EACF,GAAG,EACH,QAAQ,EACR,4BAA4B,EAC5B,cAAc,EACd,mBAAmB,EACnB,YAAY,EACZ,yBAAyB,EACzB,4BAA4B,EAC5B,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,4BAA4B,EAC5B,eAAe,EACf,cAAc,EACd,SAAS,EACT,4BAA4B,GAC7B,MAAM,aAAa,CAAA;AACpB,cAAc,2CAA2C,CAAA;AACzD,cAAc,mCAAmC,CAAA;AACjD,cAAc,wCAAwC,CAAA;AACtD,cAAc,wCAAwC,CAAA;AACtD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,sCAAsC,CAAA;AACpD,cAAc,yCAAyC,CAAA;AACvD,cAAc,oCAAoC,CAAA;AAClD,cAAc,wCAAwC,CAAA;AACtD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,sCAAsC,CAAA;AACpD,cAAc,oDAAoD,CAAA;AAClE,cAAc,kCAAkC,CAAA;AAChD,cAAc,2BAA2B,CAAA;AACzC,cAAc,kCAAkC,CAAA;AAChD,cAAc,8BAA8B,CAAA;AAC5C,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA;AACtC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,2BAA2B,CAAA;AACzC,cAAc,wBAAwB,CAAA;AACtC,cAAc,0BAA0B,CAAA;AACxC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,uBAAuB,CAAA;AACrC,cAAc,sCAAsC,CAAA;AACpD,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,2BAA2B,CAAA;AACzC,cAAc,2BAA2B,CAAA;AACzC,cAAc,0BAA0B,CAAA;AACxC,cAAc,wBAAwB,CAAA;AACtC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,wBAAwB,CAAA;AACtC,cAAc,2BAA2B,CAAA;AACzC,cAAc,uBAAuB,CAAA;AACrC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,sBAAsB,CAAA;AACpC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,kDAAkD,CAAA;AAChE,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oCAAoC,CAAA;AAClD,cAAc,mCAAmC,CAAA;AACjD,cAAc,aAAa,CAAA;AAC3B,cAAc,6CAA6C,CAAA;AAC3D,cAAc,kDAAkD,CAAA;AAChE,cAAc,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,EAAE,EACF,GAAG,EACH,QAAQ,EACR,4BAA4B,EAC5B,cAAc,EACd,mBAAmB,EACnB,YAAY,EACZ,yBAAyB,EACzB,4BAA4B,EAC5B,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,4BAA4B,EAC5B,eAAe,EACf,cAAc,EACd,SAAS,EACT,4BAA4B,GAC7B,MAAM,aAAa,CAAA;AACpB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,2CAA2C,CAAA;AACzD,cAAc,mCAAmC,CAAA;AACjD,cAAc,wCAAwC,CAAA;AACtD,cAAc,wCAAwC,CAAA;AACtD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,sCAAsC,CAAA;AACpD,cAAc,yCAAyC,CAAA;AACvD,cAAc,oCAAoC,CAAA;AAClD,cAAc,wCAAwC,CAAA;AACtD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,sCAAsC,CAAA;AACpD,cAAc,oDAAoD,CAAA;AAClE,cAAc,kCAAkC,CAAA;AAChD,cAAc,2BAA2B,CAAA;AACzC,cAAc,kCAAkC,CAAA;AAChD,cAAc,8BAA8B,CAAA;AAC5C,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA;AACtC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,2BAA2B,CAAA;AACzC,cAAc,wBAAwB,CAAA;AACtC,cAAc,0BAA0B,CAAA;AACxC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,uBAAuB,CAAA;AACrC,cAAc,sCAAsC,CAAA;AACpD,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,2BAA2B,CAAA;AACzC,cAAc,2BAA2B,CAAA;AACzC,cAAc,0BAA0B,CAAA;AACxC,cAAc,wBAAwB,CAAA;AACtC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,wBAAwB,CAAA;AACtC,cAAc,2BAA2B,CAAA;AACzC,cAAc,uBAAuB,CAAA;AACrC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,sBAAsB,CAAA;AACpC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,kDAAkD,CAAA;AAChE,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oCAAoC,CAAA;AAClD,cAAc,mCAAmC,CAAA;AACjD,cAAc,aAAa,CAAA;AAC3B,cAAc,6CAA6C,CAAA;AAC3D,cAAc,kDAAkD,CAAA;AAChE,cAAc,qBAAqB,CAAA"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // component exports
2
2
  export { cn, cva, getColor, getBackgroundAndPaddingStyle, getBorderStyle, getBorderSidesStyle, getTextStyle, getVerticalAlignmentStyle, getBackgroundAndSpacingStyle, getIdFromGid, productGidFromId, variantGidFromId, getPaddingStyle, getMarginStyle, getVerticalAlignment, mapFlexToAlignment, formatRelativeTime, stringRatioToInt, getOverlayStyle, throttleFunction, getDestinationHandler, getProductGidsFromIds, createCollectionImageMap, isFavoriteIntegrationEnabled, getSpaceBetween, getGridSpacing, pluralize, getInputPlaceholderTextProps, } from "./lib/utils";
3
+ export * from "./lib/cart.util";
3
4
  export * from "./components/contexts/translation-context";
4
5
  export * from "./components/hooks/use-collection";
5
6
  export * from "./components/hooks/use-infinite-scroll";
@@ -0,0 +1,16 @@
1
+ import { EnrichedCart, CartCalculatedDiscount, CartCalculatedAppliedGiftCard } from "app-studio-types";
2
+ export declare const isOrderLevelDiscount: (code: string, cart: EnrichedCart) => boolean;
3
+ export declare const isLineItemDiscount: (code: string, cart: EnrichedCart) => boolean;
4
+ export type CalculatedData = {
5
+ orderAndLineItemDiscounts: CartCalculatedDiscount[];
6
+ appliedGiftCards: CartCalculatedAppliedGiftCard[];
7
+ isFreeShipping: boolean;
8
+ discountsTotalAmount: number;
9
+ giftCardsTotalAmount: number;
10
+ salesAmount: number;
11
+ totalCompareAtPrice: number;
12
+ totalDiscountedPrice: number;
13
+ };
14
+ export declare const DEFAULT_CALCULATED_DATA: CalculatedData;
15
+ export declare const getCalculatedCartData: (cart: EnrichedCart) => CalculatedData;
16
+ //# sourceMappingURL=cart.util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cart.util.d.ts","sourceRoot":"","sources":["../../lib/cart.util.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,6BAA6B,EAC9B,MAAM,kBAAkB,CAAA;AAuCzB,eAAO,MAAM,oBAAoB,SAAU,MAAM,QAAQ,YAAY,YAGpE,CAAA;AAED,eAAO,MAAM,kBAAkB,SAAU,MAAM,QAAQ,YAAY,YAGlE,CAAA;AAgGD,MAAM,MAAM,cAAc,GAAG;IAC3B,yBAAyB,EAAE,sBAAsB,EAAE,CAAA;IACnD,gBAAgB,EAAE,6BAA6B,EAAE,CAAA;IACjD,cAAc,EAAE,OAAO,CAAA;IACvB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,oBAAoB,EAAE,MAAM,CAAA;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,oBAAoB,EAAE,MAAM,CAAA;CAC7B,CAAA;AAED,eAAO,MAAM,uBAAuB,EAAE,cASrC,CAAA;AAED,eAAO,MAAM,qBAAqB,SAAU,YAAY,KAAG,cA4B1D,CAAA"}
@@ -0,0 +1,144 @@
1
+ const getOrderLevelDiscounts = (cart) => {
2
+ var _a;
3
+ const discountMap = (_a = cart.discountAllocations) === null || _a === void 0 ? void 0 : _a.filter((discount) => discount.targetType !== "SHIPPING_LINE").reduce((acc, discount) => {
4
+ var _a;
5
+ const code = (_a = discount.code) !== null && _a !== void 0 ? _a : "unknown";
6
+ if (!acc[code]) {
7
+ acc[code] = 0;
8
+ }
9
+ acc[code] += parseFloat(discount.discountedAmount.amount);
10
+ return acc;
11
+ }, {});
12
+ if (!discountMap)
13
+ return [];
14
+ return Object.entries(discountMap)
15
+ .map(([code, amount]) => ({
16
+ id: code,
17
+ amount,
18
+ name: `Discount - ${code}`,
19
+ type: "ORDER_LEVEL",
20
+ }))
21
+ .filter((discount) => cart.discounts.includes(discount.id));
22
+ };
23
+ const getShippingDiscounts = (cart) => {
24
+ var _a;
25
+ if (!(cart === null || cart === void 0 ? void 0 : cart.discountAllocations))
26
+ return [];
27
+ return (_a = cart.discountAllocations) === null || _a === void 0 ? void 0 : _a.filter((discount) => discount.targetType === "SHIPPING_LINE").map((discount) => ({
28
+ amount: discount.discountedAmount.amount,
29
+ code: discount.code,
30
+ type: discount.targetType,
31
+ }));
32
+ };
33
+ export const isOrderLevelDiscount = (code, cart) => {
34
+ const orderLevelDiscounts = getOrderLevelDiscounts(cart);
35
+ return orderLevelDiscounts.some((discount) => discount.id === code);
36
+ };
37
+ export const isLineItemDiscount = (code, cart) => {
38
+ const lineItemDiscounts = getLineItemDiscounts(cart);
39
+ return lineItemDiscounts.some((discount) => discount.id === code);
40
+ };
41
+ const getAppliedGiftCards = (cart) => {
42
+ var _a;
43
+ return (_a = cart.appliedGiftCards) === null || _a === void 0 ? void 0 : _a.map((giftCard) => ({
44
+ id: giftCard.id,
45
+ amount: +giftCard.amountUsed.amount,
46
+ name: `Gift Card - ${giftCard.lastCharacters}`,
47
+ }));
48
+ };
49
+ const getSalesAmount = (cart) => {
50
+ var _a;
51
+ return (_a = cart.items) === null || _a === void 0 ? void 0 : _a.reduce((acc, item) => {
52
+ var _a, _b, _c, _d;
53
+ const compareAtPrice = +(((_b = (_a = item.variantDetails) === null || _a === void 0 ? void 0 : _a.compareAtPrice) === null || _b === void 0 ? void 0 : _b.amount) || 0);
54
+ const price = +(((_d = (_c = item.variantDetails) === null || _c === void 0 ? void 0 : _c.price) === null || _d === void 0 ? void 0 : _d.amount) || 0);
55
+ const quantity = item.quantity || 1;
56
+ if (compareAtPrice && compareAtPrice > price) {
57
+ return acc + (compareAtPrice - price) * quantity;
58
+ }
59
+ return acc;
60
+ }, 0);
61
+ };
62
+ const getLineItemDiscounts = (cart) => {
63
+ var _a, _b;
64
+ const discountMap = (_a = cart.items) === null || _a === void 0 ? void 0 : _a.reduce((acc, item) => {
65
+ var _a;
66
+ (_a = item === null || item === void 0 ? void 0 : item.discounts) === null || _a === void 0 ? void 0 : _a.forEach((discount) => {
67
+ const code = discount === null || discount === void 0 ? void 0 : discount.code;
68
+ if (!code)
69
+ return;
70
+ if (!acc[code]) {
71
+ acc[code] = { amount: 0, type: discount.type };
72
+ }
73
+ acc[code].amount += discount.amount;
74
+ });
75
+ return acc;
76
+ }, {});
77
+ if (!discountMap)
78
+ return [];
79
+ return (_b = Object.entries(discountMap)) === null || _b === void 0 ? void 0 : _b.map(([code, { amount, type }]) => ({
80
+ id: code,
81
+ name: `Discount - ${code}`,
82
+ amount,
83
+ type,
84
+ })).filter((discount) => cart.discounts.includes(discount.id));
85
+ };
86
+ const getDiscountsTotalAmount = (orderAndLineItemDiscounts) => {
87
+ return orderAndLineItemDiscounts === null || orderAndLineItemDiscounts === void 0 ? void 0 : orderAndLineItemDiscounts.reduce((acc, discount) => acc + +discount.amount, 0);
88
+ };
89
+ const getGiftCardsTotalAmount = (appliedGiftCards) => {
90
+ return appliedGiftCards === null || appliedGiftCards === void 0 ? void 0 : appliedGiftCards.reduce((acc, giftCard) => acc + +giftCard.amount, 0);
91
+ };
92
+ const getTotalCompareAtPrice = (cart) => {
93
+ var _a;
94
+ return (_a = cart.items) === null || _a === void 0 ? void 0 : _a.reduce((acc, item) => {
95
+ var _a, _b, _c, _d;
96
+ const compareAtPrice = ((_b = (_a = item.variantDetails) === null || _a === void 0 ? void 0 : _a.compareAtPrice) === null || _b === void 0 ? void 0 : _b.amount) ||
97
+ ((_d = (_c = item.variantDetails) === null || _c === void 0 ? void 0 : _c.price) === null || _d === void 0 ? void 0 : _d.amount);
98
+ const quantity = item.quantity || 1;
99
+ return acc + +(compareAtPrice || 0) * quantity;
100
+ }, 0);
101
+ };
102
+ const getTotalDiscountedPrice = (totalCompareAtPrice, discountsTotalAmount, salesAmount, giftCardsTotalAmount) => {
103
+ const total = (totalCompareAtPrice === undefined || isNaN(totalCompareAtPrice)
104
+ ? 0
105
+ : totalCompareAtPrice) -
106
+ (discountsTotalAmount === undefined || isNaN(discountsTotalAmount)
107
+ ? 0
108
+ : discountsTotalAmount) -
109
+ (salesAmount === undefined || isNaN(salesAmount) ? 0 : salesAmount) -
110
+ (giftCardsTotalAmount === undefined || isNaN(giftCardsTotalAmount)
111
+ ? 0
112
+ : giftCardsTotalAmount);
113
+ return isNaN(total) ? 0 : total;
114
+ };
115
+ export const DEFAULT_CALCULATED_DATA = {
116
+ orderAndLineItemDiscounts: [],
117
+ appliedGiftCards: [],
118
+ isFreeShipping: false,
119
+ discountsTotalAmount: 0,
120
+ salesAmount: 0,
121
+ giftCardsTotalAmount: 0,
122
+ totalCompareAtPrice: 0,
123
+ totalDiscountedPrice: 0,
124
+ };
125
+ export const getCalculatedCartData = (cart) => {
126
+ const orderAndLineItemDiscounts = getOrderLevelDiscounts(cart).concat(getLineItemDiscounts(cart));
127
+ const appliedGiftCards = getAppliedGiftCards(cart);
128
+ const isFreeShipping = getShippingDiscounts(cart).length > 0;
129
+ const discountsTotalAmount = getDiscountsTotalAmount(orderAndLineItemDiscounts);
130
+ const giftCardsTotalAmount = getGiftCardsTotalAmount(appliedGiftCards);
131
+ const salesAmount = getSalesAmount(cart);
132
+ const totalCompareAtPrice = getTotalCompareAtPrice(cart);
133
+ const totalDiscountedPrice = getTotalDiscountedPrice(totalCompareAtPrice, discountsTotalAmount, salesAmount, giftCardsTotalAmount);
134
+ return {
135
+ orderAndLineItemDiscounts,
136
+ appliedGiftCards,
137
+ isFreeShipping,
138
+ discountsTotalAmount,
139
+ giftCardsTotalAmount,
140
+ salesAmount,
141
+ totalCompareAtPrice,
142
+ totalDiscountedPrice,
143
+ };
144
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cart.util.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cart.util.test.d.ts","sourceRoot":"","sources":["../../lib/cart.util.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,150 @@
1
+ import { getCalculatedCartData } from "./cart.util";
2
+ import { DiscountApplicationTargetType } from "app-studio-types";
3
+ const baseCartData = {
4
+ id: "cart123",
5
+ subtotal: 100.0,
6
+ currency: "USD",
7
+ discounts: [],
8
+ attributes: [],
9
+ note: "",
10
+ items: [],
11
+ discountAllocations: [],
12
+ appliedGiftCards: [],
13
+ delivery: {
14
+ addresses: [],
15
+ },
16
+ deliveryGroups: [],
17
+ cost: {
18
+ subtotalAmount: { amount: "0", currencyCode: "" },
19
+ totalAmount: { amount: "0", currencyCode: "" },
20
+ totalTaxAmount: { amount: "0", currencyCode: "" },
21
+ },
22
+ };
23
+ describe("cart-provider.util", () => {
24
+ describe("getData", () => {
25
+ it("should calculate order level discounts correctly", () => {
26
+ const mockCart = Object.assign(Object.assign({}, baseCartData), { discounts: ["DISCOUNT10"], items: [], discountAllocations: [
27
+ {
28
+ targetType: DiscountApplicationTargetType.LineItem,
29
+ discountedAmount: { amount: "10.00", currencyCode: "USD" },
30
+ code: "DISCOUNT10",
31
+ },
32
+ ], appliedGiftCards: [], deliveryGroups: [] });
33
+ const result = getCalculatedCartData(mockCart);
34
+ expect(result.orderAndLineItemDiscounts).toHaveLength(1);
35
+ expect(result.orderAndLineItemDiscounts[0]).toEqual({
36
+ id: "DISCOUNT10",
37
+ amount: 10,
38
+ name: "Discount - DISCOUNT10",
39
+ type: "ORDER_LEVEL",
40
+ });
41
+ });
42
+ it("should calculate gift cards correctly", () => {
43
+ const mockCart = Object.assign(Object.assign({}, baseCartData), { discounts: [], items: [], discountAllocations: [], appliedGiftCards: [
44
+ {
45
+ id: "giftcard1",
46
+ amountUsed: { amount: "25.00", currencyCode: "USD" },
47
+ balance: { amount: "75.00", currencyCode: "USD" },
48
+ lastCharacters: "1234",
49
+ presentmentAmountUsed: { amount: "25.00", currencyCode: "USD" },
50
+ },
51
+ ], deliveryGroups: [] });
52
+ const result = getCalculatedCartData(mockCart);
53
+ expect(result.appliedGiftCards).toHaveLength(1);
54
+ expect(result.appliedGiftCards[0]).toEqual({
55
+ id: "giftcard1",
56
+ amount: 25,
57
+ name: "Gift Card - 1234",
58
+ });
59
+ });
60
+ it("should calculate sales amount correctly", () => {
61
+ const mockCart = Object.assign(Object.assign({}, baseCartData), { discounts: [], items: [
62
+ {
63
+ id: "line1",
64
+ quantity: 2,
65
+ productId: "prod1",
66
+ variantId: "var1",
67
+ productDetails: {},
68
+ variantDetails: {
69
+ compareAtPrice: { amount: "20.00", currencyCode: "USD" },
70
+ price: { amount: "15.00", currencyCode: "USD" },
71
+ },
72
+ discounts: [],
73
+ cost: { totalAmount: { amount: "30.00", currencyCode: "USD" } },
74
+ },
75
+ ], discountAllocations: [], appliedGiftCards: [], deliveryGroups: [] });
76
+ const result = getCalculatedCartData(mockCart);
77
+ expect(result.salesAmount).toBe(10); // (20-15) * 2
78
+ });
79
+ it("should detect free shipping", () => {
80
+ const mockCart = Object.assign(Object.assign({}, baseCartData), { discounts: [], items: [], discountAllocations: [
81
+ {
82
+ targetType: DiscountApplicationTargetType.ShippingLine,
83
+ discountedAmount: { amount: "5.00", currencyCode: "USD" },
84
+ code: "FREESHIP",
85
+ },
86
+ ], appliedGiftCards: [], deliveryGroups: [] });
87
+ const result = getCalculatedCartData(mockCart);
88
+ expect(result.isFreeShipping).toBe(true);
89
+ });
90
+ it("should calculate total discounted price correctly", () => {
91
+ const mockCart = Object.assign(Object.assign({}, baseCartData), { discounts: ["DISCOUNT10"], items: [
92
+ {
93
+ id: "line1",
94
+ quantity: 1,
95
+ productId: "prod1",
96
+ variantId: "var1",
97
+ productDetails: {},
98
+ variantDetails: {
99
+ compareAtPrice: { amount: "100.00", currencyCode: "USD" },
100
+ price: { amount: "80.00", currencyCode: "USD" },
101
+ },
102
+ discounts: [
103
+ {
104
+ amount: 10,
105
+ type: "LINE_ITEM",
106
+ code: "DISCOUNT10",
107
+ },
108
+ ],
109
+ cost: { totalAmount: { amount: "80.00", currencyCode: "USD" } },
110
+ },
111
+ {
112
+ id: "line2",
113
+ quantity: 1,
114
+ productId: "prod2",
115
+ variantId: "var2",
116
+ productDetails: {},
117
+ variantDetails: {
118
+ compareAtPrice: { amount: "100.00", currencyCode: "USD" },
119
+ price: { amount: "80.00", currencyCode: "USD" },
120
+ },
121
+ discounts: [
122
+ {
123
+ amount: 10,
124
+ type: "LINE_ITEM",
125
+ code: "DISCOUNT10",
126
+ },
127
+ ],
128
+ cost: { totalAmount: { amount: "80.00", currencyCode: "USD" } },
129
+ },
130
+ ], discountAllocations: [
131
+ {
132
+ targetType: DiscountApplicationTargetType.LineItem,
133
+ discountedAmount: { amount: "10.00", currencyCode: "USD" },
134
+ code: "DISCOUNT10",
135
+ },
136
+ ], appliedGiftCards: [
137
+ {
138
+ id: "giftcard1",
139
+ amountUsed: { amount: "5.00", currencyCode: "USD" },
140
+ balance: { amount: "95.00", currencyCode: "USD" },
141
+ lastCharacters: "1234",
142
+ presentmentAmountUsed: { amount: "5.00", currencyCode: "USD" },
143
+ },
144
+ ], deliveryGroups: [] });
145
+ const result = getCalculatedCartData(mockCart);
146
+ // 100 (compare) - 10 (discount) - 20 (sale) - 5 (gift card) = 65
147
+ expect(result.totalDiscountedPrice).toBe(125);
148
+ });
149
+ });
150
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tapcart/mobile-components",
3
- "version": "0.7.59",
3
+ "version": "0.7.61",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "style": "dist/styles.css",
@@ -11,6 +11,20 @@
11
11
  "license": "SEE LICENSE IN LICENSE.md",
12
12
  "author": "Tapcart Inc.",
13
13
  "homepage": "https://tapcart.com",
14
+ "scripts": {
15
+ "clean": "rm -rf dist node_modules",
16
+ "lint": "eslint \"**/*.ts*\"",
17
+ "ui:add": "pnpm dlx shadcn-ui@latest add",
18
+ "build:styles": "postcss styles/globals.css -o dist/styles.css",
19
+ "build:ts": "tsc -p tsconfig.json && tsc-alias",
20
+ "build": "pnpm run build:ts && pnpm run build:styles",
21
+ "dev:ts": "tsc -w -p tsconfig.json",
22
+ "dev:styles": "npx tailwindcss -i styles/globals.css -o dist/styles.css --watch",
23
+ "dev": "concurrently \"pnpm run dev:ts\" \"pnpm run dev:styles\"",
24
+ "test": "jest",
25
+ "test:silent": "jest --silent",
26
+ "test:watch": "jest --watch"
27
+ },
14
28
  "peerDependencies": {
15
29
  "react": "^17.0.2 || ^18.0.0",
16
30
  "react-dom": "^17.0.2 || ^18.0.0"
@@ -23,20 +37,20 @@
23
37
  "@types/pluralize": "^0.0.33",
24
38
  "@types/react": "^18.2.0",
25
39
  "@types/react-dom": "^18.2.0",
40
+ "app-studio-types": "workspace:*",
26
41
  "autoprefixer": "^10.4.14",
27
42
  "chokidar-cli": "^3.0.0",
28
43
  "concurrently": "^8.2.2",
29
44
  "eslint": "^7.32.0",
45
+ "eslint-config-custom": "workspace:*",
30
46
  "jest": "^29.7.0",
31
47
  "jest-environment-jsdom": "^29.7.0",
32
48
  "postcss": "^8.4.24",
33
49
  "tailwindcss": "^3.3.2",
34
50
  "ts-jest": "^29.2.5",
35
51
  "tsc-alias": "^1.8.10",
36
- "typescript": "^4.5.2",
37
- "app-studio-types": "0.0.6",
38
- "eslint-config-custom": "0.0.0",
39
- "tsconfig": "0.0.0"
52
+ "tsconfig": "workspace:*",
53
+ "typescript": "^4.5.2"
40
54
  },
41
55
  "dependencies": {
42
56
  "@radix-ui/react-accordion": "^1.1.2",
@@ -76,19 +90,5 @@
76
90
  "tailwind-merge": "^1.13.2",
77
91
  "tailwindcss-animate": "^1.0.6",
78
92
  "vaul": "0.9.1"
79
- },
80
- "scripts": {
81
- "clean": "rm -rf dist node_modules",
82
- "lint": "eslint \"**/*.ts*\"",
83
- "ui:add": "pnpm dlx shadcn-ui@latest add",
84
- "build:styles": "postcss styles/globals.css -o dist/styles.css",
85
- "build:ts": "tsc -p tsconfig.json && tsc-alias",
86
- "build": "pnpm run build:ts && pnpm run build:styles",
87
- "dev:ts": "tsc -w -p tsconfig.json",
88
- "dev:styles": "npx tailwindcss -i styles/globals.css -o dist/styles.css --watch",
89
- "dev": "concurrently \"pnpm run dev:ts\" \"pnpm run dev:styles\"",
90
- "test": "jest",
91
- "test:silent": "jest --silent",
92
- "test:watch": "jest --watch"
93
93
  }
94
- }
94
+ }
@@ -1,6 +0,0 @@
1
- import React from "react"
2
- export declare function useClickOutside(
3
- ref: React.RefObject<HTMLElement>,
4
- callback: () => void
5
- ): void
6
- //# sourceMappingURL=use-click-outside.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-click-outside.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-click-outside.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,wBAAgB,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAE,IAAI,CAa5F"}
@@ -1,15 +0,0 @@
1
- "use client"
2
- import React from "react"
3
- export function useClickOutside(ref, callback) {
4
- React.useEffect(() => {
5
- const handleClickOutside = (event) => {
6
- if (ref.current && !ref.current.contains(event.target)) {
7
- callback()
8
- }
9
- }
10
- document.addEventListener("mousedown", handleClickOutside)
11
- return () => {
12
- document.removeEventListener("mousedown", handleClickOutside)
13
- }
14
- }, [ref, callback])
15
- }
@@ -1,7 +0,0 @@
1
- import React from "react"
2
- declare const useClickOutside: (
3
- ref: React.RefObject<HTMLElement>,
4
- callback: () => void
5
- ) => void
6
- export default useClickOutside
7
- //# sourceMappingURL=use-outside-click.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-outside-click.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-outside-click.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,QAAA,MAAM,eAAe,QAAS,MAAM,SAAS,CAAC,WAAW,CAAC,YAAY,MAAM,IAAI,SAa/E,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -1,16 +0,0 @@
1
- "use client"
2
- import React from "react"
3
- const useClickOutside = (ref, callback) => {
4
- React.useEffect(() => {
5
- const handleClickOutside = (event) => {
6
- if (ref.current && !ref.current.contains(event.target)) {
7
- callback()
8
- }
9
- }
10
- document.addEventListener("mousedown", handleClickOutside)
11
- return () => {
12
- document.removeEventListener("mousedown", handleClickOutside)
13
- }
14
- }, [ref, callback])
15
- }
16
- export default useClickOutside