improve: v3 email template + horizontal action buttons grid in /admin/users
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions

Email: dark header with compass, company card, green checkmarks, Polish
date format, full footer with address, phone and tech support contact.
Actions: 4-column grid layout instead of vertical stack.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-02-21 18:11:04 +01:00
parent 9ff07ae57a
commit 40ee5db139
2 changed files with 97 additions and 53 deletions

View File

@ -452,48 +452,63 @@ COMPANY_ROLE_LABELS = {
COMPANY_ROLE_PERMISSIONS = {
'MANAGER': [
('Edycja profilu firmy', 'Pełna kontrola nad wszystkimi danymi firmy'),
('Zarządzanie kontaktami', 'Dodawanie, edycja i usuwanie danych kontaktowych'),
('Media społecznościowe', 'Zarządzanie profilami i publikacjami'),
('Statystyki i analityka', 'Dostęp do wszystkich raportów i statystyk'),
('Zarządzanie zespołem', 'Zapraszanie i zarządzanie uprawnieniami pracowników'),
('Edycja danych kontaktowych', 'adres, telefon, email, strona www'),
('Profile społecznościowe', 'Facebook, Instagram, LinkedIn i inne'),
('Statystyki i analityka', 'odwiedziny profilu, popularność, trendy'),
('Zarządzanie zespołem', 'zapraszanie pracowników, uprawnienia'),
],
'EMPLOYEE': [
('Edycja profilu firmy', 'Aktualizacja podstawowych informacji o firmie'),
('Zarządzanie kontaktami', 'Edycja danych kontaktowych firmy'),
('Edycja danych kontaktowych', 'adres, telefon, email, strona www'),
],
'VIEWER': [
('Podgląd profilu', 'Przeglądanie danych firmy bez możliwości edycji'),
('Podgląd profilu firmy', 'przeglądanie informacji o firmie'),
],
}
POLISH_MONTHS_GENITIVE = [
'', 'stycznia', 'lutego', 'marca', 'kwietnia', 'maja', 'czerwca',
'lipca', 'sierpnia', 'września', 'października', 'listopada', 'grudnia'
]
def _build_role_notification_html(user_name, company_name, company_slug, company_role, sender_name, sent_at):
"""Build HTML email for role/permission change notification."""
"""Build HTML email for role/permission change notification (v3 design)."""
role_label = COMPANY_ROLE_LABELS.get(company_role, company_role)
permissions = COMPANY_ROLE_PERMISSIONS.get(company_role, [])
# Green circle checkmark icon (inline SVG as data URI for email compatibility)
check_icon = (
'<td width="32" valign="top" style="padding-right:12px;">'
'<div style="width:28px; height:28px; background:#16a34a; border-radius:50%; text-align:center; line-height:28px;">'
'<span style="color:#ffffff; font-size:16px; font-weight:bold;">&#10003;</span>'
'</div></td>'
)
permissions_html = ''
for title, desc in permissions:
permissions_html += f'''
<tr>
<td style="padding: 10px 16px; border-bottom: 1px solid #e2e8f0;">
<span style="color: #16a34a; font-weight: bold; margin-right: 6px;">&#10003;</span>
<strong style="color: #1e293b;">{title}</strong>
<br><span style="color: #64748b; font-size: 13px;">{desc}</span>
</td>
</tr>'''
<tr>
<td style="padding: 12px 16px; border-bottom: 1px solid #e2e8f0;">
<table cellpadding="0" cellspacing="0"><tr>
{check_icon}
<td valign="top">
<strong style="color:#1e293b; font-size:15px;">{title}</strong>
<br><span style="color:#2563eb; font-size:13px;">{desc}</span>
</td>
</tr></table>
</td>
</tr>'''
if not permissions_html:
permissions_html = '''
<tr>
<td style="padding: 10px 16px; color: #64748b;">
Brak aktywnych uprawnień dla tej roli.
</td>
</tr>'''
<tr>
<td style="padding: 12px 16px; color: #64748b;">
Brak aktywnych uprawnień dla tej roli.
</td>
</tr>'''
company_url = f'https://nordabiznes.pl/company/{company_slug}'
date_str = sent_at.strftime('%d.%m.%Y, %H:%M')
date_str = f'{sent_at.day} {POLISH_MONTHS_GENITIVE[sent_at.month]} {sent_at.year}, godz. {sent_at.strftime("%H:%M")}'
return f'''<!DOCTYPE html>
<html lang="pl">
@ -504,61 +519,90 @@ def _build_role_notification_html(user_name, company_name, company_slug, company
<table width="600" cellpadding="0" cellspacing="0" style="background:#ffffff; border-radius:12px; overflow:hidden; box-shadow: 0 4px 24px rgba(0,0,0,0.08);">
<!-- Header -->
<tr><td style="background: linear-gradient(135deg, #1e40af, #172554); padding: 32px; text-align: center;">
<img src="https://nordabiznes.pl/static/images/logo-circle.png" width="56" height="56" alt="Norda Biznes" style="border-radius:50%; margin-bottom:12px;">
<h1 style="margin:0; color:#ffffff; font-size:22px; font-weight:700;">Zmiana uprawnień</h1>
<p style="margin:6px 0 0; color:#93c5fd; font-size:14px;">Norda Biznes Partner</p>
<tr><td style="background: linear-gradient(135deg, #1e40af, #172554); padding: 36px 32px; text-align: center;">
<img src="https://nordabiznes.pl/static/images/logo-circle.png" width="64" height="64" alt="NB" style="border-radius:50%; margin-bottom:16px; border: 2px solid rgba(255,255,255,0.3);">
<h1 style="margin:0; color:#ffffff; font-size:24px; font-weight:700;">Zmiana uprawnień</h1>
<p style="margin:8px 0 0; color:#93c5fd; font-size:14px;">Norda Biznes Partner</p>
</td></tr>
<!-- Body -->
<tr><td style="padding: 32px;">
<p style="margin:0 0 20px; color:#1e293b; font-size:16px;">Witaj <strong>{user_name}</strong>,</p>
<p style="margin:0 0 24px; color:#475569; font-size:15px;">Twoje uprawnienia w portalu Norda Biznes Partner zostały zaktualizowane.</p>
<p style="margin:0 0 16px; color:#1e293b; font-size:16px;">Witaj <strong>{user_name}</strong>,</p>
<p style="margin:0 0 28px; color:#475569; font-size:15px; line-height:1.5;">Twoje uprawnienia w portalu zostały zmienione. Poniżej znajdziesz podsumowanie.</p>
<!-- Company card -->
<table width="100%" cellpadding="0" cellspacing="0" style="background:#f8fafc; border-radius:8px; border: 1px solid #e2e8f0; margin-bottom:24px;">
<tr><td style="padding: 20px;">
<p style="margin:0 0 4px; color:#64748b; font-size:13px; text-transform:uppercase; letter-spacing:0.5px;">Firma</p>
<p style="margin:0 0 12px; color:#1e293b; font-size:18px; font-weight:600;">{company_name}</p>
<table cellpadding="0" cellspacing="0"><tr>
<td style="background:#16a34a; color:#ffffff; padding:6px 14px; border-radius:6px; font-size:14px; font-weight:600;">{role_label}</td>
<!-- Company card with dark header -->
<table width="100%" cellpadding="0" cellspacing="0" style="border-radius:10px; overflow:hidden; border: 1px solid #e2e8f0; margin-bottom:28px;">
<tr><td style="background: linear-gradient(135deg, #1e3a8a, #172554); padding: 16px 20px;">
<p style="margin:0 0 2px; color:#93c5fd; font-size:12px; text-transform:uppercase; letter-spacing:1px;">Firma</p>
<p style="margin:0; color:#ffffff; font-size:18px; font-weight:700;">{company_name}</p>
</td></tr>
<tr><td style="background:#ffffff; padding: 20px; text-align:center;">
<p style="margin:0 0 8px; color:#64748b; font-size:12px; text-transform:uppercase; letter-spacing:0.5px;">Aktualna rola</p>
<table cellpadding="0" cellspacing="0" style="margin:0 auto;"><tr>
<td style="background:#16a34a; color:#ffffff; padding:8px 20px; border-radius:20px; font-size:15px; font-weight:600;">{role_label}</td>
</tr></table>
</td></tr>
</table>
<!-- Permissions -->
<p style="margin:0 0 12px; color:#1e293b; font-size:15px; font-weight:600;">Twoje uprawnienia:</p>
<table width="100%" cellpadding="0" cellspacing="0" style="background:#f0fdf4; border-radius:8px; border: 1px solid #bbf7d0; margin-bottom:24px;">
<p style="margin:0 0 14px; color:#1e293b; font-size:16px; font-weight:600;">Co możesz teraz robić:</p>
<table width="100%" cellpadding="0" cellspacing="0" style="background:#f8fdf8; border-radius:10px; border: 1px solid #d1fae5; margin-bottom:28px;">
{permissions_html}
</table>
<!-- CTA -->
<table width="100%" cellpadding="0" cellspacing="0" style="margin-bottom:24px;">
<table width="100%" cellpadding="0" cellspacing="0" style="margin-bottom:28px;">
<tr><td align="center" style="padding: 8px 0;">
<a href="{company_url}" style="display:inline-block; padding:14px 32px; background:linear-gradient(135deg, #2563eb, #1e40af); color:#ffffff; text-decoration:none; border-radius:8px; font-size:15px; font-weight:600;">Przejdź do profilu firmy</a>
<a href="{company_url}" style="display:inline-block; padding:16px 40px; background: linear-gradient(135deg, #1e3a8a, #172554); color:#ffffff; text-decoration:none; border-radius:8px; font-size:15px; font-weight:600;">Zobacz profil firmy &rarr;</a>
</td></tr>
<tr><td align="center" style="padding: 4px 0;">
<a href="https://nordabiznes.pl/" style="color:#2563eb; font-size:14px; text-decoration:none;">lub otwórz stronę główną</a>
<tr><td align="center" style="padding: 8px 0;">
<a href="https://nordabiznes.pl/" style="color:#2563eb; font-size:14px; text-decoration:none;">lub przejdź do panelu</a>
</td></tr>
</table>
<!-- Info box -->
<table width="100%" cellpadding="0" cellspacing="0" style="background:#eff6ff; border-radius:8px; border: 1px solid #bfdbfe; margin-bottom:16px;">
<!-- Metadata -->
<table width="100%" cellpadding="0" cellspacing="0" style="margin-bottom:20px; border-top: 1px solid #e2e8f0; padding-top:16px;">
<tr>
<td style="padding-top:12px;" width="50%" valign="top">
<p style="margin:0 0 2px; color:#94a3b8; font-size:12px;">Data zmiany:</p>
<p style="margin:0; color:#64748b; font-size:13px;">{date_str}</p>
</td>
<td style="padding-top:12px;" width="50%" valign="top" align="right">
<p style="margin:0 0 2px; color:#94a3b8; font-size:12px;">Zmienił/a:</p>
<p style="margin:0; color:#64748b; font-size:13px;">{sender_name} (Administrator)</p>
</td>
</tr>
</table>
<!-- Contact box -->
<table width="100%" cellpadding="0" cellspacing="0" style="background:#eff6ff; border-radius:8px; border: 1px solid #bfdbfe;">
<tr><td style="padding: 16px;">
<p style="margin:0; color:#1e40af; font-size:14px;">
<strong>Masz pytania?</strong> Skontaktuj się z administratorem portalu lub napisz na
<p style="margin:0 0 6px; color:#1e40af; font-size:14px;">
<strong>Masz pytania?</strong> Skontaktuj się z biurem Izby:
</p>
<p style="margin:0 0 4px; color:#1e40af; font-size:14px;">
<a href="mailto:biuro@norda-biznes.info" style="color:#2563eb;">biuro@norda-biznes.info</a>
&nbsp;&middot;&nbsp;
<a href="tel:+48729716400" style="color:#2563eb;">+48 729 716 400</a>
</p>
<p style="margin:0; color:#64748b; font-size:13px;">
W sprawach technicznych: <a href="mailto:maciej.pienczyn@inpi.pl" style="color:#2563eb;">maciej.pienczyn@inpi.pl</a>
</p>
</td></tr>
</table>
<p style="margin:0; color:#94a3b8; font-size:12px;">Zmiana wykonana przez: {sender_name} &middot; {date_str}</p>
</td></tr>
<!-- Footer -->
<tr><td style="background:#f8fafc; padding: 20px; text-align:center; border-top: 1px solid #e2e8f0;">
<p style="margin:0; color:#64748b; font-size:13px;"><strong>Norda Biznes Partner</strong></p>
<p style="margin:4px 0 0; color:#94a3b8; font-size:12px;">Platforma Regionalnej Izby Przedsiębiorców &middot; <a href="https://nordabiznes.pl" style="color:#2563eb; text-decoration:none;">nordabiznes.pl</a></p>
<tr><td style="background:#f8fafc; padding: 24px; text-align:center; border-top: 1px solid #e2e8f0;">
<p style="margin:0 0 4px; color:#1e293b; font-size:14px; font-weight:600;">Norda Biznes Partner</p>
<p style="margin:0 0 2px; color:#94a3b8; font-size:12px;">Stowarzyszenie Norda Biznes</p>
<p style="margin:0 0 12px; color:#94a3b8; font-size:12px;">ul. 12 Marca 238/5, 84-200 Wejherowo</p>
<p style="margin:0 0 12px; color:#94a3b8; font-size:13px;">
<a href="https://nordabiznes.pl" style="color:#2563eb; text-decoration:none;">nordabiznes.pl</a>
&nbsp;|&nbsp;
<a href="https://www.facebook.com/nordabiznes" style="color:#2563eb; text-decoration:none;">Facebook</a>
</p>
<p style="margin:0; color:#cbd5e1; font-size:11px;">To powiadomienie zostało wysłane automatycznie.</p>
</td></tr>
</table>

View File

@ -220,9 +220,9 @@
}
.action-buttons {
display: flex;
gap: var(--spacing-xs);
flex-wrap: wrap;
display: grid;
grid-template-columns: repeat(4, 32px);
gap: 4px;
}
.btn-icon {