@moneylion/react-native-offer-carousel 1.0.10 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/lib/commonjs/capabilities/offer-catalog/src/api/offerCatalogApi.js +22 -6
  2. package/lib/commonjs/capabilities/offer-catalog/src/api/offerCatalogApi.js.map +1 -1
  3. package/lib/commonjs/components/MoneyLionOfferCarousel.js +68 -24
  4. package/lib/commonjs/components/MoneyLionOfferCarousel.js.map +1 -1
  5. package/lib/commonjs/pageData.js +3 -1
  6. package/lib/commonjs/pageData.js.map +1 -1
  7. package/lib/commonjs/services/getDynamicOffers.js +5 -2
  8. package/lib/commonjs/services/getDynamicOffers.js.map +1 -1
  9. package/lib/commonjs/utils/getOffersByProductTypes.js +8 -4
  10. package/lib/commonjs/utils/getOffersByProductTypes.js.map +1 -1
  11. package/lib/module/capabilities/offer-catalog/src/api/offerCatalogApi.js +22 -6
  12. package/lib/module/capabilities/offer-catalog/src/api/offerCatalogApi.js.map +1 -1
  13. package/lib/module/components/MoneyLionOfferCarousel.js +68 -24
  14. package/lib/module/components/MoneyLionOfferCarousel.js.map +1 -1
  15. package/lib/module/pageData.js +3 -1
  16. package/lib/module/pageData.js.map +1 -1
  17. package/lib/module/services/getDynamicOffers.js +5 -2
  18. package/lib/module/services/getDynamicOffers.js.map +1 -1
  19. package/lib/module/utils/getOffersByProductTypes.js +8 -4
  20. package/lib/module/utils/getOffersByProductTypes.js.map +1 -1
  21. package/lib/typescript/src/capabilities/offer-catalog/src/api/offerCatalogApi.d.ts +14 -1
  22. package/lib/typescript/src/capabilities/offer-catalog/src/api/offerCatalogApi.d.ts.map +1 -1
  23. package/lib/typescript/src/capabilities/offer-catalog/src/types/offerCatalogSchema.d.ts +1 -0
  24. package/lib/typescript/src/capabilities/offer-catalog/src/types/offerCatalogSchema.d.ts.map +1 -1
  25. package/lib/typescript/src/components/MoneyLionOfferCarousel.d.ts +6 -0
  26. package/lib/typescript/src/components/MoneyLionOfferCarousel.d.ts.map +1 -1
  27. package/lib/typescript/src/pageData.d.ts +1 -0
  28. package/lib/typescript/src/pageData.d.ts.map +1 -1
  29. package/lib/typescript/src/services/getDynamicOffers.d.ts +1 -0
  30. package/lib/typescript/src/services/getDynamicOffers.d.ts.map +1 -1
  31. package/lib/typescript/src/utils/getOffersByProductTypes.d.ts +2 -1
  32. package/lib/typescript/src/utils/getOffersByProductTypes.d.ts.map +1 -1
  33. package/package.json +1 -1
  34. package/src/capabilities/offer-catalog/src/api/offerCatalogApi.ts +24 -6
  35. package/src/capabilities/offer-catalog/src/types/offerCatalogSchema.ts +1 -0
  36. package/src/components/MoneyLionOfferCarousel.tsx +91 -21
  37. package/src/pageData.ts +13 -11
  38. package/src/services/getDynamicOffers.ts +4 -2
  39. package/src/utils/getOffersByProductTypes.ts +8 -6
@@ -32,6 +32,12 @@ export type MoneyLionOfferCarouselProps = {
32
32
  isDev: boolean;
33
33
  showCardBorder?: boolean;
34
34
  showDescriptionPoints?: boolean;
35
+ onError?: (error: {
36
+ code?: number;
37
+ message: string;
38
+ timestamp: string;
39
+ }) => void;
40
+ onLoad?: (numOffers: number) => void;
35
41
  };
36
42
 
37
43
  const getConfiguration = async ({
@@ -39,9 +45,10 @@ const getConfiguration = async ({
39
45
  zone,
40
46
  subAccountToken,
41
47
  isDev,
48
+ onError,
42
49
  }: Pick<
43
50
  MoneyLionOfferCarouselProps,
44
- "channel" | "zone" | "subAccountToken" | "isDev"
51
+ "channel" | "zone" | "subAccountToken" | "isDev" | "onError"
45
52
  >) => {
46
53
  const url = `${getConfigApiBaseUrl(isDev)}/network/${channel}/${zone}/api/configuration`;
47
54
 
@@ -51,13 +58,33 @@ const getConfiguration = async ({
51
58
  try {
52
59
  const response = await fetch(url, { headers });
53
60
  if (!response.ok) {
54
- throw new Error();
61
+ const errorCode = response.status;
62
+
63
+ onError?.({
64
+ code: errorCode,
65
+ message: `Configuration request failed with status: ${response.status}`,
66
+ timestamp: new Date().toISOString(),
67
+ });
68
+
69
+ throw new Error(
70
+ `Configuration request failed with status: ${response.status}`
71
+ );
55
72
  }
73
+
56
74
  const data = await response.json();
57
75
 
58
76
  return data;
59
77
  } catch (error) {
60
78
  console.error("Error fetching configuration", error);
79
+
80
+ if (!(error instanceof Error && error.message.includes("status"))) {
81
+ // Call if network error not already reported
82
+ onError?.({
83
+ message: "Network request failed",
84
+ timestamp: new Date().toISOString(),
85
+ });
86
+ }
87
+
61
88
  return localCnfContext;
62
89
  }
63
90
  };
@@ -73,6 +100,8 @@ export const MoneyLionOfferCarousel = (
73
100
  fontFamily,
74
101
  isDev,
75
102
  showDescriptionPoints = true,
103
+ onError,
104
+ onLoad,
76
105
  } = props;
77
106
 
78
107
  const {
@@ -109,21 +138,31 @@ export const MoneyLionOfferCarousel = (
109
138
  zone,
110
139
  subAccountToken,
111
140
  isDev,
141
+ onError,
112
142
  });
113
143
  setContext(data.serializableContext as CnfContext);
114
144
  } catch (err) {
115
- setError(
145
+ const errorObj =
116
146
  err instanceof Error
117
147
  ? err
118
- : new Error("Failed to fetch configuration")
119
- );
148
+ : new Error("Failed to fetch configuration");
149
+
150
+ setError(errorObj);
151
+
152
+ // Only call onError if not already called in getConfiguration
153
+ if (!errorObj.message.includes("status")) {
154
+ onError?.({
155
+ message: errorObj.message,
156
+ timestamp: new Date().toISOString(),
157
+ });
158
+ }
120
159
  } finally {
121
160
  setIsLoading(false);
122
161
  }
123
162
  };
124
163
 
125
164
  fetchConfiguration();
126
- }, [channel, zone, subAccountToken, isDev]);
165
+ }, [channel, zone, subAccountToken, isDev, onError]);
127
166
 
128
167
  useEffect(() => {
129
168
  if (isLoading) {
@@ -134,24 +173,55 @@ export const MoneyLionOfferCarousel = (
134
173
  useEffect(() => {
135
174
  const fetchPageData = async () => {
136
175
  if (context) {
137
- const data = await getPageData({
138
- context: { ...context, isDev },
139
- params: props,
140
- onRateTableSubmit,
141
- });
142
- onRateTableResponse?.({
143
- timestamp: new Date().toISOString(),
144
- isError: Boolean(data.isError),
145
- offers: data.offers,
146
- rateTableUuid: data.rateTableUuid,
147
- leadUuid: data.leadUuid,
148
- });
149
- setPageData(data);
176
+ try {
177
+ const data = await getPageData({
178
+ context: { ...context, isDev },
179
+ params: props,
180
+ onRateTableSubmit,
181
+ });
182
+
183
+ // Check for API errors in the response
184
+ if (data.isError) {
185
+ onError?.({
186
+ code: data.errorCode,
187
+ message: "Rate table error occurred",
188
+ timestamp: new Date().toISOString(),
189
+ });
190
+ }
191
+
192
+ onRateTableResponse?.({
193
+ timestamp: new Date().toISOString(),
194
+ isError: Boolean(data.isError),
195
+ offers: data.offers,
196
+ rateTableUuid: data.rateTableUuid,
197
+ leadUuid: data.leadUuid,
198
+ });
199
+
200
+ setPageData(data);
201
+ onLoad?.(data.offers.length);
202
+ } catch (err) {
203
+ const errorObj =
204
+ err instanceof Error ? err : new Error("Failed to fetch page data");
205
+
206
+ onError?.({
207
+ message: errorObj.message,
208
+ timestamp: new Date().toISOString(),
209
+ });
210
+ }
150
211
  }
151
212
  };
152
213
 
153
214
  fetchPageData();
154
- }, [context, isDev, onRateTableResponse, onRateTableSubmit, props]);
215
+ }, [
216
+ context,
217
+ isDev,
218
+ onRateTableResponse,
219
+ onRateTableSubmit,
220
+ props,
221
+ isLoading,
222
+ onError,
223
+ onLoad,
224
+ ]);
155
225
 
156
226
  if (isLoading) {
157
227
  return <DynamicOfferSkeleton displayLayout={"fixed"} />;
@@ -162,7 +232,7 @@ export const MoneyLionOfferCarousel = (
162
232
  }
163
233
 
164
234
  if (!context) {
165
- return <Text>{"Context is null"}</Text>; // Replace with your error component
235
+ return <Text>{"Context is null"}</Text>;
166
236
  }
167
237
 
168
238
  if (!pageData) {
package/src/pageData.ts CHANGED
@@ -72,20 +72,22 @@ export async function getPageData({
72
72
  });
73
73
 
74
74
  // Get offers
75
- const { offers, isError, leadUuid, rateTableUuid } = await getDynamicOffers({
76
- tags: safeTags,
77
- displayLayout: safeDisplayLayout,
78
- productTypes,
79
- resultType,
80
- isCachedOffersRequest,
81
- productTypesDefinition: [...productTypesDefinition],
82
- partnersOverrideDefinition: [...partnersOverrideDefinition],
83
- context,
84
- defaultProductType,
85
- });
75
+ const { offers, isError, leadUuid, rateTableUuid, errorCode } =
76
+ await getDynamicOffers({
77
+ tags: safeTags,
78
+ displayLayout: safeDisplayLayout,
79
+ productTypes,
80
+ resultType,
81
+ isCachedOffersRequest,
82
+ productTypesDefinition: [...productTypesDefinition],
83
+ partnersOverrideDefinition: [...partnersOverrideDefinition],
84
+ context,
85
+ defaultProductType,
86
+ });
86
87
 
87
88
  return {
88
89
  isError,
90
+ errorCode,
89
91
  leadUuid,
90
92
  rateTableUuid,
91
93
  // title,
@@ -56,7 +56,7 @@ export const getDynamicOffers = async ({
56
56
  context,
57
57
  }: Omit<GetDynamicOffersProps, "isDev">) => {
58
58
  // Get the initial offers
59
- let { offers, rateTableUuid, isError, leadUuid } =
59
+ let { offers, rateTableUuid, isError, leadUuid, errorCode } =
60
60
  await getOffersByProductTypes({
61
61
  isCachedOffersRequest,
62
62
  productTypes,
@@ -79,6 +79,7 @@ export const getDynamicOffers = async ({
79
79
  isError = fallbackResult.isError;
80
80
  leadUuid = fallbackResult.leadUuid;
81
81
  productTypes = [defaultProductType];
82
+ errorCode = fallbackResult.errorCode;
82
83
  }
83
84
 
84
85
  const sortedOffers =
@@ -93,7 +94,8 @@ export const getDynamicOffers = async ({
93
94
  addClientTagsToOfferLinks(isCachedOffersRequest, tags),
94
95
  getOffersBasedOnLayout(displayLayout)
95
96
  ),
96
- isError: isError,
97
+ isError,
98
+ errorCode,
97
99
  leadUuid: leadUuid,
98
100
  rateTableUuid,
99
101
  };
@@ -26,15 +26,17 @@ export const getOffersByProductTypes = async ({
26
26
  context: CnfContext;
27
27
  }) => {
28
28
  if (isCachedOffersRequest) {
29
- const { offers, uuid, isError, leadUuid } =
29
+ const { offers, uuid, isError, leadUuid, errorCode } =
30
30
  await getCachedOffersByProductTypes(context)(productTypes);
31
31
 
32
- return { offers, rateTableUuid: uuid, isError, leadUuid };
32
+ return { offers, rateTableUuid: uuid, isError, leadUuid, errorCode };
33
33
  }
34
34
 
35
- const { offers, uuid, isError, leadUuid } = await getOffersForProductTypes(
36
- context
37
- )(productTypes, parseClientTags(tags));
35
+ const { offers, uuid, isError, leadUuid, errorCode } =
36
+ await getOffersForProductTypes(context)(
37
+ productTypes,
38
+ parseClientTags(tags)
39
+ );
38
40
 
39
- return { offers, rateTableUuid: uuid, isError, leadUuid };
41
+ return { offers, rateTableUuid: uuid, isError, leadUuid, errorCode };
40
42
  };