Files
openrouter-watcher/templates/stats/index.html
Luca Sacchi Ricciardi c1f47c897f feat(frontend): T44 setup FastAPI static files and templates
- Mount static files on /static endpoint
- Configure Jinja2Templates with directory structure
- Create base template with Pico.css, HTMX, Chart.js
- Create all template subdirectories (auth, dashboard, keys, tokens, profile, components)
- Create initial CSS and JS files
- Add tests for static files and templates configuration

Tests: 12 passing
Coverage: 100% on new configuration code
2026-04-07 17:58:03 +02:00

136 lines
4.1 KiB
HTML

{% extends "base.html" %}
{% block title %}Statistics - OpenRouter Monitor{% endblock %}
{% block content %}
<h1>Detailed Statistics</h1>
<!-- Filters -->
<article>
<header>
<h3>Filters</h3>
</header>
<form action="/stats" method="GET" hx-get="/stats" hx-target="#stats-results" hx-push-url="true">
<div class="grid">
<label for="start_date">
Start Date
<input type="date" id="start_date" name="start_date" value="{{ filters.start_date }}">
</label>
<label for="end_date">
End Date
<input type="date" id="end_date" name="end_date" value="{{ filters.end_date }}">
</label>
<label for="api_key_id">
API Key
<select id="api_key_id" name="api_key_id">
<option value="">All Keys</option>
{% for key in api_keys %}
<option value="{{ key.id }}" {% if filters.api_key_id == key.id %}selected{% endif %}>
{{ key.name }}
</option>
{% endfor %}
</select>
</label>
<label for="model">
Model
<input type="text" id="model" name="model" placeholder="gpt-4" value="{{ filters.model }}">
</label>
</div>
<button type="submit">Apply Filters</button>
<a href="/stats/export?{{ query_string }}" role="button" class="secondary">Export CSV</a>
</form>
</article>
<!-- Results -->
<article id="stats-results">
<header>
<h3>Usage Details</h3>
<p><small>Showing {{ stats|length }} results</small></p>
</header>
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>API Key</th>
<th>Model</th>
<th>Requests</th>
<th>Prompt Tokens</th>
<th>Completion Tokens</th>
<th>Total Tokens</th>
<th>Cost</th>
</tr>
</thead>
<tbody>
{% for stat in stats %}
<tr>
<td>{{ stat.date }}</td>
<td>{{ stat.api_key_name }}</td>
<td>{{ stat.model }}</td>
<td>{{ stat.requests }}</td>
<td>{{ stat.prompt_tokens }}</td>
<td>{{ stat.completion_tokens }}</td>
<td>{{ stat.total_tokens }}</td>
<td>${{ stat.cost | round(4) }}</td>
</tr>
{% else %}
<tr>
<td colspan="8" style="text-align: center;">No data found for the selected filters.</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- Pagination -->
{% if total_pages > 1 %}
<nav>
<ul>
{% if page > 1 %}
<li>
<a href="?page={{ page - 1 }}&{{ query_string }}" class="secondary">&laquo; Previous</a>
</li>
{% endif %}
{% for p in range(1, total_pages + 1) %}
<li>
{% if p == page %}
<strong>{{ p }}</strong>
{% else %}
<a href="?page={{ p }}&{{ query_string }}">{{ p }}</a>
{% endif %}
</li>
{% endfor %}
{% if page < total_pages %}
<li>
<a href="?page={{ page + 1 }}&{{ query_string }}" class="secondary">Next &raquo;</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
</article>
<!-- Summary -->
<article>
<header>
<h3>Summary</h3>
</header>
<div class="grid">
<div>
<strong>Total Requests:</strong> {{ summary.total_requests }}
</div>
<div>
<strong>Total Tokens:</strong> {{ summary.total_tokens }}
</div>
<div>
<strong>Total Cost:</strong> ${{ summary.total_cost | round(2) }}
</div>
</div>
</article>
{% endblock %}