The reports feature gives you a visual overview of how many hours you have tracked on a project each day. Timify groups every completed and running time entry by calendar date, converts the totals from seconds to hours, and hands the result to a Recharts bar chart so you can spot patterns in your working time at a glance. Reports are scoped per project and accessible atDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Aking16/timify/llms.txt
Use this file to discover all available pages before exploring further.
/app/project/[id]/reports. The global /app/reports route reads your active project from localStorage and redirects you to that project’s reports page automatically.
Navigating to reports
Per-project reports
Visit
/app/project/[id]/reports to see the daily bar chart and summary cards for a specific project.Global reports shortcut
The sidebar link and bottom-nav Reports item point to
/app/reports, which redirects to the active project’s reports page. If no active project is set, you are sent to /app/projects first.Date range selection
The reports page includes a date range picker that controls which entries are included in the chart.The beginning of the reporting window. Defaults to 30 days before today when not explicitly chosen.
The end of the reporting window. Defaults to now when not explicitly chosen.
getReports(id, startDate, endDate) with your chosen dates.
The filter is applied on
startTime, not endTime. An entry that starts inside the date range is always included, even if it ends after the range boundary.How getReports works
getReports(id, startDate?, endDate?) is a Next.js server action that queries the time_entries table for a given project and returns an array of DailyHoursData objects sorted ascending by date.
Apply default date range
If
startDate is omitted, it is set to 30 days before Date.now(). If endDate is omitted, it defaults to now.Query time entries
getReports fetches all entries where projectId = id, startTime >= start, and startTime <= end using Drizzle’s gte and lte helpers.Calculate seconds per entry
For each entry, seconds are determined by one of three paths:
- Running entry (
isRunning = true):seconds = Math.floor((Date.now() - startTime) / 1000) - Completed with stored duration (
duration != null):seconds = entry.duration - Completed without stored duration:
seconds = Math.floor((endTime - startTime) / 1000)
Group by date
Each entry’s
startTime is formatted as YYYY-MM-DD. Seconds are accumulated into a Map<string, number> keyed by date string.Output shape
Calendar date in
YYYY-MM-DD format, derived from startTime.toISOString().split("T")[0].Total tracked hours on that date, rounded to 2 decimal places. Example:
3.75 means 3 hours and 45 minutes.Running entries in reports
Currently running entries are included in report totals. Their duration is calculated live from
startTime to Date.now() at the time the server action executes. This means the chart reflects real-time progress even for an open timer.Bar chart visualization
TheDailyHoursData[] array is passed directly to the DailyHoursBarChart component (built with Recharts). Each element in the array becomes one bar in the chart, with date on the X-axis and hours on the Y-axis.
Summary cards
Above or below the bar chart, Timify renders summary stat cards that aggregate theDailyHoursData[] array. Typical cards include:
Total Hours
Sum of all
hours values across the selected date range.Most Productive Day
The
date entry with the highest hours value.Days Tracked
Count of distinct dates that have at least one time entry.
Duration utility reference
ThecalculateDuration helper is used by the real-time UI (see useRealtimeDuration) to display a live ticking clock. It follows a consistent formula:
showFormatted: false to receive raw seconds suitable for summing before converting to hours, which avoids floating-point rounding errors from intermediate divisions. Pass showFormatted: true to get a human-readable H:MM:SS or MM:SS string directly.