feat(release-notes): Add 'Notify' button for admins

- Admin can send notifications about any release to all users
- Button visible only for logged-in admins
- Extracts first 3 highlights from 'new' section
- Shows confirmation dialog before sending
- Visual feedback: disabled during send, green when done

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-01-27 14:26:51 +01:00
parent ce7c78bda9
commit 9f47d7b5c9

View File

@ -170,6 +170,33 @@
text-align: center;
}
.notify-btn {
background: var(--primary);
color: white;
border: none;
padding: 6px 12px;
border-radius: var(--radius);
font-size: var(--font-size-xs);
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 4px;
transition: background 0.2s;
}
.notify-btn:hover {
background: var(--primary-dark, #1a56db);
}
.notify-btn:disabled {
background: var(--text-secondary);
cursor: not-allowed;
}
.notify-btn.sent {
background: #16a34a;
}
.stat-item h3 {
font-size: var(--font-size-3xl);
font-weight: 700;
@ -233,7 +260,14 @@
{% endfor %}
</div>
</div>
<div class="release-date">{{ release.date }}</div>
<div style="display: flex; align-items: center; gap: 8px;">
<div class="release-date">{{ release.date }}</div>
{% if current_user.is_authenticated and current_user.is_admin %}
<button class="notify-btn" onclick="notifyRelease('{{ release.version }}', this)" title="Wyślij powiadomienia o tej wersji">
🔔 Powiadom
</button>
{% endif %}
</div>
</div>
<div class="release-changes">
@ -287,3 +321,53 @@
</div>
</div>
{% endblock %}
{% block extra_js %}
{% if current_user.is_authenticated and current_user.is_admin %}
function notifyRelease(version, btn) {
if (!confirm('Czy na pewno chcesz wysłać powiadomienia o wersji ' + version + ' do wszystkich użytkowników?')) {
return;
}
btn.disabled = true;
btn.innerHTML = '⏳ Wysyłanie...';
// Get first 3 highlights from the release card
const card = btn.closest('.release-card');
const highlights = [];
const items = card.querySelectorAll('.change-category.new .change-list li');
items.forEach((item, i) => {
if (i < 3) highlights.push(item.textContent.trim());
});
fetch('/admin/notify-release', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': '{{ csrf_token() }}'
},
body: JSON.stringify({
version: version,
highlights: highlights
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
btn.innerHTML = '✅ Wysłano';
btn.classList.add('sent');
alert(data.message);
} else {
btn.innerHTML = '❌ Błąd';
btn.disabled = false;
alert('Błąd: ' + data.error);
}
})
.catch(error => {
btn.innerHTML = '❌ Błąd';
btn.disabled = false;
alert('Błąd połączenia: ' + error);
});
}
{% endif %}
{% endblock %}