3.8 KiB
3.8 KiB
Phase 5: Polish - Context
Gathered: 2026-04-08 Status: Ready for planning
## Phase BoundaryAdd streak indicator, summary statistics row, and weekend visual distinction to the heatmap widget. Also integrate user's start-of-week preference from Kimai.
## Implementation DecisionsStreak Indicator
- Count consecutive calendar days (including weekends) with tracked time, counting backward from today
- Display as a simple text line above or below the heatmap: "Current streak: N days"
- If today has no entries yet, check from yesterday backward (user may still be tracking today)
- Computed client-side from the fetched heatmap data — no new API endpoint
Summary Stats Row
- Rendered below the heatmap SVG, inside the same Tabler card
- Three stats: Total Hours, Avg Hours/Day (days with tracked time only), Busiest Day
- Computed client-side from the fetched heatmap data array
- Styled as inline stat items using Tabler's existing typography classes
- "Busiest Day" shows date + hours (e.g., "Mar 15 — 8.5h")
Weekend Styling
- Weekend cells (Saturday/Sunday) get reduced opacity (0.85) compared to weekday cells
- Applied via CSS class
.heatmap-weekendwith opacity rule - Empty weekend cells also get the distinction so the grid pattern is visible
- No border changes — keep existing rounded rect style
Start-of-Week Preference
- Read user's
first_weekdayfrom Kimai (exposed via User entity or system config) - Pass as
data-week-startattribute on the container div (0=Sunday, 1=Monday, etc.) - Use in d3 grid layout to set which day is row 0
- Adjust day-of-week labels to match
- Default to Monday if not available (current behavior)
Testing Strategy
- Vitest tests for streak calculation (consecutive days, gaps, weekend inclusion, today edge case)
- Vitest tests for summary stats computation (totals, averages, busiest day)
- Vitest tests for weekend cell class assignment
- CSS changes don't need unit tests — visual verification
Claude's Discretion
- Exact Tabler CSS classes for the stats row layout
- How to extract
first_weekdayfrom Kimai's User entity (check source) - Whether streak resets on weekends or not (decision: it does — every calendar day counts)
- d3 time interval function for configurable week start (d3.timeSunday vs d3.timeMonday etc.)
<code_context>
Existing Code Insights
Reusable Assets
renderHeatmap(container, data, config)— main render, needs extension for weekend classes and statsinit()— fetches data and calls render, will also compute streak/stats after data arrivesHeatmapData.daysarray — source for all client-side computationsgenerateCells()helper — can add weekend detection hereHeatmapWidget::getData()— can addweekStartto template data
Established Patterns
- d3 selections for SVG element class assignment
- Data attributes on container div for passing server config to JS
- Tabler card structure with widget template embedding
- CSS classes added to cells based on data state (
.heatmap-empty)
Integration Points
heatmap.html.twig— adddata-week-startattribute, stats container divheatmap.css— add.heatmap-weekend,.heatmap-statsstylesheatmap.ts— extendrenderHeatmapfor weekends, add streak/stats functionsHeatmapWidget.php— pass user's week start preference to template
</code_context>
## Specific Ideas- Memory note: heatmap must respect Kimai user's start-of-week preference (not hardcoded Monday)
- Stats should feel lightweight — not a full stats panel, just quick context below the heatmap
None — all three requirements (POLI-01, POLI-02, POLI-03) plus start-of-week fit within polish scope.