Template
Replace emoji UI icons with a shared SVG icon system.
Add an icons sprite and helpers so nav, actions, and protocol cards use consistent stroke icons. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+15
-14
@@ -1,4 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "macros/icons.html" import icon %}
|
||||
|
||||
{% block title_extra %} — {{ _('users_title') }}{% endblock %}
|
||||
|
||||
@@ -7,19 +8,19 @@
|
||||
<div class="flex items-center justify-between"
|
||||
style="margin-bottom: var(--space-lg); gap: var(--space-md); flex-wrap: wrap;">
|
||||
<h1 class="section-title" style="margin-bottom:0; flex-shrink: 0;">
|
||||
<span class="icon">👥</span>
|
||||
<span class="icon">{{ icon('users') }}</span>
|
||||
{{ _('users_title') }}
|
||||
</h1>
|
||||
|
||||
<div style="flex: 1; min-width: 250px; max-width: 500px; position: relative;">
|
||||
<input type="text" class="form-input" id="userSearch" placeholder="{{ _('search_placeholder') }}"
|
||||
oninput="handleSearch(this.value)" style="padding-left: 40px;">
|
||||
<span style="position: absolute; left: 14px; top: 50%; transform: translateY(-50%); opacity: 0.5;">🔍</span>
|
||||
<span style="position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--text-muted); display:flex;">{{ icon('search') }}</span>
|
||||
</div>
|
||||
|
||||
{% if current_user.role == 'admin' %}
|
||||
<button class="btn btn-primary" onclick="openModal('addUserModal')" style="flex-shrink: 0;">
|
||||
<span>+</span> {{ _('add_user') }}
|
||||
{{ icon('plus') }} {{ _('add_user') }}
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -45,7 +46,7 @@
|
||||
</div>
|
||||
|
||||
<div id="usersEmpty" class="empty-state hidden">
|
||||
<div class="empty-icon">👤</div>
|
||||
<div class="empty-icon">{{ icon('user') }}</div>
|
||||
<div class="empty-title">{{ _('nothing_found') }}</div>
|
||||
<div class="empty-desc">{{ _('search_empty_desc') }}</div>
|
||||
</div>
|
||||
@@ -496,7 +497,7 @@
|
||||
${u.enabled ? '' : `<span class="badge badge-danger" style="font-size:0.65rem;">${_('disabled')}</span>`}
|
||||
</div>
|
||||
<div class="client-meta">
|
||||
<span style="cursor:pointer; color:var(--primary); text-decoration: underline;" onclick="viewUserConnections('${u.id}', '${u.username.replace(/'/g, "\\'")}')">🔗 ${u.connections_count} ${_('connections')}</span>
|
||||
<span style="cursor:pointer; color:var(--primary); text-decoration: underline; display:inline-flex; align-items:center; gap:4px;" onclick="viewUserConnections('${u.id}', '${u.username.replace(/'/g, "\\'")}')">${uiIcon('link')} ${u.connections_count} ${_('connections')}</span>
|
||||
${u.created_at ? `<span>📅 ${u.created_at.substring(0, 10)}</span>` : ''}
|
||||
${u.telegramId ? `<span>💬 ${u.telegramId}</span>` : ''}
|
||||
${u.email ? `<span>📧 ${u.email}</span>` : ''}
|
||||
@@ -542,22 +543,22 @@
|
||||
{% if current_user.role == 'admin' %}
|
||||
<button class="btn btn-secondary btn-sm btn-icon"
|
||||
onclick="openAddConnectionForUser('${u.id}', '${u.username}')"
|
||||
title="${_('add_connection')}">🔗</button>
|
||||
title="${_('add_connection')}">${uiIcon('link')}</button>
|
||||
<button class="btn btn-secondary btn-sm btn-icon"
|
||||
onclick='openEditUser({"id": "${u.id}", "username": "${u.username}", "tg": "${u.telegramId || ""}", "email": "${u.email || ""}", "desc": "${u.description || ""}", "limit": "${u.traffic_limit ? (u.traffic_limit / Math.pow(1024, 3)).toFixed(2) : 0}", "strategy": "${u.traffic_reset_strategy || 'never'}", "expiration": "${u.expiration_date || ''}"})'
|
||||
title="${_('edit')}">✏️</button>
|
||||
title="${_('edit')}">${uiIcon('pencil')}</button>
|
||||
<button class="btn btn-secondary btn-sm btn-icon" onclick="openShareModal(this.dataset)"
|
||||
data-id="${u.id}" data-username="${u.username}" data-token="${u.share_token || ''}"
|
||||
data-enabled="${u.share_enabled ? 'true' : 'false'}"
|
||||
data-haspassword="${u.has_share_password ? 'true' : 'false'}"
|
||||
title="${_('share_access')}">📤</button>
|
||||
title="${_('share_access')}">${uiIcon('share')}</button>
|
||||
${u.id !== "{{ current_user.id }}" ? `
|
||||
<button class="btn btn-secondary btn-sm btn-icon" onclick="toggleUser(this.dataset)"
|
||||
data-id="${u.id}" data-enable="${u.enabled ? 'false' : 'true'}"
|
||||
title="${u.enabled ? _('stop_btn') : _('start_btn')}">
|
||||
${u.enabled ? '🔵' : '⚫'}
|
||||
${u.enabled ? uiIcon('pause') : uiIcon('play')}
|
||||
</button>
|
||||
<button class="btn btn-danger btn-sm btn-icon" onclick="deleteUser('${u.id}')" title="${_('delete')}">🗑</button>
|
||||
<button class="btn btn-danger btn-sm btn-icon" onclick="deleteUser('${u.id}')" title="${_('delete')}">${uiIcon('trash')}</button>
|
||||
` : ''}
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -860,17 +861,17 @@
|
||||
listEl.innerHTML += `
|
||||
<div class="client-item">
|
||||
<div class="client-info">
|
||||
<div class="client-avatar">🔗</div>
|
||||
<div class="client-avatar">${uiIcon('link')}</div>
|
||||
<div>
|
||||
<div class="client-name">${c.name || 'Connection'}</div>
|
||||
<div class="client-meta">
|
||||
<span>🖥 ${c.server_name || ''}</span>
|
||||
<span style="display:inline-flex;align-items:center;gap:4px;">${uiIcon('server')} ${c.server_name || ''}</span>
|
||||
<span>${c.protocol === 'awg' ? 'AmneziaWG' : (c.protocol === 'awg2' ? 'AmneziaWG 2.0' : (c.protocol === 'awg_legacy' ? 'AWG Legacy' : (c.protocol === 'xray' ? 'Xray' : c.protocol.toUpperCase())))}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="client-actions">
|
||||
<button class="btn btn-secondary btn-sm btn-icon" onclick="showUserConnectionConfig(${c.server_id}, '${c.client_id}', '${c.protocol}', '${(c.name || 'VPN').replace(/'/g, "\\'")}')" title="${_('config')}">📄</button>
|
||||
<button class="btn btn-secondary btn-sm btn-icon" onclick="showUserConnectionConfig(${c.server_id}, '${c.client_id}', '${c.protocol}', '${(c.name || 'VPN').replace(/'/g, "\\'")}')" title="${_('config')}">${uiIcon('file')}</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -949,7 +950,7 @@
|
||||
<div class="flex gap-sm">
|
||||
<input class="form-input" type="text" id="shareLink" readonly
|
||||
style="background: var(--bg-primary);">
|
||||
<button class="btn btn-secondary" onclick="copyShareLink()">📋</button>
|
||||
<button class="btn btn-secondary btn-icon" onclick="copyShareLink()" title="{{ _('copy') }}">{{ icon('copy') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user