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
This commit is contained in:
135
templates/stats/index.html
Normal file
135
templates/stats/index.html
Normal file
@@ -0,0 +1,135 @@
|
||||
{% 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">« 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 »</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 %}
|
||||
Reference in New Issue
Block a user