feat: service credentials (login/password) on dashboard cards with copy button
This commit is contained in:
@@ -77,23 +77,43 @@
|
||||
<section class="grid service-grid">
|
||||
{% for service in services %}
|
||||
{% set svc_cats = service_categories.get(service.id, []) %}
|
||||
<a class="tile" href="/go/{{ service.slug }}">
|
||||
<div class="tile-icon-box">
|
||||
<img class="tile-icon" src="{{ service.icon_path or '/static/service-placeholder.svg' }}" alt="icon" />
|
||||
</div>
|
||||
<h3>{{ service.name }}</h3>
|
||||
<p>Открыть сервис</p>
|
||||
{% if service.comment %}
|
||||
<small class="tile-comment">{{ service_comment_html.get(service.id, '') }}</small>
|
||||
{% endif %}
|
||||
{% if svc_cats %}
|
||||
<div class="service-categories">
|
||||
{% for category in svc_cats %}
|
||||
<span class="service-cat-badge">{{ category.name }}</span>
|
||||
{% endfor %}
|
||||
<div class="tile-wrap">
|
||||
<a class="tile" href="/go/{{ service.slug }}">
|
||||
<div class="tile-icon-box">
|
||||
<img class="tile-icon" src="{{ service.icon_path or '/static/service-placeholder.svg' }}" alt="icon" />
|
||||
</div>
|
||||
<h3>{{ service.name }}</h3>
|
||||
<p>Открыть сервис</p>
|
||||
{% if service.comment %}
|
||||
<small class="tile-comment">{{ service_comment_html.get(service.id, '') }}</small>
|
||||
{% endif %}
|
||||
{% if svc_cats %}
|
||||
<div class="service-categories">
|
||||
{% for category in svc_cats %}
|
||||
<span class="service-cat-badge">{{ category.name }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% if service.svc_login or service.svc_password %}
|
||||
<div class="svc-credentials">
|
||||
{% if service.svc_login %}
|
||||
<div class="svc-cred-row">
|
||||
<span class="svc-cred-label">Логин</span>
|
||||
<span class="svc-cred-value">{{ service.svc_login }}</span>
|
||||
<button class="svc-cred-copy" type="button" data-copy="{{ service.svc_login }}" title="Копировать логин"></button>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if service.svc_password %}
|
||||
<div class="svc-cred-row">
|
||||
<span class="svc-cred-label">Пароль</span>
|
||||
<span class="svc-cred-value svc-cred-masked">{{ service.svc_password }}</span>
|
||||
<button class="svc-cred-copy" type="button" data-copy="{{ service.svc_password }}" title="Копировать пароль"></button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="tile">
|
||||
{% if selected_category_slug %}
|
||||
@@ -194,5 +214,21 @@
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
document.querySelectorAll('.svc-cred-copy').forEach(btn => {
|
||||
btn.addEventListener('click', async (e) => {
|
||||
e.preventDefault(); e.stopPropagation();
|
||||
const text = btn.dataset.copy;
|
||||
try { await navigator.clipboard.writeText(text); } catch(_) {
|
||||
const ta = document.createElement('textarea');
|
||||
ta.value = text; ta.style.position='fixed'; ta.style.opacity='0';
|
||||
document.body.appendChild(ta); ta.select();
|
||||
document.execCommand('copy'); document.body.removeChild(ta);
|
||||
}
|
||||
btn.classList.add('copied');
|
||||
setTimeout(() => btn.classList.remove('copied'), 1500);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user