Files
vpn/app/templates/admin/xui_detail.html
T

133 lines
4.1 KiB
HTML

{% extends "admin/layout.html" %}
{% block admin_title %}{{ panel.name }}{% endblock %}
{% block admin_content %}
<div class="admin-top">
<div>
<h1>{{ panel.name }}</h1>
<div class="muted"><a href="{{ panel.base_url }}" target="_blank" rel="noopener">{{ panel.base_url }}</a></div>
</div>
<div class="actions">
<a class="btn btn-sm btn-ghost" href="/admin/xui">Назад</a>
<form method="post" action="/admin/xui/{{ panel.id }}/check" class="inline-form">
<button class="btn btn-sm btn-accent" type="submit">Обновить API</button>
</form>
</div>
</div>
{% if flash %}
{% if flash.startswith('error:') %}
<div class="flash flash-error">{{ flash[6:] }}</div>
{% elif flash == 'client_created' %}
<div class="flash">Клиент создан в 3x-ui</div>
{% endif %}
{% endif %}
{% if error %}
<div class="flash flash-error">{{ error }}</div>
{% endif %}
{% if data %}
<div class="stats">
<div class="stat">
<div class="label">Inbounds</div>
<div class="value">{{ data.inbounds|length }}</div>
</div>
<div class="stat">
<div class="label">Clients</div>
<div class="value">{{ data.clients|length }}</div>
</div>
<div class="stat">
<div class="label">Xray</div>
<div class="value" style="font-size:1.1rem">
{% if data.status and data.status.xray %}
{% if data.status.xray.state %}running{% else %}stopped{% endif %}
{% else %}—{% endif %}
</div>
</div>
</div>
<div class="panel" style="margin-bottom:1rem">
<div class="panel-head"><strong>Добавить клиента через API</strong></div>
<div class="panel-body">
<form method="post" action="/admin/xui/{{ panel.id }}/clients" class="form-grid">
<label>Email / имя
<input name="email" placeholder="user1" required />
</label>
<label>Inbound
<select name="inbound_id" required>
{% for ib in data.inbounds %}
<option value="{{ ib.id }}">#{{ ib.id }} {{ ib.remark or ib.protocol }} :{{ ib.port }}</option>
{% endfor %}
</select>
</label>
<button class="btn btn-accent" type="submit">Создать</button>
<label>Лимит GB (0 = безлимит)
<input type="number" name="total_gb" value="0" min="0" />
</label>
<label>Limit IP
<input type="number" name="limit_ip" value="0" min="0" />
</label>
</form>
</div>
</div>
<div class="panel" style="margin-bottom:1rem">
<div class="panel-head"><strong>Inbounds</strong></div>
<table>
<thead>
<tr>
<th>ID</th>
<th>Remark</th>
<th>Protocol</th>
<th>Port</th>
<th>Enable</th>
</tr>
</thead>
<tbody>
{% for ib in data.inbounds %}
<tr>
<td>{{ ib.id }}</td>
<td>{{ ib.remark or '—' }}</td>
<td><span class="badge badge-proto">{{ ib.protocol }}</span></td>
<td>{{ ib.port }}</td>
<td>{% if ib.enable %}<span class="badge badge-ok">on</span>{% else %}<span class="badge badge-off">off</span>{% endif %}</td>
</tr>
{% else %}
<tr><td colspan="5" class="muted">Нет inbound’ов</td></tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="panel">
<div class="panel-head"><strong>Clients</strong></div>
<table>
<thead>
<tr>
<th>Email</th>
<th>Enable</th>
<th>Inbounds</th>
<th>Traffic</th>
</tr>
</thead>
<tbody>
{% for c in data.clients %}
<tr>
<td>{{ c.email }}</td>
<td>{% if c.enable %}<span class="badge badge-ok">on</span>{% else %}<span class="badge badge-off">off</span>{% endif %}</td>
<td>{{ c.inboundIds or c.inbound_ids or '—' }}</td>
<td class="muted">
{% if c.traffic %}
↑ {{ c.traffic.up or 0 }} / ↓ {{ c.traffic.down or 0 }}
{% else %}—{% endif %}
</td>
</tr>
{% else %}
<tr><td colspan="4" class="muted">Нет клиентов или endpoint /clients/list недоступен</td></tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{% endblock %}