Coots commited on
Commit
cef6a45
ยท
verified ยท
1 Parent(s): 503b5f6

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +208 -142
index.html CHANGED
@@ -1,156 +1,222 @@
1
- <script>
2
- const state = {
3
- step: 'tileType',
4
- tileType: null,
5
- length: null,
6
- width: null,
7
- tileSize: null
8
- };
9
-
10
- const chatArea = document.getElementById('chat-area');
11
- const userInput = document.getElementById('user-input');
12
- const recommendations = document.getElementById('recommendations');
13
- const resetBtn = document.getElementById('reset-btn');
14
-
15
- resetBtn.addEventListener('click', resetConversation);
16
- userInput.addEventListener('keypress', (e) => {
17
- if (e.key === 'Enter') sendMessage();
18
- });
19
-
20
- function resetConversation() {
21
- state.step = 'tileType';
22
- state.tileType = null;
23
- state.length = null;
24
- state.width = null;
25
- state.tileSize = null;
26
-
27
- chatArea.innerHTML = `
28
- <div class="bot-message bg-gray-100 rounded-lg p-4 max-w-xs mb-3">
29
- <p>Hello! ๐Ÿ‘‹ I'm your Tile Calculator Assistant. Let's estimate how many tiles you need.</p>
30
- <p class="mt-2">Are you looking for <span class="font-semibold">floor</span> or <span class="font-semibold">wall</span> tiles?</p>
31
- <div class="flex gap-2 mt-3">
32
- <button onclick="selectTileType('floor')" class="quick-reply bg-white text-indigo-600 border border-indigo-600 px-4 py-2 rounded-full font-medium hover:bg-indigo-50">Floor</button>
33
- <button onclick="selectTileType('wall')" class="quick-reply bg-white text-indigo-600 border border-indigo-600 px-4 py-2 rounded-full font-medium hover:bg-indigo-50">Wall</button>
 
 
 
 
34
  </div>
 
 
 
 
 
35
  </div>
36
- `;
37
- recommendations.innerHTML = '';
38
- }
39
 
40
- function selectTileType(type) {
41
- state.tileType = type;
42
- state.step = 'length';
 
 
 
 
 
 
 
 
43
 
44
- addMessage('user', type === 'floor' ? 'Floor tiles' : 'Wall tiles');
45
- showTyping();
 
 
 
 
 
 
 
 
 
46
 
47
- setTimeout(() => {
48
- hideTyping();
49
- addMessage('bot', `Great choice! Please enter the <strong>length</strong> of the area in feet (e.g. 10):`);
50
- }, 800);
51
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
- function sendMessage() {
54
- const message = userInput.value.trim();
55
- if (!message) return;
56
 
57
- addMessage('user', message);
58
- userInput.value = '';
59
 
60
- processUserMessage(message);
61
- }
 
 
 
62
 
63
- function processUserMessage(message) {
64
- showTyping();
 
65
 
66
- setTimeout(() => {
67
- hideTyping();
68
 
69
- if (state.step === 'length') {
70
- const length = parseFloat(message);
71
- if (isNaN(length) || length <= 0) {
72
- addMessage('bot', 'Please enter a valid number for the length in feet.');
73
- return;
74
- }
75
- state.length = length;
76
- state.step = 'width';
77
- addMessage('bot', 'Now enter the <strong>width</strong> of the area in feet (e.g. 12):');
78
-
79
- } else if (state.step === 'width') {
80
- const width = parseFloat(message);
81
- if (isNaN(width) || width <= 0) {
82
- addMessage('bot', 'Please enter a valid number for the width in feet.');
83
- return;
84
- }
85
- state.width = width;
86
- state.step = 'tileSize';
87
- addMessage('bot', 'What is the tile size? (e.g. "2x2", "600x600", or "300*300")');
88
-
89
- } else if (state.step === 'tileSize') {
90
- const tileArea = parseTileSize(message);
91
- if (!tileArea) {
92
- addMessage('bot', 'I couldn\'t understand that tile size. Try: "2x2", "600x600 mm", or "200*200".');
93
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  }
 
 
95
 
96
- state.tileSize = tileArea;
97
- calculateTiles();
98
- }
99
- }, 800);
100
- }
101
-
102
- function parseTileSize(input) {
103
- input = input.toLowerCase().replace(/ร—|into|\*/g, 'x').replace(/ft|feet|mm/g, '').trim();
104
- if (input.includes('x')) {
105
- const [a, b] = input.split('x').map(s => parseFloat(s.replace(/[^\d.]/g, '')));
106
- if (isNaN(a) || isNaN(b)) return null;
107
- return (a > 20 ? (a * b) / 92903.04 : a * b);
108
- } else if (/^\d+(\.\d+)?$/.test(input)) {
109
- const val = parseFloat(input);
110
- return val > 20 ? (val * val) / 92903.04 : val * val;
111
  }
112
- return null;
113
- }
114
-
115
- function calculateTiles() {
116
- const area = state.length * state.width;
117
- const numTiles = Math.ceil((area / state.tileSize) * 1.1);
118
- const numBoxes = Math.ceil(numTiles / 10);
119
-
120
- chatArea.insertAdjacentHTML('beforeend', `
121
- <div class="bot-message bg-gray-100 rounded-lg p-4 mb-3">
122
- <p class="font-semibold">Calculation Results:</p>
123
- <p>๐Ÿงฑ Tile Type: ${state.tileType}</p>
124
- <p>๐Ÿ“ Length: ${state.length} ft</p>
125
- <p>๐Ÿ“ Width: ${state.width} ft</p>
126
- <p>๐Ÿ“ฆ Area: ${area.toFixed(2)} sq.ft</p>
127
- <p>๐Ÿงฎ Tile Size: ${state.tileSize.toFixed(2)} sq.ft per tile</p>
128
- <p class="mt-2">๐Ÿ”ข <span class="font-bold">Tiles Needed:</span> ${numTiles} (${numBoxes} boxes)</p>
129
- </div>
130
- `);
131
-
132
- state.step = 'complete';
133
- }
134
-
135
- function addMessage(sender, message) {
136
- const messageDiv = document.createElement('div');
137
- messageDiv.className = `${sender}-message ${sender === 'user' ? 'ml-auto bg-indigo-600 text-white' : 'bg-gray-100'} rounded-lg p-4 max-w-xs mb-3`;
138
- messageDiv.innerHTML = message;
139
- chatArea.appendChild(messageDiv);
140
- chatArea.scrollTop = chatArea.scrollHeight;
141
- }
142
-
143
- function showTyping() {
144
- const typingDiv = document.createElement('div');
145
- typingDiv.className = 'typing-indicator bg-gray-100 rounded-lg p-4 max-w-xs mb-3 flex gap-1';
146
- typingDiv.id = 'typing-indicator';
147
- typingDiv.innerHTML = '<span class="w-2 h-2 bg-gray-400 rounded-full"></span><span class="w-2 h-2 bg-gray-400 rounded-full"></span><span class="w-2 h-2 bg-gray-400 rounded-full"></span>';
148
- chatArea.appendChild(typingDiv);
149
- chatArea.scrollTop = chatArea.scrollHeight;
150
- }
151
-
152
- function hideTyping() {
153
- const typingIndicator = document.getElementById('typing-indicator');
154
- if (typingIndicator) typingIndicator.remove();
155
- }
156
- </script>
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
6
+ <title>Tile Calculator AI</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <style>
9
+ .chat-container {
10
+ height: 80vh;
11
+ background-image: radial-gradient(circle at 1px 1px, #e5e7eb 1px, transparent 0);
12
+ background-size: 20px 20px;
13
+ }
14
+ .typing-indicator span {
15
+ animation: bounce 1.5s infinite ease-in-out;
16
+ }
17
+ @keyframes bounce {
18
+ 0%, 60%, 100% { transform: translateY(0); }
19
+ 30% { transform: translateY(-5px); }
20
+ }
21
+ </style>
22
+ </head>
23
+ <body class="bg-gray-100">
24
+ <div class="max-w-4xl mx-auto p-4">
25
+ <div class="bg-white rounded-xl shadow-lg overflow-hidden">
26
+ <!-- Header -->
27
+ <div class="bg-indigo-600 text-white p-4 flex justify-between items-center">
28
+ <div class="flex items-center space-x-3">
29
+ <div class="w-10 h-10 bg-white rounded-full flex items-center justify-center">
30
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-indigo-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
31
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
32
+ </svg>
33
+ </div>
34
+ <div>
35
+ <h1 class="font-bold text-xl">Tile Calculator AI</h1>
36
+ <p class="text-xs opacity-80">Powered by your models</p>
37
+ </div>
38
  </div>
39
+ <button id="reset-btn" class="p-2 rounded-full hover:bg-indigo-700 transition">
40
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
41
+ <path fill-rule="evenodd" d="M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z" clip-rule="evenodd" />
42
+ </svg>
43
+ </button>
44
  </div>
 
 
 
45
 
46
+ <!-- Chat Area -->
47
+ <div class="chat-container p-4 overflow-y-auto" id="chat-area">
48
+ <div class="bot-message bg-gray-100 rounded-lg p-4 max-w-xs mb-3">
49
+ <p>Hello! ๐Ÿ‘‹ I'm your Tile Calculator Assistant. Let's estimate how many tiles you need.</p>
50
+ <p class="mt-2">Are you looking for <span class="font-semibold">floor</span> or <span class="font-semibold">wall</span> tiles?</p>
51
+ <div class="flex gap-2 mt-3">
52
+ <button onclick="selectTileType('floor')" class="quick-reply bg-white text-indigo-600 border border-indigo-600 px-4 py-2 rounded-full font-medium hover:bg-indigo-50">Floor</button>
53
+ <button onclick="selectTileType('wall')" class="quick-reply bg-white text-indigo-600 border border-indigo-600 px-4 py-2 rounded-full font-medium hover:bg-indigo-50">Wall</button>
54
+ </div>
55
+ </div>
56
+ </div>
57
 
58
+ <!-- Input Area -->
59
+ <div class="border-t p-4 bg-white">
60
+ <div class="flex gap-2">
61
+ <input type="text" id="user-input" placeholder="Type your message..." class="flex-1 border rounded-full px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500">
62
+ <button onclick="sendMessage()" class="bg-indigo-600 text-white rounded-full p-2 hover:bg-indigo-700 transition">
63
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
64
+ <path d="M10.894 2.553a1 1 0 00-1.788 0l-7 14a1 1 0 001.169 1.409l5-1.429A1 1 0 009 15.571V11a1 1 0 112 0v4.571a1 1 0 00.725.962l5 1.428a1 1 0 001.17-1.408l-7-14z" />
65
+ </svg>
66
+ </button>
67
+ </div>
68
+ </div>
69
 
70
+ <!-- Recommendations Section -->
71
+ <div class="bg-gray-50 p-4 border-t">
72
+ <h3 class="font-semibold text-gray-800 mb-3">Recommended Products</h3>
73
+ <div class="grid grid-cols-2 md:grid-cols-4 gap-4" id="recommendations"></div>
74
+ </div>
75
+ </div>
76
+ </div>
77
+
78
+ <!-- Main chatbot script -->
79
+ <script>
80
+ const state = {
81
+ step: 'tileType',
82
+ tileType: null,
83
+ area: null,
84
+ tileLength: null,
85
+ tileWidth: null
86
+ };
87
+
88
+ const chatArea = document.getElementById('chat-area');
89
+ const userInput = document.getElementById('user-input');
90
+ const recommendations = document.getElementById('recommendations');
91
+ const resetBtn = document.getElementById('reset-btn');
92
+
93
+ resetBtn.addEventListener('click', resetConversation);
94
+ userInput.addEventListener('keypress', (e) => {
95
+ if (e.key === 'Enter') sendMessage();
96
+ });
97
+
98
+ function resetConversation() {
99
+ state.step = 'tileType';
100
+ state.tileType = null;
101
+ state.area = null;
102
+ state.tileLength = null;
103
+ state.tileWidth = null;
104
+
105
+ chatArea.innerHTML = `
106
+ <div class="bot-message bg-gray-100 rounded-lg p-4 max-w-xs mb-3">
107
+ <p>Hello! ๐Ÿ‘‹ I'm your Tile Calculator Assistant. Let's estimate how many tiles you need.</p>
108
+ <p class="mt-2">Are you looking for <span class="font-semibold">floor</span> or <span class="font-semibold">wall</span> tiles?</p>
109
+ <div class="flex gap-2 mt-3">
110
+ <button onclick="selectTileType('floor')" class="quick-reply bg-white text-indigo-600 border border-indigo-600 px-4 py-2 rounded-full font-medium hover:bg-indigo-50">Floor</button>
111
+ <button onclick="selectTileType('wall')" class="quick-reply bg-white text-indigo-600 border border-indigo-600 px-4 py-2 rounded-full font-medium hover:bg-indigo-50">Wall</button>
112
+ </div>
113
+ </div>
114
+ `;
115
+ recommendations.innerHTML = '';
116
+ }
117
 
118
+ function selectTileType(type) {
119
+ state.tileType = type;
120
+ state.step = 'area';
121
 
122
+ addMessage('user', type === 'floor' ? 'Floor tiles' : 'Wall tiles');
123
+ showTyping();
124
 
125
+ setTimeout(() => {
126
+ hideTyping();
127
+ addMessage('bot', `Great choice for ${type} tiles! What's the total area you need to cover (in sq.ft)?`);
128
+ }, 1000);
129
+ }
130
 
131
+ function sendMessage() {
132
+ const message = userInput.value.trim();
133
+ if (!message) return;
134
 
135
+ addMessage('user', message);
136
+ userInput.value = '';
137
 
138
+ processUser Message(message);
139
+ }
140
+
141
+ function processUser Message(message) {
142
+ showTyping();
143
+
144
+ setTimeout(() => {
145
+ hideTyping();
146
+
147
+ if (state.step === 'area') {
148
+ const area = parseFloat(message);
149
+ if (isNaN(area)) {
150
+ addMessage('bot', 'Please enter a valid number for the area (e.g. 120).');
151
+ return;
152
+ }
153
+
154
+ state.area = area;
155
+ state.step = 'tileLength';
156
+ addMessage('bot', 'Now, please enter the tile length (e.g. "2" for 2 feet):');
157
+
158
+ } else if (state.step === 'tileLength') {
159
+ const length = parseFloat(message);
160
+ if (isNaN(length) || length <= 0) {
161
+ addMessage('bot', 'Please enter a valid positive number for the tile length.');
162
+ return;
163
+ }
164
+
165
+ state.tileLength = length;
166
+ state.step = 'tileWidth';
167
+ addMessage('bot', 'Now, please enter the tile width (e.g. "2" for 2 feet):');
168
+
169
+ } else if (state.step === 'tileWidth') {
170
+ const width = parseFloat(message);
171
+ if (isNaN(width) || width <= 0) {
172
+ addMessage('bot', 'Please enter a valid positive number for the tile width.');
173
+ return;
174
+ }
175
+
176
+ state.tileWidth = width;
177
+ calculateTiles();
178
  }
179
+ }, 1000);
180
+ }
181
 
182
+ function calculateTiles() {
183
+ const tileArea = state.tileLength * state.tileWidth; // Calculate tile area
184
+ const numTiles = Math.ceil((state.area / tileArea) * 1.1); // 10% buffer
185
+ const numBoxes = Math.ceil(numTiles / 10); // Assuming 10 tiles per box
186
+
187
+ chatArea.insertAdjacentHTML('beforeend', `
188
+ <div class="bot-message bg-gray-100 rounded-lg p-4 mb-3">
189
+ <p class="font-semibold">Calculation Results:</p>
190
+ <p>๐Ÿงฑ Tile Type: ${state.tileType}</p>
191
+ <p>๐Ÿ“ Area to Cover: ${state.area} sq.ft</p>
192
+ <p>๐Ÿงฎ Tile Size: ${state.tileLength} ft x ${state.tileWidth} ft</p>
193
+ <p class="mt-2">๐Ÿ”ข <span class="font-bold">Tiles Needed:</span> ${numTiles} (${numBoxes} boxes)</p>
194
+ </div>
195
+ `);
196
+ state.step = 'complete';
197
  }
198
+
199
+ function addMessage(sender, message) {
200
+ const messageDiv = document.createElement('div');
201
+ messageDiv.className = `${sender}-message ${sender === 'user' ? 'ml-auto bg-indigo-600 text-white' : 'bg-gray-100'} rounded-lg p-4 max-w-xs mb-3`;
202
+ messageDiv.textContent = message;
203
+ chatArea.appendChild(messageDiv);
204
+ chatArea.scrollTop = chatArea.scrollHeight;
205
+ }
206
+
207
+ function showTyping() {
208
+ const typingDiv = document.createElement('div');
209
+ typingDiv.className = 'typing-indicator bg-gray-100 rounded-lg p-4 max-w-xs mb-3 flex gap-1';
210
+ typingDiv.id = 'typing-indicator';
211
+ typingDiv.innerHTML = '<span class="w-2 h-2 bg-gray-400 rounded-full"></span><span class="w-2 h-2 bg-gray-400 rounded-full"></span><span class="w-2 h-2 bg-gray-400 rounded-full"></span>';
212
+ chatArea.appendChild(typingDiv);
213
+ chatArea.scrollTop = chatArea.scrollHeight;
214
+ }
215
+
216
+ function hideTyping() {
217
+ const typingIndicator = document.getElementById('typing-indicator');
218
+ if (typingIndicator) typingIndicator.remove();
219
+ }
220
+ </script>
221
+ </body>
222
+ </html>