93 lines
3.8 KiB
Markdown
93 lines
3.8 KiB
Markdown
# Phase 5: Polish - Context
|
|
|
|
**Gathered:** 2026-04-08
|
|
**Status:** Ready for planning
|
|
|
|
<domain>
|
|
## Phase Boundary
|
|
|
|
Add streak indicator, summary statistics row, and weekend visual distinction to the heatmap widget. Also integrate user's start-of-week preference from Kimai.
|
|
|
|
</domain>
|
|
|
|
<decisions>
|
|
## Implementation Decisions
|
|
|
|
### Streak 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-weekend` with 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_weekday` from Kimai (exposed via User entity or system config)
|
|
- Pass as `data-week-start` attribute 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_weekday` from 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.)
|
|
|
|
</decisions>
|
|
|
|
<code_context>
|
|
## Existing Code Insights
|
|
|
|
### Reusable Assets
|
|
- `renderHeatmap(container, data, config)` — main render, needs extension for weekend classes and stats
|
|
- `init()` — fetches data and calls render, will also compute streak/stats after data arrives
|
|
- `HeatmapData.days` array — source for all client-side computations
|
|
- `generateCells()` helper — can add weekend detection here
|
|
- `HeatmapWidget::getData()` — can add `weekStart` to 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` — add `data-week-start` attribute, stats container div
|
|
- `heatmap.css` — add `.heatmap-weekend`, `.heatmap-stats` styles
|
|
- `heatmap.ts` — extend `renderHeatmap` for weekends, add streak/stats functions
|
|
- `HeatmapWidget.php` — pass user's week start preference to template
|
|
|
|
</code_context>
|
|
|
|
<specifics>
|
|
## 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
|
|
|
|
</specifics>
|
|
|
|
<deferred>
|
|
## Deferred Ideas
|
|
|
|
None — all three requirements (POLI-01, POLI-02, POLI-03) plus start-of-week fit within polish scope.
|
|
|
|
</deferred>
|