diff --git a/app/admin/device-link-conflicts/page.tsx b/app/admin/device-link-conflicts/page.tsx
index 72d06fb..1f3ec8f 100644
--- a/app/admin/device-link-conflicts/page.tsx
+++ b/app/admin/device-link-conflicts/page.tsx
@@ -16,6 +16,7 @@ import {
} from '@/components/ui/select';
import { CheckCircle2, AlertTriangle, Loader2 } from 'lucide-react';
import { PageHeader } from '@/components/navigation/page-header';
+import { useUserTimezone } from '@/lib/hooks/use-user-timezone';
interface Candidate {
ciId: string;
@@ -77,6 +78,7 @@ function dedupeCandidates(candidates: Candidate[]): Candidate[] {
}
export default function DeviceLinkConflictsPage() {
+ const tz = useUserTimezone();
const [items, setItems] = useState(null);
const [total, setTotal] = useState(0);
const [error, setError] = useState(null);
@@ -220,7 +222,7 @@ export default function DeviceLinkConflictsPage() {
{r.xref.serial && serial: {r.xref.serial}}
{r.xref.mac && mac: {r.xref.mac}}
{r.xref.lastSeenAt && (
- last seen: {new Date(r.xref.lastSeenAt).toLocaleString()}
+ last seen: {new Date(r.xref.lastSeenAt).toLocaleString(undefined, { timeZone: tz })}
)}
diff --git a/app/admin/itglue-writes/page.tsx b/app/admin/itglue-writes/page.tsx
index f80f518..efc3a47 100644
--- a/app/admin/itglue-writes/page.tsx
+++ b/app/admin/itglue-writes/page.tsx
@@ -8,6 +8,7 @@ import { Button } from '@/components/ui/button';
import { Skeleton } from '@/components/ui/skeleton';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { PageHeader } from '@/components/navigation/page-header';
+import { useUserTimezone } from '@/lib/hooks/use-user-timezone';
interface WriteRow {
id: string;
@@ -47,6 +48,7 @@ function statusVariant(
}
export default function ItglueWritesPage() {
+ const tz = useUserTimezone();
const [rows, setRows] = useState(null);
const [error, setError] = useState(null);
const [statusFilter, setStatusFilter] =
@@ -141,7 +143,7 @@ export default function ItglueWritesPage() {
{w.field_name}
- {new Date(w.performed_at).toLocaleString()}
+ {new Date(w.performed_at).toLocaleString(undefined, { timeZone: tz })}
Before:
diff --git a/app/admin/rmm-overshell/page.tsx b/app/admin/rmm-overshell/page.tsx
index 5d42d61..2b04cc9 100644
--- a/app/admin/rmm-overshell/page.tsx
+++ b/app/admin/rmm-overshell/page.tsx
@@ -9,6 +9,7 @@ import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Loader2, RefreshCw, Terminal } from 'lucide-react';
import { toast } from 'sonner';
import { PageHeader } from '@/components/navigation/page-header';
+import { useUserTimezone } from '@/lib/hooks/use-user-timezone';
interface Settings {
overshellComponentUid: string | null;
@@ -35,6 +36,7 @@ interface ExecRow {
}
export default function RmmOvershellAdminPage() {
+ const tz = useUserTimezone();
const [settings, setSettings] = useState(null);
const [counts, setCounts] = useState<{ total: string; running: string; failed_24h: string } | null>(null);
const [executions, setExecutions] = useState(null);
@@ -139,7 +141,7 @@ export default function RmmOvershellAdminPage() {
{settings.discoveredAt && (
- discovered {new Date(settings.discoveredAt).toLocaleString()}
+ discovered {new Date(settings.discoveredAt).toLocaleString(undefined, { timeZone: tz })}
)}
>
@@ -196,7 +198,7 @@ export default function RmmOvershellAdminPage() {
{settings.logliftDiscoveredAt && (
discovered{' '}
- {new Date(settings.logliftDiscoveredAt).toLocaleString()}
+ {new Date(settings.logliftDiscoveredAt).toLocaleString(undefined, { timeZone: tz })}
)}
>
@@ -262,7 +264,7 @@ export default function RmmOvershellAdminPage() {
- {new Date(e.queuedAt).toLocaleString()}
+ {new Date(e.queuedAt).toLocaleString(undefined, { timeZone: tz })}
{e.errorMessage && (
diff --git a/app/admin/ticket-digest/page.tsx b/app/admin/ticket-digest/page.tsx
index ab81430..2dc9991 100644
--- a/app/admin/ticket-digest/page.tsx
+++ b/app/admin/ticket-digest/page.tsx
@@ -8,6 +8,7 @@ import {
Calendar, CalendarDays, CalendarRange, MessageSquare, Bell, Globe, ExternalLink,
} from 'lucide-react';
import { PageHeader } from '@/components/navigation/page-header';
+import { useUserTimezone } from '@/lib/hooks/use-user-timezone';
interface DigestConfig {
daily_enabled: boolean;
@@ -73,6 +74,7 @@ function PeriodIcon({ period }: { period: string }) {
}
export default function TicketDigestPage() {
+ const tz = useUserTimezone();
const [config, setConfig] = useState(null);
const [channels, setChannels] = useState([]);
const [history, setHistory] = useState([]);
@@ -407,7 +409,7 @@ export default function TicketDigestPage() {
{report.period_type}
- {new Date(report.generated_at).toLocaleString()}
+ {new Date(report.generated_at).toLocaleString(undefined, { timeZone: tz })}
diff --git a/app/admin/workflow/history/page.tsx b/app/admin/workflow/history/page.tsx
index 814931c..37df302 100644
--- a/app/admin/workflow/history/page.tsx
+++ b/app/admin/workflow/history/page.tsx
@@ -32,6 +32,7 @@ import {
ChevronRight,
} from 'lucide-react';
import { WorkflowExecutionWithSteps } from '@/lib/types/workflow';
+import { useUserTimezone } from '@/lib/hooks/use-user-timezone';
export default function ExecutionHistoryPage() {
return (
@@ -42,6 +43,7 @@ export default function ExecutionHistoryPage() {
}
function ExecutionHistoryContent() {
+ const tz = useUserTimezone();
const searchParams = useSearchParams();
const highlightId = searchParams.get('id');
@@ -189,7 +191,7 @@ function ExecutionHistoryContent() {
{exec.duration_ms ? `${exec.duration_ms}ms` : '-'}
- {new Date(exec.created_at).toLocaleString()}
+ {new Date(exec.created_at).toLocaleString(undefined, { timeZone: tz })}
))}
diff --git a/app/admin/workflow/pipelines/[id]/page.tsx b/app/admin/workflow/pipelines/[id]/page.tsx
index 0b9fb38..6ca5f12 100644
--- a/app/admin/workflow/pipelines/[id]/page.tsx
+++ b/app/admin/workflow/pipelines/[id]/page.tsx
@@ -26,6 +26,7 @@ import {
Eye,
} from 'lucide-react';
import StepConfigEditor from '@/components/admin/pipeline/StepConfigEditor';
+import { useUserTimezone } from '@/lib/hooks/use-user-timezone';
interface Pipeline {
id: number;
@@ -91,6 +92,7 @@ const STATUS_ICONS: Record = {
};
export default function PipelineEditorPage() {
+ const tz = useUserTimezone();
const params = useParams();
const router = useRouter();
const pipelineId = params.id as string;
@@ -579,7 +581,7 @@ export default function PipelineEditorPage() {
{exec.trigger_source}
{exec.duration_ms && {exec.duration_ms}ms}
- {new Date(exec.started_at).toLocaleString()}
+ {new Date(exec.started_at).toLocaleString(undefined, { timeZone: tz })}
{exec.error_message && (
diff --git a/app/admin/zabbix-wan/page.tsx b/app/admin/zabbix-wan/page.tsx
index e748a87..b1ab64d 100644
--- a/app/admin/zabbix-wan/page.tsx
+++ b/app/admin/zabbix-wan/page.tsx
@@ -51,6 +51,7 @@ import {
import { toast } from 'sonner';
import { HostManager } from '@/components/zabbix/host-manager';
import { PageHeader } from '@/components/navigation/page-header';
+import { useUserTimezone } from '@/lib/hooks/use-user-timezone';
type SyncMode = 'all' | 'client' | 'site';
@@ -139,6 +140,7 @@ interface RmmOnlyRow { alert_uid: string; site_name: string; alert_class: string
type PageTab = 'sync' | 'gaps' | 'correlation';
export default function ZabbixWanPage() {
+ const tz = useUserTimezone();
const [activeTab, setActiveTab] = useState('sync');
const [mode, setMode] = useState('all');
const [companyId, setCompanyId] = useState('');
@@ -209,8 +211,8 @@ export default function ZabbixWanPage() {
finally { setSyncing(null); }
};
- const fmtSynced = (ts: string | null) => ts ? new Date(ts).toLocaleString() : 'Never';
- const fmtTs = (ts: string | null) => ts ? new Date(ts).toLocaleString() : '—';
+ const fmtSynced = (ts: string | null) => ts ? new Date(ts).toLocaleString(undefined, { timeZone: tz }) : 'Never';
+ const fmtTs = (ts: string | null) => ts ? new Date(ts).toLocaleString(undefined, { timeZone: tz }) : '—';
const fmtDuration = (s: number | null, hasRecovery?: boolean) => {
if (s === null || s === undefined) return hasRecovery ? '< 1m' : 'Open';
if (s === 0) return hasRecovery ? '< 1m' : 'Open';