Files
openrouter-watcher/templates/tokens/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

115 lines
3.6 KiB
HTML

{% extends "base.html" %}
{% block title %}API Tokens - OpenRouter Monitor{% endblock %}
{% block content %}
<h1>API Tokens Management</h1>
<!-- Add New Token Form -->
<article>
<header>
<h3>Generate New API Token</h3>
</header>
<form action="/tokens" method="POST" hx-post="/tokens" hx-swap="afterend" hx-target="this">
<label for="token_name">
Token Name
<input type="text" id="token_name" name="name" placeholder="Mobile App Token" required>
</label>
<button type="submit">Generate Token</button>
</form>
</article>
<!-- New Token Display (shown after creation) -->
{% if new_token %}
<article style="border: 2px solid var(--warning-color);">
<header>
<h3 style="color: var(--warning-color);">Save Your Token!</h3>
</header>
<div class="alert alert-danger" role="alert">
<strong>Warning:</strong> This token will only be displayed once. Copy it now!
</div>
<label for="new_token_value">
Your New API Token
<input
type="text"
id="new_token_value"
value="{{ new_token }}"
readonly
onclick="this.select()"
style="font-family: monospace;"
>
</label>
<button onclick="navigator.clipboard.writeText(document.getElementById('new_token_value').value)">
Copy to Clipboard
</button>
</article>
{% endif %}
<!-- Tokens List -->
<article>
<header>
<h3>Your API Tokens</h3>
</header>
<table class="table" id="tokens-table">
<thead>
<tr>
<th>Name</th>
<th>Status</th>
<th>Last Used</th>
<th>Created</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for token in api_tokens %}
<tr id="token-{{ token.id }}">
<td>{{ token.name }}</td>
<td>
{% if token.is_active %}
<span style="color: var(--success-color);">Active</span>
{% else %}
<span style="color: var(--danger-color);">Revoked</span>
{% endif %}
</td>
<td>{{ token.last_used_at or 'Never' }}</td>
<td>{{ token.created_at }}</td>
<td>
{% if token.is_active %}
<button
class="outline secondary"
hx-delete="/tokens/{{ token.id }}"
hx-confirm="Are you sure you want to revoke this token? This action cannot be undone."
hx-target="#token-{{ token.id }}"
hx-swap="outerHTML"
>
Revoke
</button>
{% endif %}
</td>
</tr>
{% else %}
<tr>
<td colspan="5" style="text-align: center;">No API tokens found. Generate your first token above.</td>
</tr>
{% endfor %}
</tbody>
</table>
</article>
<!-- Usage Instructions -->
<article>
<header>
<h3>Using API Tokens</h3>
</header>
<p>Include your API token in the <code>Authorization</code> header:</p>
<pre><code>Authorization: Bearer YOUR_API_TOKEN</code></pre>
<p>Available endpoints:</p>
<ul>
<li><code>GET /api/v1/stats</code> - Get usage statistics</li>
<li><code>GET /api/v1/usage</code> - Get detailed usage data</li>
<li><code>GET /api/v1/keys</code> - List your API keys (metadata only)</li>
</ul>
</article>
{% endblock %}