Refactor templates for improved UI and UX
CI / lint-and-test (push) Has been cancelled

- Updated ads.html to enhance the display of recent ads with better styling and layout.
- Modified base.html to introduce a new color scheme and typography using Inter font and Phosphor icons.
- Revamped dashboard.html to provide a clearer overview of statistics with improved card layouts.
- Enhanced keyword_detail.html for better presentation of keyword configurations and recent matches.
- Improved keywords.html to display keyword filters and subscriber counts more effectively.
- Updated users.html to present user information in a more structured format with clear status indicators.
This commit is contained in:
2026-07-12 21:49:22 +02:00
parent 17f19e1708
commit 05adf2035a
6 changed files with 615 additions and 256 deletions
+57 -38
View File
@@ -1,52 +1,71 @@
{% extends "base.html" %}
{% block title %}Dashboard — Willhaben Tracker{% endblock %}
{% block title_in_topbar %}Dashboard{% endblock %}
{% block content %}
<div class="page-header">
<h2>Dashboard</h2>
{% if data %}
<h3 style="margin-top: 0;">Overview</h3>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 24px; margin-bottom: 32px;">
<div class="card stat-card">
<div class="stat-label">Total Keywords</div>
<div class="stat-value">{{ data.total_keywords }}</div>
<div class="stat-subtext success">
<i class="ph-fill ph-check-circle"></i> {{ data.active_keywords }} active
</div>
</div>
<div class="card stat-card">
<div class="stat-label">Total Ads Tracked</div>
<div class="stat-value">{{ data.total_ads }}</div>
<div class="stat-subtext muted">Across all time</div>
</div>
<div class="card stat-card">
<div class="stat-label">Active Users</div>
<div class="stat-value">{{ data.total_users }}</div>
<div class="stat-subtext muted">Subscribed to updates</div>
</div>
<div class="card stat-card">
<div class="stat-label">Notifications Sent</div>
<div class="stat-value">{{ data.notifications_sent }}</div>
<div class="stat-subtext muted">Via Telegram</div>
</div>
</div>
{% if data %}
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px;">
<div class="card">
<div style="font-size: 12px; color: #a0a0b0; text-transform: uppercase;">Total Keywords</div>
<div style="font-size: 32px; font-weight: 700; margin-top: 8px;">{{ data.total_keywords }}</div>
<div style="font-size: 12px; color: #0f9b58; margin-top: 4px;">{{ data.active_keywords }} active</div>
</div>
<div class="card">
<div style="font-size: 12px; color: #a0a0b0; text-transform: uppercase;">Total Ads</div>
<div style="font-size: 32px; font-weight: 700; margin-top: 8px;">{{ data.total_ads }}</div>
</div>
<div class="card">
<div style="font-size: 12px; color: #a0a0b0; text-transform: uppercase;">Active Users</div>
<div style="font-size: 32px; font-weight: 700; margin-top: 8px;">{{ data.total_users }}</div>
</div>
<div class="card">
<div style="font-size: 12px; color: #a0a0b0; text-transform: uppercase;">Notifications Sent</div>
<div style="font-size: 32px; font-weight: 700; margin-top: 8px;">{{ data.notifications_sent }}</div>
</div>
<div class="card">
<div style="font-size: 12px; color: #a0a0b0; text-transform: uppercase;">Queue Pending</div>
<div style="font-size: 32px; font-weight: 700; margin-top: 8px;">{{ data.queue_pending }}</div>
</div>
<div class="card">
<div style="font-size: 12px; color: #a0a0b0; text-transform: uppercase;">Queue Dead</div>
<div style="font-size: 32px; font-weight: 700; margin-top: 8px; color: #e94560;">{{ data.queue_dead }}</div>
</div>
<div class="card">
<div style="font-size: 12px; color: #a0a0b0; text-transform: uppercase;">Last Scheduler Run</div>
<div style="font-size: 16px; font-weight: 700; margin-top: 8px;">
<h3>System Health</h3>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px;">
<div class="card stat-card" style="border-left: 4px solid var(--border-hover);">
<div class="stat-label">Last Scheduler Run</div>
<div class="stat-value" style="font-size: 24px;">
{{ data.last_scheduler.strftime('%Y-%m-%d %H:%M:%S') if data.last_scheduler else 'Never' }}
</div>
<div class="stat-subtext muted">Worker polling rhythm</div>
</div>
<div class="card">
<div style="font-size: 12px; color: #a0a0b0; text-transform: uppercase;">HTTP Proxy</div>
<div style="font-size: 32px; font-weight: 700; margin-top: 8px; color: {{ '#0f9b58' if data.proxy_enabled else '#e94560' }};">
<div class="card stat-card" style="border-left: 4px solid {% if data.proxy_enabled %}var(--success-text){% else %}var(--border-hover){% endif %};">
<div class="stat-label">HTTP Proxy</div>
<div class="stat-value" style="font-size: 24px; color: {% if data.proxy_enabled %}var(--success-text){% else %}var(--text-primary){% endif %};">
{{ 'Enabled' if data.proxy_enabled else 'Disabled' }}
</div>
<div style="font-size: 12px; color: #a0a0b0; margin-top: 4px;">
{{ 'Outbound scraping uses the proxy' if data.proxy_enabled else 'Outbound scraping goes direct' }}
<div class="stat-subtext muted">
{{ 'Outbound scraping uses proxy' if data.proxy_enabled else 'Direct connection' }}
</div>
</div>
<div class="card stat-card" style="border-left: 4px solid {% if data.queue_dead > 0 %}var(--danger-text){% else %}var(--success-text){% endif %};">
<div class="stat-label">Delivery Queue</div>
<div class="stat-value" style="font-size: 24px;">
{{ data.queue_pending }} pending
</div>
<div class="stat-subtext {% if data.queue_dead > 0 %}danger{% else %}muted{% endif %}">
{{ data.queue_dead }} dead letters
</div>
</div>
</div>
{% endif %}
{% endblock %}
{% endblock %}