wineater-bot 1.1.2 → 1.1.4
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/dist/wineater-chatbot.mjs +123 -78
- package/dist/wineater-chatbot.umd.js +61 -26
- package/index.html +3 -1
- package/package.json +1 -1
- package/src/css/styles.css +15 -8
- package/src/index.js +10 -5
- package/src/js/api.js +6 -1
- package/src/js/chatbot.js +20 -1
- package/src/js/styles.js +42 -18
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
var l = Object.defineProperty;
|
|
2
|
+
var p = (n, t, e) => t in n ? l(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
|
|
3
|
+
var r = (n, t, e) => (p(n, typeof t != "symbol" ? t + "" : t, e), e);
|
|
4
|
+
const g = `
|
|
2
5
|
@font-face {
|
|
3
6
|
font-family: 'Poppins';
|
|
4
7
|
src: url('https://fonts.googleapis.com/css2?family=Poppins:wght@400&display=swap');
|
|
@@ -15,20 +18,27 @@ const c = `
|
|
|
15
18
|
|
|
16
19
|
/* Styling the chat icon */
|
|
17
20
|
#chat-icon {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
align-items: center;
|
|
21
|
+
height: 40px;
|
|
22
|
+
display: flex; /* Use flexbox for alignment */
|
|
23
|
+
align-items: center; /* Center items vertically */
|
|
24
|
+
justify-content: center; /* Center items horizontally */
|
|
25
|
+
padding: 8px 16px; /* Add some padding around the text and image */
|
|
26
|
+
border-radius: 20px; /* Rounded corners for the button */
|
|
27
|
+
background-color: #fff; /* Background color from your style guide */
|
|
26
28
|
cursor: pointer;
|
|
29
|
+
box-shadow: 0 2px 10px rgba(0,0,0,0.2); /* Optional: add shadow for depth */
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
#chat-icon img {
|
|
30
|
-
width:
|
|
33
|
+
width: 40px; /* Adjust icon size as needed */
|
|
31
34
|
height: auto;
|
|
35
|
+
margin-right: 8px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
#chat-icon span {
|
|
39
|
+
color: black; /* Text color */
|
|
40
|
+
font-family: 'Poppins', sans-serif; /* Font family from your style guide */
|
|
41
|
+
/* Add more text styles if needed */
|
|
32
42
|
}
|
|
33
43
|
|
|
34
44
|
/* Chat window styles */
|
|
@@ -45,7 +55,7 @@ const c = `
|
|
|
45
55
|
|
|
46
56
|
/* Header of the chat window */
|
|
47
57
|
#chat-header {
|
|
48
|
-
background-color: #
|
|
58
|
+
background-color: #fff;
|
|
49
59
|
color: white;
|
|
50
60
|
padding: 16px;
|
|
51
61
|
border-top-left-radius: 8px;
|
|
@@ -56,10 +66,31 @@ const c = `
|
|
|
56
66
|
position: relative; /* Needed for absolute positioning of the close button */
|
|
57
67
|
}
|
|
58
68
|
|
|
69
|
+
/* Powered by and logo styles */
|
|
70
|
+
#powered-by {
|
|
71
|
+
display: flex;
|
|
72
|
+
align-items: center;
|
|
73
|
+
background-color: #fff; /* White background */
|
|
74
|
+
width: 100%;
|
|
75
|
+
border-radius: 16px; /* Rounded corners for the container */
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
#powered-by span {
|
|
79
|
+
font-family: 'Poppins', sans-serif;
|
|
80
|
+
color: #7E27ED; /* Text color - using the primary color from your style guide */
|
|
81
|
+
margin-right: 8px; /* Space between the text and the logo */
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
#chatbot-logo {
|
|
85
|
+
height: 20px; /* Adjust the logo size as needed */
|
|
86
|
+
width: auto; /* Keep the logo's aspect ratio */
|
|
87
|
+
}
|
|
88
|
+
|
|
59
89
|
|
|
60
90
|
/* Style for the close button */
|
|
61
91
|
#close-btn {
|
|
62
92
|
font-size: 24px; /* Size of the close button */
|
|
93
|
+
color: #7E27ED; /* Text color - using the primary color from your style guide */
|
|
63
94
|
cursor: pointer;
|
|
64
95
|
padding: 0 10px;
|
|
65
96
|
line-height: 24px;
|
|
@@ -67,7 +98,8 @@ const c = `
|
|
|
67
98
|
|
|
68
99
|
/* Container for messages */
|
|
69
100
|
#message-container {
|
|
70
|
-
max-height:
|
|
101
|
+
max-height: 500px;
|
|
102
|
+
height: 400px;
|
|
71
103
|
overflow-y: auto;
|
|
72
104
|
padding: 15px;
|
|
73
105
|
background: #f7f7f7; /* Light grey background for the message area */
|
|
@@ -93,7 +125,7 @@ const c = `
|
|
|
93
125
|
|
|
94
126
|
#input-container button {
|
|
95
127
|
padding: 10px 20px; /* Larger padding for a larger button */
|
|
96
|
-
background-color: #
|
|
128
|
+
background-color: #7E27ED; /* Button background color from style guide */
|
|
97
129
|
border: none;
|
|
98
130
|
color: white;
|
|
99
131
|
border-radius: 4px;
|
|
@@ -186,6 +218,7 @@ const c = `
|
|
|
186
218
|
align-items: center;
|
|
187
219
|
height: 0; /* Adjust as needed */
|
|
188
220
|
visibility: hidden; /* Start off invisible */
|
|
221
|
+
background-color: #f7f7f7;
|
|
189
222
|
}
|
|
190
223
|
|
|
191
224
|
.typing-indicator span {
|
|
@@ -224,66 +257,67 @@ const c = `
|
|
|
224
257
|
.typing-indicator.visible {
|
|
225
258
|
visibility: visible;
|
|
226
259
|
height: 50px;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
height: 300px; /* adjust based on your UI needs */
|
|
232
|
-
padding: 10px;
|
|
233
|
-
}`, r = document.createElement("style");
|
|
234
|
-
r.textContent = c;
|
|
235
|
-
document.head.appendChild(r);
|
|
236
|
-
function d() {
|
|
260
|
+
}`, d = document.createElement("style");
|
|
261
|
+
d.textContent = g;
|
|
262
|
+
document.head.appendChild(d);
|
|
263
|
+
function c() {
|
|
237
264
|
document.getElementById("chat-window").classList.toggle("visible");
|
|
238
265
|
}
|
|
239
|
-
function
|
|
266
|
+
function h() {
|
|
240
267
|
document.getElementById("chat-window").classList.remove("visible");
|
|
241
268
|
}
|
|
242
|
-
function
|
|
269
|
+
function u() {
|
|
243
270
|
document.getElementById("chat-window").classList.add("visible");
|
|
244
271
|
}
|
|
245
272
|
document.addEventListener("DOMContentLoaded", () => {
|
|
246
273
|
setupCloseButton(), setupOutsideClick();
|
|
247
274
|
});
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
275
|
+
const m = ["climats", "telckel", "biobio"];
|
|
276
|
+
class f {
|
|
277
|
+
constructor(t) {
|
|
278
|
+
this.apiEndpoint = t || "https://api.wineater.com/dish/recommendations", this.store = m.find((e) => window.location.href.includes(e)), console.log(this.store);
|
|
251
279
|
}
|
|
252
|
-
async getWineRecommendations(
|
|
280
|
+
async getWineRecommendations(t) {
|
|
281
|
+
console.log(window.location.href);
|
|
253
282
|
try {
|
|
254
|
-
const
|
|
283
|
+
const e = await fetch(this.apiEndpoint, {
|
|
255
284
|
method: "POST",
|
|
256
285
|
headers: {
|
|
257
286
|
"Content-Type": "application/json"
|
|
258
287
|
},
|
|
259
|
-
body: JSON.stringify({ text:
|
|
260
|
-
}),
|
|
261
|
-
if (!
|
|
262
|
-
throw new Error(`API call failed with status ${
|
|
263
|
-
return
|
|
264
|
-
} catch (
|
|
265
|
-
throw console.error("Fetching wine recommendations failed:",
|
|
288
|
+
body: JSON.stringify({ text: t, store: this.store ? this.store.toString().charAt(0).toUpperCase() + this.store.slice(1) : void 0 })
|
|
289
|
+
}), o = await e.json();
|
|
290
|
+
if (!e.ok)
|
|
291
|
+
throw new Error(`API call failed with status ${e.status}: ${o.message || "No additional error information"}`);
|
|
292
|
+
return o;
|
|
293
|
+
} catch (e) {
|
|
294
|
+
throw console.error("Fetching wine recommendations failed:", e.message), new Error(`Error in getWineRecommendations: ${e.message}`);
|
|
266
295
|
}
|
|
267
296
|
}
|
|
268
297
|
}
|
|
269
|
-
class
|
|
298
|
+
class b {
|
|
270
299
|
constructor() {
|
|
271
|
-
this.
|
|
300
|
+
r(this, "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?");
|
|
301
|
+
this.api = new f(), this.displayFirstMessage(this.welcomeMessage);
|
|
272
302
|
}
|
|
273
303
|
initialize() {
|
|
274
|
-
document.getElementById("send-button").addEventListener("click", () => this.handleUserInput()), document.getElementById("user-input").addEventListener("keypress", (
|
|
275
|
-
|
|
304
|
+
document.getElementById("send-button").addEventListener("click", () => this.handleUserInput()), document.getElementById("user-input").addEventListener("keypress", (o) => {
|
|
305
|
+
o.key === "Enter" && this.handleUserInput();
|
|
276
306
|
});
|
|
277
307
|
}
|
|
308
|
+
displayFirstMessage(t, e = "api") {
|
|
309
|
+
const o = document.getElementById("message-container"), i = document.createElement("div");
|
|
310
|
+
i.className = `message ${e}`, i.textContent = t, o.appendChild(i), o.scrollTop = o.scrollHeight;
|
|
311
|
+
}
|
|
278
312
|
async handleUserInput() {
|
|
279
|
-
const
|
|
280
|
-
if (
|
|
281
|
-
this.displayMessage(
|
|
313
|
+
const t = document.getElementById("user-input"), e = t.value.trim();
|
|
314
|
+
if (e) {
|
|
315
|
+
this.displayMessage(e, "user"), t.value = "", this.showTypingIndicator();
|
|
282
316
|
try {
|
|
283
|
-
const
|
|
284
|
-
this.hideTypingIndicator(),
|
|
285
|
-
} catch (
|
|
286
|
-
this.hideTypingIndicator(), console.error("Error fetching wine recommendations:",
|
|
317
|
+
const o = await this.api.getWineRecommendations(e);
|
|
318
|
+
this.hideTypingIndicator(), o && o.length ? this.displayResults(o) : this.displayMessage("No results found.", "api");
|
|
319
|
+
} catch (o) {
|
|
320
|
+
this.hideTypingIndicator(), console.error("Error fetching wine recommendations:", o), this.displayMessage("Sorry, something went wrong.", "api");
|
|
287
321
|
}
|
|
288
322
|
}
|
|
289
323
|
}
|
|
@@ -293,63 +327,74 @@ class h {
|
|
|
293
327
|
hideTypingIndicator() {
|
|
294
328
|
document.getElementById("typing-indicator").classList.remove("visible");
|
|
295
329
|
}
|
|
296
|
-
displayMessage(
|
|
297
|
-
const
|
|
298
|
-
|
|
330
|
+
displayMessage(t, e) {
|
|
331
|
+
const o = document.getElementById("message-container"), i = document.createElement("div");
|
|
332
|
+
i.textContent = t, i.className = "message " + e, o.appendChild(i), o.scrollTop = o.scrollHeight;
|
|
299
333
|
}
|
|
300
|
-
displayResults(
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
334
|
+
displayResults(t) {
|
|
335
|
+
const e = document.getElementById("message-container");
|
|
336
|
+
t.forEach((o) => {
|
|
337
|
+
const i = document.createElement("div");
|
|
338
|
+
i.className = "wine-item";
|
|
339
|
+
const s = document.createElement("img");
|
|
340
|
+
s.src = o.Image, i.appendChild(s);
|
|
341
|
+
const a = document.createElement("div");
|
|
342
|
+
a.innerHTML = `
|
|
343
|
+
<strong>${o.Title}</strong><br>
|
|
344
|
+
Prix: ${o.Price}<br>
|
|
345
|
+
Région: ${o.Region}<br>
|
|
346
|
+
Type: ${o.Type}<br>
|
|
347
|
+
<a href="${o.Url}" target="_blank">Plus d'infos</a>
|
|
348
|
+
`, i.appendChild(a), e.appendChild(i);
|
|
349
|
+
}), e.scrollTop = e.scrollHeight;
|
|
310
350
|
}
|
|
311
351
|
}
|
|
312
352
|
document.addEventListener("DOMContentLoaded", () => {
|
|
313
|
-
window.toggleChatWindow =
|
|
353
|
+
window.toggleChatWindow = c, window.closeChatWindow = h, window.openChatWindow = u;
|
|
314
354
|
});
|
|
315
|
-
function
|
|
355
|
+
function y() {
|
|
316
356
|
document.body.insertAdjacentHTML("beforeend", `
|
|
317
357
|
<div id="chatbot-container">
|
|
318
358
|
<div id="chat-icon" onclick="toggleChatWindow()">
|
|
319
|
-
<img src="https://landing-static.s3.eu-central-1.amazonaws.com/images/chat-icon.svg" alt="Chat Icon">
|
|
359
|
+
<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 -->
|
|
360
|
+
<span>Accorder le vin au dîner</span>
|
|
320
361
|
</div>
|
|
321
362
|
|
|
322
363
|
<div id="chat-window" class="hidden">
|
|
323
364
|
<div id="chat-header">
|
|
324
|
-
|
|
325
|
-
|
|
365
|
+
<div id="powered-by">
|
|
366
|
+
<span>Powered by</span>
|
|
367
|
+
<img src="https://landing-static.s3.eu-central-1.amazonaws.com/images/logo.svg" alt="Wineater Logo" id="chatbot-logo">
|
|
368
|
+
</div>
|
|
369
|
+
<div id="close-btn">×</div>
|
|
326
370
|
</div>
|
|
371
|
+
|
|
327
372
|
<div id="message-container"></div>
|
|
328
373
|
<div id="typing-indicator" class="typing-indicator hidden">
|
|
329
374
|
<span></span><span></span><span></span>
|
|
330
375
|
</div>
|
|
331
376
|
<div id="input-container">
|
|
332
|
-
<input type="text" id="user-input" placeholder="
|
|
333
|
-
<button id="send-button">
|
|
377
|
+
<input type="text" id="user-input" placeholder="ex., Salade de thon">
|
|
378
|
+
<button id="send-button">Accorder</button>
|
|
334
379
|
</div>
|
|
335
380
|
</div>
|
|
336
381
|
</div>
|
|
337
382
|
`);
|
|
338
383
|
}
|
|
339
|
-
function
|
|
340
|
-
document.getElementById("close-btn").addEventListener("click",
|
|
384
|
+
function w() {
|
|
385
|
+
document.getElementById("close-btn").addEventListener("click", c);
|
|
341
386
|
}
|
|
342
|
-
function
|
|
343
|
-
window.addEventListener("click", function(
|
|
344
|
-
const
|
|
345
|
-
!
|
|
387
|
+
function x() {
|
|
388
|
+
window.addEventListener("click", function(n) {
|
|
389
|
+
const t = document.getElementById("chat-window"), e = document.getElementById("chat-icon");
|
|
390
|
+
!t.contains(n.target) && !e.contains(n.target) && t.classList.remove("visible");
|
|
346
391
|
});
|
|
347
392
|
}
|
|
348
393
|
typeof window < "u" && window.addEventListener("DOMContentLoaded", () => {
|
|
349
|
-
|
|
394
|
+
y(), w(), x(), new b().initialize();
|
|
350
395
|
});
|
|
351
396
|
export {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
397
|
+
h as closeChatWindow,
|
|
398
|
+
u as openChatWindow,
|
|
399
|
+
c as toggleChatWindow
|
|
355
400
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(n,i){typeof exports=="object"&&typeof module<"u"?i(exports):typeof define=="function"&&define.amd?define(["exports"],i):(n=typeof globalThis<"u"?globalThis:n||self,i(n.WineaterChatbot={}))})(this,function(n){"use strict";var x=Object.defineProperty;var v=(n,i,r)=>i in n?x(n,i,{enumerable:!0,configurable:!0,writable:!0,value:r}):n[i]=r;var h=(n,i,r)=>(v(n,typeof i!="symbol"?i+"":i,r),r);const i=`
|
|
2
2
|
@font-face {
|
|
3
3
|
font-family: 'Poppins';
|
|
4
4
|
src: url('https://fonts.googleapis.com/css2?family=Poppins:wght@400&display=swap');
|
|
@@ -15,20 +15,27 @@
|
|
|
15
15
|
|
|
16
16
|
/* Styling the chat icon */
|
|
17
17
|
#chat-icon {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
align-items: center;
|
|
18
|
+
height: 40px;
|
|
19
|
+
display: flex; /* Use flexbox for alignment */
|
|
20
|
+
align-items: center; /* Center items vertically */
|
|
21
|
+
justify-content: center; /* Center items horizontally */
|
|
22
|
+
padding: 8px 16px; /* Add some padding around the text and image */
|
|
23
|
+
border-radius: 20px; /* Rounded corners for the button */
|
|
24
|
+
background-color: #fff; /* Background color from your style guide */
|
|
26
25
|
cursor: pointer;
|
|
26
|
+
box-shadow: 0 2px 10px rgba(0,0,0,0.2); /* Optional: add shadow for depth */
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
#chat-icon img {
|
|
30
|
-
width:
|
|
30
|
+
width: 40px; /* Adjust icon size as needed */
|
|
31
31
|
height: auto;
|
|
32
|
+
margin-right: 8px;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
#chat-icon span {
|
|
36
|
+
color: black; /* Text color */
|
|
37
|
+
font-family: 'Poppins', sans-serif; /* Font family from your style guide */
|
|
38
|
+
/* Add more text styles if needed */
|
|
32
39
|
}
|
|
33
40
|
|
|
34
41
|
/* Chat window styles */
|
|
@@ -45,7 +52,7 @@
|
|
|
45
52
|
|
|
46
53
|
/* Header of the chat window */
|
|
47
54
|
#chat-header {
|
|
48
|
-
background-color: #
|
|
55
|
+
background-color: #fff;
|
|
49
56
|
color: white;
|
|
50
57
|
padding: 16px;
|
|
51
58
|
border-top-left-radius: 8px;
|
|
@@ -56,10 +63,31 @@
|
|
|
56
63
|
position: relative; /* Needed for absolute positioning of the close button */
|
|
57
64
|
}
|
|
58
65
|
|
|
66
|
+
/* Powered by and logo styles */
|
|
67
|
+
#powered-by {
|
|
68
|
+
display: flex;
|
|
69
|
+
align-items: center;
|
|
70
|
+
background-color: #fff; /* White background */
|
|
71
|
+
width: 100%;
|
|
72
|
+
border-radius: 16px; /* Rounded corners for the container */
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
#powered-by span {
|
|
76
|
+
font-family: 'Poppins', sans-serif;
|
|
77
|
+
color: #7E27ED; /* Text color - using the primary color from your style guide */
|
|
78
|
+
margin-right: 8px; /* Space between the text and the logo */
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#chatbot-logo {
|
|
82
|
+
height: 20px; /* Adjust the logo size as needed */
|
|
83
|
+
width: auto; /* Keep the logo's aspect ratio */
|
|
84
|
+
}
|
|
85
|
+
|
|
59
86
|
|
|
60
87
|
/* Style for the close button */
|
|
61
88
|
#close-btn {
|
|
62
89
|
font-size: 24px; /* Size of the close button */
|
|
90
|
+
color: #7E27ED; /* Text color - using the primary color from your style guide */
|
|
63
91
|
cursor: pointer;
|
|
64
92
|
padding: 0 10px;
|
|
65
93
|
line-height: 24px;
|
|
@@ -67,7 +95,8 @@
|
|
|
67
95
|
|
|
68
96
|
/* Container for messages */
|
|
69
97
|
#message-container {
|
|
70
|
-
max-height:
|
|
98
|
+
max-height: 500px;
|
|
99
|
+
height: 400px;
|
|
71
100
|
overflow-y: auto;
|
|
72
101
|
padding: 15px;
|
|
73
102
|
background: #f7f7f7; /* Light grey background for the message area */
|
|
@@ -93,7 +122,7 @@
|
|
|
93
122
|
|
|
94
123
|
#input-container button {
|
|
95
124
|
padding: 10px 20px; /* Larger padding for a larger button */
|
|
96
|
-
background-color: #
|
|
125
|
+
background-color: #7E27ED; /* Button background color from style guide */
|
|
97
126
|
border: none;
|
|
98
127
|
color: white;
|
|
99
128
|
border-radius: 4px;
|
|
@@ -186,6 +215,7 @@
|
|
|
186
215
|
align-items: center;
|
|
187
216
|
height: 0; /* Adjust as needed */
|
|
188
217
|
visibility: hidden; /* Start off invisible */
|
|
218
|
+
background-color: #f7f7f7;
|
|
189
219
|
}
|
|
190
220
|
|
|
191
221
|
.typing-indicator span {
|
|
@@ -224,31 +254,36 @@
|
|
|
224
254
|
.typing-indicator.visible {
|
|
225
255
|
visibility: visible;
|
|
226
256
|
height: 50px;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
257
|
+
}`,r=document.createElement("style");r.textContent=i,document.head.appendChild(r);function d(){document.getElementById("chat-window").classList.toggle("visible")}function c(){document.getElementById("chat-window").classList.remove("visible")}function l(){document.getElementById("chat-window").classList.add("visible")}document.addEventListener("DOMContentLoaded",()=>{setupCloseButton(),setupOutsideClick()});const u=["climats","telckel","biobio"];class m{constructor(o){this.apiEndpoint=o||"https://api.wineater.com/dish/recommendations",this.store=u.find(t=>window.location.href.includes(t)),console.log(this.store)}async getWineRecommendations(o){console.log(window.location.href);try{const t=await fetch(this.apiEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({text:o,store:this.store?this.store.toString().charAt(0).toUpperCase()+this.store.slice(1):void 0})}),e=await t.json();if(!t.ok)throw new Error(`API call failed with status ${t.status}: ${e.message||"No additional error information"}`);return e}catch(t){throw console.error("Fetching wine recommendations failed:",t.message),new Error(`Error in getWineRecommendations: ${t.message}`)}}}class f{constructor(){h(this,"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?");this.api=new m,this.displayFirstMessage(this.welcomeMessage)}initialize(){document.getElementById("send-button").addEventListener("click",()=>this.handleUserInput()),document.getElementById("user-input").addEventListener("keypress",e=>{e.key==="Enter"&&this.handleUserInput()})}displayFirstMessage(o,t="api"){const e=document.getElementById("message-container"),s=document.createElement("div");s.className=`message ${t}`,s.textContent=o,e.appendChild(s),e.scrollTop=e.scrollHeight}async handleUserInput(){const o=document.getElementById("user-input"),t=o.value.trim();if(t){this.displayMessage(t,"user"),o.value="",this.showTypingIndicator();try{const e=await this.api.getWineRecommendations(t);this.hideTypingIndicator(),e&&e.length?this.displayResults(e):this.displayMessage("No results found.","api")}catch(e){this.hideTypingIndicator(),console.error("Error fetching wine recommendations:",e),this.displayMessage("Sorry, something went wrong.","api")}}}showTypingIndicator(){document.getElementById("typing-indicator").classList.add("visible")}hideTypingIndicator(){document.getElementById("typing-indicator").classList.remove("visible")}displayMessage(o,t){const e=document.getElementById("message-container"),s=document.createElement("div");s.textContent=o,s.className="message "+t,e.appendChild(s),e.scrollTop=e.scrollHeight}displayResults(o){const t=document.getElementById("message-container");o.forEach(e=>{const s=document.createElement("div");s.className="wine-item";const p=document.createElement("img");p.src=e.Image,s.appendChild(p);const g=document.createElement("div");g.innerHTML=`
|
|
258
|
+
<strong>${e.Title}</strong><br>
|
|
259
|
+
Prix: ${e.Price}<br>
|
|
260
|
+
Région: ${e.Region}<br>
|
|
261
|
+
Type: ${e.Type}<br>
|
|
262
|
+
<a href="${e.Url}" target="_blank">Plus d'infos</a>
|
|
263
|
+
`,s.appendChild(g),t.appendChild(s)}),t.scrollTop=t.scrollHeight}}document.addEventListener("DOMContentLoaded",()=>{window.toggleChatWindow=d,window.closeChatWindow=c,window.openChatWindow=l});function b(){document.body.insertAdjacentHTML("beforeend",`
|
|
234
264
|
<div id="chatbot-container">
|
|
235
265
|
<div id="chat-icon" onclick="toggleChatWindow()">
|
|
236
|
-
<img src="https://landing-static.s3.eu-central-1.amazonaws.com/images/chat-icon.svg" alt="Chat Icon">
|
|
266
|
+
<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 -->
|
|
267
|
+
<span>Accorder le vin au dîner</span>
|
|
237
268
|
</div>
|
|
238
269
|
|
|
239
270
|
<div id="chat-window" class="hidden">
|
|
240
271
|
<div id="chat-header">
|
|
241
|
-
|
|
242
|
-
|
|
272
|
+
<div id="powered-by">
|
|
273
|
+
<span>Powered by</span>
|
|
274
|
+
<img src="https://landing-static.s3.eu-central-1.amazonaws.com/images/logo.svg" alt="Wineater Logo" id="chatbot-logo">
|
|
275
|
+
</div>
|
|
276
|
+
<div id="close-btn">×</div>
|
|
243
277
|
</div>
|
|
278
|
+
|
|
244
279
|
<div id="message-container"></div>
|
|
245
280
|
<div id="typing-indicator" class="typing-indicator hidden">
|
|
246
281
|
<span></span><span></span><span></span>
|
|
247
282
|
</div>
|
|
248
283
|
<div id="input-container">
|
|
249
|
-
<input type="text" id="user-input" placeholder="
|
|
250
|
-
<button id="send-button">
|
|
284
|
+
<input type="text" id="user-input" placeholder="ex., Salade de thon">
|
|
285
|
+
<button id="send-button">Accorder</button>
|
|
251
286
|
</div>
|
|
252
287
|
</div>
|
|
253
288
|
</div>
|
|
254
|
-
`)}function
|
|
289
|
+
`)}function y(){document.getElementById("close-btn").addEventListener("click",d)}function w(){window.addEventListener("click",function(a){const o=document.getElementById("chat-window"),t=document.getElementById("chat-icon");!o.contains(a.target)&&!t.contains(a.target)&&o.classList.remove("visible")})}typeof window<"u"&&window.addEventListener("DOMContentLoaded",()=>{b(),y(),w(),new f().initialize()}),n.closeChatWindow=c,n.openChatWindow=l,n.toggleChatWindow=d,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})});
|
package/index.html
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Chatbot</title>
|
|
7
|
-
<script src="https://unpkg.com/wineater-bot@
|
|
7
|
+
<!-- <script type="module" src="https://unpkg.com/wineater-bot@1.0.0/dist/wineater-chatbot.umd.js"></script> -->
|
|
8
|
+
<script type="module" src="./src/index.js"></script>
|
|
9
|
+
|
|
8
10
|
</head>
|
|
9
11
|
<body>
|
|
10
12
|
</body>
|
package/package.json
CHANGED
package/src/css/styles.css
CHANGED
|
@@ -14,20 +14,27 @@
|
|
|
14
14
|
|
|
15
15
|
/* Styling the chat icon */
|
|
16
16
|
#chat-icon {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
justify-content: center;
|
|
24
|
-
align-items: center;
|
|
17
|
+
display: flex; /* Use flexbox for alignment */
|
|
18
|
+
align-items: center; /* Center items vertically */
|
|
19
|
+
justify-content: center; /* Center items horizontally */
|
|
20
|
+
padding: 8px; /* Add some padding around the text and image */
|
|
21
|
+
border-radius: 20px; /* Rounded corners for the button */
|
|
22
|
+
background-color: #7E27ED; /* Background color from your style guide */
|
|
25
23
|
cursor: pointer;
|
|
24
|
+
box-shadow: 0 2px 10px rgba(0,0,0,0.2); /* Optional: add shadow for depth */
|
|
25
|
+
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
#chat-icon img {
|
|
29
29
|
width: 80%; /* Adjust icon size as needed */
|
|
30
30
|
height: auto;
|
|
31
|
+
margin-right: 8px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#chat-icon span {
|
|
35
|
+
color: white; /* Text color */
|
|
36
|
+
font-family: 'Poppins', sans-serif; /* Font family from your style guide */
|
|
37
|
+
/* Add more text styles if needed */
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
/* Chat window styles */
|
package/src/index.js
CHANGED
|
@@ -26,21 +26,26 @@ function createChatbotUI() {
|
|
|
26
26
|
const chatbotHTML = `
|
|
27
27
|
<div id="chatbot-container">
|
|
28
28
|
<div id="chat-icon" onclick="toggleChatWindow()">
|
|
29
|
-
<img src="https://landing-static.s3.eu-central-1.amazonaws.com/images/chat-icon.svg" alt="Chat Icon">
|
|
29
|
+
<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 -->
|
|
30
|
+
<span>Accorder le vin au dîner</span>
|
|
30
31
|
</div>
|
|
31
32
|
|
|
32
33
|
<div id="chat-window" class="hidden">
|
|
33
34
|
<div id="chat-header">
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
<div id="powered-by">
|
|
36
|
+
<span>Powered by</span>
|
|
37
|
+
<img src="https://landing-static.s3.eu-central-1.amazonaws.com/images/logo.svg" alt="Wineater Logo" id="chatbot-logo">
|
|
36
38
|
</div>
|
|
39
|
+
<div id="close-btn">×</div>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
37
42
|
<div id="message-container"></div>
|
|
38
43
|
<div id="typing-indicator" class="typing-indicator hidden">
|
|
39
44
|
<span></span><span></span><span></span>
|
|
40
45
|
</div>
|
|
41
46
|
<div id="input-container">
|
|
42
|
-
<input type="text" id="user-input" placeholder="
|
|
43
|
-
<button id="send-button">
|
|
47
|
+
<input type="text" id="user-input" placeholder="ex., Salade de thon">
|
|
48
|
+
<button id="send-button">Accorder</button>
|
|
44
49
|
</div>
|
|
45
50
|
</div>
|
|
46
51
|
</div>
|
package/src/js/api.js
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
// api.js
|
|
2
2
|
|
|
3
|
+
const stores = ['climats', 'telckel', 'biobio'];
|
|
4
|
+
|
|
3
5
|
export class Api {
|
|
4
6
|
constructor(apiEndpoint) {
|
|
5
7
|
// Allow users of the library to specify their own endpoint if needed
|
|
6
8
|
this.apiEndpoint = apiEndpoint || 'https://api.wineater.com/dish/recommendations';
|
|
9
|
+
this.store = stores.find(value => window.location.href.includes(value));
|
|
10
|
+
console.log(this.store);
|
|
7
11
|
}
|
|
8
12
|
|
|
9
13
|
async getWineRecommendations(text) {
|
|
14
|
+
console.log(window.location.href);
|
|
10
15
|
try {
|
|
11
16
|
const response = await fetch(this.apiEndpoint, {
|
|
12
17
|
method: 'POST',
|
|
13
18
|
headers: {
|
|
14
19
|
'Content-Type': 'application/json'
|
|
15
20
|
},
|
|
16
|
-
body: JSON.stringify({ text: text })
|
|
21
|
+
body: JSON.stringify({ text: text, store: this.store ? (this.store.toString().charAt(0).toUpperCase() + this.store.slice(1)) : undefined})
|
|
17
22
|
});
|
|
18
23
|
|
|
19
24
|
const data = await response.json();
|
package/src/js/chatbot.js
CHANGED
|
@@ -4,12 +4,16 @@ import { Api } from './api.js';
|
|
|
4
4
|
export class Chatbot {
|
|
5
5
|
constructor() {
|
|
6
6
|
this.api = new Api(); // Instantiate the Api class
|
|
7
|
+
this.displayFirstMessage(this.welcomeMessage);
|
|
7
8
|
}
|
|
8
9
|
|
|
10
|
+
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?";
|
|
11
|
+
|
|
9
12
|
initialize() {
|
|
10
13
|
// Attach event listeners
|
|
11
14
|
const sendButton = document.getElementById('send-button');
|
|
12
15
|
sendButton.addEventListener('click', () => this.handleUserInput());
|
|
16
|
+
|
|
13
17
|
|
|
14
18
|
const userInputField = document.getElementById('user-input');
|
|
15
19
|
userInputField.addEventListener('keypress', (event) => {
|
|
@@ -19,6 +23,15 @@ export class Chatbot {
|
|
|
19
23
|
});
|
|
20
24
|
}
|
|
21
25
|
|
|
26
|
+
displayFirstMessage(message, sender = 'api') {
|
|
27
|
+
const messageContainer = document.getElementById('message-container');
|
|
28
|
+
const messageDiv = document.createElement('div');
|
|
29
|
+
messageDiv.className = `message ${sender}`;
|
|
30
|
+
messageDiv.textContent = message;
|
|
31
|
+
messageContainer.appendChild(messageDiv);
|
|
32
|
+
messageContainer.scrollTop = messageContainer.scrollHeight; // Scroll to the latest message
|
|
33
|
+
}
|
|
34
|
+
|
|
22
35
|
async handleUserInput() {
|
|
23
36
|
const inputField = document.getElementById('user-input');
|
|
24
37
|
const userInput = inputField.value.trim();
|
|
@@ -80,7 +93,13 @@ export class Chatbot {
|
|
|
80
93
|
wineDiv.appendChild(image);
|
|
81
94
|
|
|
82
95
|
const contentDiv = document.createElement('div');
|
|
83
|
-
contentDiv.innerHTML =
|
|
96
|
+
contentDiv.innerHTML = `
|
|
97
|
+
<strong>${wine.Title}</strong><br>
|
|
98
|
+
Prix: ${wine.Price}<br>
|
|
99
|
+
Région: ${wine.Region}<br>
|
|
100
|
+
Type: ${wine.Type}<br>
|
|
101
|
+
<a href="${wine.Url}" target="_blank">Plus d'infos</a>
|
|
102
|
+
`;
|
|
84
103
|
wineDiv.appendChild(contentDiv);
|
|
85
104
|
|
|
86
105
|
messageContainer.appendChild(wineDiv);
|
package/src/js/styles.js
CHANGED
|
@@ -16,20 +16,27 @@ const css = `
|
|
|
16
16
|
|
|
17
17
|
/* Styling the chat icon */
|
|
18
18
|
#chat-icon {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
align-items: center;
|
|
19
|
+
height: 40px;
|
|
20
|
+
display: flex; /* Use flexbox for alignment */
|
|
21
|
+
align-items: center; /* Center items vertically */
|
|
22
|
+
justify-content: center; /* Center items horizontally */
|
|
23
|
+
padding: 8px 16px; /* Add some padding around the text and image */
|
|
24
|
+
border-radius: 20px; /* Rounded corners for the button */
|
|
25
|
+
background-color: #fff; /* Background color from your style guide */
|
|
27
26
|
cursor: pointer;
|
|
27
|
+
box-shadow: 0 2px 10px rgba(0,0,0,0.2); /* Optional: add shadow for depth */
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
#chat-icon img {
|
|
31
|
-
width:
|
|
31
|
+
width: 40px; /* Adjust icon size as needed */
|
|
32
32
|
height: auto;
|
|
33
|
+
margin-right: 8px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
#chat-icon span {
|
|
37
|
+
color: black; /* Text color */
|
|
38
|
+
font-family: 'Poppins', sans-serif; /* Font family from your style guide */
|
|
39
|
+
/* Add more text styles if needed */
|
|
33
40
|
}
|
|
34
41
|
|
|
35
42
|
/* Chat window styles */
|
|
@@ -46,7 +53,7 @@ const css = `
|
|
|
46
53
|
|
|
47
54
|
/* Header of the chat window */
|
|
48
55
|
#chat-header {
|
|
49
|
-
background-color: #
|
|
56
|
+
background-color: #fff;
|
|
50
57
|
color: white;
|
|
51
58
|
padding: 16px;
|
|
52
59
|
border-top-left-radius: 8px;
|
|
@@ -57,10 +64,31 @@ const css = `
|
|
|
57
64
|
position: relative; /* Needed for absolute positioning of the close button */
|
|
58
65
|
}
|
|
59
66
|
|
|
67
|
+
/* Powered by and logo styles */
|
|
68
|
+
#powered-by {
|
|
69
|
+
display: flex;
|
|
70
|
+
align-items: center;
|
|
71
|
+
background-color: #fff; /* White background */
|
|
72
|
+
width: 100%;
|
|
73
|
+
border-radius: 16px; /* Rounded corners for the container */
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
#powered-by span {
|
|
77
|
+
font-family: 'Poppins', sans-serif;
|
|
78
|
+
color: #7E27ED; /* Text color - using the primary color from your style guide */
|
|
79
|
+
margin-right: 8px; /* Space between the text and the logo */
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
#chatbot-logo {
|
|
83
|
+
height: 20px; /* Adjust the logo size as needed */
|
|
84
|
+
width: auto; /* Keep the logo's aspect ratio */
|
|
85
|
+
}
|
|
86
|
+
|
|
60
87
|
|
|
61
88
|
/* Style for the close button */
|
|
62
89
|
#close-btn {
|
|
63
90
|
font-size: 24px; /* Size of the close button */
|
|
91
|
+
color: #7E27ED; /* Text color - using the primary color from your style guide */
|
|
64
92
|
cursor: pointer;
|
|
65
93
|
padding: 0 10px;
|
|
66
94
|
line-height: 24px;
|
|
@@ -68,7 +96,8 @@ const css = `
|
|
|
68
96
|
|
|
69
97
|
/* Container for messages */
|
|
70
98
|
#message-container {
|
|
71
|
-
max-height:
|
|
99
|
+
max-height: 500px;
|
|
100
|
+
height: 400px;
|
|
72
101
|
overflow-y: auto;
|
|
73
102
|
padding: 15px;
|
|
74
103
|
background: #f7f7f7; /* Light grey background for the message area */
|
|
@@ -94,7 +123,7 @@ const css = `
|
|
|
94
123
|
|
|
95
124
|
#input-container button {
|
|
96
125
|
padding: 10px 20px; /* Larger padding for a larger button */
|
|
97
|
-
background-color: #
|
|
126
|
+
background-color: #7E27ED; /* Button background color from style guide */
|
|
98
127
|
border: none;
|
|
99
128
|
color: white;
|
|
100
129
|
border-radius: 4px;
|
|
@@ -187,6 +216,7 @@ const css = `
|
|
|
187
216
|
align-items: center;
|
|
188
217
|
height: 0; /* Adjust as needed */
|
|
189
218
|
visibility: hidden; /* Start off invisible */
|
|
219
|
+
background-color: #f7f7f7;
|
|
190
220
|
}
|
|
191
221
|
|
|
192
222
|
.typing-indicator span {
|
|
@@ -225,12 +255,6 @@ const css = `
|
|
|
225
255
|
.typing-indicator.visible {
|
|
226
256
|
visibility: visible;
|
|
227
257
|
height: 50px;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
#message-container {
|
|
231
|
-
overflow-y: auto;
|
|
232
|
-
height: 300px; /* adjust based on your UI needs */
|
|
233
|
-
padding: 10px;
|
|
234
258
|
}`;
|
|
235
259
|
|
|
236
260
|
const style = document.createElement('style');
|