style(ui): design polish + replace CUI badge with +RO/−RO

6 design review fixes: diff summary badge in modal header, PF indicator,
eFactura risk icon (octagon vs triangle for colorblind), aria labels,
extract .denom-mismatch CSS class, remove dead .addr-table CSS.

Replace vague "Corectat" badge with directional +RO (green, prefix added)
or −RO (orange, prefix removed). Kit items show "Kit" badge instead of
price match dot. Cache-bust shared.js v24, style.css v31.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-04-02 13:01:50 +00:00
parent ffd4cc0800
commit 84c38e3641
3 changed files with 72 additions and 35 deletions

View File

@@ -1229,26 +1229,21 @@ tr.mapping-deleted td {
flex-shrink: 0;
filter: drop-shadow(0 0 3px rgba(202,138,4,0.3));
}
.addr-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.addr-table th {
font-family: var(--font-display);
font-size: 12px;
font-weight: 500;
text-transform: uppercase;
color: var(--text-muted);
padding: 6px 8px;
text-align: left;
.addr-line .bi-exclamation-octagon {
color: var(--error-text);
flex-shrink: 0;
filter: drop-shadow(0 0 3px rgba(220,38,38,0.3));
}
.addr-table td { padding: 8px; vertical-align: top; font-family: var(--font-body); }
.addr-mismatch { background: var(--warning-light) !important; }
.addr-efactura-risk { background: var(--error-light) !important; }
.addr-label {
font-family: var(--font-display);
font-size: 11px;
/* Denomination mismatch alert */
.denom-mismatch {
background: var(--warning-light);
padding: 8px 12px;
border-radius: var(--card-radius);
}
.denom-mismatch-title {
font-size: 12px;
color: var(--warning-text);
font-weight: 500;
text-transform: uppercase;
color: var(--text-secondary);
margin-bottom: 4px;
}
/* Mobile address cards */
.addr-card { border: 1px solid var(--border); border-radius: var(--card-radius); margin-bottom: 8px; overflow: hidden; }

View File

@@ -517,15 +517,20 @@ async function renderOrderDetailModal(orderNumber, opts) {
if (priceCheckEl) priceCheckEl.innerHTML = '';
const reconEl = document.getElementById('detailInvoiceRecon');
if (reconEl) { reconEl.innerHTML = ''; reconEl.style.display = 'none'; }
// Remove diff badge from previous render
const prevDiffBadge = document.querySelector('.diff-badge');
if (prevDiffBadge) prevDiffBadge.remove();
// Reset compact header elements
const partenerRoa = document.getElementById('detailPartenerRoa');
if (partenerRoa) { partenerRoa.style.display = 'none'; partenerRoa.textContent = ''; }
const cuiGomag = document.getElementById('detailCuiGomag');
if (cuiGomag) cuiGomag.style.display = 'none';
const cuiRoa = document.getElementById('detailCuiRoa');
if (cuiRoa) cuiRoa.style.display = 'none';
const anafArea = document.getElementById('detailPartnerAnafArea');
if (anafArea) anafArea.innerHTML = '';
if (cuiRoa) {
cuiRoa.style.display = 'none';
// Restore original structure (may have been replaced by PF indicator)
cuiRoa.innerHTML = '<small class="text-muted">CUI:</small> <span class="font-data" id="detailCuiRoaVal"></span><span id="detailPartnerAnafArea"></span>';
}
const denomMismatch = document.getElementById('detailDenomMismatch');
if (denomMismatch) { denomMismatch.style.display = 'none'; denomMismatch.innerHTML = ''; }
const addressBlock = document.getElementById('detailAddressBlock');
@@ -693,7 +698,10 @@ async function renderOrderDetailModal(orderNumber, opts) {
const priceInfo = { pret_roa: item.pret_roa, match: item.price_match };
const pretRoaHtml = priceInfo.pret_roa != null ? fmtNum(priceInfo.pret_roa) : '';
let matchDot, rowStyle;
if (priceInfo.pret_roa == null && priceInfo.match == null) {
if (item.kit) {
matchDot = '<span class="badge" style="background:var(--info-light);color:var(--info-text);font-size:10px;padding:2px 6px">Kit</span>';
rowStyle = '';
} else if (priceInfo.pret_roa == null && priceInfo.match == null) {
matchDot = '<span class="dot dot-gray"></span>';
rowStyle = '';
} else if (priceInfo.match === false) {
@@ -895,10 +903,16 @@ function _renderHeaderInfo(order) {
document.getElementById('detailCuiRoaVal').textContent = pi.cod_fiscal_roa || '\u2014';
cuiRoaEl.style.display = '';
// CUI correction badge
// CUI correction badge: +RO (added prefix) or RO (removed prefix)
let cuiCorrHtml = '';
if (pi.anaf_cod_fiscal_adjusted) {
cuiCorrHtml = ' <span class="anaf-badge anaf-badge-warn"><i class="bi bi-arrow-left-right"></i> Corectat</span>';
if (pi.anaf_cod_fiscal_adjusted && pi.cod_fiscal_gomag && pi.cod_fiscal_roa) {
const gomagHasRO = /^RO\s*/i.test(pi.cod_fiscal_gomag);
const roaHasRO = /^RO\s*/i.test(pi.cod_fiscal_roa);
if (!gomagHasRO && roaHasRO) {
cuiCorrHtml = ' <span class="anaf-badge anaf-badge-ok" aria-label="Prefix RO adaugat conform ANAF"><i class="bi bi-plus-circle"></i> +RO</span>';
} else if (gomagHasRO && !roaHasRO) {
cuiCorrHtml = ' <span class="anaf-badge anaf-badge-warn" aria-label="Prefix RO eliminat conform ANAF"><i class="bi bi-dash-circle"></i> RO</span>';
}
}
// ANAF badge
@@ -906,15 +920,24 @@ function _renderHeaderInfo(order) {
if (anafArea) {
let anafBadge;
if (pi.anaf_platitor_tva === 1) {
anafBadge = '<span class="anaf-badge anaf-badge-ok">Platitor TVA</span>';
anafBadge = '<span class="anaf-badge anaf-badge-ok" aria-label="Platitor TVA">Platitor TVA</span>';
} else if (pi.anaf_platitor_tva === 0) {
anafBadge = '<span class="anaf-badge anaf-badge-warn">Neplatitor TVA</span>';
anafBadge = '<span class="anaf-badge anaf-badge-warn" aria-label="Neplatitor TVA">Neplatitor TVA</span>';
} else {
anafBadge = '<span class="anaf-badge anaf-badge-gray">?</span>';
anafBadge = '<span class="anaf-badge anaf-badge-gray" aria-label="Status TVA necunoscut">?</span>';
}
anafArea.innerHTML = cuiCorrHtml + ' ' + anafBadge;
}
}
} else {
// PF indicator — show muted text in CUI area
const cuiRoaEl = document.getElementById('detailCuiRoa');
if (cuiRoaEl) {
document.getElementById('detailCuiRoaVal').textContent = '';
document.getElementById('detailPartnerAnafArea').innerHTML = '';
cuiRoaEl.innerHTML = '<small class="text-muted" style="font-style:italic">Persoana fizica</small>';
cuiRoaEl.style.display = '';
}
}
// ERROR orders: muted dashes for ROA fields
@@ -927,8 +950,8 @@ function _renderHeaderInfo(order) {
if (isPJ && pi.anaf_denumire_mismatch && pi.denumire_anaf) {
const denomEl = document.getElementById('detailDenomMismatch');
if (denomEl) {
denomEl.innerHTML = `<div style="background:var(--warning-light);padding:8px 12px;border-radius:var(--card-radius)">
<span style="font-size:12px;color:var(--warning-text);font-weight:500"><i class="bi bi-exclamation-triangle"></i> Denumire diferita</span><br>
denomEl.innerHTML = `<div class="denom-mismatch">
<span class="denom-mismatch-title"><i class="bi bi-exclamation-triangle"></i> Denumire diferita</span><br>
<span style="font-size:13px">GoMag: <strong>${esc(order.customer_name || '')}</strong></span><br>
<span style="font-size:13px">ANAF: <strong>${esc(pi.denumire_anaf)}</strong></span>
</div>`;
@@ -952,11 +975,11 @@ function _renderHeaderInfo(order) {
const escaped = esc(text);
let icon = '';
if (matchIcon === 'match') {
icon = ' <i class="bi bi-check-lg addr-line-match" title="Adrese identice"></i>';
icon = ' <i class="bi bi-check-lg addr-line-match" title="Adrese identice" role="img" aria-label="Adrese identice"></i>';
} else if (matchIcon === 'mismatch') {
icon = ' <i class="bi bi-exclamation-triangle" title="Adrese diferite"></i>';
icon = ' <i class="bi bi-exclamation-triangle" title="Adrese diferite" role="img" aria-label="Adrese diferite"></i>';
} else if (matchIcon === 'risk') {
icon = ' <i class="bi bi-exclamation-triangle" title="Risc eFactura" style="color:var(--error-text)"></i>';
icon = ' <i class="bi bi-exclamation-octagon" title="Risc eFactura" role="img" aria-label="Risc eFactura" style="color:var(--error-text)"></i>';
}
return `<div class="addr-line">
<span class="addr-line-label">${label}</span>
@@ -989,4 +1012,23 @@ function _renderHeaderInfo(order) {
}
addressLines.innerHTML = html;
// Diff summary badge in modal header
let diffCount = 0;
if (isPJ && pi.anaf_denumire_mismatch) diffCount++;
if (order.price_check && order.price_check.mismatches > 0) diffCount += order.price_check.mismatches;
if (addr) {
if (addr.livrare_roa && !addrMatch(addr.livrare_gomag, addr.livrare_roa)) diffCount++;
if (addr.facturare_roa && !addrMatch(addr.facturare_gomag, addr.facturare_roa)) diffCount++;
}
const orderNumEl = document.getElementById('detailOrderNumber');
if (orderNumEl && diffCount > 0) {
const existing = orderNumEl.querySelector('.diff-badge');
if (existing) existing.remove();
const badge = document.createElement('span');
badge.className = 'diff-badge badge ms-2';
badge.style.cssText = 'background:var(--warning-light);color:var(--warning-text);font-size:11px;vertical-align:middle';
badge.textContent = diffCount + ' diferente';
orderNumEl.parentNode.insertBefore(badge, orderNumEl.nextSibling);
}
}

View File

@@ -19,7 +19,7 @@
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.2/font/bootstrap-icons.css" rel="stylesheet">
{% set rp = request.scope.get('root_path', '') %}
<link href="{{ rp }}/static/css/style.css?v=30" rel="stylesheet">
<link href="{{ rp }}/static/css/style.css?v=31" rel="stylesheet">
</head>
<body>
<!-- Top Navbar (hidden on mobile via CSS) -->
@@ -161,7 +161,7 @@
<script>window.ROOT_PATH = "{{ rp }}";</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="{{ rp }}/static/js/shared.js?v=22"></script>
<script src="{{ rp }}/static/js/shared.js?v=24"></script>
<script>
// Dark mode toggle
function toggleDarkMode() {