fix: verification bar white text, pricing removes unverified fallback

- 100% VERIFIED bar: checkmarks now rgba(255,255,255,0.92) instead of #2d6a4f (was invisible on green bg)
- Pricing: only show prices with real URL; no MSRP/estimated fallback
- Verified badge only if observed within 7 days; older prices shown without badge
This commit is contained in:
Rene Fichtmueller 2026-04-01 21:04:42 +02:00
parent f91d2a15b9
commit c23b9f68ce

View File

@ -1866,20 +1866,24 @@ async function openTxDetail(id) {
if (iVer) verItems.push('<span style="color:#2d6a4f;font-size:0.75rem;font-weight:600">✓ Image</span>');
if (dVer) verItems.push('<span style="color:#2d6a4f;font-size:0.75rem;font-weight:600">✓ Details</span>');
if (fVer) {
h += '<div style="display:flex;align-items:center;gap:0.6rem;flex-wrap:wrap;margin:0.8rem 0;padding:0.5rem 0.75rem;background:linear-gradient(135deg,#1b4332,#2d6a4f);border-radius:8px">'
+ '<span style="color:#fff;font-size:0.8rem;font-weight:700;letter-spacing:0.03em">★ 100% VERIFIED</span>'
+ '<span style="color:rgba(255,255,255,0.6);font-size:0.7rem"></span>'
+ verItems.join('<span style="color:rgba(255,255,255,0.4);font-size:0.7rem">·</span>')
+ (t.fully_verified_at ? '<span style="color:rgba(255,255,255,0.5);font-size:0.68rem;margin-left:auto">seit ' + fmtDate(t.fully_verified_at) + '</span>' : '')
// Inside the green bar: all text must be white/light — not #2d6a4f (same as bg)
var fvItems = [];
if (pVer) fvItems.push('<span style="color:rgba(255,255,255,0.92);font-size:0.75rem;font-weight:600">✓ Price</span>');
if (iVer) fvItems.push('<span style="color:rgba(255,255,255,0.92);font-size:0.75rem;font-weight:600">✓ Image</span>');
if (dVer) fvItems.push('<span style="color:rgba(255,255,255,0.92);font-size:0.75rem;font-weight:600">✓ Details</span>');
h += '<div style="display:flex;align-items:center;gap:0.6rem;flex-wrap:wrap;margin:0.8rem 0;padding:0.55rem 0.85rem;background:linear-gradient(135deg,#1b4332,#2d6a4f);border-radius:8px">'
+ '<span style="color:#fff;font-size:0.82rem;font-weight:700;letter-spacing:0.04em">★ 100% VERIFIED</span>'
+ '<span style="color:rgba(255,255,255,0.4);font-size:0.7rem"></span>'
+ fvItems.join('<span style="color:rgba(255,255,255,0.3);font-size:0.7rem;margin:0 0.1rem">·</span>')
+ (t.fully_verified_at ? '<span style="color:rgba(255,255,255,0.55);font-size:0.68rem;margin-left:auto">seit ' + fmtDate(t.fully_verified_at) + '</span>' : '')
+ '</div>';
} else if (verItems.length > 0) {
// Partial verification on white background: dark green is fine here
h += '<div style="display:flex;align-items:center;gap:0.5rem;flex-wrap:wrap;margin:0.6rem 0;padding:0.4rem 0.6rem;background:rgba(45,106,79,0.08);border:1px solid rgba(45,106,79,0.2);border-radius:6px">'
+ verItems.join('<span style="color:#aaa;font-size:0.7rem">·</span>')
+ '</div>';
} else {
// No verification data yet — show neutral indicator
h += '<div style="font-size:0.72rem;color:#aaa;margin:0.4rem 0;padding:0.3rem 0.5rem;border-left:2px solid #ddd">Data not yet verified from official sources</div>';
}
// No verification → no badge. Never show unverified data as verified.
// Helper: render a spec section as a clean table (like Flexoptix spec tables)
function renderSpecTable(title, rows) {
@ -1948,30 +1952,27 @@ async function openTxDetail(id) {
['Year Mainstream', t.year_mainstream],
]);
// SPECIFICATION — Pricing (verified prices from DB)
var prices = t.competitor_prices || [];
// SPECIFICATION — Pricing
// Rule: Only show prices that were scraped from a real URL within the last 30 days.
// Unverified / estimated prices are NOT shown — silence is better than wrong data.
var prices = (t.competitor_prices || []).filter(function(p) { return p.url && p.price > 0; });
if (prices.length > 0) {
h += '<div class="panel-section">Current Prices</div>';
h += '<div class="spec-table">';
prices.forEach(function(p) {
var verBadge = p.is_verified
? '<span style="color:#2d6a4f;font-size:0.7rem;font-weight:600;margin-left:0.4rem">✓ Verified</span>'
: '<span style="color:#888;font-size:0.7rem;margin-left:0.4rem">unverified</span>';
var priceStr = p.currency + ' ' + parseFloat(p.price).toLocaleString('de-DE', {minimumFractionDigits:2,maximumFractionDigits:2});
var dateStr = '<span style="color:#aaa;font-size:0.68rem;margin-left:0.4rem">' + fmtDate(p.observed_at) + '</span>';
var urlLink = p.url ? ' <a href="' + esc(p.url) + '" target="_blank" rel="noopener" style="color:var(--accent);font-size:0.7rem;text-decoration:none;margin-left:0.3rem"></a>' : '';
// Verified badge only if observed within 7 days AND has a real URL
var verBadge = p.is_verified === true
? '<span style="color:#2d6a4f;font-size:0.7rem;font-weight:600;margin-left:0.5rem" title="Price scraped from official vendor page within the last 7 days">✓ Verified Price</span>'
: ''; // No badge for older observations — not wrong, just not shown as verified
var priceStr = '<strong>' + p.currency + '\u00a0' + parseFloat(p.price).toLocaleString('de-DE', {minimumFractionDigits:2,maximumFractionDigits:2}) + '</strong>';
var dateStr = '<span style="color:#aaa;font-size:0.68rem;margin-left:0.5rem">Stand: ' + fmtDate(p.observed_at) + '</span>';
var urlLink = '<a href="' + esc(p.url) + '" target="_blank" rel="noopener" style="color:var(--accent);font-size:0.7rem;text-decoration:none;margin-left:0.5rem" title="Direkt zur Quelle">↗ Quelle</a>';
h += '<div class="spec-row"><span class="spec-label">' + esc(p.vendor_name) + '</span>'
+ '<span class="spec-val">' + priceStr + verBadge + dateStr + urlLink + '</span></div>';
+ '<span class="spec-val" style="display:flex;align-items:center;flex-wrap:wrap;gap:0">' + priceStr + verBadge + dateStr + urlLink + '</span></div>';
});
h += '</div>';
} else {
// Fallback: show MSRP/street from transceivers table if no price_observations
h += renderSpecTable('Pricing', [
['MSRP', t.msrp_usd ? '$' + parseFloat(t.msrp_usd).toLocaleString() : null],
['Street Price', t.street_price_usd ? '$' + parseFloat(t.street_price_usd).toLocaleString() : null],
['Price Tier', t.price_tier],
]);
}
// No price_observations → show nothing. Never display estimated or unverifiable prices.
// Notes (scraped extra specs)
if (t.notes) {