Spaces:
Running
Running
fix all feeds into app using free APis - Follow Up Deployment
Browse files- index.html +279 -51
index.html
CHANGED
|
@@ -183,45 +183,10 @@
|
|
| 183 |
<span>Trending Topics</span>
|
| 184 |
</h2>
|
| 185 |
|
| 186 |
-
<div class="space-y-4">
|
| 187 |
-
<
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
</div>
|
| 191 |
-
<div>
|
| 192 |
-
<h3 class="font-medium group-hover:text-cyan-400 transition-all">Quantum Computing</h3>
|
| 193 |
-
<p class="text-xs text-gray-400">+1,245 articles today</p>
|
| 194 |
-
</div>
|
| 195 |
-
</div>
|
| 196 |
-
|
| 197 |
-
<div class="flex items-start group cursor-pointer">
|
| 198 |
-
<div class="bg-purple-900 bg-opacity-50 rounded-lg p-2 mr-3 group-hover:bg-opacity-70 transition-all">
|
| 199 |
-
<i class="fas fa-robot text-purple-300"></i>
|
| 200 |
-
</div>
|
| 201 |
-
<div>
|
| 202 |
-
<h3 class="font-medium group-hover:text-cyan-400 transition-all">AI Regulation</h3>
|
| 203 |
-
<p class="text-xs text-gray-400">+892 articles today</p>
|
| 204 |
-
</div>
|
| 205 |
-
</div>
|
| 206 |
-
|
| 207 |
-
<div class="flex items-start group cursor-pointer">
|
| 208 |
-
<div class="bg-green-900 bg-opacity-50 rounded-lg p-2 mr-3 group-hover:bg-opacity-70 transition-all">
|
| 209 |
-
<i class="fas fa-leaf text-green-300"></i>
|
| 210 |
-
</div>
|
| 211 |
-
<div>
|
| 212 |
-
<h3 class="font-medium group-hover:text-cyan-400 transition-all">Climate Tech</h3>
|
| 213 |
-
<p class="text-xs text-gray-400">+1,532 articles today</p>
|
| 214 |
-
</div>
|
| 215 |
-
</div>
|
| 216 |
-
|
| 217 |
-
<div class="flex items-start group cursor-pointer">
|
| 218 |
-
<div class="bg-yellow-900 bg-opacity-50 rounded-lg p-2 mr-3 group-hover:bg-opacity-70 transition-all">
|
| 219 |
-
<i class="fas fa-dna text-yellow-300"></i>
|
| 220 |
-
</div>
|
| 221 |
-
<div>
|
| 222 |
-
<h3 class="font-medium group-hover:text-cyan-400 transition-all">CRISPR Breakthrough</h3>
|
| 223 |
-
<p class="text-xs text-gray-400">+756 articles today</p>
|
| 224 |
-
</div>
|
| 225 |
</div>
|
| 226 |
</div>
|
| 227 |
|
|
@@ -239,23 +204,37 @@
|
|
| 239 |
|
| 240 |
<!-- AI Assistant -->
|
| 241 |
<div class="mt-6 bg-gray-800 bg-opacity-50 rounded-xl p-6 backdrop-blur-sm border border-gray-700 holographic">
|
| 242 |
-
<div class="flex items-center mb-4">
|
| 243 |
-
<div class="
|
| 244 |
-
<div class="
|
| 245 |
-
<
|
|
|
|
|
|
|
|
|
|
| 246 |
</div>
|
| 247 |
-
<
|
| 248 |
</div>
|
| 249 |
-
<
|
|
|
|
|
|
|
| 250 |
</div>
|
| 251 |
|
| 252 |
-
<div class="bg-gray-900 rounded-lg p-3 mb-3 text-sm">
|
| 253 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 254 |
</div>
|
| 255 |
|
| 256 |
<div class="flex">
|
| 257 |
-
<input type="text" placeholder="Ask me anything..."
|
| 258 |
-
|
|
|
|
|
|
|
| 259 |
<i class="fas fa-paper-plane"></i>
|
| 260 |
</button>
|
| 261 |
</div>
|
|
@@ -469,6 +448,118 @@
|
|
| 469 |
</div>
|
| 470 |
|
| 471 |
<script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 472 |
// Toggle Settings Panel
|
| 473 |
document.getElementById('settingsBtn').addEventListener('click', function() {
|
| 474 |
const panel = document.getElementById('settingsPanel');
|
|
@@ -514,8 +605,109 @@
|
|
| 514 |
});
|
| 515 |
});
|
| 516 |
|
| 517 |
-
//
|
| 518 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 519 |
const loader = document.createElement('div');
|
| 520 |
loader.className = 'flex justify-center my-4';
|
| 521 |
loader.innerHTML = '<i class="fas fa-circle-notch fa-spin text-2xl text-cyan-400"></i>';
|
|
@@ -531,6 +723,42 @@
|
|
| 531 |
}, 1500);
|
| 532 |
});
|
| 533 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 534 |
// Dynamic theme switcher (simplified)
|
| 535 |
document.querySelector('button:contains("Dark/Light Mode")').addEventListener('click', function() {
|
| 536 |
document.body.classList.toggle('gradient-bg');
|
|
|
|
| 183 |
<span>Trending Topics</span>
|
| 184 |
</h2>
|
| 185 |
|
| 186 |
+
<div class="space-y-4" id="trendingTopics">
|
| 187 |
+
<!-- Will be populated by JavaScript -->
|
| 188 |
+
<div class="flex justify-center py-4">
|
| 189 |
+
<i class="fas fa-circle-notch fa-spin text-cyan-400"></i>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 190 |
</div>
|
| 191 |
</div>
|
| 192 |
|
|
|
|
| 204 |
|
| 205 |
<!-- AI Assistant -->
|
| 206 |
<div class="mt-6 bg-gray-800 bg-opacity-50 rounded-xl p-6 backdrop-blur-sm border border-gray-700 holographic">
|
| 207 |
+
<div class="flex items-center justify-between mb-4">
|
| 208 |
+
<div class="flex items-center">
|
| 209 |
+
<div class="relative">
|
| 210 |
+
<div class="w-10 h-10 rounded-full bg-gradient-to-br from-purple-500 to-pink-600 flex items-center justify-center">
|
| 211 |
+
<i class="fas fa-robot text-white"></i>
|
| 212 |
+
</div>
|
| 213 |
+
<div class="absolute -bottom-1 -right-1 w-4 h-4 bg-green-400 rounded-full border-2 border-gray-800"></div>
|
| 214 |
</div>
|
| 215 |
+
<h3 class="ml-3 font-medium">Nexus AI Assistant</h3>
|
| 216 |
</div>
|
| 217 |
+
<button id="clearChat" class="text-xs text-gray-400 hover:text-cyan-400">
|
| 218 |
+
<i class="fas fa-trash-alt mr-1"></i> Clear
|
| 219 |
+
</button>
|
| 220 |
</div>
|
| 221 |
|
| 222 |
+
<div id="chatContainer" class="bg-gray-900 rounded-lg p-3 mb-3 text-sm h-64 overflow-y-auto space-y-3">
|
| 223 |
+
<div class="flex items-start">
|
| 224 |
+
<div class="w-8 h-8 rounded-full bg-purple-500 flex-shrink-0 flex items-center justify-center mr-2">
|
| 225 |
+
<i class="fas fa-robot text-white text-xs"></i>
|
| 226 |
+
</div>
|
| 227 |
+
<div class="bg-gray-800 rounded-lg p-2 px-3">
|
| 228 |
+
<p>Hi there! I'm your Nexus AI Assistant. I can summarize articles, find related content, or answer questions about what you're reading. How can I help you today?</p>
|
| 229 |
+
</div>
|
| 230 |
+
</div>
|
| 231 |
</div>
|
| 232 |
|
| 233 |
<div class="flex">
|
| 234 |
+
<input id="aiInput" type="text" placeholder="Ask me anything..."
|
| 235 |
+
class="flex-1 bg-gray-700 border border-gray-600 rounded-l-lg px-3 py-2 text-sm focus:outline-none focus:border-cyan-500"
|
| 236 |
+
onkeypress="if(event.keyCode === 13) sendAIQuery()">
|
| 237 |
+
<button id="sendAIQuery" class="bg-cyan-600 hover:bg-cyan-700 px-4 rounded-r-lg transition-all">
|
| 238 |
<i class="fas fa-paper-plane"></i>
|
| 239 |
</button>
|
| 240 |
</div>
|
|
|
|
| 448 |
</div>
|
| 449 |
|
| 450 |
<script>
|
| 451 |
+
// API Configuration
|
| 452 |
+
const NEWS_API_KEY = 'YOUR_NEWSAPI_KEY'; // Get free key from newsapi.org
|
| 453 |
+
const GNEWS_API_KEY = 'YOUR_GNEWS_KEY'; // Get free key from gnews.io
|
| 454 |
+
|
| 455 |
+
// Fetch from NewsAPI
|
| 456 |
+
async function fetchNewsAPI() {
|
| 457 |
+
try {
|
| 458 |
+
const response = await fetch(`https://newsapi.org/v2/top-headlines?country=us&apiKey=${NEWS_API_KEY}`);
|
| 459 |
+
const data = await response.json();
|
| 460 |
+
return data.articles;
|
| 461 |
+
} catch (error) {
|
| 462 |
+
console.error('Error fetching from NewsAPI:', error);
|
| 463 |
+
return [];
|
| 464 |
+
}
|
| 465 |
+
}
|
| 466 |
+
|
| 467 |
+
// Fetch from GNews
|
| 468 |
+
async function fetchGNews() {
|
| 469 |
+
try {
|
| 470 |
+
const response = await fetch(`https://gnews.io/api/v4/top-headlines?token=${GNEWS_API_KEY}&lang=en`);
|
| 471 |
+
const data = await response.json();
|
| 472 |
+
return data.articles;
|
| 473 |
+
} catch (error) {
|
| 474 |
+
console.error('Error fetching from GNews:', error);
|
| 475 |
+
return [];
|
| 476 |
+
}
|
| 477 |
+
}
|
| 478 |
+
|
| 479 |
+
// AI Assistant functionality
|
| 480 |
+
function sendAIQuery() {
|
| 481 |
+
const input = document.getElementById('aiInput');
|
| 482 |
+
const query = input.value.trim();
|
| 483 |
+
if (!query) return;
|
| 484 |
+
|
| 485 |
+
const chatContainer = document.getElementById('chatContainer');
|
| 486 |
+
|
| 487 |
+
// Add user message
|
| 488 |
+
chatContainer.innerHTML += `
|
| 489 |
+
<div class="flex items-start justify-end">
|
| 490 |
+
<div class="bg-cyan-600 rounded-lg p-2 px-3 max-w-xs">
|
| 491 |
+
<p>${query}</p>
|
| 492 |
+
</div>
|
| 493 |
+
</div>
|
| 494 |
+
`;
|
| 495 |
+
|
| 496 |
+
input.value = '';
|
| 497 |
+
|
| 498 |
+
// Show typing indicator
|
| 499 |
+
chatContainer.innerHTML += `
|
| 500 |
+
<div class="flex items-start">
|
| 501 |
+
<div class="w-8 h-8 rounded-full bg-purple-500 flex-shrink-0 flex items-center justify-center mr-2">
|
| 502 |
+
<i class="fas fa-robot text-white text-xs"></i>
|
| 503 |
+
</div>
|
| 504 |
+
<div class="bg-gray-800 rounded-lg p-2 px-3 w-16">
|
| 505 |
+
<div class="flex space-x-1">
|
| 506 |
+
<div class="w-2 h-2 bg-gray-400 rounded-full animate-bounce"></div>
|
| 507 |
+
<div class="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style="animation-delay: 0.2s"></div>
|
| 508 |
+
<div class="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style="animation-delay: 0.4s"></div>
|
| 509 |
+
</div>
|
| 510 |
+
</div>
|
| 511 |
+
</div>
|
| 512 |
+
`;
|
| 513 |
+
|
| 514 |
+
chatContainer.scrollTop = chatContainer.scrollHeight;
|
| 515 |
+
|
| 516 |
+
// Simulate AI response after delay
|
| 517 |
+
setTimeout(() => {
|
| 518 |
+
// Remove typing indicator
|
| 519 |
+
chatContainer.removeChild(chatContainer.lastChild);
|
| 520 |
+
|
| 521 |
+
// Add AI response (in a real app, this would come from an API)
|
| 522 |
+
const responses = [
|
| 523 |
+
`I found some information about "${query}". According to recent articles, this technology is advancing rapidly with several new breakthroughs expected this year.`,
|
| 524 |
+
`Interesting question about ${query}! Based on your reading history, you might want to check the latest research papers on this topic.`,
|
| 525 |
+
`Here's a summary of ${query}: The current state shows promising developments, though challenges remain in scalability and real-world implementation.`,
|
| 526 |
+
`Regarding ${query}, I can recommend these related articles: "New Advances in the Field" and "Future Applications". Would you like me to fetch them?`
|
| 527 |
+
];
|
| 528 |
+
|
| 529 |
+
const randomResponse = responses[Math.floor(Math.random() * responses.length)];
|
| 530 |
+
|
| 531 |
+
chatContainer.innerHTML += `
|
| 532 |
+
<div class="flex items-start">
|
| 533 |
+
<div class="w-8 h-8 rounded-full bg-purple-500 flex-shrink-0 flex items-center justify-center mr-2">
|
| 534 |
+
<i class="fas fa-robot text-white text-xs"></i>
|
| 535 |
+
</div>
|
| 536 |
+
<div class="bg-gray-800 rounded-lg p-2 px-3">
|
| 537 |
+
<p>${randomResponse}</p>
|
| 538 |
+
</div>
|
| 539 |
+
</div>
|
| 540 |
+
`;
|
| 541 |
+
|
| 542 |
+
chatContainer.scrollTop = chatContainer.scrollHeight;
|
| 543 |
+
}, 1500);
|
| 544 |
+
}
|
| 545 |
+
|
| 546 |
+
// Clear chat history
|
| 547 |
+
document.getElementById('clearChat').addEventListener('click', function() {
|
| 548 |
+
document.getElementById('chatContainer').innerHTML = `
|
| 549 |
+
<div class="flex items-start">
|
| 550 |
+
<div class="w-8 h-8 rounded-full bg-purple-500 flex-shrink-0 flex items-center justify-center mr-2">
|
| 551 |
+
<i class="fas fa-robot text-white text-xs"></i>
|
| 552 |
+
</div>
|
| 553 |
+
<div class="bg-gray-800 rounded-lg p-2 px-3">
|
| 554 |
+
<p>Hi there! I'm your Nexus AI Assistant. I can summarize articles, find related content, or answer questions about what you're reading. How can I help you today?</p>
|
| 555 |
+
</div>
|
| 556 |
+
</div>
|
| 557 |
+
`;
|
| 558 |
+
});
|
| 559 |
+
|
| 560 |
+
// Send query on button click
|
| 561 |
+
document.getElementById('sendAIQuery').addEventListener('click', sendAIQuery);
|
| 562 |
+
|
| 563 |
// Toggle Settings Panel
|
| 564 |
document.getElementById('settingsBtn').addEventListener('click', function() {
|
| 565 |
const panel = document.getElementById('settingsPanel');
|
|
|
|
| 605 |
});
|
| 606 |
});
|
| 607 |
|
| 608 |
+
// Render articles from API data
|
| 609 |
+
async function renderArticles() {
|
| 610 |
+
const mainFeed = document.querySelector('.lg\\:col-span-2');
|
| 611 |
+
const articleContainer = mainFeed.querySelector('.space-y-6');
|
| 612 |
+
|
| 613 |
+
// Clear existing articles (except first 3 demo ones)
|
| 614 |
+
const articles = articleContainer.querySelectorAll('.article-card');
|
| 615 |
+
for (let i = 3; i < articles.length; i++) {
|
| 616 |
+
articles[i].remove();
|
| 617 |
+
}
|
| 618 |
+
|
| 619 |
+
// Show loading
|
| 620 |
+
const loader = document.createElement('div');
|
| 621 |
+
loader.className = 'flex justify-center my-4';
|
| 622 |
+
loader.innerHTML = '<i class="fas fa-circle-notch fa-spin text-2xl text-cyan-400"></i>';
|
| 623 |
+
articleContainer.appendChild(loader);
|
| 624 |
+
|
| 625 |
+
try {
|
| 626 |
+
// Fetch from both APIs
|
| 627 |
+
const [newsAPIArticles, gNewsArticles] = await Promise.all([
|
| 628 |
+
fetchNewsAPI(),
|
| 629 |
+
fetchGNews()
|
| 630 |
+
]);
|
| 631 |
+
|
| 632 |
+
// Combine and shuffle articles
|
| 633 |
+
const allArticles = [...newsAPIArticles, ...gNewsArticles]
|
| 634 |
+
.sort(() => 0.5 - Math.random())
|
| 635 |
+
.slice(0, 10); // Show 10 random articles
|
| 636 |
+
|
| 637 |
+
// Remove loader
|
| 638 |
+
loader.remove();
|
| 639 |
+
|
| 640 |
+
// Render each article
|
| 641 |
+
allArticles.forEach(article => {
|
| 642 |
+
if (!article.title || !article.description) return;
|
| 643 |
+
|
| 644 |
+
const categories = article.source?.name ? [article.source.name] : ['General'];
|
| 645 |
+
if (article.urlToImage) categories.push('Multimedia');
|
| 646 |
+
|
| 647 |
+
const articleEl = document.createElement('article');
|
| 648 |
+
articleEl.className = 'article-card bg-gray-800 bg-opacity-50 rounded-xl overflow-hidden border border-gray-700 backdrop-blur-sm hover:border-cyan-500 transition-all';
|
| 649 |
+
articleEl.innerHTML = `
|
| 650 |
+
<div class="p-6">
|
| 651 |
+
<div class="flex items-center justify-between mb-3">
|
| 652 |
+
<div class="flex items-center">
|
| 653 |
+
<div class="w-8 h-8 rounded-full bg-blue-900 flex items-center justify-center mr-2">
|
| 654 |
+
<i class="fas fa-newspaper text-blue-300 text-xs"></i>
|
| 655 |
+
</div>
|
| 656 |
+
<span class="text-sm">${article.source?.name || 'News Source'} • ${new Date(article.publishedAt).toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}</span>
|
| 657 |
+
</div>
|
| 658 |
+
<button class="text-gray-400 hover:text-cyan-400">
|
| 659 |
+
<i class="fas fa-bookmark"></i>
|
| 660 |
+
</button>
|
| 661 |
+
</div>
|
| 662 |
+
|
| 663 |
+
<h2 class="text-xl font-semibold mb-2 hover:text-cyan-400 cursor-pointer">
|
| 664 |
+
${article.title}
|
| 665 |
+
</h2>
|
| 666 |
+
|
| 667 |
+
<p class="text-gray-300 mb-4">
|
| 668 |
+
${article.description || 'No description available...'}
|
| 669 |
+
</p>
|
| 670 |
+
|
| 671 |
+
<div class="flex flex-wrap gap-2 mb-4">
|
| 672 |
+
${categories.map(cat =>
|
| 673 |
+
`<span class="px-2 py-1 bg-blue-900 bg-opacity-50 rounded-full text-xs">${cat}</span>`
|
| 674 |
+
).join('')}
|
| 675 |
+
</div>
|
| 676 |
+
|
| 677 |
+
<div class="flex items-center justify-between">
|
| 678 |
+
<div class="flex items-center space-x-4">
|
| 679 |
+
<button class="flex items-center text-sm text-gray-400 hover:text-cyan-400">
|
| 680 |
+
<i class="fas fa-eye mr-1"></i> ${Math.floor(Math.random() * 9000) + 1000}
|
| 681 |
+
</button>
|
| 682 |
+
<button class="flex items-center text-sm text-gray-400 hover:text-cyan-400">
|
| 683 |
+
<i class="fas fa-comment mr-1"></i> ${Math.floor(Math.random() * 500)}
|
| 684 |
+
</button>
|
| 685 |
+
<button class="flex items-center text-sm text-gray-400 hover:text-cyan-400">
|
| 686 |
+
<i class="fas fa-share-alt mr-1"></i>
|
| 687 |
+
</button>
|
| 688 |
+
</div>
|
| 689 |
+
|
| 690 |
+
<a href="${article.url}" target="_blank" class="text-sm bg-cyan-600 hover:bg-cyan-700 px-4 py-1 rounded-lg transition-all flex items-center">
|
| 691 |
+
<span>Read</span>
|
| 692 |
+
<i class="fas fa-arrow-right ml-1 text-xs"></i>
|
| 693 |
+
</a>
|
| 694 |
+
</div>
|
| 695 |
+
</div>
|
| 696 |
+
`;
|
| 697 |
+
|
| 698 |
+
articleContainer.appendChild(articleEl);
|
| 699 |
+
});
|
| 700 |
+
|
| 701 |
+
} catch (error) {
|
| 702 |
+
loader.innerHTML = '<p class="text-red-400">Failed to load articles. Please try again later.</p>';
|
| 703 |
+
}
|
| 704 |
+
}
|
| 705 |
+
|
| 706 |
+
// Load articles on page load
|
| 707 |
+
document.addEventListener('DOMContentLoaded', renderArticles);
|
| 708 |
+
|
| 709 |
+
// Load more articles
|
| 710 |
+
document.querySelector('button:contains("Load More Articles")').addEventListener('click', renderArticles);
|
| 711 |
const loader = document.createElement('div');
|
| 712 |
loader.className = 'flex justify-center my-4';
|
| 713 |
loader.innerHTML = '<i class="fas fa-circle-notch fa-spin text-2xl text-cyan-400"></i>';
|
|
|
|
| 723 |
}, 1500);
|
| 724 |
});
|
| 725 |
|
| 726 |
+
// Fetch trending topics
|
| 727 |
+
async function fetchTrendingTopics() {
|
| 728 |
+
const container = document.getElementById('trendingTopics');
|
| 729 |
+
|
| 730 |
+
try {
|
| 731 |
+
const response = await fetch('https://newsapi.org/v2/top-headlines/sources?apiKey=' + NEWS_API_KEY);
|
| 732 |
+
const data = await response.json();
|
| 733 |
+
|
| 734 |
+
container.innerHTML = '';
|
| 735 |
+
|
| 736 |
+
// Show first 4 categories
|
| 737 |
+
data.sources.slice(0, 4).forEach(source => {
|
| 738 |
+
const topicEl = document.createElement('div');
|
| 739 |
+
topicEl.className = 'flex items-start group cursor-pointer';
|
| 740 |
+
topicEl.innerHTML = `
|
| 741 |
+
<div class="bg-blue-900 bg-opacity-50 rounded-lg p-2 mr-3 group-hover:bg-opacity-70 transition-all">
|
| 742 |
+
<i class="fas fa-newspaper text-blue-300"></i>
|
| 743 |
+
</div>
|
| 744 |
+
<div>
|
| 745 |
+
<h3 class="font-medium group-hover:text-cyan-400 transition-all">${source.category}</h3>
|
| 746 |
+
<p class="text-xs text-gray-400">${source.country} coverage</p>
|
| 747 |
+
</div>
|
| 748 |
+
`;
|
| 749 |
+
container.appendChild(topicEl);
|
| 750 |
+
});
|
| 751 |
+
} catch (error) {
|
| 752 |
+
container.innerHTML = '<p class="text-red-400 text-sm">Failed to load trending topics</p>';
|
| 753 |
+
}
|
| 754 |
+
}
|
| 755 |
+
|
| 756 |
+
// Initialize on load
|
| 757 |
+
document.addEventListener('DOMContentLoaded', () => {
|
| 758 |
+
renderArticles();
|
| 759 |
+
fetchTrendingTopics();
|
| 760 |
+
});
|
| 761 |
+
|
| 762 |
// Dynamic theme switcher (simplified)
|
| 763 |
document.querySelector('button:contains("Dark/Light Mode")').addEventListener('click', function() {
|
| 764 |
document.body.classList.toggle('gradient-bg');
|