fix: UTC timezone correction for all JS date parsing across portal
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

Added global parseUTC() helper in base.html that appends 'Z' to
naive ISO dates from server. Applied to:
- Notification bell (base.html) — formatTimeAgo
- NordaGPT conversation sort (chat.html)
- B2B interest dates (classifieds/view.html)
- Admin forum moderation dates (admin/forum.html)
- Admin AI insights dates (admin/insights.html)

Same fix as conversations.js parseUTC, now available globally.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-04-10 06:09:42 +02:00
parent 43c9ba6c77
commit 39da377065
5 changed files with 16 additions and 6 deletions

View File

@ -1220,7 +1220,7 @@
${r.is_deleted ? '<span style="color: var(--error); font-size: var(--font-size-xs);"> (usunięty)</span>' : ''}
<div class="result-preview">${r.content_preview}</div>
<div class="result-meta">
${r.author_name} &bull; ${new Date(r.created_at).toLocaleString('pl-PL')}
${r.author_name} &bull; ${parseUTC(r.created_at).toLocaleString('pl-PL')}
${r.category_label ? ` &bull; ${r.category_label}` : ''}
</div>
</div>
@ -1415,7 +1415,7 @@
<a href="${a.url}">${a.title}</a>
${a.is_deleted ? '<span style="color: var(--error);"> (usunięty)</span>' : ''}
</div>
<span class="activity-date">${new Date(a.created_at).toLocaleString('pl-PL')}</span>
<span class="activity-date">${parseUTC(a.created_at).toLocaleString('pl-PL')}</span>
</div>
`).join('');
}

View File

@ -312,7 +312,7 @@ async function loadInsights() {
<option value="rejected">Odrzucony</option>
</select>
<span style="font-size: var(--font-size-xs); color: var(--text-muted);">
${insight.source_type} | ${insight.created_at ? new Date(insight.created_at).toLocaleDateString('pl-PL') : ''}
${insight.source_type} | ${insight.created_at ? parseUTC(insight.created_at).toLocaleDateString('pl-PL') : ''}
</span>
</div>
</div>

View File

@ -858,7 +858,7 @@
let html = '';
data.notifications.forEach(n => {
const timeAgo = formatTimeAgo(new Date(n.created_at));
const timeAgo = formatTimeAgo(parseUTC(n.created_at));
const unreadClass = n.is_read ? '' : 'unread';
const dotHtml = n.is_read ? '' : '<span class="notification-dot"></span>';
const icon = getNotificationIcon(n.notification_type);
@ -987,6 +987,16 @@
}
}
// Parse server UTC datetime — append Z if no timezone info
function parseUTC(dateStr) {
if (!dateStr) return new Date();
if (typeof dateStr === 'object') return dateStr;
if (dateStr.indexOf('Z') === -1 && dateStr.indexOf('+') === -1 && dateStr.indexOf('T') !== -1) {
return new Date(dateStr + 'Z');
}
return new Date(dateStr);
}
function formatTimeAgo(date) {
const now = new Date();
const diff = now - date;

View File

@ -2265,7 +2265,7 @@ async function togglePin(conversationId) {
// Re-sort: pinned first, then by updated_at
conversations.sort((a, b) => {
if (a.is_pinned !== b.is_pinned) return b.is_pinned ? 1 : -1;
return new Date(b.updated_at) - new Date(a.updated_at);
return parseUTC(b.updated_at) - parseUTC(a.updated_at);
});
renderConversationsList();
}

View File

@ -1078,7 +1078,7 @@ async function showInterestsModal() {
${i.company_name ? `<div class="interest-company">${i.company_name}</div>` : ''}
${i.message ? `<div class="interest-message">"${i.message}"</div>` : ''}
</div>
<div class="interest-date">${new Date(i.created_at).toLocaleDateString('pl-PL')}</div>
<div class="interest-date">${parseUTC(i.created_at).toLocaleDateString('pl-PL')}</div>
</div>
`).join('');
}