Fix Issue #17: Standardize admin page styling and eliminate inconsistencies
## Problems Fixed: 1. **Template inheritance inconsistency** - Some admin pages used standalone HTML while others extended base.html 2. **CSS duplication** - Each admin page had duplicate styles for similar components 3. **Header styling variations** - Different admin pages had slightly different header styles 4. **Inconsistent class naming** - Mixed naming patterns across admin templates ## Root Cause: Admin pages were developed independently without a shared styling foundation, leading to code duplication and visual inconsistencies. ## Solution Implemented: ### New Shared Admin Base - **Created `_admin_base.html`** - Unified base template for all admin pages - **Consolidated styles** - Moved common admin styles to shared base template - **Standardized components** - Unified buttons, tables, badges, forms, etc. - **Consistent layout** - Standard admin container, header, and navigation structure ### Refactored Templates - **`admin.html`** - Now extends `_admin_base.html`, removed 300+ lines of duplicate CSS - **`admin_polling.html`** - Converted to use base template, cleaner structure - **`admin_polling_logs.html`** - Completely rewritten to use base template - **Consistent class names** - All admin tables now use `.admin-table` instead of mixed names ### Benefits - **Maintainability** - Single source of truth for admin styling - **Consistency** - All admin pages now have identical look and feel - **Performance** - Reduced CSS duplication improves load times - **Extensibility** - Easy to add new admin pages with consistent styling All admin pages now share a unified, professional appearance\! Commit: [current] 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,52 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Polling Management - Admin - {{ APP_NAME }}</title>
|
||||
<link rel="stylesheet" href="{{ url_for('serve_theme', filename='modern-card-ui/styles.css') }}">
|
||||
<style>
|
||||
.admin-container {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
padding: 24px;
|
||||
}
|
||||
{% extends "_admin_base.html" %}
|
||||
|
||||
.admin-header {
|
||||
background: linear-gradient(135deg, var(--primary-dark) 0%, #2a5068 100%);
|
||||
color: white;
|
||||
padding: 32px;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
{% block title %}Polling Management - Admin - {{ APP_NAME }}{% endblock %}
|
||||
|
||||
.status-badge {
|
||||
display: inline-block;
|
||||
padding: 4px 12px;
|
||||
border-radius: 12px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
{% block page_title %}Polling Management{% endblock %}
|
||||
{% block page_description %}Manage data collection sources and schedules{% endblock %}
|
||||
|
||||
.status-enabled {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
|
||||
.status-disabled {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
}
|
||||
|
||||
.status-success {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
|
||||
.status-error {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
}
|
||||
{% block admin_styles %}
|
||||
|
||||
.source-card {
|
||||
background: var(--surface-color);
|
||||
@@ -174,23 +133,62 @@
|
||||
padding: 48px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{% include '_nav.html' %}
|
||||
<div class="admin-container">
|
||||
<div class="admin-header">
|
||||
<h1>📡 Polling Management</h1>
|
||||
<p>Configure automatic data collection from content sources</p>
|
||||
</div>
|
||||
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{ category }}">{{ message }}</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
.add-source-form {
|
||||
background: var(--surface-color);
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 500;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.form-input, .form-select {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 6px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.scheduler-status {
|
||||
background: var(--surface-color);
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.help-text {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-secondary);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
}
|
||||
{% endblock %}
|
||||
|
||||
{% block admin_content %}
|
||||
|
||||
<!-- Scheduler Status -->
|
||||
<div class="scheduler-status">
|
||||
@@ -498,6 +496,58 @@
|
||||
function closeEditModal() {
|
||||
document.getElementById('edit-modal').style.display = 'none';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
{% endblock %}
|
||||
|
||||
{% block admin_scripts %}
|
||||
<script>
|
||||
const platformConfig = {{ platform_config|tojson|safe }};
|
||||
|
||||
function updateSourceOptions() {
|
||||
const platformSelect = document.getElementById('platform');
|
||||
const sourceSelect = document.getElementById('source_id');
|
||||
const selectedPlatform = platformSelect.value;
|
||||
|
||||
// Clear existing options
|
||||
sourceSelect.innerHTML = '<option value="">Select source...</option>';
|
||||
|
||||
if (selectedPlatform && platformConfig.platforms[selectedPlatform]) {
|
||||
const communities = platformConfig.platforms[selectedPlatform].communities || [];
|
||||
communities.forEach(community => {
|
||||
const option = document.createElement('option');
|
||||
option.value = community.id;
|
||||
option.textContent = community.display_name || community.name;
|
||||
option.dataset.displayName = community.display_name || community.name;
|
||||
sourceSelect.appendChild(option);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateDisplayName() {
|
||||
const sourceSelect = document.getElementById('source_id');
|
||||
const displayNameInput = document.getElementById('display_name');
|
||||
const selectedOption = sourceSelect.options[sourceSelect.selectedIndex];
|
||||
|
||||
if (selectedOption && selectedOption.dataset.displayName) {
|
||||
displayNameInput.value = selectedOption.dataset.displayName;
|
||||
}
|
||||
}
|
||||
|
||||
function openEditModal(sourceId, displayName, interval, maxPosts, fetchComments, priority) {
|
||||
// Fill form with current values
|
||||
const modal2 = document.getElementById('edit-modal');
|
||||
const form = document.getElementById('edit-form');
|
||||
form.action = `/admin/polling/${sourceId}/update`;
|
||||
document.getElementById('edit_display_name').value = displayName;
|
||||
document.getElementById('edit_interval').value = interval;
|
||||
document.getElementById('edit_max_posts').value = maxPosts;
|
||||
document.getElementById('edit_fetch_comments').value = fetchComments;
|
||||
document.getElementById('edit_priority').value = priority;
|
||||
|
||||
modal2.style.display = 'block';
|
||||
}
|
||||
|
||||
function closeEditModal() {
|
||||
document.getElementById('edit-modal').style.display = 'none';
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user