- FastAPI REST API with JWT auth - aiogram 3 Telegram bot with admin middleware - APScheduler daily tasks (expiry, reminders, revoke, sync) - SQLAlchemy 2 async ORM with Alembic migrations - Jinja2 admin panel (Dashboard, Users, Payments, Servers, Tariffs) - VPN provider abstraction with MockProvider - Stats service with revenue/subscription analytics - Docker Compose (PostgreSQL + Redis + app) - Healthcheck endpoint
39 lines
1.1 KiB
HTML
39 lines
1.1 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}Users — VPN Control Panel{% endblock %}
|
|
{% block content %}
|
|
<h2>Users</h2>
|
|
<div class="count">{{ users|length }} total</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Telegram ID</th>
|
|
<th>Username</th>
|
|
<th>Full Name</th>
|
|
<th>Language</th>
|
|
<th>Status</th>
|
|
<th>Created</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for u in users %}
|
|
<tr>
|
|
<td>{{ u.id }}</td>
|
|
<td>{{ u.telegram_id }}</td>
|
|
<td>{% if u.username %}@{{ u.username }}{% else %}—{% endif %}</td>
|
|
<td>{{ u.full_name }}</td>
|
|
<td>{{ u.language_code }}</td>
|
|
<td>
|
|
{% if u.is_active %}
|
|
<span class="badge badge-green">Active</span>
|
|
{% else %}
|
|
<span class="badge badge-red">Inactive</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>{{ u.created_at.strftime("%Y-%m-%d") }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
{% endblock %}
|