Time Tracking
Track time spent on tasks with a built-in timer or manual entries.
Features
- Timer - Start/stop timer for active work
- Manual Entries - Add time after the fact
- Time Reports - View time per task, user, or board
- Time Column - Display total time in table view
Using the Timer
Start Timer
- Open a task
- Click the Timer button
- Timer starts counting
Or via store:
const startTimer = useAppStore((s) => s.startTimer)
startTimer(taskId)Stop Timer
- Click the Stop button on the active timer
- Time entry is automatically saved
const stopTimer = useAppStore((s) => s.stopTimer)
stopTimer(taskId)Manual Time Entry
Add time after completing work:
const addManualTimeEntry = useAppStore((s) => s.addManualTimeEntry)
addManualTimeEntry(
taskId,
3600, // Duration in seconds (1 hour)
"Bug investigation and fix"
)Time Entry Schema
interface TimeEntry {
id: string
taskId: string
userId: string
startTime: string // ISO date
endTime?: string // ISO date (empty if timer running)
duration: number // Seconds
description?: string
}Active Timers
The store tracks active timers:
// Active timers: { taskId: startTimestamp }
activeTimers: Record<string, number>
// Check if timer is running
const activeTimers = useAppStore((s) => s.activeTimers)
const isRunning = taskId in activeTimers
// Get elapsed time
const elapsed = Date.now() - activeTimers[taskId]Displaying Time
Format Duration
function formatDuration(seconds: number): string {
const hours = Math.floor(seconds / 3600)
const minutes = Math.floor((seconds % 3600) / 60)
if (hours > 0) {
return `${hours}h ${minutes}m`
}
return `${minutes}m`
}Total Time for Task
function getTotalTime(task: Task): number {
return task.timeEntries.reduce(
(total, entry) => total + entry.duration,
0
)
}Time Tracking Column
Add a timeTracking column to display time in table view:
{
id: 'time-col',
name: 'Time Spent',
type: 'timeTracking'
}This column shows:
- Total logged time
- Active timer indicator
- Click to expand entries
Store Usage
import { useAppStore } from '@/lib/store'
// Timer actions
const startTimer = useAppStore((s) => s.startTimer)
const stopTimer = useAppStore((s) => s.stopTimer)
const addManualTimeEntry = useAppStore((s) => s.addManualTimeEntry)
// Get active timers
const activeTimers = useAppStore((s) => s.activeTimers)
// Get time entries for a task
const task = useAppStore((s) =>
s.tasks.find(t => t.id === taskId)
)
const entries = task?.timeEntries ?? []
const totalTime = entries.reduce((sum, e) => sum + e.duration, 0)