huggingfaceninja's picture
add tech news and tie in hackernews api
93eb5ba verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MapleLeaf HackerHub - Canadian Tech News</title>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<script src="https://unpkg.com/feather-icons"></script>
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/animejs/lib/anime.min.js"></script>
<script>
// HackerNews API integration
const HN_API_BASE = 'https://hacker-news.firebaseio.com/v0';
let topStories = [];
async function fetchTopStories() {
try {
const response = await fetch(`${HN_API_BASE}/topstories.json`);
const storyIds = await response.json();
topStories = storyIds.slice(0, 9); // Get top 9 stories
const stories = await Promise.all(
topStories.map(id => fetch(`${HN_API_BASE}/item/${id}.json`).then(r => r.json())
);
displayTechNews(stories);
} catch (error) {
console.error('Error fetching HackerNews stories:', error);
displayFallbackNews();
}
}
function displayTechNews(stories) {
const container = document.getElementById('tech-news-container');
container.innerHTML = '';
stories.forEach((story, index) => {
if (story && story.title) {
const newsCard = document.createElement('div');
newsCard.className = 'news-card glass-effect rounded-xl p-6';
newsCard.innerHTML = `
<div class="flex items-center space-x-3 mb-4">
<div class="w-10 h-10 bg-gradient-to-r from-${getRandomColor()}-500 to-${getRandomColor()}-500 rounded-full flex items-center justify-center">
<i data-feather="${getRandomIcon()}" class="w-5 h-5 text-white"></i>
</div>
<div>
<h4 class="font-semibold line-clamp-2">${story.title}</h4>
<p class="text-sm text-gray-400">${formatTime(story.time)}${story.score || 0} points</p>
</div>
</div>
<p class="text-gray-300 text-sm mb-4 line-clamp-3">
${story.text ? story.text.replace(/<[^>]*>/g, '').substring(0, 150) + '...' : 'Read the full story on HackerNews.'}
</p>
<a href="${story.url || `https://news.ycombinator.com/item?id=${story.id}`}"
target="_blank"
class="text-blue-400 hover:text-blue-300 text-sm font-semibold flex items-center space-x-1">
<span>Read Story</span>
<i data-feather="external-link" class="w-4 h-4"></i>
</a>
</div>
`;
container.appendChild(newsCard);
}
});
// Re-initialize feather icons for new content
setTimeout(() => feather.replace(), 100);
}
function displayFallbackNews() {
const container = document.getElementById('tech-news-container');
container.innerHTML = `
<div class="news-card glass-effect rounded-xl p-6">
<div class="flex items-center space-x-3 mb-4">
<div class="w-10 h-10 bg-gradient-to-r from-red-500 to-blue-500 rounded-full flex items-center justify-center">
<i data-feather="trending-up" class="w-5 h-5 text-white"></i>
</div>
<div>
<h4 class="font-semibold">Live HackerNews Feed</h4>
<p class="text-sm text-gray-400">Real-time tech stories</p>
</div>
</div>
<p class="text-gray-300 text-sm mb-4">
Loading the latest technology news from HackerNews API...
</p>
<div class="animate-pulse text-blue-400 text-sm font-semibold">
Fetching stories...
</div>
`;
}
function getRandomColor() {
const colors = ['red', 'blue', 'green', 'purple', 'pink', 'indigo', 'teal'];
return colors[Math.floor(Math.random() * colors.length)];
}
function getRandomIcon() {
const icons = ['code', 'cpu', 'server', 'terminal', 'zap', 'shield', 'trending-up', 'users'];
return icons[Math.floor(Math.random() * icons.length)];
}
function formatTime(timestamp) {
const date = new Date(timestamp * 1000);
const now = new Date();
const diffMs = now - date;
const diffHrs = Math.floor(diffMs / 3600000);
if (diffHrs < 1) return 'Just now';
if (diffHrs === 1) return '1 hour ago';
if (diffHrs < 24) return `${diffHrs} hours ago`;
return `${Math.floor(diffHrs / 24)} days ago';
}
// Auto-refresh news every 5 minutes
function startAutoRefresh() {
setInterval(fetchTopStories, 300000);
}
</script>
<style>
.vanta-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
}
.glass-effect {
backdrop-filter: blur(10px);
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
}
.category-chip {
transition: all 0.3s ease;
}
.category-chip:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.2);
}
.news-card {
transition: all 0.3s ease;
}
.news-card:hover {
transform: translateY(-5px);
box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.3);
}
</style>
</head>
<body class="bg-gray-900 text-white min-h-screen">
<!-- Vanta.js Background -->
<div id="vanta-bg" class="vanta-bg"></div>
<!-- Navigation -->
<nav class="glass-effect sticky top-0 z-50">
<div class="container mx-auto px-4 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-4">
<img src="https://www.digitalassets.ca/uploads/chrome_2016-06-04_14-58-44.png"
alt="HackerNews Canada"
class="w-12 h-12 rounded-lg">
<div>
<h1 class="text-2xl font-bold">MapleLeaf HackerHub</h1>
<p class="text-sm text-gray-300">Canadian Tech Edition</p>
</div>
</div>
<div class="flex items-center space-x-4">
<span class="text-sm bg-red-500 text-white px-3 py-1 rounded-full animate-pulse">LIVE</span>
<div class="text-right">
<p class="text-sm">Updated: Friday 10th of October 2025</p>
</div>
</div>
</div>
</div>
</nav>
<!-- Main Content -->
<main class="container mx-auto px-4 py-8 relative z-10">
<!-- Hero Section -->
<section class="text-center mb-12">
<div class="glass-effect rounded-2xl p-8 max-w-4xl mx-auto">
<h2 class="text-4xl font-bold mb-4 bg-gradient-to-r from-red-500 to-blue-500 bg-clip-text text-transparent">
SEARCH HACKER NEWS - CANADIAN EDITION
</h2>
<p class="text-xl text-gray-300 mb-6">
Your gateway to Canadian tech innovation and cybersecurity
</p>
<div class="flex justify-center space-x-4">
<a href="https://hackernews.ca/threatmapgrid/"
class="bg-gradient-to-r from-red-500 to-blue-500 text-white px-6 py-3 rounded-full font-semibold hover:from-red-600 hover:to-blue-600 transition-all duration-300 flex items-center space-x-2">
<i data-feather="map"></i>
<span>Threat Map Grid</span>
</a>
<a href="https://hackernews.ca/"
class="border-2 border-white text-white px-6 py-3 rounded-full font-semibold hover:bg-white hover:text-gray-900 transition-all duration-300 flex items-center space-x-2">
<i data-feather="external-link"></i>
<span>Visit Original</span>
</a>
</div>
</div>
</section>
<!-- Categories Grid -->
<section class="mb-12">
<h3 class="text-2xl font-bold mb-6 text-center">Explore Tech Categories</h3>
<div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-4">
<!-- Programming & Development -->
<a href="https://hackernews.ca/index.php?feed=python" class="category-chip bg-gradient-to-br from-blue-500 to-purple-600 text-white p-4 rounded-xl text-center hover:from-blue-600 hover:to-purple-700">
<i data-feather="code" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">Python</span>
</a>
<a href="https://hackernews.ca/index.php?feed=javascript" class="category-chip bg-gradient-to-br from-yellow-500 to-orange-500 text-white p-4 rounded-xl text-center hover:from-yellow-600 hover:to-orange-600">
<i data-feather="code" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">JavaScript</span>
</a>
<a href="https://hackernews.ca/index.php?feed=php" class="category-chip bg-gradient-to-br from-purple-500 to-pink-500 text-white p-4 rounded-xl text-center hover:from-purple-600 hover:to-pink-600">
<i data-feather="code" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">PHP</span>
</a>
<a href="https://hackernews.ca/index.php?feed=HTML" class="category-chip bg-gradient-to-br from-red-500 to-orange-500 text-white p-4 rounded-xl text-center hover:from-red-600 hover:to-orange-600">
<i data-feather="code" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">HTML</span>
</a>
<a href="https://hackernews.ca/index.php?feed=CSS" class="category-chip bg-gradient-to-br from-blue-400 to-blue-600 text-white p-4 rounded-xl text-center hover:from-blue-500 hover:to-blue-700">
<i data-feather="code" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">CSS</span>
</a>
<a href="https://hackernews.ca/index.php?feed=programming" class="category-chip bg-gradient-to-br from-green-500 to-teal-500 text-white p-4 rounded-xl text-center hover:from-green-600 hover:to-teal-600">
<i data-feather="cpu" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">Programming</span>
</a>
<!-- Security & Hacking -->
<a href="https://hackernews.ca/index.php?feed=hacking" class="category-chip bg-gradient-to-br from-gray-700 to-black text-white p-4 rounded-xl text-center hover:from-gray-800 hover:to-gray-900">
<i data-feather="shield" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">Hacking</span>
</a>
<a href="https://hackernews.ca/index.php?feed=whitehat" class="category-chip bg-gradient-to-br from-white to-gray-300 text-gray-800 p-4 rounded-xl text-center hover:from-gray-100 hover:to-gray-400">
<i data-feather="shield" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">White Hat</span>
</a>
<a href="https://hackernews.ca/index.php?feed=blackhat" class="category-chip bg-gradient-to-br from-black to-gray-800 text-white p-4 rounded-xl text-center hover:from-gray-900 hover:to-gray-700">
<i data-feather="shield-off" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">Black Hat</span>
</a>
<a href="https://hackernews.ca/index.php?feed=kali" class="category-chip bg-gradient-to-br from-blue-600 to-purple-700 text-white p-4 rounded-xl text-center hover:from-blue-700 hover:to-purple-800">
<i data-feather="terminal" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">Kali Linux</span>
</a>
<a href="https://hackernews.ca/index.php?feed=nmap" class="category-chip bg-gradient-to-br from-orange-500 to-red-500 text-white p-4 rounded-xl text-center hover:from-orange-600 hover:to-red-600">
<i data-feather="search" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">Nmap</span>
</a>
<!-- Linux & Systems -->
<a href="https://hackernews.ca/index.php?feed=linux" class="category-chip bg-gradient-to-br from-yellow-400 to-orange-500 text-white p-4 rounded-xl text-center hover:from-yellow-500 hover:to-orange-600">
<i data-feather="server" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">Linux</span>
</a>
<a href="https://hackernews.ca/index.php?feed=ubuntu" class="category-chip bg-gradient-to-br from-orange-500 to-purple-500 text-white p-4 rounded-xl text-center hover:from-orange-600 hover:to-purple-600">
<i data-feather="server" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">Ubuntu</span>
</a>
<a href="https://hackernews.ca/index.php?feed=docker" class="category-chip bg-gradient-to-br from-blue-400 to-blue-600 text-white p-4 rounded-xl text-center hover:from-blue-500 hover:to-blue-700">
<i data-feather="box" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">Docker</span>
</a>
<!-- Hardware & IoT -->
<a href="https://hackernews.ca/index.php?feed=Raspberry" class="category-chip bg-gradient-to-br from-red-500 to-pink-500 text-white p-4 rounded-xl text-center hover:from-red-600 hover:to-pink-600">
<i data-feather="pie-chart" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">Raspberry Pi</span>
</a>
<a href="https://hackernews.ca/index.php?feed=Arduino" class="category-chip bg-gradient-to-br from-blue-600 to-teal-500 text-white p-4 rounded-xl text-center hover:from-blue-700 hover:to-teal-600">
<i data-feather="cpu" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">Arduino</span>
</a>
<!-- Crypto & Blockchain -->
<a href="https://hackernews.ca/index.php?feed=bitcoin" class="category-chip bg-gradient-to-br from-orange-500 to-yellow-500 text-white p-4 rounded-xl text-center hover:from-orange-600 hover:to-yellow-600">
<i data-feather="dollar-sign" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">Bitcoin</span>
</a>
<!-- Web & CMS -->
<a href="https://hackernews.ca/index.php?feed=WordPress" class="category-chip bg-gradient-to-br from-gray-700 to-blue-800 text-white p-4 rounded-xl text-center hover:from-gray-800 hover:to-blue-900">
<i data-feather="globe" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">WordPress</span>
</a>
<a href="https://hackernews.ca/index.php?feed=bootstrap" class="category-chip bg-gradient-to-br from-purple-500 to-pink-500 text-white p-4 rounded-xl text-center hover:from-purple-600 hover:to-pink-600">
<i data-feather="layout" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">Bootstrap</span>
</a>
<a href="https://hackernews.ca/index.php?feed=jQuery" class="category-chip bg-gradient-to-br from-blue-500 to-blue-700 text-white p-4 rounded-xl text-center hover:from-blue-600 hover:to-blue-800">
<i data-feather="zap" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">jQuery</span>
</a>
<!-- Science & Education -->
<a href="https://hackernews.ca/index.php?feed=Science" class="category-chip bg-gradient-to-br from-green-500 to-blue-500 text-white p-4 rounded-xl text-center hover:from-green-600 hover:to-blue-600">
<i data-feather="book" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">Science</span>
</a>
<a href="https://hackernews.ca/index.php?feed=Coding" class="category-chip bg-gradient-to-br from-indigo-500 to-purple-500 text-white p-4 rounded-xl text-center hover:from-indigo-600 hover:to-purple-600">
<i data-feather="book-open" class="w-6 h-6 mx-auto mb-2"></i>
<span class="font-semibold">Coding</span>
</a>
</div>
</section>
<!-- About Section -->
<section class="glass-effect rounded-2xl p-8 mb-12">
<div class="flex items-start space-x-6">
<div class="flex-1">
<h3 class="text-2xl font-bold mb-4">About HackerNews.ca</h3>
<p class="text-gray-300 mb-4 leading-relaxed">
Inspired by the legendary Hacker News community, we've created this Canadian-focused platform
to showcase the incredible tech innovation happening across the Great White North. From cybersecurity
to programming, hardware to blockchain - we cover it all with a uniquely Canadian perspective.
</p>
<div class="flex items-center space-x-2 text-sm text-gray-400">
<i data-feather="heart" class="w-4 h-4"></i>
<span>Kudo's to Hacker News for the inspiration to create this page.</span>
</div>
</div>
<div class="w-24 h-24 flex-shrink-0">
<img src="https://www.digitalassets.ca/uploads/chrome_2016-06-04_14-58-44.png"
alt="HackerNews Canada"
class="w-full h-full rounded-lg object-cover">
</div>
</div>
</section>
<!-- Live Tech News Section -->
<section class="mb-12">
<div class="flex items-center justify-center mb-6">
<h3 class="text-2xl font-bold mr-3">Live Tech News</h3>
<div class="flex items-center space-x-2">
<span class="text-sm bg-green-500 text-white px-3 py-1 rounded-full flex items-center space-x-1">
<i data-feather="wifi" class="w-3 h-3"></i>
<span>Powered by HackerNews API</span>
</div>
</div>
<div id="tech-news-container" class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- News cards will be dynamically populated here -->
<div class="news-card glass-effect rounded-xl p-6">
<div class="flex items-center space-x-3 mb-4">
<div class="w-10 h-10 bg-gradient-to-r from-red-500 to-blue-500 rounded-full flex items-center justify-center">
<i data-feather="refresh-cw" class="w-5 h-5 text-white animate-spin"></i>
</div>
<div>
<h4 class="font-semibold">Loading Latest Tech News...</h4>
<p class="text-sm text-gray-400">Fetching from HackerNews</div>
</div>
<p class="text-gray-300 text-sm">Connecting to HackerNews API to bring you the hottest tech stories.</p>
</div>
</section>
<!-- Stats Section -->
<section class="glass-effect rounded-2xl p-8 mb-12">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="text-center">
<div class="text-3xl font-bold text-blue-400 mb-2" id="total-stories">-</div>
<div class="text-sm text-gray-400">Total Stories Today</div>
</div>
<div class="text-center">
<div class="text-3xl font-bold text-green-400 mb-2" id="active-users">-</div>
<div class="text-sm text-gray-400">Active HackerNews Users</div>
</div>
<div class="text-center">
<div class="text-3xl font-bold text-purple-400 mb-2" id="api-status">Live</div>
<div class="text-sm text-gray-400">API Status</div>
</div>
</div>
</section>
</main>
<!-- Footer -->
<footer class="glass-effect mt-12 py-8">
<div class="container mx-auto px-4">
<div class="flex flex-col md:flex-row justify-between items-center">
<div class="flex items-center space-x-4 mb-4 md:mb-0">
<img src="https://www.digitalassets.ca/uploads/chrome_2016-06-04_14-58-44.png"
alt="HackerNews Canada"
class="w-8 h-8 rounded">
<span class="text-sm text-gray-300">© 2025 MapleLeaf HackerHub. All rights reserved.</span>
</div>
<div class="flex space-x-4">
<a href="#" class="text-gray-400 hover:text-white transition-colors">
<i data-feather="github"></i>
</a>
<a href="#" class="text-gray-400 hover:text-white transition-colors">
<i data-feather="twitter"></i>
</a>
<a href="#" class="text-gray-400 hover:text-white transition-colors">
<i data-feather="linkedin"></i>
</a>
</div>
</div>
</div>
</footer>
<script>
// Initialize Vanta.js background
VANTA.GLOBE({
el: "#vanta-bg",
mouseControls: true,
touchControls: true,
gyroControls: false,
minHeight: 200.00,
minWidth: 200.00,
scale: 1.00,
scaleMobile: 1.00,
color: 0x3b82f6,
backgroundColor: 0x111827,
size: 1.00
});
// Initialize Feather Icons
feather.replace();
// Fetch tech news on page load
fetchTopStories();
startAutoRefresh();
// Update stats
document.getElementById('total-stories').textContent = '500+';
document.getElementById('active-users').textContent = '10K+';
// Add some interactive animations
document.addEventListener('DOMContentLoaded', function() {
// Animate category chips on load
const chips = document.querySelectorAll('.category-chip');
chips.forEach((chip, index) => {
chip.style.opacity = '0';
chip.style.transform = 'translateY(20px)';
setTimeout(() => {
chip.style.transition = 'all 0.6s ease';
chip.style.opacity = '1';
chip.style.transform = 'translateY(0)';
}, index * 100);
});
// Add hover effects to news cards
const newsCards = document.querySelectorAll('.news-card');
newsCards.forEach(card => {
card.addEventListener('mouseenter', () => {
card.style.transform = 'translateY(-5px) scale(1.02)';
});
card.addEventListener('mouseleave', () => {
card.style.transform = 'translateY(0) scale(1)';
});
});
});
</script>
</body>
</html>