notify-me-wl 1.1.0 → 1.2.1

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 (4) hide show
  1. package/README.md +206 -65
  2. package/index.html +3 -3
  3. package/index.js +34 -12
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -1,16 +1,15 @@
1
- ## Notify Me Widget
1
+ ### Coming Soon/Notify Me Widget
2
2
 
3
- This widget allows users to sign up for notifications when a specific product variant is back in stock. The widget can be integrated into a Shopify store or any other e-commerce platform. Users can provide their email, mobile number, and name to register their interest.
3
+ This JavaScript widget allows users to register their interest in a product that is either "coming soon" or "out of stock". Depending on the `data-type` attribute provided, the widget will display appropriate messages and functionality.
4
4
 
5
- ### Features
6
-
7
- - Dynamic form fields based on data attributes
8
- - Customizable styling
9
- - Integration with an external Wishlist API to handle form submissions
5
+ #### Features:
6
+ - Dynamically display a form to collect user information (email, mobile, first name, last name).
7
+ - Adjust form and button text based on the widget type (`notify-me` or `coming-soon`).
8
+ - Submit user data to a specified API endpoint with email or mobile as a path parameter and appropriate query parameters.
10
9
 
11
10
  ### Installation
12
11
 
13
- Include the widget script in your HTML file:
12
+ Add the following script to your HTML to include the widget:
14
13
 
15
14
  ```html
16
15
  <script src="https://cdn.jsdelivr.net/npm/notify-me-wl/index.js"></script>
@@ -18,73 +17,60 @@ Include the widget script in your HTML file:
18
17
 
19
18
  ### Usage
20
19
 
21
- 1. Add a button to your HTML where the widget will be initialized. The button should have an ID of `popup-open` and a `data-fields` attribute that specifies the fields to be included in the form:
20
+ Add a button to your HTML where you want the widget to appear. The button should have an `id` of `popup-open`, a `data-fields` attribute with the fields you want to include in the form (as a JSON string), and a `data-type` attribute to specify the widget type (`notify-me` or `coming-soon`).
22
21
 
23
22
  ```html
24
- <div id="notify-me">
25
- <button id="popup-open" class="notify-me-btn" type="button" data-fields='["email", "mobile", "firstName", "lastName"]'>NOTIFY ME - JOIN WAITLIST</button>
26
- </div>
23
+ <div id="notification-widget"></div>
24
+ <button id="popup-open" data-fields='["email", "mobile", "firstName", "lastName"]' data-type="notify-me">Open Popup</button>
27
25
  ```
28
26
 
29
- 2. The script will automatically create a popup form with the specified fields when the button is clicked.
30
-
31
- ### Customization
32
-
33
- #### Fields
34
-
35
- The `data-fields` attribute on the button determines which fields will be included in the form. Possible values include:
27
+ ### Configuration
36
28
 
37
- - `email`
38
- - `mobile`
39
- - `firstName`
40
- - `lastName`
29
+ - `data-fields`: A JSON array specifying the fields to include in the form. Possible values are `"email"`, `"mobile"`, `"firstName"`, and `"lastName"`.
30
+ - `data-type`: Specifies the type of the widget. Possible values are `"notify-me"` and `"coming-soon"`.
41
31
 
42
- Example:
32
+ ### Example
43
33
 
44
34
  ```html
45
- <button id="popup-open" class="notify-me-btn" type="button" data-fields='["email", "mobile"]'>NOTIFY ME - JOIN WAITLIST</button>
46
- ```
35
+ <div id="notification-widget"></div>
36
+ <button id="popup-open" data-fields='["email", "mobile"]' data-type="notify-me">Open Popup</button>
47
37
 
48
- #### Styles
38
+ <script>
39
+ // The script provided will be included here
40
+ </script>
41
+ ```
49
42
 
50
- The widget includes default styles for the button and popup form. You can customize these styles by modifying the `styles` variable in the JavaScript file or by overriding the styles in your own CSS.
43
+ ### How It Works
51
44
 
52
- ### API Integration
45
+ 1. **Initialization**: The script listens for the `DOMContentLoaded` event to initialize the widget.
46
+ 2. **Styles Injection**: It injects necessary styles for the modal and form elements.
47
+ 3. **Modal Creation**: Creates the modal structure and appends it to the `notification-widget` div.
48
+ 4. **Dynamic Content**: Based on the `data-type`, it sets the appropriate messages and button text.
49
+ 5. **Form Submission**: Collects form data and submits it to the API with the email or mobile number as a path parameter. If a mobile number is provided, it also appends `isMobile=true` to the query string.
53
50
 
54
- The widget sends the form data to the specified API endpoint:
51
+ ### API Request Example
55
52
 
56
- ```plaintext
57
- https://api.au-sandbox.thewishlist.io/services/wsservice/api/wishlist/items/customerInterest
53
+ For email:
54
+ ```
55
+ https://api.au-aws.thewishlist.io/services/wsservice/api/wishlist/items/customerInterest/{email}
58
56
  ```
59
57
 
60
- #### Example Payload
61
-
62
- ```json
63
- {
64
- "productRef": 6786188247105,
65
- "variantRef": 1,
66
- "email": "example@example.com",
67
- "mobile": "1234567890",
68
- "firstName": "John",
69
- "lastName": "Doe",
70
- "isMobile": true
71
- }
58
+ For mobile:
59
+ ```
60
+ https://api.au-aws.thewishlist.io/services/wsservice/api/wishlist/items/customerInterest/{mobile}?isMobile=true
72
61
  ```
73
62
 
74
- ### Complete HTML Example
63
+ ### Full Script
75
64
 
76
- Here is a complete example of an HTML file that includes the Notify Me Widget:
65
+ ```javascript
66
+ const ACCESS_TOKEN = "123"; // // Replace `ACCESS_TOKEN` with your actual access token to authenticate API requests.
77
67
 
78
- ```html
79
- <!DOCTYPE html>
80
- <html lang="en">
81
- <head>
82
- <meta charset="UTF-8">
83
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
84
- <title>Notify Me Widget</title>
85
- <style>
86
- /* Custom styles for the button and popup form */
87
- .notify-me-btn {
68
+ document.addEventListener("DOMContentLoaded", function () {
69
+ const wrapper = document.getElementById("notification-widget");
70
+ if (!wrapper) return;
71
+
72
+ const styles = `
73
+ .notification-btn {
88
74
  background-color: #fff;
89
75
  border: 1px solid black;
90
76
  color: black;
@@ -196,15 +182,170 @@ Here is a complete example of an HTML file that includes the Notify Me Widget:
196
182
  border-top: var(--size) solid black;
197
183
  top: 55%;
198
184
  }
199
- </style>
200
- </head>
201
- <body>
202
- <div id="notify-me">
203
- <button id="popup-open" class="notify-me-btn" type="button" data-fields='["email", "mobile", "first-name", "last-name"]'>NOTIFY ME - JOIN WAITLIST</button>
204
- </div>
185
+ `;
186
+
187
+ const styleSheet = document.createElement("style");
188
+ styleSheet.type = "text/css";
189
+ styleSheet.innerText = styles;
190
+ document.head.appendChild(styleSheet);
191
+
192
+ const overlay = document.createElement("div");
193
+ overlay.innerHTML = `
194
+ <div id="popup-body" class="overlay">
195
+ <div id="popup-wrapper">
196
+ <h3 id="popup-title"></h3>
197
+ <span id="popup-close">&times;</span>
198
+ <div id="popup-text"></div>
199
+ <form id="popup-form">
200
+ <div class="custom-select">
201
+ <select name="select-size" required>
202
+ </select>
203
+ </div>
204
+ </form>
205
+ </div>
206
+ </div>
207
+ `;
208
+
209
+ wrapper.appendChild(overlay);
210
+
211
+ const popupBody = document.getElementById("popup-body");
212
+ const popupClose = document.getElementById("popup-close");
213
+ const popupOpenButton = document.getElementById("popup-open");
214
+ const popupTitle = document.getElementById("popup-title");
215
+ const popupText = document.getElementById("popup-text");
216
+ const sizeSelect = document.querySelector("select[name='select-size']");
217
+ const form = overlay.querySelector("#popup-form");
218
+
219
+ if (!popupBody || !popupClose || !popupOpenButton || !popupTitle || !sizeSelect) return;
220
+
221
+ const fields = JSON.parse(popupOpenButton.getAttribute("data-fields") || '["email"]');
222
+ const type = popupOpenButton.getAttribute("data-type") || "notify-me";
223
+
224
+ const typeConfig = {
225
+ "notify-me": {
226
+ text: "Register to receive a notification as soon as this item is back in stock",
227
+ buttonText: "Notify me",
228
+ },
229
+ "coming-soon": {
230
+ text: "Register your interest to hear more about this item",
231
+ buttonText: "Register Interest",
232
+ },
233
+ };
234
+
235
+ // Get product data from Shopify's global variable
236
+ const productData = window.Shopify?.product || {
237
+ id: 6786188247105,
238
+ title: "THE ATG SCULPT FLARES TALL",
239
+ product_option_value: {
240
+ name: "BUTTER BLACK",
241
+ },
242
+ variants: [
243
+ { id: 1, title: "S" },
244
+ { id: 2, title: "M" },
245
+ { id: 3, title: "L" },
246
+ { id: 4, title: "XL" },
247
+ ],
248
+ };
249
+
250
+ popupTitle.innerHTML = productData.title + "<br/>" + productData.product_option_value.name;
251
+ popupText.innerText = typeConfig[type].text;
252
+ productData.variants.forEach((variant) => {
253
+ const option = document.createElement("option");
254
+ option.value = variant.title;
255
+ option.textContent = variant.title;
256
+ sizeSelect.appendChild(option);
257
+ });
258
+
259
+ const fieldMap = {
260
+ email: `<input name="email" placeholder="Email" type="email" required />`,
261
+ mobile: `<input name="mobile" placeholder="Mobile"
262
+
263
+ type="tel" required />`,
264
+ firstName: `<input name="firstName" placeholder="First name" type="text" required />`,
265
+ lastName: `<input name="lastName" placeholder="Last name" type="text" required />`,
266
+ };
267
+
268
+ fields.forEach((field) => {
269
+ if (fieldMap[field]) {
270
+ form.insertAdjacentHTML("beforeend", fieldMap[field]);
271
+ }
272
+ });
273
+ form.insertAdjacentHTML("beforeend", `<button type="submit">${typeConfig[type].buttonText}</button>`);
274
+
275
+ function showPopup() {
276
+ popupBody.style.visibility = "visible";
277
+ popupBody.style.opacity = 1;
278
+ }
279
+
280
+ function hidePopup() {
281
+ popupBody.style.visibility = "hidden";
282
+ popupBody.style.opacity = 0;
283
+ }
284
+
285
+ popupOpenButton.addEventListener("click", showPopup);
286
+ popupClose.addEventListener("click", hidePopup);
287
+
288
+ if (form) {
289
+ form.addEventListener("submit", function (event) {
290
+ event.preventDefault();
291
+
292
+ const selectedSize = sizeSelect.value;
293
+ const selectedVariant = productData.variants.find((variant) => variant.title === selectedSize);
294
+
295
+ if (selectedVariant) {
296
+ const formData = {
297
+ productRef: productData.id,
298
+ variantRef: selectedVariant.id,
299
+ };
300
+
301
+ let contactInfo = "";
302
+ if (fields.includes("email")) {
303
+ formData.email = form.querySelector("input[name='email']").value;
304
+ contactInfo = formData.email;
305
+ }
306
+ if (fields.includes("firstName")) {
307
+ formData.firstName = form.querySelector("input[name='firstName']").value;
308
+ }
309
+ if (fields.includes("lastName")) {
310
+ formData.lastName = form.querySelector("input[name='lastName']").value;
311
+ }
312
+ if (fields.includes("mobile")) {
313
+ formData.mobile = form.querySelector("input[name='mobile']").value;
314
+ formData.isMobile = true;
315
+ contactInfo = formData.mobile;
316
+ }
317
+
318
+ let url = `https://api.au-aws.thewishlist.io/services/wsservice/api/wishlist/items/customerInterest/${contactInfo}?notifyMe=true`;
319
+ if (formData.isMobile) {
320
+ url += "&isMobile=true";
321
+ }
205
322
 
206
- <script src="https://cdn.jsdelivr.net/npm/notify-me-wl/index.js"></script>
207
- </body>
208
- </html>
323
+ fetch(url, {
324
+ method: "POST",
325
+ headers: {
326
+ "Content-Type": "application/json",
327
+ Authorization: ACCESS_TOKEN,
328
+ },
329
+ body: JSON.stringify(formData),
330
+ })
331
+ .then((response) => {
332
+ if (response.ok) {
333
+ alert("Form submitted");
334
+ hidePopup();
335
+ } else {
336
+ alert("Form submission failed");
337
+ }
338
+ })
339
+ .catch((error) => {
340
+ console.error("Error submitting form:", error);
341
+ alert("Form submission failed");
342
+ });
343
+ } else {
344
+ alert("Selected variant not found");
345
+ }
346
+ });
347
+ }
348
+ });
209
349
  ```
210
350
 
351
+ Replace `ACCESS_TOKEN` with your actual access token to authenticate API requests.
package/index.html CHANGED
@@ -13,9 +13,9 @@
13
13
  </style>
14
14
  </head>
15
15
  <body>
16
- <div id="notify-me">
17
- <button id="popup-open" class="notify-me-btn" data-fields='["email", "mobile"]' type="button">NOTIFY ME - JOIN WAITLIST</button>
18
- </div>
16
+ <div id="notification-widget">
17
+ <button id="popup-open" class="notification-btn" type="button" data-type="notify-me" data-fields='["email", "mobile", "firstName", "lastName"]'>Notify Me - Join Waitlist</button>
18
+ </div>
19
19
  </body>
20
20
  <script src="/index.js"></script>
21
21
  </html>
package/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  // Access token for the API
2
- const ACCESS_TOKEN = "123";
2
+ const ACCESS_TOKEN = "123"; // Replace `ACCESS_TOKEN` with your actual access token to authenticate API requests.
3
3
 
4
4
  document.addEventListener("DOMContentLoaded", function () {
5
- const wrapper = document.getElementById("notify-me");
5
+ const wrapper = document.getElementById("notification-widget");
6
6
  if (!wrapper) return;
7
7
 
8
8
  // Define and apply styles for the popup and button
9
9
  const styles = `
10
- .notify-me-btn {
10
+ .notification-btn {
11
11
  background-color: #fff;
12
12
  border: 1px solid black;
13
13
  color: black;
@@ -133,7 +133,7 @@ document.addEventListener("DOMContentLoaded", function () {
133
133
  <div id="popup-wrapper">
134
134
  <h3 id="popup-title"></h3>
135
135
  <span id="popup-close">&times;</span>
136
- <div id="popup-text">Register to receive a notification as soon as this item is back in stock</div>
136
+ <div id="popup-text"></div>
137
137
  <form id="popup-form">
138
138
  <div class="custom-select">
139
139
  <select name="select-size" required>
@@ -150,13 +150,25 @@ document.addEventListener("DOMContentLoaded", function () {
150
150
  const popupClose = document.getElementById("popup-close");
151
151
  const popupOpenButton = document.getElementById("popup-open");
152
152
  const popupTitle = document.getElementById("popup-title");
153
+ const popupText = document.getElementById("popup-text");
153
154
  const sizeSelect = document.querySelector("select[name='select-size']");
154
155
  const form = overlay.querySelector("#popup-form");
155
156
 
156
157
  if (!popupBody || !popupClose || !popupOpenButton || !popupTitle || !sizeSelect) return;
157
158
 
158
- // Parse fields to be included in the form from data attribute
159
+ // Parse fields and type to be included in the form from data attribute
159
160
  const fields = JSON.parse(popupOpenButton.getAttribute("data-fields") || '["email"]');
161
+ const type = popupOpenButton.getAttribute("data-type") || "notify-me";
162
+ const typeConfig = {
163
+ "notify-me": {
164
+ text: "Register to receive a notification as soon as this item is back in stock",
165
+ buttonText: "Notify me",
166
+ },
167
+ "coming-soon": {
168
+ text: "Register your interest to hear more about this item",
169
+ buttonText: "Register Interest",
170
+ },
171
+ };
160
172
 
161
173
  // Get product data from Shopify's global variable
162
174
  const productData = window.Shopify?.product || {
@@ -183,6 +195,15 @@ document.addEventListener("DOMContentLoaded", function () {
183
195
  });
184
196
 
185
197
  // Map for form fields
198
+ popupTitle.innerHTML = productData.title + "<br/>" + productData.product_option_value.name;
199
+ popupText.innerText = typeConfig[type].text;
200
+ productData.variants.forEach((variant) => {
201
+ const option = document.createElement("option");
202
+ option.value = variant.title;
203
+ option.textContent = variant.title;
204
+ sizeSelect.appendChild(option);
205
+ });
206
+
186
207
  const fieldMap = {
187
208
  email: `<input name="email" placeholder="Email" type="email" required />`,
188
209
  mobile: `<input name="mobile" placeholder="Mobile" type="tel" required />`,
@@ -196,7 +217,7 @@ document.addEventListener("DOMContentLoaded", function () {
196
217
  form.insertAdjacentHTML("beforeend", fieldMap[field]);
197
218
  }
198
219
  });
199
- form.insertAdjacentHTML("beforeend", `<button type="submit">Notify me</button>`);
220
+ form.insertAdjacentHTML("beforeend", `<button type="submit">${typeConfig[type].buttonText}</button>`);
200
221
 
201
222
  // Show/hide the popup
202
223
  function showPopup() {
@@ -227,20 +248,21 @@ document.addEventListener("DOMContentLoaded", function () {
227
248
  };
228
249
 
229
250
  if (fields.includes("email")) {
230
- formData.email = form.querySelector("input[type='email']").value;
251
+ formData.email = form.querySelector("input[name='email']").value;
231
252
  }
232
253
  if (fields.includes("firstName")) {
233
- formData.firstName = form.querySelector("input[placeholder='First name']").value;
254
+ formData.firstName = form.querySelector("input[name='firstName']").value;
234
255
  }
235
256
  if (fields.includes("lastName")) {
236
- formData.lastName = form.querySelector("input[placeholder='Last name']").value;
257
+ formData.lastName = form.querySelector("input[name='lastName']").value;
237
258
  }
238
259
  if (fields.includes("mobile")) {
239
- formData.mobile = form.querySelector("input[type='tel']").value;
240
- formData.isMobile = true;
260
+ formData.mobile = form.querySelector("input[name='mobile']").value;
241
261
  }
242
262
 
243
- fetch(`https://api.au-sandbox.thewishlist.io/services/wsservice/api/wishlist/items/customerInterest/${formData.email || formData.mobile}`, {
263
+ let url = `https://api.au-aws.thewishlist.io/services/wsservice/api/wishlist/items/customerInterest`;
264
+
265
+ fetch(url, {
244
266
  method: "POST",
245
267
  headers: {
246
268
  "Content-Type": "application/json",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "notify-me-wl",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"