Adds the full Django application layer on top of sportstime_parser: - core: Sport, Team, Stadium, Game models with aliases and league structure - scraper: orchestration engine, adapter, job management, Celery tasks - cloudkit: CloudKit sync client, sync state tracking, sync jobs - dashboard: staff dashboard for monitoring scrapers, sync, review queue - notifications: email reports for scrape/sync results - Docker setup for deployment (Dockerfile, docker-compose, entrypoint) Game exports now use game_datetime_utc (ISO 8601 UTC) instead of venue-local date+time strings, matching the canonical format used by the iOS app. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
75 lines
2.8 KiB
HTML
75 lines
2.8 KiB
HTML
{% extends "dashboard/base.html" %}
|
|
|
|
{% block dashboard_content %}
|
|
<div class="stat-card">
|
|
<h3>Review Queue Summary</h3>
|
|
<div class="stat-grid">
|
|
<div class="stat-item">
|
|
<div class="stat-value">{{ total_pending }}</div>
|
|
<div class="stat-label">Total Pending</div>
|
|
</div>
|
|
{% for item in review_summary %}
|
|
<div class="stat-item">
|
|
<div class="stat-value">{{ item.count }}</div>
|
|
<div class="stat-label">{{ item.sport__short_name }} {{ item.item_type }}s</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="stat-card">
|
|
<h3>Pending Review Items</h3>
|
|
{% if pending_items %}
|
|
<div class="table-responsive">
|
|
<table class="dashboard-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Sport</th>
|
|
<th>Raw Value</th>
|
|
<th>Suggested Match</th>
|
|
<th>Confidence</th>
|
|
<th>Reason</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for item in pending_items %}
|
|
<tr>
|
|
<td>{{ item.item_type }}</td>
|
|
<td>{{ item.sport.short_name }}</td>
|
|
<td><code>{{ item.raw_value }}</code></td>
|
|
<td>
|
|
{% if item.suggested_id %}
|
|
<code style="background: #e8f5e9;">{{ item.suggested_id }}</code>
|
|
{% else %}
|
|
<span style="color: #999;">None</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if item.confidence > 0 %}
|
|
<span style="color: {% if item.confidence >= 0.85 %}#5cb85c{% elif item.confidence >= 0.7 %}#f0ad4e{% else %}#d9534f{% endif %}; font-weight: bold;">
|
|
{{ item.confidence_display }}
|
|
</span>
|
|
{% else %}-{% endif %}
|
|
</td>
|
|
<td>{{ item.get_reason_display }}</td>
|
|
<td>
|
|
<a href="{% url 'admin:scraper_manualreviewitem_change' item.id %}" class="btn-action">Review</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% if total_pending > 50 %}
|
|
<p style="margin-top: 15px; color: #666;">
|
|
Showing 50 of {{ total_pending }} items. <a href="{% url 'admin:scraper_manualreviewitem_changelist' %}?status__exact=pending">View all in admin</a>.
|
|
</p>
|
|
{% endif %}
|
|
{% else %}
|
|
<p style="color: #5cb85c; font-weight: bold;">No pending review items! 🎉</p>
|
|
{% endif %}
|
|
</div>
|
|
{% endblock %}
|