import type { TimerState } from "@sprint/shared"; import { useEffect, useState } from "react"; import { Button } from "@/components/ui/button"; import { parseError, timer } from "@/lib/server"; import { cn, formatTime } from "@/lib/utils"; export function IssueTimer({ issueId, onEnd }: { issueId: number; onEnd?: (data: TimerState) => void }) { const [timerState, setTimerState] = useState(null); const [displayTime, setDisplayTime] = useState(0); const [error, setError] = useState(null); // fetch current timer state on mount useEffect(() => { timer.get({ issueId, onSuccess: (data) => { setTimerState(data); if (data) { setDisplayTime(data.workTimeMs); } }, onError: (err) => setError(parseError(err)), }); }, [issueId]); // update display time every second when running useEffect(() => { if (!timerState?.isRunning) return; const startTime = Date.now(); const baseTime = timerState.workTimeMs; const interval = setInterval(() => { setDisplayTime(baseTime + (Date.now() - startTime)); }, 1000); return () => clearInterval(interval); }, [timerState?.isRunning, timerState?.workTimeMs]); const handleToggle = () => { timer.toggle({ issueId, onSuccess: (data) => { if (data) { setTimerState(data); setDisplayTime(data.workTimeMs); } setError(null); }, onError: (err) => setError(parseError(err)), }); }; const handleEnd = () => { timer.end({ issueId, onSuccess: (data) => { if (data) { setTimerState(data); setDisplayTime(data.workTimeMs); onEnd?.(data); } setError(null); }, onError: (err) => setError(parseError(err)), }); }; return (
{formatTime(displayTime)}
{error &&

{error}

}
); }