feat(dashboard): period URL state + resolved range label + chart drill-down to Costs#605
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e3bb5ce904
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| case 'day': | ||
| return fmtDay(now); | ||
| case 'week': { | ||
| const weekAgo = new Date(now.getTime() - 6 * 24 * 60 * 60 * 1000); |
There was a problem hiding this comment.
Match week label to the actual 7-day query window
The new range label for period='week' is off by one day compared to the backend filter: formatPeriodRange subtracts 6 days, while periodToRange('week') subtracts 7 days before querying analytics. In practice, a dashboard filtered with the current week request can include data from an extra calendar day (e.g., Apr 16), but the UI label will display Apr 17 – Apr 23, which misstates the range users are interpreting.
Useful? React with 👍 / 👎.
Scope
PR 2 of 8 from the improvement roadmap. Covers the low-risk parts of P.2 (period UX) and P.3 (drill-down):
day/week/month/season) is persisted in the URL as?period=…. Refresh, share and back-button now preserve the filter. A small monospace label under the segmented control shows the actual resolved date range (e.g.23 квіт 2026,17 – 23 квіт 2026,квіт 2026,Весь час)./economics/costs?from=YYYY-MM-01&to=YYYY-MM-lastday, pre-filtered to that month. The Costs page now readsfrom/tofrom the URL, reflects them in the RangePicker, and writes manual range changes back to the URL.Deferred to a later PR (require product input):
‹ ›anchor-date navigation (needs a decision on whether month/week should be anchored to a non-today date — dashboard backend currently only acceptsfrom/to, so this needs a small API extension).RevenueAnalytics.tsx) — same pattern, different page, kept out to keep this PR focused.Changes
Dashboard container
frontend/src/pages/Dashboard.tsx— period now comes fromuseSearchParams.seasonis the default and is stored as no query param (keeps URLs clean).DashboardV2 (presentational)
.rangeLabelinDashboardV2.module.css, stacked layout).handleChartPointClickparses the point'sYYYY-MMname and navigates to the Costs page with the whole month pre-selected.onPointClickprop intoRevenueCostChart.RevenueCostChart
onPointClick(name)prop. Wired to Recharts'<AreaChart onClick>; the chart gainscursor: pointeronly when a handler is supplied so the existing non-interactive embeds are unaffected.Costs page
frontend/src/pages/Economics/CostRecords.tsx— reads?from/?tofrom the URL on mount (validated asYYYY-MM-DD), binds them to the AntDRangePicker, and writes user-driven range changes back to the URL with{ replace: true }.New util
frontend/src/utils/formatPeriodRange.ts— locale-aware label formatter shared between the dashboard and any future callers.i18n
dashboard.allTimeto bothuk.ts("Весь час") anden.ts("All time").Verification
cd frontend && npx tsc --noEmit— clean./dashboard?period=month→ month tab is active and the range label reads the current month. Click a chart point for 2026-03 → lands on/economics/costs?from=2026-03-01&to=2026-03-31with the RangePicker pre-filled.