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:
+32
-28
@@ -28,12 +28,13 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% from "macros/icons.html" import icon %}
|
||||
<div class="toast-container" id="toastContainer"></div>
|
||||
|
||||
<div class="app-container">
|
||||
<header class="app-header">
|
||||
<a href="/" class="app-logo" style="text-decoration:none">
|
||||
<div class="logo-icon">{{ site_settings.logo }}</div>
|
||||
<div class="logo-icon">{% if site_settings.logo and site_settings.logo|length <= 3 and not site_settings.logo.startswith('<') %}{{ site_settings.logo }}{% else %}{{ icon('shield') }}{% endif %}</div>
|
||||
<div>
|
||||
<div class="logo-text">{{ site_settings.title }}</div>
|
||||
<div class="logo-subtitle">{{ site_settings.subtitle }}</div>
|
||||
@@ -43,24 +44,23 @@
|
||||
{% if current_user %}
|
||||
<nav class="header-nav">
|
||||
{% if current_user.role in ['admin', 'support'] %}
|
||||
<a href="/" class="nav-link">{{ _('nav_servers') }}</a>
|
||||
<a href="/users" class="nav-link">{{ _('nav_users') }}</a>
|
||||
<a href="/invites" class="nav-link">{{ _('nav_invites') }}</a>
|
||||
<a href="/" class="nav-link">{{ icon('server') }} {{ _('nav_servers') }}</a>
|
||||
<a href="/users" class="nav-link">{{ icon('users') }} {{ _('nav_users') }}</a>
|
||||
<a href="/invites" class="nav-link">{{ icon('link') }} {{ _('nav_invites') }}</a>
|
||||
{% endif %}
|
||||
{% if current_user.role == 'admin' %}
|
||||
<a href="/settings" class="nav-link">{{ _('nav_settings') }}</a>
|
||||
<a href="/settings" class="nav-link">{{ icon('settings') }} {{ _('nav_settings') }}</a>
|
||||
{% endif %}
|
||||
<a href="/my" class="nav-link">{{ _('nav_connections') }}</a>
|
||||
<a href="/my" class="nav-link">{{ icon('layers') }} {{ _('nav_connections') }}</a>
|
||||
</nav>
|
||||
|
||||
<div class="nav-user">
|
||||
<button class="theme-toggle" onclick="openModal('langModal')" title="{{ _('select_lang') }}"
|
||||
style="margin-right: var(--space-sm);">
|
||||
{% if lang == 'ru' %}🇷🇺{% elif lang == 'fr' %}🇫🇷{% elif lang == 'zh' %}🇨🇳{% elif lang == 'fa'
|
||||
%}🇮🇷{% else %}🇺🇸{% endif %}
|
||||
style="margin-right: var(--space-sm);" type="button">
|
||||
{{ icon('globe') }}
|
||||
</button>
|
||||
<button class="theme-toggle" onclick="toggleTheme()" title="{{ _('toggle_theme') }}"
|
||||
id="themeToggle">🌙</button>
|
||||
id="themeToggle" type="button">{{ icon('moon') }}</button>
|
||||
<span class="nav-username">{{ current_user.username }}</span>
|
||||
<span
|
||||
class="badge badge-{{ 'success' if current_user.role == 'admin' else ('info' if current_user.role == 'support' else 'warn') }}"
|
||||
@@ -72,12 +72,11 @@
|
||||
{% else %}
|
||||
<div class="nav-user">
|
||||
<button class="theme-toggle" onclick="openModal('langModal')" title="{{ _('select_lang') }}"
|
||||
style="margin-right: var(--space-sm);">
|
||||
{% if lang == 'ru' %}🇷🇺{% elif lang == 'fr' %}🇫🇷{% elif lang == 'zh' %}🇨🇳{% elif lang == 'fa'
|
||||
%}🇮🇷{% else %}🇺🇸{% endif %}
|
||||
style="margin-right: var(--space-sm);" type="button">
|
||||
{{ icon('globe') }}
|
||||
</button>
|
||||
<button class="theme-toggle" onclick="toggleTheme()" title="{{ _('toggle_theme') }}"
|
||||
id="themeToggle">🌙</button>
|
||||
id="themeToggle" type="button">{{ icon('moon') }}</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</header>
|
||||
@@ -96,19 +95,19 @@
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: var(--space-sm);">
|
||||
{% set langs = [
|
||||
('en', '🇺🇸', 'lang_en'),
|
||||
('ru', '🇷🇺', 'lang_ru'),
|
||||
('fr', '🇫🇷', 'lang_fr'),
|
||||
('zh', '🇨🇳', 'lang_zh'),
|
||||
('fa', '🇮🇷', 'lang_fa')
|
||||
('en', 'EN', 'lang_en'),
|
||||
('ru', 'RU', 'lang_ru'),
|
||||
('fr', 'FR', 'lang_fr'),
|
||||
('zh', 'ZH', 'lang_zh'),
|
||||
('fa', 'FA', 'lang_fa')
|
||||
] %}
|
||||
{% for l_code, l_flag, l_key in langs %}
|
||||
<a href="/set_lang/{{ l_code }}" class="btn btn-secondary"
|
||||
style="justify-content: flex-start; gap: var(--space-md); padding: var(--space-md);">
|
||||
<span style="font-size: 1.4rem;">{{ l_flag }}</span>
|
||||
<span class="lang-code">{{ l_flag }}</span>
|
||||
<span style="font-weight: 500;">{{ _(l_key) }}</span>
|
||||
{% if lang == l_code %}
|
||||
<span class="lang-check">✓</span>
|
||||
<span class="lang-check">{{ icon('check') }}</span>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% endfor %}
|
||||
@@ -120,6 +119,12 @@
|
||||
window.I18N = {{ translations_json | safe }};
|
||||
window._ = function (key) { return window.I18N[key] || key; };
|
||||
|
||||
/* ===== SVG icons (same sprite as templates) ===== */
|
||||
window.uiIcon = function (name, className) {
|
||||
const cls = className ? `ui-icon ${className}` : 'ui-icon';
|
||||
return `<svg class="${cls}" aria-hidden="true" focusable="false"><use href="/static/icons.svg#${name}"></use></svg>`;
|
||||
};
|
||||
|
||||
/* ===== Theme Toggle ===== */
|
||||
(function () {
|
||||
const saved = localStorage.getItem('theme') || 'dark';
|
||||
@@ -128,10 +133,9 @@
|
||||
const updateUI = () => {
|
||||
const isLight = document.documentElement.getAttribute('data-theme') === 'light';
|
||||
document.querySelectorAll('.theme-toggle').forEach(btn => {
|
||||
const isLang = btn.getAttribute('onclick').includes('langModal');
|
||||
if (!isLang) {
|
||||
btn.textContent = isLight ? '☀️' : '🌙';
|
||||
}
|
||||
const onclick = btn.getAttribute('onclick') || '';
|
||||
if (onclick.includes('langModal')) return;
|
||||
btn.innerHTML = uiIcon(isLight ? 'sun' : 'moon');
|
||||
});
|
||||
};
|
||||
|
||||
@@ -166,8 +170,8 @@
|
||||
const toast = document.createElement('div');
|
||||
toast.className = `toast toast-${type}`;
|
||||
|
||||
const icons = { success: '✓', error: '✕', info: 'ℹ' };
|
||||
toast.innerHTML = `<span>${icons[type] || 'ℹ'}</span> <span>${message}</span>`;
|
||||
const icons = { success: 'check', error: 'x', info: 'info' };
|
||||
toast.innerHTML = `${uiIcon(icons[type] || 'info')} <span>${message}</span>`;
|
||||
|
||||
container.appendChild(toast);
|
||||
setTimeout(() => {
|
||||
@@ -273,4 +277,4 @@
|
||||
{% block scripts %}{% endblock %}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user