From b5dd5e7082967ec591a66d88dc6a0453fa2430ca Mon Sep 17 00:00:00 2001 From: Usman Baig Date: Wed, 11 Mar 2026 23:33:24 +0100 Subject: [PATCH] feat: add This week / This month period options and fix comparison labels --- CHANGELOG.md | 4 ++ app/sites/[id]/page.tsx | 71 +++++++++++++++++++++++----------- components/dashboard/Chart.tsx | 17 ++++++-- 3 files changed, 66 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e9d3a5..fce77f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### Improved +- **New date range options.** The period selector now includes "This week" (Monday to today) and "This month" (1st to today) alongside the existing rolling windows. Your selection is remembered between sessions. +- **Smarter comparison labels.** The "vs …" label under each stat now matches the period you're viewing — "vs yesterday" for today, "vs last week" for this week, "vs last month" for this month, and "vs previous N days" for rolling windows. +- **Refreshed stat headers.** The Unique Visitors, Total Pageviews, Bounce Rate, and Visit Duration stats at the top of the chart have a new look — uppercase labels, the percentage change shown inline next to the number, and an orange underline on whichever metric you're currently graphing. +- **Consistent green and red colors.** The up/down percentage indicators now use the same green and red as the rest of the app, instead of slightly different shades. - **Scroll Depth is now a radar chart.** The Scroll Depth panel has been redesigned from a bar chart into a radar chart. The four scroll milestones (25%, 50%, 75%, 100%) are plotted as axes, with the filled shape showing how far visitors are getting through your pages at a glance. - **Polished Goals & Events panel.** The Goals & Events block on your dashboard got a visual refresh to match the style of the Pages, Referrers, and Locations panels. Events are now ranked with a number on the left, counts are shown in a consistent style, and hovering any row reveals what percentage of total events that action accounts for — sliding in smoothly from the right. - **Smarter bot protection.** The security checks on shared dashboard access and organization settings now use action-specific tokens tied to each page. A token earned on one page can't be reused on another, making it harder for automated tools to bypass the captcha. diff --git a/app/sites/[id]/page.tsx b/app/sites/[id]/page.tsx index c7e4762..9bb8a15 100644 --- a/app/sites/[id]/page.tsx +++ b/app/sites/[id]/page.tsx @@ -64,6 +64,20 @@ function loadSavedSettings(): { } } +function getThisWeekRange(): { start: string; end: string } { + const today = new Date() + const dayOfWeek = today.getDay() + const monday = new Date(today) + monday.setDate(today.getDate() - (dayOfWeek === 0 ? 6 : dayOfWeek - 1)) + return { start: formatDate(monday), end: formatDate(today) } +} + +function getThisMonthRange(): { start: string; end: string } { + const today = new Date() + const firstOfMonth = new Date(today.getFullYear(), today.getMonth(), 1) + return { start: formatDate(firstOfMonth), end: formatDate(today) } +} + function getInitialDateRange(): { start: string; end: string } { const settings = loadSavedSettings() if (settings?.type === 'today') { @@ -71,10 +85,16 @@ function getInitialDateRange(): { start: string; end: string } { return { start: today, end: today } } if (settings?.type === '7') return getDateRange(7) + if (settings?.type === 'week') return getThisWeekRange() + if (settings?.type === 'month') return getThisMonthRange() if (settings?.type === 'custom' && settings.dateRange) return settings.dateRange return getDateRange(30) } +function getInitialPeriod(): string { + return loadSavedSettings()?.type || '30' +} + export default function SiteDashboardPage() { @@ -84,6 +104,7 @@ export default function SiteDashboardPage() { const siteId = params.id as string // UI state - initialized from localStorage synchronously to avoid double-fetch + const [period, setPeriod] = useState(getInitialPeriod) const [dateRange, setDateRange] = useState(getInitialDateRange) const [todayInterval, setTodayInterval] = useState<'minute' | 'hour'>( () => loadSavedSettings()?.todayInterval || 'hour' @@ -457,40 +478,44 @@ export default function SiteDashboardPage() {