@buddy-technology/offer-component 0.3.3 → 1.0.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.
- package/CHANGELOG.md +20 -2
- package/README.md +77 -16
- package/dist/index.js +304 -136
- package/dist/index.js.map +1 -0
- package/dist/index.modern.mjs +273 -0
- package/dist/index.modern.mjs.map +1 -0
- package/lib/components/BuddyOfferElement.d.ts +5 -0
- package/lib/components/BuddyOfferElement.d.ts.map +1 -0
- package/lib/components/index.d.ts +2 -0
- package/lib/components/index.d.ts.map +1 -0
- package/lib/hooks/index.d.ts +3 -0
- package/lib/hooks/index.d.ts.map +1 -0
- package/lib/hooks/useConfig.d.ts +7 -0
- package/lib/hooks/useConfig.d.ts.map +1 -0
- package/lib/hooks/useUpdateEffect.d.ts +4 -0
- package/lib/hooks/useUpdateEffect.d.ts.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/interface/index.d.ts +70 -0
- package/lib/interface/index.d.ts.map +1 -0
- package/lib/util/dictionary.d.ts +21 -0
- package/lib/util/dictionary.d.ts.map +1 -0
- package/lib/util/index.d.ts +9 -0
- package/lib/util/index.d.ts.map +1 -0
- package/package.json +23 -29
- package/release.config.js +22 -0
- package/setupTests.ts +8 -0
- package/tsconfig.eslint.json +12 -0
- package/API.md +0 -184
- package/dist/util.js +0 -252
- package/lib/types.d.ts +0 -151
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
# @buddy-technology/offer-component-v1.0.0 (2023-12-01)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* eslint ts set up ([28438bd](https://github.com/Buddy-Technology/ion-to-react/commit/28438bd5d8709a653bbacdbc4e58044b9229d2b4))
|
|
7
|
+
* ts interfaces ([69f26ae](https://github.com/Buddy-Technology/ion-to-react/commit/69f26ae6e09ce086be15d331d2e49bc3b22132ba))
|
|
8
|
+
* typo in readme ([7969747](https://github.com/Buddy-Technology/ion-to-react/commit/7969747aff3a697edc41b912844bb44134ae7de1))
|
|
9
|
+
* update repo field in package jsons ([9a2b638](https://github.com/Buddy-Technology/ion-to-react/commit/9a2b638de3dbbac4d3af649d8410b5249885720c))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
* convert to typescript ([4d27be6](https://github.com/Buddy-Technology/ion-to-react/commit/4d27be6f7020394b32808e442558eea3367e810e))
|
|
15
|
+
* expose hook for loading configs ([81bd708](https://github.com/Buddy-Technology/ion-to-react/commit/81bd7089ae3f3f13da3f3179a1882882e39ab84b))
|
|
16
|
+
* map config inside the Buddy obj ([fda8376](https://github.com/Buddy-Technology/ion-to-react/commit/fda8376cd44e10195b388e43a01cb1eced3d7320))
|
|
17
|
+
* offer component and example app added ([e72aa94](https://github.com/Buddy-Technology/ion-to-react/commit/e72aa94b22053f94f753bed6d0a26ebbad6fa60a))
|
|
18
|
+
* test-utils ([7d44088](https://github.com/Buddy-Technology/ion-to-react/commit/7d4408827fff795ab6fd88c1c80765a6b014e2cb))
|
|
19
|
+
|
|
1
20
|
# CHANGELOG
|
|
2
21
|
|
|
3
22
|
### v0.3.3
|
|
@@ -104,5 +123,4 @@
|
|
|
104
123
|
- add changelog
|
|
105
124
|
- add env urls
|
|
106
125
|
- check for required props in loadScript
|
|
107
|
-
---
|
|
108
|
-
|
|
126
|
+
---
|
package/README.md
CHANGED
|
@@ -29,6 +29,40 @@ function App() {
|
|
|
29
29
|
}
|
|
30
30
|
export default App;
|
|
31
31
|
```
|
|
32
|
+
|
|
33
|
+
## Combined with useConfig hook
|
|
34
|
+
```javascript
|
|
35
|
+
import React from 'react';
|
|
36
|
+
import BuddyOfferElement, { useConfig } from '@buddy-technology/offer-component';
|
|
37
|
+
|
|
38
|
+
function App() {
|
|
39
|
+
const { config, isLoading } = useConfig('https://config-domain.com/config.js');
|
|
40
|
+
|
|
41
|
+
if (isLoading || !config) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// grab relevant properties from config
|
|
46
|
+
const theme = config.themeBase;
|
|
47
|
+
const data = config.data;
|
|
48
|
+
const handleUserEvents = config.userEvents;
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div id="app">
|
|
52
|
+
<h1>My App</h1>
|
|
53
|
+
<BuddyOfferElement
|
|
54
|
+
ion="MY_ION"
|
|
55
|
+
partnerID="my-partner-id"
|
|
56
|
+
stage="staging"
|
|
57
|
+
theme={theme}
|
|
58
|
+
data={data}
|
|
59
|
+
onUserEvent={handleUserEvents}
|
|
60
|
+
/>
|
|
61
|
+
</div>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
export default App;
|
|
65
|
+
```
|
|
32
66
|
---
|
|
33
67
|
## Props
|
|
34
68
|
|
|
@@ -43,7 +77,7 @@ export default App;
|
|
|
43
77
|
| onUserEvent | function | | A callback for tracking user behavioral data. See [Capturing Data](#capturing-data) for details. |
|
|
44
78
|
| includeCheckout | boolean | `true` | Toggles whether to render the secure checkout. |
|
|
45
79
|
| onAddToCart | function | | The callback fired when a user opts into an offer. See Buddy's Partner API docs for details on how to complete the transaction.|
|
|
46
|
-
|
|
|
80
|
+
| onRemoveFromCart | function | | The callback fired when a user opts out of the offer. |
|
|
47
81
|
_*required_
|
|
48
82
|
|
|
49
83
|
---
|
|
@@ -53,7 +87,8 @@ Buddy's Offer Element comes in three different view types:
|
|
|
53
87
|
|
|
54
88
|
- __paginated__ (default) - A paginated form where users click through to the next section.
|
|
55
89
|
- __single form__ - A single form where all fields are displayed in the same, scrollable view.
|
|
56
|
-
- __offer only__ -
|
|
90
|
+
- __offer only__ - View for displaying just the insurance offer with a quote and checkbox that fires `onAddToCart` when checked and `onRemoveFromCart` when unchecked (see [For full stack apps](#for-full-stack-apps) for more info).
|
|
91
|
+
**NOTE**: Offer-Only implementations are meant to be rendered in a controlled environment with necessary data passed into it, and will require a payment integration for checkout (see Buddy's [Partner API docs](https://buddyinsurance.stoplight.io/docs/partner-api-documentation/ZG9jOjE1NDc1MzQx)). If any fields are missing or invalid, a step-through form will render with the individual views that include the needed fields. Views with satisfied fields will be skipped. Once users rectify any needed info, they will land on the offer only screen.
|
|
57
92
|
|
|
58
93
|
---
|
|
59
94
|
## Checkout
|
|
@@ -71,16 +106,52 @@ To use this mode, set `includeCheckout` to `false`, or set viewType to `offer-on
|
|
|
71
106
|
When users opt in, the `onAddToCart` callback is fired with the completed application object. If a user opts out, `onRemoveFromCart` will be called.
|
|
72
107
|
|
|
73
108
|
```javascript
|
|
109
|
+
// simple paginated example to collect data
|
|
74
110
|
import React from 'react';
|
|
75
111
|
import BuddyOfferElement from '@buddy-technology/offer-component';
|
|
112
|
+
import { handleAddToCart, handleRemoveFromCart } from './myApi';
|
|
76
113
|
|
|
77
114
|
function App() {
|
|
78
115
|
const handleAddToCart = (payload) => {
|
|
79
|
-
|
|
116
|
+
handleAddToCart(payload)
|
|
80
117
|
};
|
|
81
118
|
|
|
82
119
|
const handleRemoveFromCart = (payload) => {
|
|
83
|
-
|
|
120
|
+
handleRemoveFromCart(payload)
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
return (
|
|
124
|
+
<div id="app">
|
|
125
|
+
<h1>My App</h1>
|
|
126
|
+
<BuddyOfferElement
|
|
127
|
+
ion="MY_ION"
|
|
128
|
+
partnerID="my-partner-id"
|
|
129
|
+
viewType="paginated"
|
|
130
|
+
includeCheckout={false}
|
|
131
|
+
onAddToCart={handleAddToCart}
|
|
132
|
+
onRemoveFromCart={handleRemoveFromCart}
|
|
133
|
+
stage="PRODUCTION"
|
|
134
|
+
/>
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
export default App;
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
```javascript
|
|
142
|
+
// example using offer-only and passing in customer/policy data
|
|
143
|
+
import React from 'react';
|
|
144
|
+
import BuddyOfferElement from '@buddy-technology/offer-component';
|
|
145
|
+
import { handleAddToCart, handleRemoveFromCart } from './myApi';
|
|
146
|
+
|
|
147
|
+
// passing down data as prop in this example
|
|
148
|
+
function App({ userAndPolicyData }) {
|
|
149
|
+
const handleAddToCart = (payload) => {
|
|
150
|
+
handleAddToCart(payload)
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const handleRemoveFromCart = (payload) => {
|
|
154
|
+
handleRemoveFromCart(payload)
|
|
84
155
|
};
|
|
85
156
|
|
|
86
157
|
return (
|
|
@@ -90,6 +161,7 @@ function App() {
|
|
|
90
161
|
ion="MY_ION"
|
|
91
162
|
partnerID="my-partner-id"
|
|
92
163
|
viewType="offer-only"
|
|
164
|
+
data={userAndPolicyData} // data is passed in, if any fields are invalid, they will be displayed to user to rectify before purchasing.
|
|
93
165
|
onAddToCart={handleAddToCart}
|
|
94
166
|
onRemoveFromCart={handleRemoveFromCart}
|
|
95
167
|
stage="PRODUCTION"
|
|
@@ -202,17 +274,6 @@ function App() {
|
|
|
202
274
|
}
|
|
203
275
|
export default App;
|
|
204
276
|
```
|
|
205
|
-
### Base Themes
|
|
206
|
-
|
|
207
|
-
We currently offer two baseThemes to start with (with more coming soon!) If you plan on doing very extensive overrides, set the baseTheme to `'none'`.
|
|
208
|
-
|
|
209
|
-
#### Available themes:
|
|
210
|
-
|
|
211
|
-
`'base`':
|
|
212
|
-

|
|
213
|
-
|
|
214
|
-
`'buddy'`:
|
|
215
|
-

|
|
216
277
|
|
|
217
278
|
### Color Palettes
|
|
218
279
|
We currently offer two color palettes to start with (with more coming soon!).
|
|
@@ -540,4 +601,4 @@ function App() {
|
|
|
540
601
|
);
|
|
541
602
|
}
|
|
542
603
|
export default App;
|
|
543
|
-
```
|
|
604
|
+
```
|
package/dist/index.js
CHANGED
|
@@ -1,149 +1,317 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
var
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
* @property {String} partnerID - The partner ID required for instantiating the Offer
|
|
112
|
-
* @property {String} [stage="STAGING"] - toggle's the environment for the Offer Component. Defaults to STAGING. Must be set to "PRODUCTION" before going live.
|
|
113
|
-
* @property {String} [viewType="paginated"] - establishes how the offer should display to the user. One of: 'paginated', 'single-form' or 'offer-only.'
|
|
114
|
-
* @property {ThemeObject} [theme] - theming object for customizing offer component's styles
|
|
115
|
-
* @property {DataObject} [data] - Any customer or policy data to pre-fill the offer with. Refer to your individual ION for data structure.
|
|
116
|
-
* @property {OnUserEventCallback} [onUserEvent] - callback function for tracking user behavioral data. Triggers on user interactions such as input focus/blur, in-app navigation, etc. Refer to the docs for more details.
|
|
117
|
-
* @property {AddToCartFunction} [onAddToCart] - callback function triggered when users opt into an offer-only offer.
|
|
118
|
-
* @property {RemoveFromCartFunction} [onRemoveFromCart] - callback function triggered when users opt out of an offer-only offer.
|
|
119
|
-
* @property {ScrollToTopFunction} [overrideScrollToTop] - When present, this overrides the default scroll to top of offer element behavior when navigating between screens.
|
|
120
|
-
* @property {boolean} [includeCheckout] - toggles whether or not to display the card capture checkout view. Defaults to true. When false, an AddToCart callback must be provided.
|
|
121
|
-
* @property {LogoOverride} [logoOverride] - object for overriding Buddy's trust badge.
|
|
122
|
-
*/
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* @function BuddyOfferElement
|
|
126
|
-
* @param {BuddyOfferElementProps} options
|
|
127
|
-
* @returns {FunctionComponent<BuddyOfferElementProps>}
|
|
128
|
-
*/
|
|
129
|
-
function BuddyOfferElement(options) {
|
|
130
|
-
const getScript = async () => {
|
|
1
|
+
var React = require('react');
|
|
2
|
+
|
|
3
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
4
|
+
|
|
5
|
+
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
6
|
+
|
|
7
|
+
function _extends() {
|
|
8
|
+
_extends = Object.assign || function (target) {
|
|
9
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
10
|
+
var source = arguments[i];
|
|
11
|
+
|
|
12
|
+
for (var key in source) {
|
|
13
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
14
|
+
target[key] = source[key];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return target;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
return _extends.apply(this, arguments);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
var EXISTING_SCRIPT_MESSAGE = 'Buddy Offer Script is already loaded.';
|
|
26
|
+
var SCRIPTS = {
|
|
27
|
+
LOCAL: {
|
|
28
|
+
URL: 'http://localhost:8008/index.js'
|
|
29
|
+
},
|
|
30
|
+
// TODO: Delete this in favor of "testing", once we're sure nothing is using it.
|
|
31
|
+
DEVELOPMENT: {
|
|
32
|
+
URL: 'https://js.buddy.insure/v2/dev/index.js'
|
|
33
|
+
},
|
|
34
|
+
TESTING: {
|
|
35
|
+
URL: 'https://js.buddy.insure/v2/testing/index.js'
|
|
36
|
+
},
|
|
37
|
+
STAGING: {
|
|
38
|
+
URL: 'https://js.buddy.insure/v2/staging/index.js'
|
|
39
|
+
},
|
|
40
|
+
PRODUCTION: {
|
|
41
|
+
URL: 'https://js.buddy.insure/v2/index.js'
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var STAGES = Object.keys(SCRIPTS);
|
|
45
|
+
|
|
46
|
+
var defaultOptions = {
|
|
47
|
+
stage: 'STAGING'
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
var isEmptyOrNil = function isEmptyOrNil(value) {
|
|
51
|
+
var isNil = function isNil(val) {
|
|
52
|
+
return [undefined, null].includes(val);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
var isEmptyStr = function isEmptyStr(str) {
|
|
56
|
+
return typeof str === 'string' && str.trim().length === 0;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
var isEmptyObjOrArr = function isEmptyObjOrArr(obj) {
|
|
60
|
+
return typeof obj === 'object' && obj.length === undefined && Object.keys(obj).length === 0 || Array.isArray(obj) && obj.length === 0;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return isNil(value) || isEmptyStr(value) || isEmptyObjOrArr(value);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
var validatePropertiesOfObject = function validatePropertiesOfObject(propsToCheck, obj) {
|
|
67
|
+
var emptyProps = propsToCheck.filter(function (prop) {
|
|
68
|
+
return isEmptyOrNil(obj[prop]);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
if (emptyProps.length) {
|
|
72
|
+
var displayMissingProps = emptyProps.reduce(function (prev, current, i) {
|
|
73
|
+
var isLastEl = i === emptyProps.length - 1;
|
|
74
|
+
return isLastEl ? "" + prev + current + "." : "" + prev + current + ", ";
|
|
75
|
+
}, '');
|
|
76
|
+
return "The following props are required: " + displayMissingProps;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return null;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
var findScript = function findScript(url) {
|
|
83
|
+
var scripts = Array.from(document.querySelectorAll('script'));
|
|
84
|
+
return scripts.find(function (_ref) {
|
|
85
|
+
var src = _ref.src;
|
|
86
|
+
return src.startsWith(url);
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
var findOfferScript = function findOfferScript(stage) {
|
|
90
|
+
if (stage === void 0) {
|
|
91
|
+
stage = defaultOptions.stage;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
var URL = SCRIPTS[stage].URL;
|
|
95
|
+
var matchedScript = findScript(URL);
|
|
96
|
+
return matchedScript;
|
|
97
|
+
};
|
|
98
|
+
var updateOffer = function updateOffer(options) {
|
|
99
|
+
if (window.Buddy) {
|
|
100
|
+
try {
|
|
101
|
+
window.Buddy.updateOffer(options);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
// eslint-disable-next-line no-console
|
|
104
|
+
console.error(error);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
var createOffer = function createOffer(options) {
|
|
110
|
+
if (window.Buddy) {
|
|
131
111
|
try {
|
|
132
|
-
|
|
112
|
+
window.Buddy.createOffer(options);
|
|
133
113
|
} catch (error) {
|
|
134
114
|
// eslint-disable-next-line no-console
|
|
135
115
|
console.error(error);
|
|
136
116
|
}
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
var injectScript = function injectScript(options) {
|
|
121
|
+
var finalOptions = _extends({}, defaultOptions, options);
|
|
122
|
+
|
|
123
|
+
var script = document.createElement('script');
|
|
124
|
+
script.src = "" + SCRIPTS[finalOptions.stage].URL;
|
|
125
|
+
|
|
126
|
+
script.onload = function () {
|
|
127
|
+
return createOffer(finalOptions);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
document.body.appendChild(script);
|
|
131
|
+
return script;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
var scriptPromise = null;
|
|
135
|
+
var loadScript = function loadScript(options) {
|
|
136
|
+
// Ensure that we only attempt to script once
|
|
137
|
+
if (scriptPromise !== null) {
|
|
138
|
+
return scriptPromise;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
scriptPromise = new Promise(function (resolve, reject) {
|
|
142
|
+
var _window$Buddy;
|
|
143
|
+
|
|
144
|
+
if (typeof window === 'undefined') {
|
|
145
|
+
// Resolve to null when imported server side. This makes the module
|
|
146
|
+
// safe to import in an isomorphic code base.
|
|
147
|
+
resolve(null);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if ((_window$Buddy = window.Buddy) != null && _window$Buddy.createOffer) {
|
|
152
|
+
// eslint-disable-next-line no-console
|
|
153
|
+
console.warn(EXISTING_SCRIPT_MESSAGE);
|
|
154
|
+
resolve(window.Buddy);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
try {
|
|
159
|
+
var requiredProps = ['ion', 'partnerID'];
|
|
160
|
+
var missingRequiredProps = validatePropertiesOfObject(requiredProps, options);
|
|
161
|
+
|
|
162
|
+
if (missingRequiredProps) {
|
|
163
|
+
reject(new Error(missingRequiredProps));
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (!(options != null && options.stage)) {
|
|
168
|
+
// eslint-disable-next-line no-console
|
|
169
|
+
console.warn("No stage passed to BuddyOfferElement. Using default stage: " + defaultOptions.stage);
|
|
170
|
+
} // If stage is passed, ensure it is one of the prescribed options.
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
if (options != null && options.stage && !STAGES.includes(options.stage)) {
|
|
174
|
+
var msg = "The stage prop must be one of: [" + STAGES.join(' , ') + "], but received \"" + options.stage + ".\"";
|
|
175
|
+
reject(new Error(msg));
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
var script = findOfferScript(options == null ? void 0 : options.stage);
|
|
180
|
+
|
|
181
|
+
if (script) {
|
|
182
|
+
var _window$Buddy2;
|
|
183
|
+
|
|
184
|
+
// eslint-disable-next-line no-console
|
|
185
|
+
console.warn(EXISTING_SCRIPT_MESSAGE);
|
|
186
|
+
|
|
187
|
+
if ((_window$Buddy2 = window.Buddy) != null && _window$Buddy2.createOffer) {
|
|
188
|
+
resolve(window.Buddy);
|
|
189
|
+
} else {
|
|
190
|
+
reject(new Error('Buddy Offer Element not available'));
|
|
191
|
+
}
|
|
192
|
+
} else if (!script) {
|
|
193
|
+
script = injectScript(options);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
script.addEventListener('load', function () {
|
|
197
|
+
var _window$Buddy3;
|
|
198
|
+
|
|
199
|
+
if ((_window$Buddy3 = window.Buddy) != null && _window$Buddy3.createOffer) {
|
|
200
|
+
resolve(window.Buddy);
|
|
201
|
+
} else {
|
|
202
|
+
reject(new Error('Buddy Offer Element not available'));
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
script.addEventListener('error', function () {
|
|
206
|
+
reject(new Error('Failed to load Buddy Offer Element'));
|
|
207
|
+
});
|
|
208
|
+
} catch (error) {
|
|
209
|
+
reject(error);
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
return scriptPromise;
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
function useConfig(src) {
|
|
216
|
+
var _useState = React.useState(null),
|
|
217
|
+
config = _useState[0],
|
|
218
|
+
setConfig = _useState[1];
|
|
219
|
+
|
|
220
|
+
var _useState2 = React.useState(true),
|
|
221
|
+
isLoading = _useState2[0],
|
|
222
|
+
setIsLoading = _useState2[1];
|
|
223
|
+
|
|
224
|
+
var hasConfig = typeof window !== 'undefined';
|
|
225
|
+
React.useEffect(function () {
|
|
226
|
+
var script = findScript(src);
|
|
227
|
+
|
|
228
|
+
if (!script) {
|
|
229
|
+
script = document.createElement('script');
|
|
230
|
+
script.src = src;
|
|
231
|
+
|
|
232
|
+
script.onload = function () {
|
|
233
|
+
// Assuming the script sets a global variable named 'config'
|
|
234
|
+
if (hasConfig) {
|
|
235
|
+
setConfig(window.Buddy.config);
|
|
236
|
+
setIsLoading(false);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
document.body.appendChild(script);
|
|
241
|
+
} else {
|
|
242
|
+
// eslint-disable-next-line no-console
|
|
243
|
+
console.warn('Config script is already loaded.');
|
|
244
|
+
|
|
245
|
+
if (hasConfig) {
|
|
246
|
+
setConfig(window.Buddy.config);
|
|
247
|
+
setIsLoading(false);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return function () {
|
|
252
|
+
if (script) {
|
|
253
|
+
document.body.removeChild(script);
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
}, [src]);
|
|
257
|
+
return {
|
|
258
|
+
config: config,
|
|
259
|
+
isLoading: isLoading
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
var useUpdateEffect = function useUpdateEffect(effect, deps) {
|
|
264
|
+
var isFirstMount = React.useRef(true); // need to return only in the else condition in case a cleanup func is passed in effect.
|
|
265
|
+
// eslint-disable-next-line consistent-return
|
|
266
|
+
|
|
267
|
+
React.useEffect(function () {
|
|
268
|
+
if (isFirstMount) {
|
|
269
|
+
isFirstMount.current = false;
|
|
270
|
+
} else {
|
|
271
|
+
return effect();
|
|
272
|
+
}
|
|
273
|
+
}, deps);
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
function _catch(body, recover) {
|
|
277
|
+
try {
|
|
278
|
+
var result = body();
|
|
279
|
+
} catch (e) {
|
|
280
|
+
return recover(e);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (result && result.then) {
|
|
284
|
+
return result.then(void 0, recover);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return result;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function BuddyOfferElement(options) {
|
|
291
|
+
var getScript = function getScript() {
|
|
292
|
+
try {
|
|
293
|
+
var _temp2 = _catch(function () {
|
|
294
|
+
return Promise.resolve(loadScript(options)).then(function () {});
|
|
295
|
+
}, function (error) {
|
|
296
|
+
// eslint-disable-next-line no-console
|
|
297
|
+
console.error(error);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(function () {}) : void 0);
|
|
301
|
+
} catch (e) {
|
|
302
|
+
return Promise.reject(e);
|
|
303
|
+
}
|
|
137
304
|
};
|
|
138
305
|
|
|
139
306
|
getScript();
|
|
140
|
-
(
|
|
141
|
-
|
|
307
|
+
useUpdateEffect(function () {
|
|
308
|
+
updateOffer(options);
|
|
142
309
|
}, [options]);
|
|
143
|
-
return /*#__PURE__*/
|
|
310
|
+
return /*#__PURE__*/React__default["default"].createElement("div", {
|
|
144
311
|
id: "buddy_offer"
|
|
145
312
|
});
|
|
146
313
|
}
|
|
147
314
|
|
|
148
|
-
|
|
149
|
-
exports.
|
|
315
|
+
exports["default"] = BuddyOfferElement;
|
|
316
|
+
exports.useConfig = useConfig;
|
|
317
|
+
//# sourceMappingURL=index.js.map
|