Ikyy commited on
Commit
ef5fdbc
·
verified ·
1 Parent(s): 5a3db39

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +198 -73
index.html CHANGED
@@ -2,108 +2,145 @@
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>Chatbot Animasi</title>
7
  <style>
8
  :root {
9
- --primary-color: #2196F3;
10
- --secondary-color: #ffffff;
 
 
 
 
 
11
  }
12
 
13
  body {
14
- font-family: Arial, sans-serif;
15
  margin: 0;
16
  padding: 0;
17
- display: flex;
18
- justify-content: center;
19
- align-items: center;
20
- min-height: 100vh;
21
- background-color: #f0f0f0;
 
22
  }
23
 
24
  .chat-container {
25
- width: 90%;
26
- max-width: 400px;
27
- background: white;
28
- border-radius: 20px;
29
- box-shadow: 0 0 20px rgba(0,0,0,0.1);
30
- overflow: hidden;
31
- transform: translateY(20px);
32
- opacity: 0;
33
- animation: slideUp 0.5s ease forwards;
34
  }
35
 
36
  .chat-header {
37
- background: var(--primary-color);
38
- color: white;
39
  padding: 1rem;
40
  text-align: center;
 
 
 
 
 
41
  }
42
 
43
  .chat-messages {
44
- height: 400px;
45
  overflow-y: auto;
46
  padding: 1rem;
47
  display: flex;
48
  flex-direction: column;
49
- gap: 10px;
 
50
  }
51
 
52
  .message {
53
- max-width: 80%;
54
- padding: 10px 15px;
55
- border-radius: 15px;
56
- animation: fadeIn 0.3s ease;
 
 
 
57
  }
58
 
59
  .user-message {
60
- background: var(--primary-color);
61
- color: white;
62
  align-self: flex-end;
 
 
 
63
  }
64
 
65
  .bot-message {
66
- background: #e0e0e0;
67
  align-self: flex-start;
 
 
68
  }
69
 
70
  .input-container {
71
  display: flex;
72
  padding: 1rem;
73
- background: #f5f5f5;
 
 
 
 
74
  }
75
 
76
  input[type="text"] {
77
  flex: 1;
78
- padding: 10px;
79
- border: 1px solid #ddd;
80
  border-radius: 25px;
81
- margin-right: 10px;
82
- outline: none;
 
 
 
 
 
 
 
 
83
  }
84
 
85
  button {
86
- background: var(--primary-color);
87
- color: white;
88
  border: none;
89
- padding: 10px 20px;
90
  border-radius: 25px;
 
 
91
  cursor: pointer;
92
- transition: transform 0.2s ease;
 
93
  }
94
 
95
- button:hover {
96
- transform: scale(1.05);
 
97
  }
98
 
99
- @keyframes slideUp {
100
- to {
101
- transform: translateY(0);
102
- opacity: 1;
103
- }
 
 
 
 
 
 
 
 
 
 
104
  }
105
 
106
- @keyframes fadeIn {
107
  from {
108
  opacity: 0;
109
  transform: translateY(10px);
@@ -114,11 +151,51 @@
114
  }
115
  }
116
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  @media (max-width: 480px) {
118
- .chat-container {
119
- width: 100%;
120
- height: 100vh;
121
- border-radius: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  }
123
  }
124
  </style>
@@ -126,54 +203,102 @@
126
  <body>
127
  <div class="chat-container">
128
  <div class="chat-header">
129
- <h2>Chatbot Pintar</h2>
130
  </div>
131
- <div class="chat-messages" id="chatMessages"></div>
 
 
 
 
132
  <div class="input-container">
133
- <input type="text" id="userInput" placeholder="Ketik pesan...">
134
- <button onclick="sendMessage()">Kirim</button>
135
  </div>
136
  </div>
137
 
138
  <script>
139
  const chatMessages = document.getElementById('chatMessages');
140
  const userInput = document.getElementById('userInput');
 
141
 
142
- // Handle Enter key
143
- userInput.addEventListener('keypress', (e) => {
144
- if (e.key === 'Enter') sendMessage();
145
- });
146
-
147
- function appendMessage(message, isUser) {
148
- const messageDiv = document.createElement('div');
149
- messageDiv.className = `message ${isUser ? 'user-message' : 'bot-message'}`;
150
- messageDiv.textContent = message;
151
- chatMessages.appendChild(messageDiv);
152
- chatMessages.scrollTop = chatMessages.scrollHeight;
 
153
  }
154
 
155
  async function sendMessage() {
156
  const message = userInput.value.trim();
157
- if (!message) return;
158
 
159
- appendMessage(message, true);
 
 
 
 
 
160
  userInput.value = '';
 
 
 
 
 
 
 
161
 
162
  try {
163
  const response = await fetch('http://localhost:3000/chat', {
164
  method: 'POST',
165
- headers: {
166
- 'Content-Type': 'application/json',
167
- },
168
  body: JSON.stringify({ message })
169
  });
170
 
171
  const data = await response.json();
172
- appendMessage(data.reply, false);
 
 
 
 
 
 
 
 
173
  } catch (error) {
174
- appendMessage('Maaf, terjadi kesalahan koneksi', false);
 
 
 
 
 
 
 
175
  }
176
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  </script>
178
  </body>
179
  </html>
 
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
6
+ <title>Glow Chatbot</title>
7
  <style>
8
  :root {
9
+ --neon-color: #0ff;
10
+ --bg-color: #0a0a0a;
11
+ --text-color: rgba(255,255,255,0.9);
12
+ }
13
+
14
+ * {
15
+ box-sizing: border-box;
16
  }
17
 
18
  body {
 
19
  margin: 0;
20
  padding: 0;
21
+ background: var(--bg-color);
22
+ font-family: 'Courier New', monospace;
23
+ color: var(--text-color);
24
+ touch-action: manipulation;
25
+ height: 100vh;
26
+ overflow: hidden;
27
  }
28
 
29
  .chat-container {
30
+ width: 100%;
31
+ height: 100vh;
32
+ display: flex;
33
+ flex-direction: column;
34
+ background: radial-gradient(circle at center, #1a1a1a 0%, #0a0a0a 100%);
 
 
 
 
35
  }
36
 
37
  .chat-header {
 
 
38
  padding: 1rem;
39
  text-align: center;
40
+ background: rgba(0,0,0,0.3);
41
+ border-bottom: 2px solid var(--neon-color);
42
+ box-shadow: 0 0 15px var(--neon-color);
43
+ position: relative;
44
+ z-index: 2;
45
  }
46
 
47
  .chat-messages {
48
+ flex: 1;
49
  overflow-y: auto;
50
  padding: 1rem;
51
  display: flex;
52
  flex-direction: column;
53
+ gap: 15px;
54
+ -webkit-overflow-scrolling: touch;
55
  }
56
 
57
  .message {
58
+ max-width: 85%;
59
+ padding: 12px 18px;
60
+ border-radius: 20px;
61
+ position: relative;
62
+ animation: messageAppear 0.3s ease;
63
+ word-break: break-word;
64
+ line-height: 1.4;
65
  }
66
 
67
  .user-message {
68
+ background: linear-gradient(145deg, #006666, #009999);
 
69
  align-self: flex-end;
70
+ color: white;
71
+ border: 1px solid var(--neon-color);
72
+ box-shadow: 0 0 10px var(--neon-color);
73
  }
74
 
75
  .bot-message {
76
+ background: linear-gradient(145deg, #1a1a1a, #2a2a2a);
77
  align-self: flex-start;
78
+ border: 1px solid #444;
79
+ box-shadow: 0 0 10px rgba(0,255,255,0.2);
80
  }
81
 
82
  .input-container {
83
  display: flex;
84
  padding: 1rem;
85
+ gap: 10px;
86
+ background: rgba(0,0,0,0.5);
87
+ border-top: 1px solid var(--neon-color);
88
+ position: relative;
89
+ z-index: 2;
90
  }
91
 
92
  input[type="text"] {
93
  flex: 1;
94
+ padding: 15px;
95
+ border: none;
96
  border-radius: 25px;
97
+ background: rgba(255,255,255,0.1);
98
+ color: var(--neon-color);
99
+ font-size: 16px;
100
+ text-shadow: 0 0 5px var(--neon-color);
101
+ caret-color: var(--neon-color);
102
+ }
103
+
104
+ input::placeholder {
105
+ color: #4d4d4d;
106
+ font-style: italic;
107
  }
108
 
109
  button {
110
+ background: linear-gradient(145deg, #006666, #009999);
 
111
  border: none;
112
+ padding: 0 25px;
113
  border-radius: 25px;
114
+ color: white;
115
+ font-weight: bold;
116
  cursor: pointer;
117
+ transition: all 0.3s ease;
118
+ min-width: 50px;
119
  }
120
 
121
+ button:active {
122
+ transform: scale(0.95);
123
+ filter: brightness(1.2);
124
  }
125
 
126
+ .typing-indicator {
127
+ display: inline-flex;
128
+ padding: 10px 15px;
129
+ background: rgba(0,0,0,0.5);
130
+ border-radius: 15px;
131
+ gap: 5px;
132
+ align-items: center;
133
+ }
134
+
135
+ .typing-dot {
136
+ width: 8px;
137
+ height: 8px;
138
+ background: var(--neon-color);
139
+ border-radius: 50%;
140
+ animation: typing 1.4s infinite ease-in-out;
141
  }
142
 
143
+ @keyframes messageAppear {
144
  from {
145
  opacity: 0;
146
  transform: translateY(10px);
 
151
  }
152
  }
153
 
154
+ @keyframes typing {
155
+ 0%, 100% {
156
+ transform: translateY(0);
157
+ opacity: 0.5;
158
+ }
159
+ 50% {
160
+ transform: translateY(-5px);
161
+ opacity: 1;
162
+ }
163
+ }
164
+
165
+ /* Scrollbar Styling */
166
+ ::-webkit-scrollbar {
167
+ width: 5px;
168
+ }
169
+
170
+ ::-webkit-scrollbar-track {
171
+ background: rgba(0,0,0,0.2);
172
+ }
173
+
174
+ ::-webkit-scrollbar-thumb {
175
+ background: var(--neon-color);
176
+ border-radius: 5px;
177
+ }
178
+
179
  @media (max-width: 480px) {
180
+ .message {
181
+ max-width: 90%;
182
+ padding: 10px 15px;
183
+ font-size: 14px;
184
+ }
185
+
186
+ input[type="text"] {
187
+ padding: 12px;
188
+ font-size: 14px;
189
+ }
190
+
191
+ button {
192
+ padding: 0 20px;
193
+ font-size: 14px;
194
+ }
195
+
196
+ .typing-dot {
197
+ width: 6px;
198
+ height: 6px;
199
  }
200
  }
201
  </style>
 
203
  <body>
204
  <div class="chat-container">
205
  <div class="chat-header">
206
+ <h1 style="color: var(--neon-color); text-shadow: 0 0 10px var(--neon-color); margin: 0;">GLOW CHAT</h1>
207
  </div>
208
+
209
+ <div class="chat-messages" id="chatMessages">
210
+ <!-- Pesan akan muncul di sini -->
211
+ </div>
212
+
213
  <div class="input-container">
214
+ <input type="text" id="userInput" placeholder="Ketik pesan..." autocomplete="off">
215
+ <button onclick="sendMessage()">➤</button>
216
  </div>
217
  </div>
218
 
219
  <script>
220
  const chatMessages = document.getElementById('chatMessages');
221
  const userInput = document.getElementById('userInput');
222
+ let isBotTyping = false;
223
 
224
+ function createTypingIndicator() {
225
+ const container = document.createElement('div');
226
+ container.className = 'message bot-message typing-indicator';
227
+
228
+ for(let i = 0; i < 3; i++) {
229
+ const dot = document.createElement('div');
230
+ dot.className = 'typing-dot';
231
+ dot.style.animationDelay = `${i * 0.2}s`;
232
+ container.appendChild(dot);
233
+ }
234
+
235
+ return container;
236
  }
237
 
238
  async function sendMessage() {
239
  const message = userInput.value.trim();
240
+ if (!message || isBotTyping) return;
241
 
242
+ // Tambahkan pesan pengguna
243
+ const userDiv = document.createElement('div');
244
+ userDiv.className = 'message user-message';
245
+ userDiv.textContent = message;
246
+ chatMessages.appendChild(userDiv);
247
+
248
  userInput.value = '';
249
+ scrollToBottom();
250
+
251
+ // Tampilkan typing indicator
252
+ isBotTyping = true;
253
+ const typingIndicator = createTypingIndicator();
254
+ chatMessages.appendChild(typingIndicator);
255
+ scrollToBottom();
256
 
257
  try {
258
  const response = await fetch('http://localhost:3000/chat', {
259
  method: 'POST',
260
+ headers: { 'Content-Type': 'application/json' },
 
 
261
  body: JSON.stringify({ message })
262
  });
263
 
264
  const data = await response.json();
265
+
266
+ // Hapus typing indicator dan tampilkan balasan
267
+ typingIndicator.remove();
268
+ const botDiv = document.createElement('div');
269
+ botDiv.className = 'message bot-message';
270
+ botDiv.textContent = data.reply;
271
+ chatMessages.appendChild(botDiv);
272
+ scrollToBottom();
273
+
274
  } catch (error) {
275
+ typingIndicator.remove();
276
+ const errorDiv = document.createElement('div');
277
+ errorDiv.className = 'message bot-message';
278
+ errorDiv.textContent = '⚠️ Gagal terhubung ke server';
279
+ chatMessages.appendChild(errorDiv);
280
+ scrollToBottom();
281
+ } finally {
282
+ isBotTyping = false;
283
  }
284
  }
285
+
286
+ function scrollToBottom() {
287
+ chatMessages.scrollTop = chatMessages.scrollHeight;
288
+ }
289
+
290
+ // Handle keyboard events
291
+ userInput.addEventListener('keypress', (e) => {
292
+ if (e.key === 'Enter' && !e.shiftKey) {
293
+ e.preventDefault();
294
+ sendMessage();
295
+ }
296
+ });
297
+
298
+ // Auto-focus input saat halaman dimuat
299
+ window.addEventListener('load', () => {
300
+ userInput.focus();
301
+ });
302
  </script>
303
  </body>
304
  </html>