DevBM commited on
Commit
2a57a98
·
verified ·
1 Parent(s): a555746

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +227 -30
index.html CHANGED
@@ -418,6 +418,52 @@
418
 
419
  <script>
420
  const API_BASE = 'https://tmkoc-quotes-api.onrender.com/v1';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
421
 
422
  function showLoading(containerId) {
423
  const container = document.getElementById(containerId);
@@ -430,31 +476,68 @@
430
  `;
431
  }
432
 
433
- function showError(containerId, message) {
434
  const container = document.getElementById(containerId);
435
  container.style.display = 'block';
436
  container.innerHTML = `
437
  <div class="error">
438
  <i class="fas fa-exclamation-triangle"></i>
439
  Error: ${message}
 
 
 
 
 
 
 
440
  </div>
441
  `;
442
  }
443
 
444
- function displaySingleQuote(quote) {
445
- document.getElementById('randomQuoteText').textContent = quote.quote;
446
- document.getElementById('randomQuoteAuthor').textContent = `— ${quote.author}`;
 
 
 
 
 
 
 
 
 
 
 
 
 
447
 
448
- const tagsContainer = document.getElementById('randomQuoteTags');
449
- if (quote.tags && quote.tags.length > 0) {
450
- tagsContainer.innerHTML = quote.tags.map(tag =>
451
- `<span class="tag">#${tag}</span>`
452
- ).join('');
453
- } else {
454
- tagsContainer.innerHTML = '';
455
  }
 
 
 
 
 
 
 
 
 
 
456
 
457
- document.getElementById('randomQuoteDisplay').style.display = 'flex';
 
 
 
 
 
 
 
 
 
 
458
  }
459
 
460
  function displayMultipleQuotes(quotes, containerId) {
@@ -477,24 +560,93 @@
477
  `).join('');
478
  }
479
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
480
  async function makeAPICall(endpoint) {
481
- const response = await fetch(`${API_BASE}${endpoint}`);
482
- if (!response.ok) {
483
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
  }
485
- return await response.json();
486
  }
487
-
488
  async function getRandomQuote() {
489
  try {
490
  document.getElementById('multipleQuotesDisplay').style.display = 'none';
491
  showLoading('randomQuoteDisplay');
492
 
493
- const quotes = await makeAPICall('/quotes');
494
- document.getElementById('randomQuoteDisplay').style.display = 'none';
495
- displaySingleQuote(quotes[0]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
496
  } catch (error) {
497
- showError('randomQuoteDisplay', error.message);
 
 
498
  }
499
  }
500
 
@@ -503,20 +655,49 @@
503
  document.getElementById('randomQuoteDisplay').style.display = 'none';
504
  showLoading('multipleQuotesDisplay');
505
 
506
- const quotes = await makeAPICall('/quotes/3');
 
 
 
 
 
 
 
 
 
 
 
 
507
  displayMultipleQuotes(quotes, 'multipleQuotesDisplay');
508
  } catch (error) {
509
- showError('multipleQuotesDisplay', error.message);
510
  }
511
  }
512
 
513
  async function getQuotesByCharacter(character) {
514
  try {
515
  showLoading('characterQuotesDisplay');
516
- const quotes = await makeAPICall(`/quotes/character/${encodeURIComponent(character)}`);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
517
  displayMultipleQuotes(quotes, 'characterQuotesDisplay');
518
  } catch (error) {
519
- showError('characterQuotesDisplay', error.message);
520
  }
521
  }
522
 
@@ -541,14 +722,30 @@
541
  try {
542
  showLoading('searchResults');
543
 
544
- const params = new URLSearchParams();
545
- if (author) params.append('author', author);
546
- if (text) params.append('text', text);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
547
 
548
- const quotes = await makeAPICall(`/quotes/search?${params.toString()}`);
549
  displayMultipleQuotes(quotes, 'searchResults');
550
  } catch (error) {
551
- showError('searchResults', error.message);
552
  }
553
  }
554
 
 
418
 
419
  <script>
420
  const API_BASE = 'https://tmkoc-quotes-api.onrender.com/v1';
421
+
422
+ // Sample quotes as fallback
423
+ const sampleQuotes = [
424
+ {
425
+ "quote": "Tapu ke papa, sambhal ke!",
426
+ "author": "Daya Gada",
427
+ "tags": ["classic", "funny"]
428
+ },
429
+ {
430
+ "quote": "Jethalal, ye kya tamasha bana rakha hai!",
431
+ "author": "Champaklal Gada",
432
+ "tags": ["classic"]
433
+ },
434
+ {
435
+ "quote": "Hey Maa, Mataji!",
436
+ "author": "Daya",
437
+ "tags": ["surprised", "classic"]
438
+ },
439
+ {
440
+ "quote": "Fire! Fire! Fire!",
441
+ "author": "Jethalal",
442
+ "tags": ["funny", "panic"]
443
+ },
444
+ {
445
+ "quote": "Pappu pass ho gaya!",
446
+ "author": "Tapu Sena",
447
+ "tags": ["celebration", "school"]
448
+ },
449
+ {
450
+ "quote": "Bas kar pagle, rulayega kya?",
451
+ "author": "Jethalal",
452
+ "tags": ["emotional", "funny"]
453
+ },
454
+ {
455
+ "quote": "Arre yaar, kya baat hai!",
456
+ "author": "Popatlal",
457
+ "tags": ["excitement"]
458
+ },
459
+ {
460
+ "quote": "Shanti, shanti, shanti!",
461
+ "author": "Taarak Mehta",
462
+ "tags": ["peace", "wisdom"]
463
+ }
464
+ ];
465
+
466
+ let useAPIFallback = false;
467
 
468
  function showLoading(containerId) {
469
  const container = document.getElementById(containerId);
 
476
  `;
477
  }
478
 
479
+ function showError(containerId, message, showFallbackOption = false) {
480
  const container = document.getElementById(containerId);
481
  container.style.display = 'block';
482
  container.innerHTML = `
483
  <div class="error">
484
  <i class="fas fa-exclamation-triangle"></i>
485
  Error: ${message}
486
+ ${showFallbackOption ? `
487
+ <br><br>
488
+ <button class="btn btn-secondary" onclick="enableFallbackMode()" style="margin-top: 10px;">
489
+ <i class="fas fa-shield-alt"></i> Use Demo Mode
490
+ </button>
491
+ <p style="margin-top: 8px; font-size: 0.9rem;">Demo mode uses sample quotes when API is unavailable</p>
492
+ ` : ''}
493
  </div>
494
  `;
495
  }
496
 
497
+ function enableFallbackMode() {
498
+ useAPIFallback = true;
499
+ showApiStatus();
500
+ getRandomQuote();
501
+ }
502
+
503
+ function showApiStatus() {
504
+ const statusDiv = document.createElement('div');
505
+ statusDiv.id = 'api-status';
506
+ statusDiv.innerHTML = `
507
+ <div style="background: #fff3cd; color: #856404; padding: 10px; border-radius: 8px; margin-bottom: 20px; border: 1px solid #ffeaa7;">
508
+ <i class="fas fa-info-circle"></i>
509
+ <strong>Demo Mode:</strong> Using sample quotes since the API is unavailable.
510
+ <button onclick="testAPI()" style="background: none; border: none; color: #667eea; text-decoration: underline; cursor: pointer;">Try API again</button>
511
+ </div>
512
+ `;
513
 
514
+ const container = document.querySelector('.container');
515
+ const firstSection = container.querySelector('.demo-section');
516
+ if (!document.getElementById('api-status')) {
517
+ container.insertBefore(statusDiv, firstSection);
 
 
 
518
  }
519
+ }
520
+
521
+ async function testAPI() {
522
+ useAPIFallback = false;
523
+ const statusEl = document.getElementById('api-status');
524
+ if (statusEl) statusEl.remove();
525
+ await getRandomQuote();
526
+ }
527
+ function displaySingleQuote(quote) {
528
+ const container = document.getElementById('randomQuoteDisplay');
529
 
530
+ // Build the entire quote display using innerHTML
531
+ const tagsHTML = quote.tags && quote.tags.length > 0
532
+ ? `<div class="quote-tags">${quote.tags.map(tag => `<span class="tag">#${tag}</span>`).join('')}</div>`
533
+ : '';
534
+
535
+ container.innerHTML = `
536
+ <div class="quote-text">${quote.quote}</div>
537
+ <div class="quote-author">— ${quote.author}</div>
538
+ ${tagsHTML}
539
+ `;
540
+ container.style.display = 'flex';
541
  }
542
 
543
  function displayMultipleQuotes(quotes, containerId) {
 
560
  `).join('');
561
  }
562
 
563
+ function getRandomSampleQuotes(count = 1) {
564
+ const shuffled = [...sampleQuotes].sort(() => 0.5 - Math.random());
565
+ return shuffled.slice(0, count);
566
+ }
567
+
568
+ function filterSampleQuotesByCharacter(character) {
569
+ return sampleQuotes.filter(quote =>
570
+ quote.author.toLowerCase().includes(character.toLowerCase())
571
+ );
572
+ }
573
+
574
+ function searchSampleQuotes(author, text) {
575
+ return sampleQuotes.filter(quote => {
576
+ const matchesAuthor = !author || quote.author.toLowerCase().includes(author.toLowerCase());
577
+ const matchesText = !text || quote.quote.toLowerCase().includes(text.toLowerCase());
578
+ return matchesAuthor && matchesText;
579
+ });
580
+ }
581
+
582
  async function makeAPICall(endpoint) {
583
+ const controller = new AbortController();
584
+ const timeoutId = setTimeout(() => controller.abort(), 15000); // 15 second timeout
585
+
586
+ try {
587
+ console.log(`Making API call to: ${API_BASE}${endpoint}`);
588
+
589
+ const response = await fetch(`${API_BASE}${endpoint}`, {
590
+ signal: controller.signal,
591
+ method: 'GET',
592
+ mode: 'cors',
593
+ headers: {
594
+ 'Accept': 'application/json',
595
+ 'Content-Type': 'application/json',
596
+ }
597
+ });
598
+
599
+ clearTimeout(timeoutId);
600
+
601
+ console.log(`API Response status: ${response.status}`);
602
+
603
+ if (!response.ok) {
604
+ const errorText = await response.text();
605
+ throw new Error(`HTTP ${response.status}: ${response.statusText}${errorText ? ` - ${errorText}` : ''}`);
606
+ }
607
+
608
+ const data = await response.json();
609
+ console.log('API Response data:', data);
610
+ return data;
611
+ } catch (error) {
612
+ clearTimeout(timeoutId);
613
+ console.error('API Call failed:', error);
614
+
615
+ if (error.name === 'AbortError') {
616
+ throw new Error('Request timed out - API server may be sleeping on free hosting');
617
+ }
618
+ if (error.message.includes('Failed to fetch') || error.message.includes('NetworkError')) {
619
+ throw new Error('Network error - API server may be down or have CORS issues');
620
+ }
621
+ throw error;
622
  }
 
623
  }
 
624
  async function getRandomQuote() {
625
  try {
626
  document.getElementById('multipleQuotesDisplay').style.display = 'none';
627
  showLoading('randomQuoteDisplay');
628
 
629
+ let quote;
630
+ if (useAPIFallback) {
631
+ quote = getRandomSampleQuotes(1)[0];
632
+ } else {
633
+ try {
634
+ quote = await makeAPICall('/quotes');
635
+ } catch (error) {
636
+ console.error('API Error:', error);
637
+ // Remove next line (redundant)
638
+ showError('randomQuoteDisplay', `${error.message}. The API might be sleeping on free hosting.`, true);
639
+ return;
640
+ }
641
+ }
642
+
643
+ // REMOVE THIS LINE: It's unnecessary and causes flickering
644
+ // document.getElementById('randomQuoteDisplay').style.display = 'none';
645
+ displaySingleQuote(quote);
646
  } catch (error) {
647
+ // REMOVE THIS LINE: showError already handles display
648
+ // document.getElementById('randomQuoteDisplay').style.display = 'none';
649
+ showError('randomQuoteDisplay', error.message, !useAPIFallback);
650
  }
651
  }
652
 
 
655
  document.getElementById('randomQuoteDisplay').style.display = 'none';
656
  showLoading('multipleQuotesDisplay');
657
 
658
+ let quotes;
659
+ if (useAPIFallback) {
660
+ quotes = getRandomSampleQuotes(3);
661
+ } else {
662
+ try {
663
+ quotes = await makeAPICall('/quotes/3');
664
+ } catch (error) {
665
+ console.error('API Error:', error);
666
+ showError('multipleQuotesDisplay', `${error.message}. The API might be sleeping on free hosting.`, true);
667
+ return;
668
+ }
669
+ }
670
+
671
  displayMultipleQuotes(quotes, 'multipleQuotesDisplay');
672
  } catch (error) {
673
+ showError('multipleQuotesDisplay', error.message, !useAPIFallback);
674
  }
675
  }
676
 
677
  async function getQuotesByCharacter(character) {
678
  try {
679
  showLoading('characterQuotesDisplay');
680
+
681
+ let quotes;
682
+ if (useAPIFallback) {
683
+ quotes = filterSampleQuotesByCharacter(character);
684
+ if (quotes.length === 0) {
685
+ showError('characterQuotesDisplay', `No quotes found for character "${character}" in demo data`);
686
+ return;
687
+ }
688
+ } else {
689
+ try {
690
+ quotes = await makeAPICall(`/quotes/character/${encodeURIComponent(character)}`);
691
+ } catch (error) {
692
+ console.error('API Error:', error);
693
+ showError('characterQuotesDisplay', `${error.message}. The API might be sleeping on free hosting.`, true);
694
+ return;
695
+ }
696
+ }
697
+
698
  displayMultipleQuotes(quotes, 'characterQuotesDisplay');
699
  } catch (error) {
700
+ showError('characterQuotesDisplay', error.message, !useAPIFallback);
701
  }
702
  }
703
 
 
722
  try {
723
  showLoading('searchResults');
724
 
725
+ let quotes;
726
+ if (useAPIFallback) {
727
+ quotes = searchSampleQuotes(author, text);
728
+ if (quotes.length === 0) {
729
+ showError('searchResults', 'No quotes found matching your search in demo data');
730
+ return;
731
+ }
732
+ } else {
733
+ try {
734
+ const params = new URLSearchParams();
735
+ if (author) params.append('author', author);
736
+ if (text) params.append('text', text);
737
+
738
+ quotes = await makeAPICall(`/quotes/search?${params.toString()}`);
739
+ } catch (error) {
740
+ console.error('API Error:', error);
741
+ showError('searchResults', `${error.message}. The API might be sleeping on free hosting.`, true);
742
+ return;
743
+ }
744
+ }
745
 
 
746
  displayMultipleQuotes(quotes, 'searchResults');
747
  } catch (error) {
748
+ showError('searchResults', error.message, !useAPIFallback);
749
  }
750
  }
751