06/16 Phase 6 (continue)

This commit is contained in:
2026-06-17 17:06:43 -04:00
parent 479afde2fa
commit 68a842d6b6
26 changed files with 1027 additions and 61 deletions
+61
View File
@@ -0,0 +1,61 @@
{% extends "base.html" %}
{% block title %}{{ _('Admin · Transactions') }}{% endblock %}
{% block content %}
{% include "admin/_nav.html" %}
<div class="card">
<h2>{{ _('Transactions') }}</h2>
<p class="muted">{{ _('All-time revenue (succeeded): $%(amount)s', amount='%.2f'|format(total_cents / 100)) }}</p>
<form method="get" class="admin-filter-row">
<div class="field">
<label>{{ _('Type') }}</label>
<select class="input" name="type">
<option value="">{{ _('All') }}</option>
<option value="subscription" {{ 'selected' if filters.get('type') == 'subscription' }}>{{ _('Subscription') }}</option>
<option value="boost" {{ 'selected' if filters.get('type') == 'boost' }}>{{ _('Boost') }}</option>
<option value="refund" {{ 'selected' if filters.get('type') == 'refund' }}>{{ _('Refund') }}</option>
</select>
</div>
<div class="field">
<label>{{ _('Status') }}</label>
<select class="input" name="status">
<option value="">{{ _('All') }}</option>
<option value="succeeded" {{ 'selected' if filters.get('status') == 'succeeded' }}>{{ _('Succeeded') }}</option>
<option value="failed" {{ 'selected' if filters.get('status') == 'failed' }}>{{ _('Failed') }}</option>
<option value="pending" {{ 'selected' if filters.get('status') == 'pending' }}>{{ _('Pending') }}</option>
</select>
</div>
<button class="btn ghost" type="submit">{{ _('Filter') }}</button>
{% if filters.get('type') or filters.get('status') %}<a class="btn ghost" href="{{ url_for('admin.transactions') }}">{{ _('Clear') }}</a>{% endif %}
</form>
<table class="list">
<thead><tr>
<th>{{ _('Date') }}</th>
<th>{{ _('User') }}</th>
<th>{{ _('Type') }}</th>
<th>{{ _('Amount') }}</th>
<th>{{ _('Status') }}</th>
<th>{{ _('Stripe ID') }}</th>
</tr></thead>
{% for txn in pagination.items %}
<tr>
<td class="muted small">{{ txn.created_at.strftime('%Y-%m-%d') }}</td>
<td><a href="{{ url_for('admin.user_detail', user_id=txn.user_id) }}">{{ txn.user.display_name }}</a></td>
<td><span class="badge cat">{{ txn.type }}</span></td>
<td>${{ '%.2f'|format(txn.amount_cents / 100) }}</td>
<td><span class="badge {{ 'ok' if txn.status == 'succeeded' else 'warn' }}">{{ txn.status }}</span></td>
<td class="muted small">{{ txn.stripe_object_id or '—' }}</td>
</tr>
{% else %}
<tr><td colspan="6" class="muted">{{ _('No transactions.') }}</td></tr>
{% endfor %}
</table>
<div class="pager">
{% if pagination.has_prev %}<a href="{{ url_for('admin.transactions', **merge_query(page=pagination.prev_num)) }}">&larr; {{ _('Prev') }}</a>{% endif %}
<span class="muted">{{ _('Page %(p)s of %(t)s', p=pagination.page, t=pagination.pages) }}</span>
{% if pagination.has_next %}<a href="{{ url_for('admin.transactions', **merge_query(page=pagination.next_num)) }}">{{ _('Next') }} &rarr;</a>{% endif %}
</div>
</div>
{% endblock %}