Date Range
One date picker controls every metric on the page. Here's how the propagation works and what does NOT respect it.
State location
The date range is local state in ClientDashboard.tsx:
const [dateRange, setDateRange] = useState<DateRange>(() => presetToRange('30D'))
// shorthand reused in every fetch
const dateQs = `start_date=${dateRange.start}&end_date=${dateRange.end}`DateRange is { start: string, end: string, preset: string, label: string }. Both dates are YYYY-MM-DD strings (ISO date, no time component).
The picker UI
src/components/dashboard/DateRangePicker.tsx renders the dropdown that hosts presets (Today, Yesterday, 7D, 30D, 90D, 6M, 12M, MTD, QTD, YTD, This Month Last Year, Custom) and a custom date input.
- The selected preset is stored in
dateRange.preset. - Switching tabs does not reset the date range.
- The label shown next to charts ("Last 30 days") reads from
dateRange.label— full preset map covers every option, not just 7D/30D/90D.
What respects the date range
- GA4 (all sub-routes: traffic, pages, acquisition, metrics).
- Search Console (metrics + keywords).
- GBP Performance API.
- GHL — leads, appointments, won, revenue. This was the April 2026 fix.
- Google Ads.
- Meta Ads.
- RFMS Historical Revenue.
What does NOT respect the date range
- PageSpeed Insights — always live, point-in-time measurement.
- YouTube — channel statistics are all-time. Video stats use the 10 most recent uploads regardless of date range.
- GBP Reviews — Places API returns a snapshot of current rating + review count.
- DataForSEO rankings — uses the most recent weekly snapshot.
- Pipeline Rates chart (weekly trend) — intentionally always shows the last 12 weeks for trend visibility.
- External / n8n keys — these are pushed values without a date dimension; they show whatever was last pushed.
change field is computed against a previous period of equal length. Custom dates work too: 2026-04-01 → 2026-04-30 (30 days) compares against 2026-03-02 → 2026-03-31. The label on the dashboard says vs previous period rather than "vs previous 28 days" so it stays accurate as the range changes.Default range
The dashboard opens at Last 30 days. This was chosen because it is the standard reporting window for most clients, and it gives enough data for the Conversion Rate / Click-Through-Rate metrics to be meaningful.
Adding a new date-aware metric
When you wire a new metric, three things must happen:
- The route accepts
start_dateandend_datequery params. - The route uses those dates when calling the upstream API or filtering.
- The fetch call in
ClientDashboard.tsxincludes them indateQsand theuseEffectdependency array includesdateRange.startanddateRange.end.