feat(07.1-05): user-tz on engagement overview + profile pages
- 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.
This commit is contained in:
parent
b417988ee6
commit
a709144685
2 changed files with 16 additions and 12 deletions
|
|
@ -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<SummaryData | null>(null);
|
||||
|
|
@ -839,7 +841,7 @@ export default function EngagementPage() {
|
|||
</TableCell>
|
||||
<TableCell className="text-right text-xs text-muted-foreground hidden xl:table-cell">
|
||||
{user.lastActivity
|
||||
? new Date(user.lastActivity).toLocaleDateString()
|
||||
? new Date(user.lastActivity).toLocaleDateString(undefined, { timeZone: tz })
|
||||
: '—'}
|
||||
</TableCell>
|
||||
<TableCell className="text-right text-sm tabular-nums hidden xl:table-cell">
|
||||
|
|
@ -1007,7 +1009,7 @@ export default function EngagementPage() {
|
|||
}] : []),
|
||||
]} />
|
||||
{snap?.last_activity_date && (
|
||||
<p className="text-xs text-muted-foreground mt-3">Last activity: {new Date(snap.last_activity_date).toLocaleDateString()}</p>
|
||||
<p className="text-xs text-muted-foreground mt-3">Last activity: {new Date(snap.last_activity_date).toLocaleDateString(undefined, { timeZone: tz })}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
|
@ -1103,7 +1105,7 @@ export default function EngagementPage() {
|
|||
)}
|
||||
</div>
|
||||
<span className="text-xs text-muted-foreground shrink-0">
|
||||
{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`}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -1222,7 +1224,7 @@ export default function EngagementPage() {
|
|||
</div>
|
||||
<div className="flex items-center gap-2 shrink-0 ml-2 text-xs text-muted-foreground">
|
||||
<span>{formatDuration(call.durationSeconds)}</span>
|
||||
<span>{new Date(call.startTime).toLocaleDateString()}</span>
|
||||
<span>{new Date(call.startTime).toLocaleDateString(undefined, { timeZone: tz })}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
|
@ -1250,7 +1252,7 @@ export default function EngagementPage() {
|
|||
)}
|
||||
</div>
|
||||
<span className="text-xs text-muted-foreground shrink-0">
|
||||
{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`}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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<string, DayData> = {};
|
||||
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<UserOption[]>([]);
|
||||
const [usersLoading, setUsersLoading] = useState(true);
|
||||
const [selectedUserId, setSelectedUserId] = useState<string>('');
|
||||
|
|
@ -496,7 +498,7 @@ export default function EngagementProfilePage() {
|
|||
{peakMonth ? peakMonth.hoursWorked.toFixed(0) + 'h' : '—'}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{peakMonth ? monthLabel(peakMonth.month) : ''}
|
||||
{peakMonth ? monthLabel(peakMonth.month, tz) : ''}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
|
@ -510,7 +512,7 @@ export default function EngagementProfilePage() {
|
|||
</CardHeader>
|
||||
<CardContent>
|
||||
{history.daily.length > 0 ? (
|
||||
<ActivityHeatmap daily={history.daily} />
|
||||
<ActivityHeatmap daily={history.daily} tz={tz} />
|
||||
) : (
|
||||
<p className="text-sm text-muted-foreground py-6 text-center">
|
||||
No time entry data available
|
||||
|
|
@ -612,7 +614,7 @@ export default function EngagementProfilePage() {
|
|||
key={m.month}
|
||||
className={cn(isEmpty && 'opacity-40')}
|
||||
>
|
||||
<TableCell className="font-medium">{monthLabel(m.month)}</TableCell>
|
||||
<TableCell className="font-medium">{monthLabel(m.month, tz)}</TableCell>
|
||||
<TableCell className="text-right num">
|
||||
{m.hoursWorked > 0 ? m.hoursWorked.toFixed(1) : '—'}
|
||||
</TableCell>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue