fix: sidebar In Session timer ticks every second and shows seconds

Timer now uses 1s interval (not 60s) and displays seconds when under
a minute so it matches the session timer in the flow UI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-03-15 15:55:37 -04:00
parent d0af8357a6
commit 3c05a614b3

View File

@@ -9,34 +9,37 @@ interface SidebarStatsBarProps {
activeSessionStartTimes: string[] activeSessionStartTimes: string[]
} }
function formatDuration(minutes: number): string { function formatDuration(totalSeconds: number): string {
if (minutes < 60) return `${minutes}m` if (totalSeconds < 60) return `${totalSeconds}s`
const h = Math.floor(minutes / 60) const totalMinutes = Math.floor(totalSeconds / 60)
const m = minutes % 60 if (totalMinutes < 60) return `${totalMinutes}m`
const h = Math.floor(totalMinutes / 60)
const m = totalMinutes % 60
return m > 0 ? `${h}h ${m}m` : `${h}h` return m > 0 ? `${h}h ${m}m` : `${h}h`
} }
function calcActiveMinutes(startTimes: string[]): number { function calcActiveSeconds(startTimes: string[]): number {
const now = Date.now() const now = Date.now()
return startTimes.reduce((sum, st) => { return startTimes.reduce((sum, st) => {
const elapsed = Math.floor((now - new Date(st).getTime()) / 60000) const elapsed = Math.floor((now - new Date(st).getTime()) / 1000)
return sum + Math.max(0, elapsed) return sum + Math.max(0, elapsed)
}, 0) }, 0)
} }
export function SidebarStatsBar({ resolved, active, completedMinutes, activeSessionStartTimes }: SidebarStatsBarProps) { export function SidebarStatsBar({ resolved, active, completedMinutes, activeSessionStartTimes }: SidebarStatsBarProps) {
const [liveMinutes, setLiveMinutes] = useState(() => calcActiveMinutes(activeSessionStartTimes)) const [liveSeconds, setLiveSeconds] = useState(() => calcActiveSeconds(activeSessionStartTimes))
// Tick every 60s to keep the timer live // Tick every second to keep the timer in sync with the session timer
useEffect(() => { useEffect(() => {
setLiveMinutes(calcActiveMinutes(activeSessionStartTimes)) setLiveSeconds(calcActiveSeconds(activeSessionStartTimes))
if (activeSessionStartTimes.length === 0) return
const interval = setInterval(() => { const interval = setInterval(() => {
setLiveMinutes(calcActiveMinutes(activeSessionStartTimes)) setLiveSeconds(calcActiveSeconds(activeSessionStartTimes))
}, 60000) }, 1000)
return () => clearInterval(interval) return () => clearInterval(interval)
}, [activeSessionStartTimes]) }, [activeSessionStartTimes])
const totalMinutes = completedMinutes + liveMinutes const totalSeconds = (completedMinutes * 60) + liveSeconds
return ( return (
<div <div
@@ -71,9 +74,9 @@ export function SidebarStatsBar({ resolved, active, completedMinutes, activeSess
<div className="flex-1 rounded-md bg-[rgba(255,255,255,0.02)] px-1 py-1.5 text-center"> <div className="flex-1 rounded-md bg-[rgba(255,255,255,0.02)] px-1 py-1.5 text-center">
<div <div
className="font-label text-sm font-semibold leading-none text-muted-foreground" className="font-label text-sm font-semibold leading-none text-muted-foreground"
aria-label={`${formatDuration(totalMinutes)} in session today`} aria-label={`${formatDuration(totalSeconds)} in session today`}
> >
{formatDuration(totalMinutes)} {formatDuration(totalSeconds)}
</div> </div>
<div className="mt-1 font-label text-[7px] uppercase tracking-[0.1em] text-[#3d4350]"> <div className="mt-1 font-label text-[7px] uppercase tracking-[0.1em] text-[#3d4350]">
In Session In Session