Restyle UI with Tailwind CSS: consistent cards, forms, tables and badges across all pages
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
parent
628246c5c5
commit
08b32d2aa9
+112
-42
@@ -2,48 +2,118 @@
|
||||
{% block title %}Peers - WireGuard Admin{% endblock %}
|
||||
{% block breadcrumbs %}<span>/</span> <span>Peers</span>{% endblock %}
|
||||
{% block content %}
|
||||
<h1>Peers</h1>
|
||||
<h1 class="mb-6 text-2xl font-bold">Peers</h1>
|
||||
|
||||
{% if error %}<p class="error">{{ error }}</p>{% endif %}
|
||||
<form method="post" action="/peers" class="add-peer">
|
||||
<input name="name" placeholder="Peer name" required>
|
||||
<input name="note" placeholder="Note (optional)">
|
||||
<input name="address" placeholder="IP (auto if empty)" class="mid">
|
||||
<input name="dns" placeholder="DNS (default {{ settings.wg_dns }})" class="mid">
|
||||
<label class="muted">Quota GiB <input name="quota_gib" type="number" step="0.1" min="0" class="narrow" placeholder="0"></label>
|
||||
<label class="muted">Count <input name="count" type="number" min="1" max="50" value="1" class="narrow"></label>
|
||||
<label class="muted">Expires <input name="expires_at" type="datetime-local"></label>
|
||||
<button type="submit">Add peer(s)</button>
|
||||
</form>
|
||||
<p class="muted">Count > 1 creates a batch named name-1, name-2, ... (custom IP ignored). Quota 0 = unlimited.</p>
|
||||
{% if error %}
|
||||
<p class="mb-4 rounded-md bg-red-50 px-3 py-2 text-sm text-red-700">{{ error }}</p>
|
||||
{% endif %}
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Name</th><th>Address</th><th>Enabled</th><th>Status</th><th>Usage</th><th>Note</th><th></th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for peer in peers %}
|
||||
{% set ps = status.peers.get(peer.public_key) %}
|
||||
<tr>
|
||||
<td><a href="/peers/{{ peer.id }}">{{ peer.name }}</a></td>
|
||||
<td>{{ peer.address }}</td>
|
||||
<td>{% if peer.enabled %}<span class="badge ok">enabled</span>{% elif peer.over_quota %}<span class="badge err">over quota</span>{% else %}<span class="badge err">disabled</span>{% endif %}</td>
|
||||
<td>{% if ps and ps.online %}<span class="badge ok">online</span>{% else %}<span class="badge muted">offline</span>{% endif %}</td>
|
||||
<td class="muted">{{ peer.cum_total | fmt_bytes }}{% if peer.quota_bytes %} / {{ peer.quota_bytes | fmt_bytes }}{% endif %}</td>
|
||||
<td class="muted">{{ peer.note }}</td>
|
||||
<td class="actions">
|
||||
<form method="post" action="/peers/{{ peer.id }}/toggle" class="inline">
|
||||
<button type="submit">{{ "Disable" if peer.enabled else "Enable" }}</button>
|
||||
</form>
|
||||
<form method="post" action="/peers/{{ peer.id }}/delete" class="inline"
|
||||
onsubmit="return confirm('Delete peer {{ peer.name }}?')">
|
||||
<button type="submit" class="danger">Delete</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr><td colspan="7" class="muted">No peers yet. Add one above.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="mb-8 rounded-xl bg-white p-5 shadow-sm">
|
||||
<h2 class="mb-4 text-xs font-semibold uppercase tracking-wide text-slate-400">Add peer</h2>
|
||||
<form method="post" action="/peers" class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<label class="block text-sm font-medium text-slate-600">Name
|
||||
<input name="name" required placeholder="laptop"
|
||||
class="mt-1 w-full rounded-md border border-slate-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500">
|
||||
</label>
|
||||
<label class="block text-sm font-medium text-slate-600">Note
|
||||
<input name="note" placeholder="optional"
|
||||
class="mt-1 w-full rounded-md border border-slate-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500">
|
||||
</label>
|
||||
<label class="block text-sm font-medium text-slate-600">IP address
|
||||
<input name="address" placeholder="auto"
|
||||
class="mt-1 w-full rounded-md border border-slate-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500">
|
||||
</label>
|
||||
<label class="block text-sm font-medium text-slate-600">DNS
|
||||
<input name="dns" placeholder="{{ settings.wg_dns }}"
|
||||
class="mt-1 w-full rounded-md border border-slate-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500">
|
||||
</label>
|
||||
<label class="block text-sm font-medium text-slate-600">Quota (GiB)
|
||||
<input name="quota_gib" type="number" step="0.1" min="0" placeholder="unlimited"
|
||||
class="mt-1 w-full rounded-md border border-slate-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500">
|
||||
</label>
|
||||
<label class="block text-sm font-medium text-slate-600">Count
|
||||
<input name="count" type="number" min="1" max="50" value="1"
|
||||
class="mt-1 w-full rounded-md border border-slate-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500">
|
||||
</label>
|
||||
<label class="block text-sm font-medium text-slate-600">Expires
|
||||
<input name="expires_at" type="datetime-local"
|
||||
class="mt-1 w-full rounded-md border border-slate-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500">
|
||||
</label>
|
||||
<div class="flex items-end">
|
||||
<button type="submit"
|
||||
class="w-full rounded-md bg-blue-600 px-4 py-2 text-sm font-semibold text-white hover:bg-blue-700">
|
||||
Add peer(s)
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<p class="mt-3 text-xs text-slate-400">
|
||||
Count > 1 creates a batch named name-1, name-2, ... (custom IP ignored). Empty quota = unlimited.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="overflow-hidden rounded-xl bg-white shadow-sm">
|
||||
<table class="w-full text-sm">
|
||||
<thead>
|
||||
<tr class="bg-slate-50 text-left text-xs uppercase tracking-wide text-slate-400">
|
||||
<th class="px-4 py-3 font-semibold">Name</th>
|
||||
<th class="px-4 py-3 font-semibold">Address</th>
|
||||
<th class="px-4 py-3 font-semibold">Enabled</th>
|
||||
<th class="px-4 py-3 font-semibold">Status</th>
|
||||
<th class="px-4 py-3 font-semibold">Usage</th>
|
||||
<th class="px-4 py-3 font-semibold">Note</th>
|
||||
<th class="px-4 py-3"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-100">
|
||||
{% for peer in peers %}
|
||||
{% set ps = status.peers.get(peer.public_key) %}
|
||||
<tr class="hover:bg-slate-50">
|
||||
<td class="px-4 py-3">
|
||||
<a href="/peers/{{ peer.id }}" class="font-medium text-blue-600 hover:underline">{{ peer.name }}</a>
|
||||
</td>
|
||||
<td class="px-4 py-3 font-mono text-xs">{{ peer.address }}</td>
|
||||
<td class="px-4 py-3">
|
||||
{% if peer.enabled %}
|
||||
<span class="rounded-full bg-emerald-100 px-2 py-0.5 text-xs font-medium text-emerald-700">enabled</span>
|
||||
{% elif peer.over_quota %}
|
||||
<span class="rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-700">over quota</span>
|
||||
{% else %}
|
||||
<span class="rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-700">disabled</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
{% if ps and ps.online %}
|
||||
<span class="rounded-full bg-emerald-100 px-2 py-0.5 text-xs font-medium text-emerald-700">online</span>
|
||||
{% else %}
|
||||
<span class="rounded-full bg-slate-100 px-2 py-0.5 text-xs font-medium text-slate-500">offline</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-slate-500">
|
||||
{{ peer.cum_total | fmt_bytes }}{% if peer.quota_bytes %} / {{ peer.quota_bytes | fmt_bytes }}{% endif %}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-slate-500">{{ peer.note }}</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<div class="flex justify-end gap-2">
|
||||
<form method="post" action="/peers/{{ peer.id }}/toggle">
|
||||
<button type="submit"
|
||||
class="rounded-md border border-slate-300 px-3 py-1 text-xs font-medium text-slate-600 hover:bg-slate-100">
|
||||
{{ "Disable" if peer.enabled else "Enable" }}
|
||||
</button>
|
||||
</form>
|
||||
<form method="post" action="/peers/{{ peer.id }}/delete"
|
||||
onsubmit="return confirm('Delete peer {{ peer.name }}?')">
|
||||
<button type="submit"
|
||||
class="rounded-md border border-red-200 px-3 py-1 text-xs font-medium text-red-600 hover:bg-red-50">
|
||||
Delete
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr><td colspan="7" class="px-4 py-6 text-center text-slate-400">No peers yet. Add one above.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user