From a709144685f37a81d6ef3d1bd2b557e610ce76e4 Mon Sep 17 00:00:00 2001
From: lorentz
Date: Thu, 7 May 2026 08:23:24 -0400
Subject: [PATCH] feat(07.1-05): user-tz on engagement overview + profile pages
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- app/engagement/page.tsx: useUserTimezone in EngagementPage; thread tz
into 7 toLocale* callsites (lines 844, 1012, 1108, 1227, 1255 — last
two have 2 calls per line for date+time).
- app/engagement/profile/page.tsx: useUserTimezone in EngagementProfilePage;
add tz prop to ActivityHeatmap; convert module-scope monthLabel(m) to
monthLabel(m, tz); update 2 callsites of monthLabel.
Migrates 9 of 81 audit leak callsites.
---
app/engagement/page.tsx | 12 +++++++-----
app/engagement/profile/page.tsx | 16 +++++++++-------
2 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/app/engagement/page.tsx b/app/engagement/page.tsx
index b91469c..86af00a 100644
--- a/app/engagement/page.tsx
+++ b/app/engagement/page.tsx
@@ -44,6 +44,7 @@ import {
Legend,
CartesianGrid,
} from 'recharts';
+import { useUserTimezone } from '@/lib/hooks/use-user-timezone';
interface SummaryData {
totalStaff: number;
@@ -460,6 +461,7 @@ function SummaryCard({
}
export default function EngagementPage() {
+ const tz = useUserTimezone();
const [period, setPeriod] = useState<'D7' | 'D30' | 'D90'>('D7');
const [activeTab, setActiveTab] = useState<'overview' | 'by-employee'>('by-employee');
const [summary, setSummary] = useState(null);
@@ -839,7 +841,7 @@ export default function EngagementPage() {
{user.lastActivity
- ? new Date(user.lastActivity).toLocaleDateString()
+ ? new Date(user.lastActivity).toLocaleDateString(undefined, { timeZone: tz })
: '—'}
@@ -1007,7 +1009,7 @@ export default function EngagementPage() {
}] : []),
]} />
{snap?.last_activity_date && (
- Last activity: {new Date(snap.last_activity_date).toLocaleDateString()}
+ Last activity: {new Date(snap.last_activity_date).toLocaleDateString(undefined, { timeZone: tz })}
)}
@@ -1103,7 +1105,7 @@ export default function EngagementPage() {
)}
- {d.toLocaleDateString()} {d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
+ {d.toLocaleDateString(undefined, { timeZone: tz })} {d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', timeZone: tz })}
{mtg.durationMinutes != null && ` · ${mtg.durationMinutes}m`}
@@ -1222,7 +1224,7 @@ export default function EngagementPage() {
{formatDuration(call.durationSeconds)}
- {new Date(call.startTime).toLocaleDateString()}
+ {new Date(call.startTime).toLocaleDateString(undefined, { timeZone: tz })}
))}
@@ -1250,7 +1252,7 @@ export default function EngagementPage() {
)}
- {d.toLocaleDateString()} {d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
+ {d.toLocaleDateString(undefined, { timeZone: tz })} {d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', timeZone: tz })}
{mtg.durationMinutes != null && ` · ${mtg.durationMinutes}m`}
diff --git a/app/engagement/profile/page.tsx b/app/engagement/profile/page.tsx
index e45925a..de86376 100644
--- a/app/engagement/profile/page.tsx
+++ b/app/engagement/profile/page.tsx
@@ -25,6 +25,7 @@ import {
PolarRadiusAxis,
Radar,
} from 'recharts';
+import { useUserTimezone } from '@/lib/hooks/use-user-timezone';
import { Users, RefreshCw } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
@@ -100,7 +101,7 @@ function hoursLevel(h: number): number {
return 4;
}
-function ActivityHeatmap({ daily }: { daily: DayData[] }) {
+function ActivityHeatmap({ daily, tz }: { daily: DayData[]; tz: string }) {
const dailyMap: Record = {};
for (const d of daily) dailyMap[d.date] = d;
@@ -138,7 +139,7 @@ function ActivityHeatmap({ daily }: { daily: DayData[] }) {
if (m !== lastMonth) {
monthLabels.push({
weekIndex: wi,
- label: d.toLocaleDateString('en-US', { month: 'short' }),
+ label: d.toLocaleDateString('en-US', { month: 'short', timeZone: tz }),
});
lastMonth = m;
}
@@ -260,8 +261,8 @@ function buildRadarData(monthly: MonthData[]) {
];
}
-function monthLabel(m: string) {
- return new Date(m + '-02').toLocaleDateString('en-US', { month: 'short', year: 'numeric' });
+function monthLabel(m: string, tz: string) {
+ return new Date(m + '-02').toLocaleDateString('en-US', { month: 'short', year: 'numeric', timeZone: tz });
}
interface BackfillStatus {
@@ -276,6 +277,7 @@ interface BackfillStatus {
}
export default function EngagementProfilePage() {
+ const tz = useUserTimezone();
const [users, setUsers] = useState([]);
const [usersLoading, setUsersLoading] = useState(true);
const [selectedUserId, setSelectedUserId] = useState('');
@@ -496,7 +498,7 @@ export default function EngagementProfilePage() {
{peakMonth ? peakMonth.hoursWorked.toFixed(0) + 'h' : '—'}
- {peakMonth ? monthLabel(peakMonth.month) : ''}
+ {peakMonth ? monthLabel(peakMonth.month, tz) : ''}
@@ -510,7 +512,7 @@ export default function EngagementProfilePage() {
{history.daily.length > 0 ? (
-
+
) : (
No time entry data available
@@ -612,7 +614,7 @@ export default function EngagementProfilePage() {
key={m.month}
className={cn(isEmpty && 'opacity-40')}
>
- {monthLabel(m.month)}
+ {monthLabel(m.month, tz)}
{m.hoursWorked > 0 ? m.hoursWorked.toFixed(1) : '—'}