wineater-bot 1.6.1 → 1.7.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.
@@ -282,35 +282,35 @@ g.textContent = b;
282
282
  document.head.appendChild(g);
283
283
  function y() {
284
284
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(o) {
285
- const t = Math.random() * 16 | 0;
286
- return (o === "x" ? t : t & 3 | 8).toString(16);
285
+ const e = Math.random() * 16 | 0;
286
+ return (o === "x" ? e : e & 3 | 8).toString(16);
287
287
  });
288
288
  }
289
- function h(o, t, e) {
289
+ function h(o, e, t) {
290
290
  let n = "";
291
- if (e) {
291
+ if (t) {
292
292
  const i = /* @__PURE__ */ new Date();
293
- i.setTime(i.getTime() + e * 24 * 60 * 60 * 1e3), n = "; expires=" + i.toUTCString();
293
+ i.setTime(i.getTime() + t * 24 * 60 * 60 * 1e3), n = "; expires=" + i.toUTCString();
294
294
  }
295
- document.cookie = o + "=" + (t || "") + n + "; path=/; secure; samesite=strict";
295
+ document.cookie = o + "=" + (e || "") + n + "; path=/; secure; samesite=strict";
296
296
  }
297
297
  function s(o) {
298
- const t = o + "=", e = document.cookie.split(";");
299
- for (let n = 0; n < e.length; n++) {
300
- let i = e[n];
298
+ const e = o + "=", t = document.cookie.split(";");
299
+ for (let n = 0; n < t.length; n++) {
300
+ let i = t[n];
301
301
  for (; i.charAt(0) === " "; )
302
302
  i = i.substring(1, i.length);
303
- if (i.indexOf(t) === 0)
304
- return i.substring(t.length, i.length);
303
+ if (i.indexOf(e) === 0)
304
+ return i.substring(e.length, i.length);
305
305
  }
306
306
  return null;
307
307
  }
308
308
  function x() {
309
309
  const o = "uniqueUserID";
310
- let t = s(o);
311
- return t || (t = y(), h(o, t, 365)), t;
310
+ let e = s(o);
311
+ return e || (e = y(), h(o, e, 365)), e;
312
312
  }
313
- function d(o, t) {
313
+ function d(o, e) {
314
314
  fetch("https://api.wineater.com/proxy/track", {
315
315
  method: "POST",
316
316
  headers: {
@@ -318,7 +318,7 @@ function d(o, t) {
318
318
  },
319
319
  body: JSON.stringify({
320
320
  event: o,
321
- properties: t
321
+ properties: e
322
322
  })
323
323
  }).then((i) => {
324
324
  i.ok || console.error("Mixpanel tracking failed", i);
@@ -342,8 +342,8 @@ function k(o) {
342
342
  d("Product Clicked", { distinct_id: s("uniqueUserID"), product_id: o, client: s("chatbotToken") });
343
343
  }
344
344
  function m() {
345
- const o = document.getElementById("chat-window"), t = document.getElementById("chat-icon");
346
- o.classList.contains("visible") ? (u(), o.classList.remove("visible"), t.style.display = "flex") : (p(), o.classList.add("visible"), t.style.display = "none");
345
+ const o = document.getElementById("chat-window"), e = document.getElementById("chat-icon");
346
+ o.classList.contains("visible") ? (u(), o.classList.remove("visible"), e.style.display = "flex") : (p(), o.classList.add("visible"), e.style.display = "none");
347
347
  }
348
348
  function I() {
349
349
  u(), document.getElementById("chat-window").classList.remove("visible");
@@ -356,44 +356,44 @@ document.addEventListener("DOMContentLoaded", () => {
356
356
  });
357
357
  const C = ["climats", "telckel", "biobio", "weinpoint", "vinigrandi"], T = "OuhXJRleF6sROjsQZPWx1yqjrL6APeJxmHswqyOBWbgIqtXcht3MDadvI9DtOOoL";
358
358
  class f {
359
- constructor(t) {
360
- var e;
361
- this.baseURL = "https://api.wineater.com/", this.store = C.find((n) => window.location.href.includes(n)), this.token = ((e = window == null ? void 0 : window.wineaterData) == null ? void 0 : e.CLIENT_TOKEN) || T;
359
+ constructor(e) {
360
+ var t;
361
+ this.baseURL = "http://localhost:3000/", this.store = C.find((n) => window.location.href.includes(n)), this.token = ((t = window == null ? void 0 : window.wineaterData) == null ? void 0 : t.CLIENT_TOKEN) || T;
362
362
  }
363
- async getStoreConfig(t) {
364
- console.log(t);
363
+ async getStoreConfig(e) {
364
+ console.log(e);
365
365
  try {
366
- const e = await fetch(`${this.baseURL}stores/store`, {
366
+ const t = await fetch(`${this.baseURL}stores/store`, {
367
367
  method: "POST",
368
368
  headers: {
369
369
  "Content-Type": "application/json",
370
370
  Authorization: `Bearer ${this.token}`
371
371
  },
372
- body: JSON.stringify({ store: t })
372
+ body: JSON.stringify({ store: e })
373
373
  });
374
- if (!e.ok)
375
- throw new Error(`HTTP error! Status: ${e.status}`);
376
- return await e.json();
377
- } catch (e) {
378
- throw console.error("Error fetching store configuration:", e), e;
374
+ if (!t.ok)
375
+ throw new Error(`HTTP error! Status: ${t.status}`);
376
+ return await t.json();
377
+ } catch (t) {
378
+ throw console.error("Error fetching store configuration:", t), t;
379
379
  }
380
380
  }
381
- async getWineRecommendations(t) {
381
+ async getWineRecommendations(e) {
382
382
  console.log(window.location.href);
383
383
  try {
384
- const e = await fetch(`${this.baseURL}dish/recommendations`, {
384
+ const t = await fetch(`${this.baseURL}dish/recommendations`, {
385
385
  method: "POST",
386
386
  headers: {
387
387
  "Content-Type": "application/json",
388
388
  Authorization: `Bearer ${this.token}`
389
389
  },
390
- body: JSON.stringify({ text: t, store: this.store ? this.store.toString().charAt(0).toUpperCase() + this.store.slice(1) : void 0 })
391
- }), n = await e.json();
392
- if (!e.ok)
393
- throw new Error(`API call failed with status ${e.status}: ${n.message || "No additional error information"}`);
390
+ body: JSON.stringify({ text: e, store: this.store ? this.store.toString().charAt(0).toUpperCase() + this.store.slice(1) : void 0 })
391
+ }), n = await t.json();
392
+ if (!t.ok)
393
+ throw new Error(`API call failed with status ${t.status}: ${n.message || "No additional error information"}`);
394
394
  return n;
395
- } catch (e) {
396
- throw console.error("Fetching wine recommendations failed:", e.message), new Error(`Error in getWineRecommendations: ${e.message}`);
395
+ } catch (t) {
396
+ throw console.error("Fetching wine recommendations failed:", t.message), new Error(`Error in getWineRecommendations: ${t.message}`);
397
397
  }
398
398
  }
399
399
  }
@@ -454,39 +454,41 @@ class B {
454
454
  }
455
455
  };
456
456
  }
457
- async fetchConfig(t = "Demo") {
457
+ async fetchConfig(e = "Demo") {
458
458
  try {
459
- const e = await this.api.getStoreConfig(t);
460
- this.language = e.lang;
459
+ const t = await this.api.getStoreConfig(e);
460
+ this.language = t.lang;
461
461
  } catch {
462
462
  this.language = "en";
463
463
  }
464
464
  }
465
- translate(t) {
466
- return this.translations[this.language][t] || t;
465
+ translate(e) {
466
+ return this.translations[this.language][e] || e;
467
467
  }
468
468
  }
469
469
  const a = new B();
470
- class W {
470
+ class S {
471
471
  constructor() {
472
- this.api = new f(), this.displayFirstMessage(a.translate("welcomeMessage"));
472
+ this.api = new f();
473
+ const e = window.wineaterData.FIRST_MESSAGE_TEXT || a.translate("welcomeMessage");
474
+ this.displayFirstMessage(e);
473
475
  }
474
476
  initialize() {
475
477
  document.getElementById("send-button").addEventListener("click", () => this.handleUserInput()), document.getElementById("user-input").addEventListener("keypress", (n) => {
476
478
  n.key === "Enter" && this.handleUserInput();
477
479
  });
478
480
  }
479
- displayFirstMessage(t, e = "api") {
481
+ displayFirstMessage(e, t = "api") {
480
482
  const n = document.getElementById("message-container"), i = document.createElement("div");
481
- i.className = `message ${e}`, i.textContent = t, n.appendChild(i), n.scrollTop = n.scrollHeight;
483
+ i.className = `message ${t}`, i.textContent = e, n.appendChild(i), n.scrollTop = n.scrollHeight;
482
484
  }
483
485
  async handleUserInput() {
484
- const t = document.getElementById("user-input"), e = t.value.trim();
485
- if (e) {
486
- this.displayMessage(e, "user"), t.value = "", this.showTypingIndicator();
486
+ const e = document.getElementById("user-input"), t = e.value.trim();
487
+ if (t) {
488
+ this.displayMessage(t, "user"), e.value = "", this.showTypingIndicator();
487
489
  try {
488
- w(e);
489
- const n = await this.api.getWineRecommendations(e);
490
+ w(t);
491
+ const n = await this.api.getWineRecommendations(t);
490
492
  this.hideTypingIndicator(), n && n.length ? this.displayResults(n) : this.displayMessage("No results found.", "api");
491
493
  } catch {
492
494
  this.hideTypingIndicator(), this.displayMessage(a.translate("somethingWentWrong"), "api");
@@ -499,16 +501,16 @@ class W {
499
501
  hideTypingIndicator() {
500
502
  document.getElementById("typing-indicator").classList.remove("visible");
501
503
  }
502
- displayMessage(t, e) {
504
+ displayMessage(e, t) {
503
505
  const n = document.getElementById("message-container"), i = document.createElement("div");
504
- i.textContent = t, i.className = "message " + e, n.appendChild(i), n.scrollTop = n.scrollHeight;
506
+ i.textContent = e, i.className = "message " + t, n.appendChild(i), n.scrollTop = n.scrollHeight;
505
507
  }
506
- sendAnalytics(t) {
507
- k(t);
508
+ sendAnalytics(e) {
509
+ k(e);
508
510
  }
509
- displayResults(t) {
510
- const e = document.getElementById("message-container");
511
- v(t.map((n) => n.Title)), t.forEach((n) => {
511
+ displayResults(e) {
512
+ const t = document.getElementById("message-container");
513
+ v(e.map((n) => n.Title)), e.forEach((n) => {
512
514
  const i = document.createElement("div");
513
515
  i.className = "wine-item";
514
516
  const r = document.createElement("img");
@@ -520,20 +522,20 @@ class W {
520
522
  ${a.translate("region")}: ${n.Region}<br>
521
523
  ${a.translate("type")}: ${n.Type}<br>
522
524
  <a href="${n.Url}" onclick="sendAnalytics(${n.Title})" target="_blank">${a.translate("moreInfo")}</a>
523
- `, i.appendChild(c), e.appendChild(i), this.displayFirstMessage(n.Reason);
524
- }), e.scrollTop = e.scrollHeight;
525
+ `, i.appendChild(c), t.appendChild(i), this.displayFirstMessage(n.Reason);
526
+ }), t.scrollTop = t.scrollHeight;
525
527
  }
526
528
  }
527
- const L = "OuhXJRleF6sROjsQZPWx1yqjrL6APeJxmHswqyOBWbgIqtXcht3MDadvI9DtOOoL";
529
+ const W = "OuhXJRleF6sROjsQZPWx1yqjrL6APeJxmHswqyOBWbgIqtXcht3MDadvI9DtOOoL";
528
530
  document.addEventListener("DOMContentLoaded", () => {
529
531
  window.toggleChatWindow = m, window.closeChatWindow = I, window.openChatWindow = E;
530
532
  });
531
- function P() {
532
- const o = `
533
+ function L() {
534
+ const e = `
533
535
  <div id="chatbot-container">
534
536
  <div id="chat-icon" onclick="toggleChatWindow()">
535
537
  <img src="https://landing-static.s3.eu-central-1.amazonaws.com/images/chat-icon.svg" alt="Chat Icon"> <!-- Update the path to your logo image -->
536
- <span>${a.translate("chatButton")}</span>
538
+ <span>${window.wineaterData.BUTTON_TEXT || a.translate("chatButton")}</span>
537
539
  </div>
538
540
 
539
541
  <div id="chat-window" class="hidden">
@@ -558,30 +560,30 @@ function P() {
558
560
  </div>
559
561
  </div>
560
562
  `;
561
- document.body.insertAdjacentHTML("beforeend", o);
563
+ document.body.insertAdjacentHTML("beforeend", e);
562
564
  }
563
- function S() {
565
+ function P() {
564
566
  document.getElementById("close-btn").addEventListener("click", m);
565
567
  }
566
568
  function O() {
567
569
  window.addEventListener("click", function(o) {
568
- const t = document.getElementById("chat-window"), e = document.getElementById("chat-icon");
569
- !t.contains(o.target) && !e.contains(o.target) && (t.classList.remove("visible"), e.style.display = "flex");
570
+ const e = document.getElementById("chat-window"), t = document.getElementById("chat-icon");
571
+ !e.contains(o.target) && !t.contains(o.target) && (e.classList.remove("visible"), t.style.display = "flex");
570
572
  });
571
573
  }
572
574
  function M(o) {
573
575
  console.log(o);
574
- const t = document.getElementById("chat-icon"), e = document.getElementById("chat-window");
575
- t.className = "", e.className = "", o === "right-center" ? (t.classList.add("chat-icon-right-center"), e.classList.add("right-center-aligned")) : t.classList.add("chat-icon-bottom-right");
576
+ const e = document.getElementById("chat-icon"), t = document.getElementById("chat-window");
577
+ e.className = "", t.className = "", o === "right-center" ? (e.classList.add("chat-icon-right-center"), t.classList.add("right-center-aligned")) : e.classList.add("chat-icon-bottom-right");
576
578
  }
577
579
  var l;
578
580
  if (typeof window < "u") {
579
581
  let o = ((l = window.wineaterData) == null ? void 0 : l.POSITION) || "bottom-right";
580
582
  window.addEventListener("DOMContentLoaded", async () => {
581
583
  var r;
582
- const e = ["climats", "telckel", "biobio", "weinpoint", "vinigrandi"].find((c) => window.location.href.includes(c)) || null;
584
+ const t = ["climats", "telckel", "biobio", "weinpoint", "vinigrandi"].find((c) => window.location.href.includes(c)) || null;
583
585
  let n;
584
- e && (n = e.charAt(0).toUpperCase() + e.slice(1), n === "Biobio" && (o = "right-center")), await a.fetchConfig(n || "Demo"), P(), S(), O(), M(o), h("chatbotToken", ((r = window.wineaterData) == null ? void 0 : r.CLIENT_TOKEN) || L, 365), x(), new W().initialize();
586
+ t && (n = t.charAt(0).toUpperCase() + t.slice(1), n === "Biobio" && (o = "right-center")), await a.fetchConfig(n || "Demo"), L(), P(), O(), M(o), h("chatbotToken", ((r = window.wineaterData) == null ? void 0 : r.CLIENT_TOKEN) || W, 365), x(), new S().initialize();
585
587
  });
586
588
  }
587
589
  export {
@@ -1,4 +1,4 @@
1
- (function(r,d){typeof exports=="object"&&typeof module<"u"?d(exports):typeof define=="function"&&define.amd?define(["exports"],d):(r=typeof globalThis<"u"?globalThis:r||self,d(r.WineaterChatbot={}))})(this,function(r){"use strict";var w;const d=`
1
+ (function(r,d){typeof exports=="object"&&typeof module<"u"?d(exports):typeof define=="function"&&define.amd?define(["exports"],d):(r=typeof globalThis<"u"?globalThis:r||self,d(r.WineaterChatbot={}))})(this,function(r){"use strict";var x;const d=`
2
2
  @font-face {
3
3
  font-family: 'Poppins';
4
4
  src: url('https://fonts.googleapis.com/css2?family=Poppins:wght@400&display=swap');
@@ -277,17 +277,17 @@
277
277
  .typing-indicator.visible {
278
278
  visibility: visible;
279
279
  height: 50px;
280
- }`,p=document.createElement("style");p.textContent=d,document.head.appendChild(p);function v(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(o){const t=Math.random()*16|0;return(o==="x"?t:t&3|8).toString(16)})}function u(o,t,e){let n="";if(e){const i=new Date;i.setTime(i.getTime()+e*24*60*60*1e3),n="; expires="+i.toUTCString()}document.cookie=o+"="+(t||"")+n+"; path=/; secure; samesite=strict"}function s(o){const t=o+"=",e=document.cookie.split(";");for(let n=0;n<e.length;n++){let i=e[n];for(;i.charAt(0)===" ";)i=i.substring(1,i.length);if(i.indexOf(t)===0)return i.substring(t.length,i.length)}return null}function k(){const o="uniqueUserID";let t=s(o);return t||(t=v(),u(o,t,365)),t}function c(o,t){fetch("https://api.wineater.com/proxy/track",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({event:o,properties:t})}).then(i=>{i.ok||console.error("Mixpanel tracking failed",i)}).catch(i=>{console.error("Mixpanel tracking error",i)})}function m(){c("Chatbot Opened",{distinct_id:s("uniqueUserID"),client:s("chatbotToken")})}function f(){c("Chatbot Closed",{distinct_id:s("uniqueUserID"),client:s("chatbotToken")})}function I(o){c("Message Sent",{distinct_id:s("uniqueUserID"),message_content:o,client:s("chatbotToken")})}function C(o){c("Products Got",{distinct_id:s("uniqueUserID"),products:o,client:s("chatbotToken")})}function E(o){c("Product Clicked",{distinct_id:s("uniqueUserID"),product_id:o,client:s("chatbotToken")})}function h(){const o=document.getElementById("chat-window"),t=document.getElementById("chat-icon");o.classList.contains("visible")?(f(),o.classList.remove("visible"),t.style.display="flex"):(m(),o.classList.add("visible"),t.style.display="none")}function b(){f(),document.getElementById("chat-window").classList.remove("visible")}function y(){m(),document.getElementById("chat-window").classList.add("visible")}document.addEventListener("DOMContentLoaded",()=>{setupCloseButton(),setupOutsideClick()});const T=["climats","telckel","biobio","weinpoint","vinigrandi"],B="OuhXJRleF6sROjsQZPWx1yqjrL6APeJxmHswqyOBWbgIqtXcht3MDadvI9DtOOoL";class x{constructor(t){var e;this.baseURL="https://api.wineater.com/",this.store=T.find(n=>window.location.href.includes(n)),this.token=((e=window==null?void 0:window.wineaterData)==null?void 0:e.CLIENT_TOKEN)||B}async getStoreConfig(t){console.log(t);try{const e=await fetch(`${this.baseURL}stores/store`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`},body:JSON.stringify({store:t})});if(!e.ok)throw new Error(`HTTP error! Status: ${e.status}`);return await e.json()}catch(e){throw console.error("Error fetching store configuration:",e),e}}async getWineRecommendations(t){console.log(window.location.href);try{const e=await fetch(`${this.baseURL}dish/recommendations`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`},body:JSON.stringify({text:t,store:this.store?this.store.toString().charAt(0).toUpperCase()+this.store.slice(1):void 0})}),n=await e.json();if(!e.ok)throw new Error(`API call failed with status ${e.status}: ${n.message||"No additional error information"}`);return n}catch(e){throw console.error("Fetching wine recommendations failed:",e.message),new Error(`Error in getWineRecommendations: ${e.message}`)}}}class W{constructor(){this.api=new x,this.language="en",this.translations={fr:{welcomeMessage:"Sublimez votre expérience gastronomique. Il vous suffit de donner les détails de votre plat, et obtenez la recommandation de compagnon de vin idéale. Que voulez-vous manger?",noResultsFound:"Aucun résultat trouvé.",somethingWentWrong:"Désolé, quelque chose a mal tourné.",chatButton:"Accorder le vin au dîner",inputPlaceholder:"ex., Salade de thon",sendButton:"Accorder",price:"Prix",region:"Région",type:"Type",reason:"Suggestion",moreInfo:"Plus d'infos"},es:{welcomeMessage:"Mejore su experiencia gastronómica. Solo proporcione los detalles de su plato y obtenga la recomendación de vino ideal. ¿Qué le gustaría comer?",noResultsFound:"No se encontraron resultados.",somethingWentWrong:"Lo sentimos, algo salió mal.",chatButton:"Maridar vino con cena",inputPlaceholder:"ej., Ensalada de atún",sendButton:"Maridar",price:"Precio",region:"Región",type:"Tipo",reason:"Sugerencia",moreInfo:"Más info"},en:{welcomeMessage:"Enhance your dining experience. Just provide your dish details and get the ideal wine pairing. What would you like to eat?",noResultsFound:"No results found.",somethingWentWrong:"Sorry, something went wrong.",chatButton:"Pair wine with dinner",inputPlaceholder:"e.g., Tuna Salad",sendButton:"Pair",price:"Price",region:"Region",type:"Type",reason:"Suggestion",moreInfo:"More info"},de:{welcomeMessage:"Verbessern Sie Ihr kulinarisches Erlebnis. Geben Sie einfach die Details Ihres Gerichts an und erhalten Sie die ideale Weinempfehlung. Was möchten Sie essen?",noResultsFound:"Keine Ergebnisse gefunden.",somethingWentWrong:"Entschuldigung, etwas ist schief gelaufen.",chatButton:"Wein zum Abendessen",inputPlaceholder:"z.B., Thunfischsalat",sendButton:"Kombinieren",price:"Preis",region:"Region",type:"Typ",reason:"Anregung",moreInfo:"Mehr Info"}}}async fetchConfig(t="Demo"){try{const e=await this.api.getStoreConfig(t);this.language=e.lang}catch{this.language="en"}}translate(t){return this.translations[this.language][t]||t}}const a=new W;class L{constructor(){this.api=new x,this.displayFirstMessage(a.translate("welcomeMessage"))}initialize(){document.getElementById("send-button").addEventListener("click",()=>this.handleUserInput()),document.getElementById("user-input").addEventListener("keypress",n=>{n.key==="Enter"&&this.handleUserInput()})}displayFirstMessage(t,e="api"){const n=document.getElementById("message-container"),i=document.createElement("div");i.className=`message ${e}`,i.textContent=t,n.appendChild(i),n.scrollTop=n.scrollHeight}async handleUserInput(){const t=document.getElementById("user-input"),e=t.value.trim();if(e){this.displayMessage(e,"user"),t.value="",this.showTypingIndicator();try{I(e);const n=await this.api.getWineRecommendations(e);this.hideTypingIndicator(),n&&n.length?this.displayResults(n):this.displayMessage("No results found.","api")}catch{this.hideTypingIndicator(),this.displayMessage(a.translate("somethingWentWrong"),"api")}}}showTypingIndicator(){document.getElementById("typing-indicator").classList.add("visible")}hideTypingIndicator(){document.getElementById("typing-indicator").classList.remove("visible")}displayMessage(t,e){const n=document.getElementById("message-container"),i=document.createElement("div");i.textContent=t,i.className="message "+e,n.appendChild(i),n.scrollTop=n.scrollHeight}sendAnalytics(t){E(t)}displayResults(t){const e=document.getElementById("message-container");C(t.map(n=>n.Title)),t.forEach(n=>{const i=document.createElement("div");i.className="wine-item";const l=document.createElement("img");l.src=n.Image,i.appendChild(l);const g=document.createElement("div");g.innerHTML=`
280
+ }`,p=document.createElement("style");p.textContent=d,document.head.appendChild(p);function v(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(o){const e=Math.random()*16|0;return(o==="x"?e:e&3|8).toString(16)})}function u(o,e,t){let n="";if(t){const i=new Date;i.setTime(i.getTime()+t*24*60*60*1e3),n="; expires="+i.toUTCString()}document.cookie=o+"="+(e||"")+n+"; path=/; secure; samesite=strict"}function s(o){const e=o+"=",t=document.cookie.split(";");for(let n=0;n<t.length;n++){let i=t[n];for(;i.charAt(0)===" ";)i=i.substring(1,i.length);if(i.indexOf(e)===0)return i.substring(e.length,i.length)}return null}function k(){const o="uniqueUserID";let e=s(o);return e||(e=v(),u(o,e,365)),e}function c(o,e){fetch("https://api.wineater.com/proxy/track",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({event:o,properties:e})}).then(i=>{i.ok||console.error("Mixpanel tracking failed",i)}).catch(i=>{console.error("Mixpanel tracking error",i)})}function m(){c("Chatbot Opened",{distinct_id:s("uniqueUserID"),client:s("chatbotToken")})}function f(){c("Chatbot Closed",{distinct_id:s("uniqueUserID"),client:s("chatbotToken")})}function I(o){c("Message Sent",{distinct_id:s("uniqueUserID"),message_content:o,client:s("chatbotToken")})}function E(o){c("Products Got",{distinct_id:s("uniqueUserID"),products:o,client:s("chatbotToken")})}function C(o){c("Product Clicked",{distinct_id:s("uniqueUserID"),product_id:o,client:s("chatbotToken")})}function h(){const o=document.getElementById("chat-window"),e=document.getElementById("chat-icon");o.classList.contains("visible")?(f(),o.classList.remove("visible"),e.style.display="flex"):(m(),o.classList.add("visible"),e.style.display="none")}function b(){f(),document.getElementById("chat-window").classList.remove("visible")}function y(){m(),document.getElementById("chat-window").classList.add("visible")}document.addEventListener("DOMContentLoaded",()=>{setupCloseButton(),setupOutsideClick()});const T=["climats","telckel","biobio","weinpoint","vinigrandi"],B="OuhXJRleF6sROjsQZPWx1yqjrL6APeJxmHswqyOBWbgIqtXcht3MDadvI9DtOOoL";class w{constructor(e){var t;this.baseURL="http://localhost:3000/",this.store=T.find(n=>window.location.href.includes(n)),this.token=((t=window==null?void 0:window.wineaterData)==null?void 0:t.CLIENT_TOKEN)||B}async getStoreConfig(e){console.log(e);try{const t=await fetch(`${this.baseURL}stores/store`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`},body:JSON.stringify({store:e})});if(!t.ok)throw new Error(`HTTP error! Status: ${t.status}`);return await t.json()}catch(t){throw console.error("Error fetching store configuration:",t),t}}async getWineRecommendations(e){console.log(window.location.href);try{const t=await fetch(`${this.baseURL}dish/recommendations`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`},body:JSON.stringify({text:e,store:this.store?this.store.toString().charAt(0).toUpperCase()+this.store.slice(1):void 0})}),n=await t.json();if(!t.ok)throw new Error(`API call failed with status ${t.status}: ${n.message||"No additional error information"}`);return n}catch(t){throw console.error("Fetching wine recommendations failed:",t.message),new Error(`Error in getWineRecommendations: ${t.message}`)}}}class W{constructor(){this.api=new w,this.language="en",this.translations={fr:{welcomeMessage:"Sublimez votre expérience gastronomique. Il vous suffit de donner les détails de votre plat, et obtenez la recommandation de compagnon de vin idéale. Que voulez-vous manger?",noResultsFound:"Aucun résultat trouvé.",somethingWentWrong:"Désolé, quelque chose a mal tourné.",chatButton:"Accorder le vin au dîner",inputPlaceholder:"ex., Salade de thon",sendButton:"Accorder",price:"Prix",region:"Région",type:"Type",reason:"Suggestion",moreInfo:"Plus d'infos"},es:{welcomeMessage:"Mejore su experiencia gastronómica. Solo proporcione los detalles de su plato y obtenga la recomendación de vino ideal. ¿Qué le gustaría comer?",noResultsFound:"No se encontraron resultados.",somethingWentWrong:"Lo sentimos, algo salió mal.",chatButton:"Maridar vino con cena",inputPlaceholder:"ej., Ensalada de atún",sendButton:"Maridar",price:"Precio",region:"Región",type:"Tipo",reason:"Sugerencia",moreInfo:"Más info"},en:{welcomeMessage:"Enhance your dining experience. Just provide your dish details and get the ideal wine pairing. What would you like to eat?",noResultsFound:"No results found.",somethingWentWrong:"Sorry, something went wrong.",chatButton:"Pair wine with dinner",inputPlaceholder:"e.g., Tuna Salad",sendButton:"Pair",price:"Price",region:"Region",type:"Type",reason:"Suggestion",moreInfo:"More info"},de:{welcomeMessage:"Verbessern Sie Ihr kulinarisches Erlebnis. Geben Sie einfach die Details Ihres Gerichts an und erhalten Sie die ideale Weinempfehlung. Was möchten Sie essen?",noResultsFound:"Keine Ergebnisse gefunden.",somethingWentWrong:"Entschuldigung, etwas ist schief gelaufen.",chatButton:"Wein zum Abendessen",inputPlaceholder:"z.B., Thunfischsalat",sendButton:"Kombinieren",price:"Preis",region:"Region",type:"Typ",reason:"Anregung",moreInfo:"Mehr Info"}}}async fetchConfig(e="Demo"){try{const t=await this.api.getStoreConfig(e);this.language=t.lang}catch{this.language="en"}}translate(e){return this.translations[this.language][e]||e}}const a=new W;class S{constructor(){this.api=new w;const e=window.wineaterData.FIRST_MESSAGE_TEXT||a.translate("welcomeMessage");this.displayFirstMessage(e)}initialize(){document.getElementById("send-button").addEventListener("click",()=>this.handleUserInput()),document.getElementById("user-input").addEventListener("keypress",n=>{n.key==="Enter"&&this.handleUserInput()})}displayFirstMessage(e,t="api"){const n=document.getElementById("message-container"),i=document.createElement("div");i.className=`message ${t}`,i.textContent=e,n.appendChild(i),n.scrollTop=n.scrollHeight}async handleUserInput(){const e=document.getElementById("user-input"),t=e.value.trim();if(t){this.displayMessage(t,"user"),e.value="",this.showTypingIndicator();try{I(t);const n=await this.api.getWineRecommendations(t);this.hideTypingIndicator(),n&&n.length?this.displayResults(n):this.displayMessage("No results found.","api")}catch{this.hideTypingIndicator(),this.displayMessage(a.translate("somethingWentWrong"),"api")}}}showTypingIndicator(){document.getElementById("typing-indicator").classList.add("visible")}hideTypingIndicator(){document.getElementById("typing-indicator").classList.remove("visible")}displayMessage(e,t){const n=document.getElementById("message-container"),i=document.createElement("div");i.textContent=e,i.className="message "+t,n.appendChild(i),n.scrollTop=n.scrollHeight}sendAnalytics(e){C(e)}displayResults(e){const t=document.getElementById("message-container");E(e.map(n=>n.Title)),e.forEach(n=>{const i=document.createElement("div");i.className="wine-item";const l=document.createElement("img");l.src=n.Image,i.appendChild(l);const g=document.createElement("div");g.innerHTML=`
281
281
  <strong>${n.Title}</strong><br>
282
282
  ${a.translate("price")}: ${n.Price}<br>
283
283
  ${a.translate("region")}: ${n.Region}<br>
284
284
  ${a.translate("type")}: ${n.Type}<br>
285
285
  <a href="${n.Url}" onclick="sendAnalytics(${n.Title})" target="_blank">${a.translate("moreInfo")}</a>
286
- `,i.appendChild(g),e.appendChild(i),this.displayFirstMessage(n.Reason)}),e.scrollTop=e.scrollHeight}}const P="OuhXJRleF6sROjsQZPWx1yqjrL6APeJxmHswqyOBWbgIqtXcht3MDadvI9DtOOoL";document.addEventListener("DOMContentLoaded",()=>{window.toggleChatWindow=h,window.closeChatWindow=b,window.openChatWindow=y});function S(){const o=`
286
+ `,i.appendChild(g),t.appendChild(i),this.displayFirstMessage(n.Reason)}),t.scrollTop=t.scrollHeight}}const L="OuhXJRleF6sROjsQZPWx1yqjrL6APeJxmHswqyOBWbgIqtXcht3MDadvI9DtOOoL";document.addEventListener("DOMContentLoaded",()=>{window.toggleChatWindow=h,window.closeChatWindow=b,window.openChatWindow=y});function P(){const e=`
287
287
  <div id="chatbot-container">
288
288
  <div id="chat-icon" onclick="toggleChatWindow()">
289
289
  <img src="https://landing-static.s3.eu-central-1.amazonaws.com/images/chat-icon.svg" alt="Chat Icon"> <!-- Update the path to your logo image -->
290
- <span>${a.translate("chatButton")}</span>
290
+ <span>${window.wineaterData.BUTTON_TEXT||a.translate("chatButton")}</span>
291
291
  </div>
292
292
 
293
293
  <div id="chat-window" class="hidden">
@@ -311,4 +311,4 @@
311
311
  </div>
312
312
  </div>
313
313
  </div>
314
- `;document.body.insertAdjacentHTML("beforeend",o)}function O(){document.getElementById("close-btn").addEventListener("click",h)}function M(){window.addEventListener("click",function(o){const t=document.getElementById("chat-window"),e=document.getElementById("chat-icon");!t.contains(o.target)&&!e.contains(o.target)&&(t.classList.remove("visible"),e.style.display="flex")})}function D(o){console.log(o);const t=document.getElementById("chat-icon"),e=document.getElementById("chat-window");t.className="",e.className="",o==="right-center"?(t.classList.add("chat-icon-right-center"),e.classList.add("right-center-aligned")):t.classList.add("chat-icon-bottom-right")}if(typeof window<"u"){let o=((w=window.wineaterData)==null?void 0:w.POSITION)||"bottom-right";window.addEventListener("DOMContentLoaded",async()=>{var l;const e=["climats","telckel","biobio","weinpoint","vinigrandi"].find(g=>window.location.href.includes(g))||null;let n;e&&(n=e.charAt(0).toUpperCase()+e.slice(1),n==="Biobio"&&(o="right-center")),await a.fetchConfig(n||"Demo"),S(),O(),M(),D(o),u("chatbotToken",((l=window.wineaterData)==null?void 0:l.CLIENT_TOKEN)||P,365),k(),new L().initialize()})}r.closeChatWindow=b,r.openChatWindow=y,r.toggleChatWindow=h,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})});
314
+ `;document.body.insertAdjacentHTML("beforeend",e)}function O(){document.getElementById("close-btn").addEventListener("click",h)}function M(){window.addEventListener("click",function(o){const e=document.getElementById("chat-window"),t=document.getElementById("chat-icon");!e.contains(o.target)&&!t.contains(o.target)&&(e.classList.remove("visible"),t.style.display="flex")})}function D(o){console.log(o);const e=document.getElementById("chat-icon"),t=document.getElementById("chat-window");e.className="",t.className="",o==="right-center"?(e.classList.add("chat-icon-right-center"),t.classList.add("right-center-aligned")):e.classList.add("chat-icon-bottom-right")}if(typeof window<"u"){let o=((x=window.wineaterData)==null?void 0:x.POSITION)||"bottom-right";window.addEventListener("DOMContentLoaded",async()=>{var l;const t=["climats","telckel","biobio","weinpoint","vinigrandi"].find(g=>window.location.href.includes(g))||null;let n;t&&(n=t.charAt(0).toUpperCase()+t.slice(1),n==="Biobio"&&(o="right-center")),await a.fetchConfig(n||"Demo"),P(),O(),M(),D(o),u("chatbotToken",((l=window.wineaterData)==null?void 0:l.CLIENT_TOKEN)||L,365),k(),new S().initialize()})}r.closeChatWindow=b,r.openChatWindow=y,r.toggleChatWindow=h,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wineater-bot",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "module": "src/index.js",
package/src/index.js CHANGED
@@ -28,11 +28,12 @@ export {
28
28
  };
29
29
 
30
30
  function createChatbotUI() {
31
+ const buttonText = window.wineaterData.BUTTON_TEXT || translator.translate('chatButton');
31
32
  const chatbotHTML = `
32
33
  <div id="chatbot-container">
33
34
  <div id="chat-icon" onclick="toggleChatWindow()">
34
35
  <img src="https://landing-static.s3.eu-central-1.amazonaws.com/images/chat-icon.svg" alt="Chat Icon"> <!-- Update the path to your logo image -->
35
- <span>${translator.translate('chatButton')}</span>
36
+ <span>${buttonText}</span>
36
37
  </div>
37
38
 
38
39
  <div id="chat-window" class="hidden">
package/src/js/api.js CHANGED
@@ -6,8 +6,8 @@ const DEMO_TOKEN='OuhXJRleF6sROjsQZPWx1yqjrL6APeJxmHswqyOBWbgIqtXcht3MDadvI9DtOO
6
6
  export class Api {
7
7
  constructor(apiEndpoint) {
8
8
  // Allow users of the library to specify their own endpoint if needed
9
- this.baseURL = 'https://api.wineater.com/';
10
- // this.baseURL = 'http://localhost:3000/'
9
+ // this.baseURL = 'https://api.wineater.com/';
10
+ this.baseURL = 'http://localhost:3000/'
11
11
  this.store = stores.find(value => window.location.href.includes(value));
12
12
  this.token = window?.wineaterData?.CLIENT_TOKEN || DEMO_TOKEN;
13
13
  }
package/src/js/chatbot.js CHANGED
@@ -6,7 +6,8 @@ import { trackMessageSent, trackProductClick, trackRecommendationsGet } from './
6
6
  export class Chatbot {
7
7
  constructor() {
8
8
  this.api = new Api(); // Instantiate the Api class
9
- this.displayFirstMessage(translator.translate('welcomeMessage'));
9
+ const firstMessageText = window.wineaterData.FIRST_MESSAGE_TEXT || translator.translate('welcomeMessage');
10
+ this.displayFirstMessage(firstMessageText);
10
11
  }
11
12
 
12
13
  initialize() {