fix: apply parseUTC to dashboard, unify date helpers in date-utils.ts

Agent-Logs-Url: https://github.com/christianlouis/InboxConverge/sessions/3f06f1fc-4d21-47eb-b883-070c6cbefa93

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-28 21:27:51 +00:00
parent 129d8a1bdd
commit db3ce61467
5 changed files with 47 additions and 51 deletions
+1 -14
View File
@@ -8,7 +8,7 @@ import { useAuthStore } from '@/store/authStore';
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';
import { adminApi, AdminProcessingRun } from '@/lib/api';
import { parseUTC } from '@/lib/date-utils';
import { formatDate, formatDuration } from '@/lib/date-utils';
import {
Activity,
ChevronLeft,
@@ -25,19 +25,6 @@ const STATUS_STYLES: Record<string, string> = {
running: 'bg-blue-100 text-blue-800',
};
function formatDuration(seconds?: number | null): string {
if (seconds == null) return '—';
if (seconds < 60) return `${seconds.toFixed(1)}s`;
return `${Math.floor(seconds / 60)}m ${Math.round(seconds % 60)}s`;
}
function formatDate(iso: string): string {
return parseUTC(iso).toLocaleString(undefined, {
dateStyle: 'short',
timeStyle: 'medium',
});
}
export default function AdminLogsPage() {
const { user } = useAuthStore();
const router = useRouter();
+1 -11
View File
@@ -4,6 +4,7 @@ import { AuthGuard } from '@/components/AuthGuard';
import { DashboardLayout } from '@/components/DashboardLayout';
import { useQuery } from '@tanstack/react-query';
import { mailAccountsApi, MailAccount } from '@/lib/api';
import { formatRelative } from '@/lib/date-utils';
import Link from 'next/link';
import {
Mail,
@@ -16,17 +17,6 @@ import {
Inbox,
} from 'lucide-react';
function formatRelative(iso?: string | null): string {
if (!iso) return 'Never';
const diff = Date.now() - new Date(iso).getTime();
const minutes = Math.floor(diff / 60000);
if (minutes < 1) return 'Just now';
if (minutes < 60) return `${minutes}m ago`;
const hours = Math.floor(minutes / 60);
if (hours < 24) return `${hours}h ago`;
return `${Math.floor(hours / 24)}d ago`;
}
interface StatCardProps {
title: string;
value: string | number;
+1 -26
View File
@@ -5,7 +5,7 @@ import { AuthGuard } from '@/components/AuthGuard';
import { DashboardLayout } from '@/components/DashboardLayout';
import { useQuery } from '@tanstack/react-query';
import { processingRunsApi, mailAccountsApi, MailAccount, ProcessingRun, ProcessingLog } from '@/lib/api';
import { parseUTC } from '@/lib/date-utils';
import { formatRelative, formatDate, formatDuration } from '@/lib/date-utils';
import {
Inbox,
ChevronLeft,
@@ -19,31 +19,6 @@ import {
AlertTriangle,
} from 'lucide-react';
function formatRelative(iso?: string | null): string {
if (!iso) return 'Never';
const diff = Date.now() - parseUTC(iso).getTime();
const minutes = Math.floor(diff / 60000);
if (minutes < 1) return 'Just now';
if (minutes < 60) return `${minutes}m ago`;
const hours = Math.floor(minutes / 60);
if (hours < 24) return `${hours}h ago`;
return `${Math.floor(hours / 24)}d ago`;
}
function formatDate(iso: string): string {
return parseUTC(iso).toLocaleString(undefined, {
dateStyle: 'short',
timeStyle: 'medium',
});
}
function formatDuration(seconds?: number | null): string {
if (seconds == null) return '—';
if (seconds < 60) return `${seconds.toFixed(1)}s`;
const totalSecs = Math.floor(seconds);
return `${Math.floor(totalSecs / 60)}m ${totalSecs % 60}s`;
}
function RunDetailRow({ run }: { run: ProcessingRun }) {
const [expanded, setExpanded] = useState(false);
const [logsPage, setLogsPage] = useState(1);
+37
View File
@@ -14,3 +14,40 @@
export function parseUTC(iso: string): Date {
return new Date(/Z|[+-]\d{2}:?\d{2}$/.test(iso) ? iso : iso + 'Z');
}
/**
* Format an ISO-8601 UTC timestamp as a human-readable relative time string
* (e.g. "3m ago", "2h ago", "1d ago"). Returns "Never" for falsy input.
*/
export function formatRelative(iso?: string | null): string {
if (!iso) return 'Never';
const diff = Date.now() - parseUTC(iso).getTime();
const minutes = Math.floor(diff / 60000);
if (minutes < 1) return 'Just now';
if (minutes < 60) return `${minutes}m ago`;
const hours = Math.floor(minutes / 60);
if (hours < 24) return `${hours}h ago`;
return `${Math.floor(hours / 24)}d ago`;
}
/**
* Format an ISO-8601 UTC timestamp as a locale-aware short date + medium time
* string, e.g. "28.03.26, 22:19:44".
*/
export function formatDate(iso: string): string {
return parseUTC(iso).toLocaleString(undefined, {
dateStyle: 'short',
timeStyle: 'medium',
});
}
/**
* Format a duration in seconds as a human-readable string,
* e.g. "3.1s" or "2m 5s". Returns "—" for null/undefined input.
*/
export function formatDuration(seconds?: number | null): string {
if (seconds == null) return '—';
if (seconds < 60) return `${seconds.toFixed(1)}s`;
const totalSecs = Math.floor(seconds);
return `${Math.floor(totalSecs / 60)}m ${totalSecs % 60}s`;
}