feat(ui): улучшения UX для промокодов и форм заказа
- Добавлена кнопка копирования промокода в клипборд с визуальной обратной связью - Улучшено отображение ошибок валидации в форме заказа (is-invalid класс) - Добавлен флаг _draftFieldsFilled для корректной обработки пустого черновика - Убран value="1" для quantity чтобы избежать конфликтов с draft-data Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -76,7 +76,14 @@
|
||||
{% for promo in promocodes %}
|
||||
<tr>
|
||||
<td>
|
||||
<code class="fs-5">{{ promo.code }}</code>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<code class="fs-5 promo-code-text">{{ promo.code }}</code>
|
||||
<button class="btn btn-sm btn-outline-secondary btn-copy-promo"
|
||||
data-code="{{ promo.code }}"
|
||||
title="Скопировать">
|
||||
<i class="bi bi-copy"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{% url 'system_settings:discounts:update' promo.discount.id %}" class="text-decoration-none">
|
||||
@@ -199,4 +206,50 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const copyButtons = document.querySelectorAll('.btn-copy-promo');
|
||||
|
||||
copyButtons.forEach(button => {
|
||||
button.addEventListener('click', async function() {
|
||||
const code = this.getAttribute('data-code');
|
||||
const icon = this.querySelector('i');
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(code);
|
||||
// Визуальная обратная связь - зелёная галочка на белом
|
||||
icon.className = 'bi bi-check2 text-success';
|
||||
this.classList.remove('btn-outline-secondary');
|
||||
this.classList.add('btn-light', 'border-success');
|
||||
|
||||
setTimeout(() => {
|
||||
icon.className = 'bi bi-copy';
|
||||
this.classList.remove('btn-light', 'border-success');
|
||||
this.classList.add('btn-outline-secondary');
|
||||
}, 1500);
|
||||
} catch (err) {
|
||||
// Fallback для старых браузеров
|
||||
const textArea = document.createElement('textarea');
|
||||
textArea.value = code;
|
||||
textArea.style.position = 'fixed';
|
||||
textArea.style.left = '-9999px';
|
||||
document.body.appendChild(textArea);
|
||||
textArea.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(textArea);
|
||||
|
||||
icon.className = 'bi bi-check2 text-success';
|
||||
this.classList.remove('btn-outline-secondary');
|
||||
this.classList.add('btn-light', 'border-success');
|
||||
setTimeout(() => {
|
||||
icon.className = 'bi bi-copy';
|
||||
this.classList.remove('btn-light', 'border-success');
|
||||
this.classList.add('btn-outline-secondary');
|
||||
}, 1500);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user