Features
Time Tracking

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

  1. Open a task
  2. Click the Timer button
  3. Timer starts counting

Or via store:

const startTimer = useAppStore((s) => s.startTimer)
startTimer(taskId)

Stop Timer

  1. Click the Stop button on the active timer
  2. 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)