Andrewbluebird commited on
Commit
17d2409
·
verified ·
1 Parent(s): 6298ac4

Manual changes saved

Browse files
Files changed (1) hide show
  1. index.html +421 -86
index.html CHANGED
@@ -1,11 +1,10 @@
1
-
2
  <!DOCTYPE html>
3
  <html lang="en">
4
  <head>
5
  <meta charset="UTF-8">
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>FurryChat.ai - Introduction</title>
8
- <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
9
  <script src="https://cdn.tailwindcss.com"></script>
10
  <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
11
  <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
@@ -149,8 +148,7 @@
149
  </style>
150
  </head>
151
  <body class="bg-gray-50">
152
- <!-- Renamed to IntroPage.html -->
153
- <!-- Hero Section with Vanta.js Background -->
154
  <div id="vanta-bg" class="absolute top-0 left-0 w-full h-screen z-0"></div>
155
 
156
  <div class="relative z-10">
@@ -167,100 +165,106 @@
167
  <a href="#" class="text-gray-600 hover:text-blue-600 transition-colors">Pricing</a>
168
  <a href="#" class="text-gray-600 hover:text-blue-600 transition-colors">About</a>
169
  </div>
170
- <a href="SignIn.html" class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors">
171
- Login
172
- </a>
173
- </div>
174
  </nav>
175
 
176
- <!-- Hero Section -->
177
- <section class="py-20 px-4 relative">
178
- <div class="container mx-auto text-center">
179
- <h1 class="text-5xl md:text-6xl font-bold mb-6 text-gray-800">Where <span class="text-blue-600">Furry Friends</span> Come to Life</h1>
180
- <p class="text-xl md:text-2xl text-gray-600 max-w-4xl mx-auto mb-10">
181
- AI-powered roleplay with your favorite anthropomorphic characters. Create, chat, and bond with your digital furry companions.
182
- </p>
183
- <div class="flex flex-col md:flex-row justify-center gap-4">
184
- <a href="SignIn.html" class="bg-blue-600 hover:bg-blue-700 text-white px-8 py-3 rounded-lg font-semibold transition-colors">
185
- Login
186
- </a>
187
- <a href="#" class="bg-white hover:bg-gray-100 text-gray-800 px-8 py-3 rounded-lg font-semibold border border-gray-200 transition-colors">
188
- Meet Our Characters
189
- </a>
190
- </div>
191
- <div class="mt-12 max-w-md mx-auto bg-white p-6 rounded-lg shadow-sm">
192
- <h3 class="text-lg font-medium text-center mb-4">Get updates via WhatsApp (HK)</h3>
193
- <div class="flex">
194
- <select class="bg-gray-100 border border-gray-300 text-gray-700 py-2 px-3 rounded-l-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
195
- <option>+852</option>
196
- </select>
197
- <input type="tel" placeholder="Phone number" class="flex-1 border border-gray-300 rounded-r-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" pattern="[0-9]{8}">
198
  </div>
199
- <button class="w-full mt-4 bg-green-600 hover:bg-green-700 text-white font-medium py-2 px-4 rounded-lg transition-colors">
200
- Subscribe via WhatsApp
201
- </button>
202
  </div>
203
- </div>
204
- </section>
205
 
206
- <!-- Featured Characters -->
207
- <section class="py-16 px-4">
208
- <div class="container mx-auto">
209
- <h2 class="text-3xl font-bold text-center mb-12 text-gray-800">Meet Our <span class="text-blue-600">Furry Pals</span></h2>
210
- <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
211
- <!-- Character 1 -->
212
- <div class="bg-white rounded-xl shadow-md overflow-hidden hover:shadow-lg transition-shadow">
213
- <img src="http://static.photos/animals/640x360/1" alt="Luna the Wolf" class="w-full h-48 object-cover">
214
- <div class="p-6">
215
- <h3 class="text-xl font-bold mb-2 text-gray-800">Luna the Wolf</h3>
216
- <p class="text-gray-600 mb-4">Mystical and wise, Luna guides with ancestral knowledge.</p>
217
- <a href="#" class="inline-block text-blue-600 hover:text-blue-700 font-medium">Chat with Luna →</a>
 
 
 
 
218
  </div>
219
- </div>
220
-
221
- <!-- Character 2 -->
222
- <div class="bg-white rounded-xl shadow-md overflow-hidden hover:shadow-lg transition-shadow">
223
- <img src="http://static.photos/animals/640x360/2" alt="Rex the Fox" class="w-full h-48 object-cover">
224
- <div class="p-6">
225
- <h3 class="text-xl font-bold mb-2 text-gray-800">Rex the Fox</h3>
226
- <p class="text-gray-600 mb-4">Clever and playful, Rex always has a trick up his sleeve.</p>
227
- <a href="#" class="inline-block text-blue-600 hover:text-blue-700 font-medium">Chat with Rex →</a>
228
  </div>
229
- </div>
230
- </div>
231
- </div>
232
- </section>
233
- <!-- Features Section (changed from Chat section) -->
234
- <section class="py-16 px-4">
235
- <div class="container mx-auto">
236
- <h2 class="text-3xl font-bold text-center mb-12 text-gray-800">Amazing <span class="text-blue-600">Features</span></h2>
237
- <div class="grid grid-cols-1 md:grid-cols-3 gap-8">
238
- <div class="text-center">
239
- <div class="bg-blue-100 rounded-full w-16 h-16 flex items-center justify-center mx-auto mb-4">
240
- <i data-feather="cpu" class="text-blue-600 w-8 h-8"></i>
241
  </div>
242
- <h3 class="text-xl font-semibold mb-2">Advanced AI</h3>
243
- <p class="text-gray-600">Our characters learn and remember your preferences for more natural conversations.</p>
244
  </div>
245
- <div class="text-center">
246
- <div class="bg-blue-100 rounded-full w-16 h-16 flex items-center justify-center mx-auto mb-4">
247
- <i data-feather="sliders" class="text-blue-600 w-8 h-8"></i>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  </div>
249
- <h3 class="text-xl font-semibold mb-2">Customization</h3>
250
- <p class="text-gray-600">Create your own furry character with unique traits and personality.</p>
251
- </div>
252
- <div class="text-center">
253
- <div class="bg-blue-100 rounded-full w-16 h-16 flex items-center justify-center mx-auto mb-4">
254
- <i data-feather="globe" class="text-blue-600 w-8 h-8"></i>
 
 
 
 
255
  </div>
256
- <h3 class="text-xl font-semibold mb-2">Multi-platform</h3>
257
- <p class="text-gray-600">Chat anywhere, anytime - web, mobile, and desktop apps available.</p>
258
  </div>
259
  </div>
260
  </div>
261
- </section>
262
 
263
- <!-- Footer -->
 
 
264
  <footer class="bg-gray-800 text-white mt-16 py-8">
265
  <div class="container mx-auto px-4">
266
  <div class="grid grid-cols-1 md:grid-cols-4 gap-8">
@@ -311,7 +315,338 @@
311
  </footer>
312
  </div>
313
 
314
-
315
- <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
  </body>
317
  </html>
 
 
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>FurryChat.ai</title>
7
+ <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
8
  <script src="https://cdn.tailwindcss.com"></script>
9
  <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
10
  <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
 
148
  </style>
149
  </head>
150
  <body class="bg-gray-50">
151
+ <!-- Hero Section with Vanta.js Background -->
 
152
  <div id="vanta-bg" class="absolute top-0 left-0 w-full h-screen z-0"></div>
153
 
154
  <div class="relative z-10">
 
165
  <a href="#" class="text-gray-600 hover:text-blue-600 transition-colors">Pricing</a>
166
  <a href="#" class="text-gray-600 hover:text-blue-600 transition-colors">About</a>
167
  </div>
168
+ <button class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors">
169
+ Get Started
170
+ </button>
171
+ </div>
172
  </nav>
173
 
174
+ <!-- Main Content -->
175
+ <div class="container mx-auto px-4 py-8">
176
+ <!-- Combined Avatar and Chat Window -->
177
+ <div class="max-w-4xl mx-auto bg-white rounded-xl shadow-lg overflow-hidden" data-aos="fade-up">
178
+ <!-- Combined Header with Avatar and Chat Info -->
179
+ <div class="bg-gradient-to-r from-blue-600 to-purple-600 p-6 text-white">
180
+ <div class="flex items-center space-x-4">
181
+ <!-- 3D Avatar Container -->
182
+ <div class="w-16 h-16 bg-white bg-opacity-20 rounded-lg overflow-hidden">
183
+ <div id="avatar-canvas" style="height: 64px; width: 64px;"></div>
184
+ </div>
185
+ <div>
186
+ <h2 class="text-xl font-semibold">Sancia</h2>
187
+ <p class="text-blue-100 text-sm">The Free-to-try furry AI</p>
188
+ </div>
 
 
 
 
 
 
 
189
  </div>
 
 
 
190
  </div>
 
 
191
 
192
+ <!-- Combined Chat Container -->
193
+ <div class="flex" style="height: 500px;">
194
+ <!-- 3D Avatar Side Panel -->
195
+ <div class="w-1/3 bg-gray-100 border-r border-gray-200 flex flex-col">
196
+ <!-- 3D Model Viewer -->
197
+ <div class="flex-1 p-4">
198
+ <model-viewer
199
+ id="model-viewer"
200
+ src=""
201
+ alt="A 3D model"
202
+ auto-rotate
203
+ camera-controls
204
+ shadow-intensity="1"
205
+ environment-image="neutral"
206
+ exposure="1">
207
+ </model-viewer>
208
  </div>
209
+
210
+ <!-- Upload Section -->
211
+ <div class="upload-section">
212
+ <h3 class="font-semibold text-gray-800 mb-2">Upload 3D Model</h3>
213
+ <input type="file" id="model-upload" accept=".glb,.gltf" style="display: none;">
214
+ <button class="upload-btn" id="upload-btn">Choose 3D Model File</button>
215
+ <p class="model-info" id="model-info">No model loaded. Supported formats: .glb, .gltf</p>
 
 
216
  </div>
217
+
218
+ <!-- Animation Controls -->
219
+ <div class="animation-controls" id="animation-controls" style="display: none;">
220
+ <h3 class="font-semibold text-gray-800 mb-2">Test Animation Controls</h3>
221
+ <div class="animation-buttons" id="animation-buttons">
222
+ <!-- Animation buttons will be added dynamically -->
223
+ </div>
 
 
 
 
 
224
  </div>
 
 
225
  </div>
226
+
227
+ <!-- Chat Container -->
228
+ <div class="w-2/3 flex flex-col">
229
+ <div class="chat-container p-4 bg-gray-50 flex-1" id="chat-messages">
230
+ <!-- Welcome message -->
231
+ <div class="message bg-white rounded-lg p-4 shadow-sm mb-4 ml-auto" data-aos="fade-left">
232
+ <p class="text-gray-800">Hello! I'm Sancia, Free to try Furry AI. What topics would you like to talk with?</p>
233
+ <p class="text-gray-800">(Pro tip: Sign up or Log in FurryChat.ai to get access to huge collection of community made AI Furries and make and customize your own AI Furry)</p>
234
+ <span class="text-xs text-gray-500 block mt-1">Just now</span>
235
+ </div>
236
+
237
+ <!-- Sample conversation starters -->
238
+ <div class="grid grid-cols-1 gap-2 mb-4">
239
+ <button class="suggestion-btn bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg p-3 text-sm transition-colors" data-message="What can you do?">
240
+ <i data-feather="help-circle" class="w-4 h-4 inline mr-1"></i> What can you do?
241
+ </button>
242
+ <button class="suggestion-btn bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg p-3 text-sm transition-colors" data-message="Tell me about you">
243
+ <i data-feather="smile" class="w-4 h-4 inline mr-1"></i> Tell me a joke
244
+ </button>
245
+ <button class="suggestion-btn bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg p-3 text-sm transition-colors" data-message="How does AI Furry work?">
246
+ <i data-feather="code" class="w-4 h-4 inline mr-1"></i> How does AI Furry work?
247
+ </button>
248
+ </div>
249
  </div>
250
+
251
+ <!-- Input Area -->
252
+ <div class="border-t border-gray-200 p-4 bg-white">
253
+ <div class="flex space-x-2">
254
+ <input type="text" id="user-input" placeholder="Type your message here..."
255
+ class="flex-1 border border-gray-300 rounded-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
256
+ <button id="send-btn" class="bg-blue-600 text-white p-3 rounded-lg hover:bg-blue-700 transition-colors">
257
+ <i data-feather="send" class="w-5 h-5"></i>
258
+ </button>
259
+ </div>
260
  </div>
 
 
261
  </div>
262
  </div>
263
  </div>
 
264
 
265
+ </div>
266
+
267
+ <!-- Footer -->
268
  <footer class="bg-gray-800 text-white mt-16 py-8">
269
  <div class="container mx-auto px-4">
270
  <div class="grid grid-cols-1 md:grid-cols-4 gap-8">
 
315
  </footer>
316
  </div>
317
 
318
+ <script>
319
+ // Initialize animations and icons
320
+ AOS.init({
321
+ duration: 800,
322
+ easing: 'ease-in-out',
323
+ once: true
324
+ });
325
+ feather.replace();
326
+
327
+ // Initialize Vanta.js background
328
+ VANTA.GLOBE({
329
+ el: "#vanta-bg",
330
+ mouseControls: true,
331
+ touchControls: true,
332
+ gyroControls: false,
333
+ minHeight: 200.00,
334
+ minWidth: 200.00,
335
+ scale: 1.00,
336
+ scaleMobile: 1.00,
337
+ color: 0x3b82f6,
338
+ backgroundColor: 0xf8fafc,
339
+ size: 0.8
340
+ });
341
+
342
+ // Initialize 3D Avatar
343
+ function initAvatar() {
344
+ const canvas = document.getElementById('avatar-canvas');
345
+ const mainCanvas = document.getElementById('avatar-canvas-main');
346
+
347
+ // Create React component for small avatar in header
348
+ const SmallAvatar = () => {
349
+ return React.createElement(
350
+ ReactThreeFiber.Canvas,
351
+ {
352
+ camera: { position: [0, 0, 2], fov: 60 },
353
+ style: { height: '100%', width: '100%' }
354
+ },
355
+ React.createElement(
356
+ ReactThreeFiber.Suspense,
357
+ { fallback: null },
358
+ React.createElement(
359
+ ReactThreeFiber.mesh,
360
+ { rotation: [0.5, 0.5, 0] },
361
+ React.createElement(
362
+ ReactThreeDrei.BoxGeometry,
363
+ { args: [0.8, 0.8, 0.8] }
364
+ ),
365
+ React.createElement(
366
+ ReactThreeFiber.meshStandardMaterial,
367
+ { color: '#ffffff' }
368
+ )
369
+ ),
370
+ React.createElement(
371
+ ReactThreeFiber.ambientLight,
372
+ { intensity: 0.7 }
373
+ ),
374
+ React.createElement(
375
+ ReactThreeFiber.pointLight,
376
+ { position: [2, 2, 2], intensity: 0.8 }
377
+ )
378
+ )
379
+ );
380
+ };
381
+
382
+ // Create React component for main avatar
383
+ const MainAvatar = () => {
384
+ return React.createElement(
385
+ ReactThreeFiber.Canvas,
386
+ {
387
+ camera: { position: [0, 0, 3], fov: 75 },
388
+ style: { height: '100%', width: '100%' }
389
+ },
390
+ React.createElement(
391
+ ReactThreeFiber.Suspense,
392
+ { fallback: null },
393
+ React.createElement(
394
+ ReactThreeFiber.mesh,
395
+ { rotation: [0, 0, 0] },
396
+ React.createElement(
397
+ ReactThreeDrei.BoxGeometry,
398
+ { args: [1, 1, 1] }
399
+ ),
400
+ React.createElement(
401
+ ReactThreeFiber.meshStandardMaterial,
402
+ { color: '#3b82f6' }
403
+ )
404
+ ),
405
+ React.createElement(
406
+ ReactThreeFiber.ambientLight,
407
+ { intensity: 0.5 }
408
+ ),
409
+ React.createElement(
410
+ ReactThreeFiber.pointLight,
411
+ { position: [5, 5, 5], intensity: 1 }
412
+ ),
413
+ React.createElement(
414
+ ReactThreeFiber.pointLight,
415
+ { position: [-5, -5, -5], intensity: 0.5 }
416
+ )
417
+ )
418
+ );
419
+ };
420
+
421
+ // Render both avatars
422
+ ReactDOM.render(React.createElement(SmallAvatar), canvas);
423
+ ReactDOM.render(React.createElement(MainAvatar), mainCanvas);
424
+ }
425
+
426
+ // Initialize avatar after page load
427
+ setTimeout(initAvatar, 100);
428
+
429
+ // 3D Model Viewer Functionality
430
+ document.addEventListener('DOMContentLoaded', function() {
431
+ const modelViewer = document.getElementById('model-viewer');
432
+ const uploadBtn = document.getElementById('upload-btn');
433
+ const modelUpload = document.getElementById('model-upload');
434
+ const modelInfo = document.getElementById('model-info');
435
+ const animationControls = document.getElementById('animation-controls');
436
+ const animationButtons = document.getElementById('animation-buttons');
437
+
438
+ let currentAnimations = [];
439
+
440
+ // Handle file upload
441
+ uploadBtn.addEventListener('click', function() {
442
+ modelUpload.click();
443
+ });
444
+
445
+ modelUpload.addEventListener('change', function(e) {
446
+ const file = e.target.files[0];
447
+ if (file) {
448
+ const url = URL.createObjectURL(file);
449
+ modelViewer.src = url;
450
+ modelInfo.textContent = `Loaded: ${file.name}`;
451
+
452
+ // Reset animation state
453
+ currentAnimations = [];
454
+ animationControls.style.display = 'none';
455
+ animationButtons.innerHTML = '';
456
+
457
+ // Check for animations after model loads
458
+ modelViewer.addEventListener('load', function() {
459
+ checkForAnimations();
460
+ });
461
+ }
462
+ });
463
+
464
+ // Check if the model has animations
465
+ function checkForAnimations() {
466
+ // This is a simplified approach - in a real implementation,
467
+ // you would need to access the Three.js scene and check for animations
468
+ // For now, we'll simulate this with a timeout
469
+
470
+ setTimeout(() => {
471
+ // Simulate finding animations
472
+ const availableAnimations = ['Idle', 'Wave', 'Jump', 'Dance'];
473
+
474
+ if (availableAnimations.length > 0) {
475
+ currentAnimations = availableAnimations;
476
+ setupAnimationControls(availableAnimations);
477
+ } else {
478
+ // No animations found
479
+ }
480
+ }, 1000);
481
+ }
482
+
483
+ // Set up animation control buttons
484
+ function setupAnimationControls(animations) {
485
+ animationControls.style.display = 'block';
486
+ animationButtons.innerHTML = '';
487
+
488
+ animations.forEach(animation => {
489
+ const button = document.createElement('button');
490
+ button.classList.add('animation-btn');
491
+ button.textContent = animation;
492
+ button.addEventListener('click', () => {
493
+ playAnimation(animation);
494
+
495
+ // Update active state
496
+ document.querySelectorAll('.animation-btn').forEach(btn => {
497
+ btn.classList.remove('active');
498
+ });
499
+ button.classList.add('active');
500
+ });
501
+
502
+ animationButtons.appendChild(button);
503
+ });
504
+
505
+ // Add stop button
506
+ const stopButton = document.createElement('button');
507
+ stopButton.classList.add('animation-btn');
508
+ stopButton.textContent = 'Stop';
509
+ stopButton.addEventListener('click', () => {
510
+ stopAnimation();
511
+
512
+ // Remove active state from all buttons
513
+ document.querySelectorAll('.animation-btn').forEach(btn => {
514
+ btn.classList.remove('active');
515
+ });
516
+ });
517
+
518
+ animationButtons.appendChild(stopButton);
519
+ }
520
+
521
+ // Play animation
522
+ function playAnimation(animationName) {
523
+ // In a real implementation, this would use Three.js AnimationMixer
524
+ // For this demo, we'll simulate the behavior
525
+
526
+ console.log(`Playing animation: ${animationName}`);
527
+
528
+ // In a real implementation, you would:
529
+ // 1. Get the animation clip by name
530
+ // 2. Create an AnimationMixer if it doesn't exist
531
+ // 3. Play the animation
532
+ }
533
+
534
+ // Stop animation
535
+ function stopAnimation() {
536
+ // In a real implementation, this would stop the AnimationMixer
537
+
538
+ console.log("Animation stopped");
539
+ }
540
+ });
541
+
542
+ // Chat functionality with better error handling
543
+ document.addEventListener('DOMContentLoaded', function() {
544
+ const chatMessages = document.getElementById('chat-messages');
545
+ const userInput = document.getElementById('user-input');
546
+ const sendBtn = document.getElementById('send-btn');
547
+
548
+ // Test API connection on load
549
+ testAPIConnection();
550
+
551
+ async function testAPIConnection() {
552
+ try {
553
+ const response = await fetch('/api/test');
554
+ const data = await response.json();
555
+ console.log('API test:', data);
556
+ } catch (error) {
557
+ console.error('API test failed:', error);
558
+ }
559
+ }
560
+
561
+ function handleKeyPress(event) {
562
+ if (event.key === 'Enter') {
563
+ sendMessage();
564
+ }
565
+ }
566
+
567
+ async function sendMessage() {
568
+ const message = userInput.value.trim();
569
+ if (!message) return;
570
+
571
+ // Add user message to chat
572
+ addMessage(message, 'user');
573
+ userInput.value = '';
574
+ sendBtn.disabled = true;
575
+
576
+ try {
577
+ console.log('Sending message to API...');
578
+
579
+ const response = await fetch('/api/chat', {
580
+ method: 'POST',
581
+ headers: {
582
+ 'Content-Type': 'application/json',
583
+ },
584
+ body: JSON.stringify({
585
+ message: message,
586
+ conversation_history: []
587
+ })
588
+ });
589
+
590
+ console.log('Response status:', response.status);
591
+
592
+ // Check if response is JSON
593
+ const contentType = response.headers.get('content-type');
594
+ if (!contentType || !contentType.includes('application/json')) {
595
+ const text = await response.text();
596
+ console.error('Non-JSON response:', text.substring(0, 200));
597
+ throw new Error('Server returned HTML instead of JSON. Check the API endpoint.');
598
+ }
599
+
600
+ const data = await response.json();
601
+ console.log('Response data:', data);
602
+
603
+ if (response.ok) {
604
+ addMessage(data.response, 'bot');
605
+ } else {
606
+ addMessage(`Error: ${data.error || 'Unknown error'}`, 'bot');
607
+ }
608
+ } catch (error) {
609
+ console.error('Network error:', error);
610
+ addMessage(`Network error: ${error.message}`, 'bot');
611
+ } finally {
612
+ sendBtn.disabled = false;
613
+ userInput.focus();
614
+ }
615
+ }
616
+
617
+ function addMessage(text, sender) {
618
+ const messageDiv = document.createElement('div');
619
+
620
+ if (sender === 'user') {
621
+ messageDiv.className = 'message bg-blue-100 rounded-lg p-4 shadow-sm mb-4 ml-auto';
622
+ messageDiv.innerHTML = `
623
+ <p class="text-blue-800">${text}</p>
624
+ <span class="text-xs text-blue-600 block mt-1">${new Date().toLocaleTimeString()}</span>
625
+ `;
626
+ } else {
627
+ messageDiv.className = 'message bg-white rounded-lg p-4 shadow-sm mb-4 mr-auto';
628
+ messageDiv.innerHTML = `
629
+ <p class="text-gray-800">${text}</p>
630
+ <span class="text-xs text-gray-500 block mt-1">${new Date().toLocaleTimeString()}</span>
631
+ `;
632
+ }
633
+
634
+ chatMessages.appendChild(messageDiv);
635
+ chatMessages.scrollTop = chatMessages.scrollHeight;
636
+ }
637
+
638
+ // Event listeners
639
+ sendBtn.addEventListener('click', sendMessage);
640
+ userInput.addEventListener('keypress', handleKeyPress);
641
+
642
+ // Suggestion buttons functionality
643
+ document.querySelectorAll('.suggestion-btn').forEach(button => {
644
+ button.addEventListener('click', function() {
645
+ userInput.value = this.getAttribute('data-message');
646
+ sendMessage();
647
+ });
648
+ });
649
+ });
650
+ </script>
651
  </body>
652
  </html>