grok_test / templates /index.html
broadfield-dev's picture
Update templates/index.html
40c26bb verified
raw
history blame
7.14 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>News Feed Hub</title>
<style>
body {
font-family: 'Arial', sans-serif;
margin: 0;
padding: 20px;
background-color: #f5f5f5; /* Light grey background from screenshot */
color: #333;
}
h1 {
text-align: center;
color: #2c3e50;
margin-bottom: 20px;
font-size: 2em;
}
.search-container {
text-align: center;
margin: 20px 0;
}
.search-bar {
width: 50%;
padding: 12px;
font-size: 16px;
border: 2px solid #3498db; /* Blue from screenshot */
border-radius: 25px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
outline: none;
transition: border-color 0.3s;
background-color: white;
}
.search-bar:focus {
border-color: #2980b9;
}
.category-section {
margin: 30px 0;
}
.category-title {
background-color: #3498db; /* Blue header from screenshot */
color: white;
padding: 10px;
border-radius: 5px;
font-size: 1.4em;
text-align: center;
margin-bottom: 15px;
}
.tiles {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
justify-content: center;
}
.article-tile {
background-color: white;
padding: 15px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1); /* Subtle shadow like screenshot */
transition: transform 0.2s;
overflow: hidden;
border: 1px solid #e0e0e0; /* Subtle grey outline from screenshot */
}
.article-tile:hover {
transform: scale(1.05);
box-shadow: 0 6px 12px rgba(0,0,0,0.15);
}
.article-tile img, .article-tile svg {
width: 100%;
height: 150px;
object-fit: cover;
border-radius: 5px;
}
.title a {
font-size: 1.1em;
color: #2c3e50;
text-decoration: none;
display: block;
margin: 10px 0;
font-weight: bold;
}
.title a:hover {
color: #3498db;
}
.description {
color: #555;
font-size: 0.9em;
margin: 5px 0;
line-height: 1.4;
}
.published {
font-size: 0.8em;
color: #95a5a6;
margin-top: 10px;
}
#loading {
display: none; /* Initially hidden, shown during new feed loading */
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
z-index: 1000;
}
.loader {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 50px;
height: 50px;
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: translate(-50%, -50%) rotate(0deg); }
100% { transform: translate(-50%, -50%) rotate(360deg); }
}
.loading-message {
text-align: center;
margin-top: 20px;
color: #2c3e50;
font-size: 1em;
}
</style>
</head>
<body>
<div id="loading"><div class="loader"></div></div>
<h1>News Feed Hub</h1>
<div class="search-container">
<form method="POST" id="searchForm">
<input type="text" name="search" class="search-bar" placeholder="Search news semantically...">
</form>
</div>
{% if loading_new_feeds %}
<div class="loading-message">Loading new RSS feeds in the background...</div>
{% endif %}
{% for category, articles in categorized_articles.items() %}
<div class="category-section">
<div class="category-title">{{ category }}</div>
<div class="tiles">
{% for article in articles %}
<div class="article-tile">
{% if article.image != "svg" %}
<img src="{{ article.image }}" alt="Article Image">
{% else %}
<svg width="100%" height="150" viewBox="0 0 300 150" xmlns="http://www.w3.org/2000/svg">
<rect width="300" height="150" fill="#e0e0e0"/>
<text x="50%" y="50%" text-anchor="middle" dy=".3em" font-size="20" fill="#666">
No Image Available
</text>
</svg>
{% endif %}
<div class="title"><a href="{{ article.link }}" target="_blank">{{ article.title }}</a></div>
<div class="description">{{ article.description }}</div>
<div class="published">Published: {{ article.published }}</div>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
<script>
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('searchForm');
const loading = document.getElementById('loading');
form.addEventListener('submit', () => {
loading.style.display = 'block';
});
// Poll until new feeds are loaded (if loading_new_feeds is True)
if ("{{ loading_new_feeds }}" === "True") {
function checkNewFeeds() {
fetch('/check_feeds')
.then(response => response.json())
.then(data => {
if (data.status === "loaded") {
location.reload(); // Refresh to show new articles
} else if (data.status === "error") {
console.error('Error loading new feeds:', data.message);
loading.style.display = 'none';
alert('Failed to load new RSS feeds. Please try again.');
} else {
setTimeout(checkNewFeeds, 1000); // Check every second
}
})
.catch(error => {
console.error('Error checking new feeds:', error);
loading.style.display = 'none';
alert('Network error while loading new feeds. Please try again.');
});
}
checkNewFeeds();
}
});
</script>
</body>
</html>