From e6f3f3b4b40a490d5cb050471baa0999366dab2a Mon Sep 17 00:00:00 2001 From: Serhii Zghama Date: Wed, 25 Mar 2026 16:39:50 +0700 Subject: [PATCH 1/7] fix: use settings timezone in revenue chart date range The revenue chart was using the browser's local timezone instead of the timezone configured in Umami settings. This caused the chart to show different time boundaries than the stats shown in the header (total, average, transactions). The fix mirrors the same pattern used by EventsChart: pass timezone from useTimezone() into useDateRange() so that parseDateRange() computes start/end dates relative to the correct timezone. Fixes #4107 --- .../websites/[websiteId]/(reports)/revenue/RevenuePage.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/(main)/websites/[websiteId]/(reports)/revenue/RevenuePage.tsx b/src/app/(main)/websites/[websiteId]/(reports)/revenue/RevenuePage.tsx index 3e429c187..4dc19e012 100644 --- a/src/app/(main)/websites/[websiteId]/(reports)/revenue/RevenuePage.tsx +++ b/src/app/(main)/websites/[websiteId]/(reports)/revenue/RevenuePage.tsx @@ -1,13 +1,14 @@ 'use client'; import { Column } from '@umami/react-zen'; import { WebsiteControls } from '@/app/(main)/websites/[websiteId]/WebsiteControls'; -import { useDateRange } from '@/components/hooks'; +import { useDateRange, useTimezone } from '@/components/hooks'; import { Revenue } from './Revenue'; export function RevenuePage({ websiteId }: { websiteId: string }) { + const { timezone } = useTimezone(); const { dateRange: { startDate, endDate, unit }, - } = useDateRange(); + } = useDateRange({ timezone }); return ( From 26ced6cdf22802132aa487926aec3d52270e1083 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Tue, 31 Mar 2026 13:17:33 -0700 Subject: [PATCH 2/7] sharePage hotfix --- .../[websiteId]/sessions/SessionsDataTable.tsx | 12 ++++++++++-- .../[websiteId]/sessions/SessionsTable.tsx | 17 +++++++++-------- src/app/share/[slug]/[[...path]]/SharePage.tsx | 2 +- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx index 4b07a16c7..b4714b430 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx @@ -1,14 +1,22 @@ import { DataGrid } from '@/components/common/DataGrid'; -import { useWebsiteSessionsQuery } from '@/components/hooks'; +import { useNavigation, useWebsiteSessionsQuery } from '@/components/hooks'; import { SessionsTable } from './SessionsTable'; export function SessionsDataTable({ websiteId }: { websiteId: string }) { const queryResult = useWebsiteSessionsQuery(websiteId); + const { pathname } = useNavigation(); + const isSharePage = pathname.includes('/share/'); return ( {({ data }) => { - return ; + return ( + undefined : undefined} + /> + ); }} ); diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx index b4c684a47..69f32afa7 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx @@ -16,15 +16,16 @@ export function SessionsTable({ return ( - {(row: any) => ( - + {(row: any) => { + const href = getSessionHref ? getSessionHref(row) : `/websites/${websiteId}/sessions/${row.id}`; + return href ? ( + + + + ) : ( - - )} + ); + }} diff --git a/src/app/share/[slug]/[[...path]]/SharePage.tsx b/src/app/share/[slug]/[[...path]]/SharePage.tsx index 283b3f38f..a1103ffd9 100644 --- a/src/app/share/[slug]/[[...path]]/SharePage.tsx +++ b/src/app/share/[slug]/[[...path]]/SharePage.tsx @@ -125,7 +125,7 @@ export function SharePage() { - + From 726ee586b02c05a58ddfc94516b0d0610da125e3 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Tue, 31 Mar 2026 13:17:33 -0700 Subject: [PATCH 3/7] sharePage hotfix --- .../[websiteId]/sessions/SessionsDataTable.tsx | 12 ++++++++++-- .../[websiteId]/sessions/SessionsTable.tsx | 17 +++++++++-------- src/app/share/[slug]/[[...path]]/SharePage.tsx | 2 +- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx index 4b07a16c7..b4714b430 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx @@ -1,14 +1,22 @@ import { DataGrid } from '@/components/common/DataGrid'; -import { useWebsiteSessionsQuery } from '@/components/hooks'; +import { useNavigation, useWebsiteSessionsQuery } from '@/components/hooks'; import { SessionsTable } from './SessionsTable'; export function SessionsDataTable({ websiteId }: { websiteId: string }) { const queryResult = useWebsiteSessionsQuery(websiteId); + const { pathname } = useNavigation(); + const isSharePage = pathname.includes('/share/'); return ( {({ data }) => { - return ; + return ( + undefined : undefined} + /> + ); }} ); diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx index b4c684a47..69f32afa7 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx @@ -16,15 +16,16 @@ export function SessionsTable({ return ( - {(row: any) => ( - + {(row: any) => { + const href = getSessionHref ? getSessionHref(row) : `/websites/${websiteId}/sessions/${row.id}`; + return href ? ( + + + + ) : ( - - )} + ); + }} diff --git a/src/app/share/[slug]/[[...path]]/SharePage.tsx b/src/app/share/[slug]/[[...path]]/SharePage.tsx index f066940dc..4131521d8 100644 --- a/src/app/share/[slug]/[[...path]]/SharePage.tsx +++ b/src/app/share/[slug]/[[...path]]/SharePage.tsx @@ -118,7 +118,7 @@ export function SharePage() { - + From 163e46d1f15bd6b4d1bac650cbf8480aa640a2d6 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Tue, 31 Mar 2026 13:36:23 -0700 Subject: [PATCH 4/7] Fix session avatar href --- .../sessions/SessionsDataTable.tsx | 19 ++++++++----------- .../[websiteId]/sessions/SessionsPage.tsx | 2 ++ .../[websiteId]/sessions/SessionsTable.tsx | 13 ++++--------- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx index b4714b430..1b8f441a5 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx @@ -4,20 +4,17 @@ import { SessionsTable } from './SessionsTable'; export function SessionsDataTable({ websiteId }: { websiteId: string }) { const queryResult = useWebsiteSessionsQuery(websiteId); - const { pathname } = useNavigation(); - const isSharePage = pathname.includes('/share/'); + const { updateParams } = useNavigation(); return ( - {({ data }) => { - return ( - undefined : undefined} - /> - ); - }} + {({ data }) => ( + updateParams({ session: row.id })} + /> + )} ); } diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionsPage.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionsPage.tsx index adce5ec9c..f891f2ad7 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/SessionsPage.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/SessionsPage.tsx @@ -5,6 +5,7 @@ import { WebsiteControls } from '@/app/(main)/websites/[websiteId]/WebsiteContro import { Panel } from '@/components/common/Panel'; import { useMessages } from '@/components/hooks'; import { getItem, setItem } from '@/lib/storage'; +import { SessionModal } from './SessionModal'; import { SessionProperties } from './SessionProperties'; import { SessionsDataTable } from './SessionsDataTable'; @@ -22,6 +23,7 @@ export function SessionsPage({ websiteId }) { return ( + diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx index 69f32afa7..1f3d451a7 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx @@ -16,16 +16,11 @@ export function SessionsTable({ return ( - {(row: any) => { - const href = getSessionHref ? getSessionHref(row) : `/websites/${websiteId}/sessions/${row.id}`; - return href ? ( - - - - ) : ( + {(row: any) => ( + - ); - }} + + )} From c0b17f7787702ccb81c398ada7bfdc88023c0444 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Tue, 31 Mar 2026 13:36:23 -0700 Subject: [PATCH 5/7] Fix session avatar href --- .../sessions/SessionsDataTable.tsx | 19 ++++++++----------- .../[websiteId]/sessions/SessionsPage.tsx | 2 ++ .../[websiteId]/sessions/SessionsTable.tsx | 13 ++++--------- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx index b4714b430..1b8f441a5 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx @@ -4,20 +4,17 @@ import { SessionsTable } from './SessionsTable'; export function SessionsDataTable({ websiteId }: { websiteId: string }) { const queryResult = useWebsiteSessionsQuery(websiteId); - const { pathname } = useNavigation(); - const isSharePage = pathname.includes('/share/'); + const { updateParams } = useNavigation(); return ( - {({ data }) => { - return ( - undefined : undefined} - /> - ); - }} + {({ data }) => ( + updateParams({ session: row.id })} + /> + )} ); } diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionsPage.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionsPage.tsx index adce5ec9c..f891f2ad7 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/SessionsPage.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/SessionsPage.tsx @@ -5,6 +5,7 @@ import { WebsiteControls } from '@/app/(main)/websites/[websiteId]/WebsiteContro import { Panel } from '@/components/common/Panel'; import { useMessages } from '@/components/hooks'; import { getItem, setItem } from '@/lib/storage'; +import { SessionModal } from './SessionModal'; import { SessionProperties } from './SessionProperties'; import { SessionsDataTable } from './SessionsDataTable'; @@ -22,6 +23,7 @@ export function SessionsPage({ websiteId }) { return ( + diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx index 69f32afa7..1f3d451a7 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx @@ -16,16 +16,11 @@ export function SessionsTable({ return ( - {(row: any) => { - const href = getSessionHref ? getSessionHref(row) : `/websites/${websiteId}/sessions/${row.id}`; - return href ? ( - - - - ) : ( + {(row: any) => ( + - ); - }} + + )} From 1d04a02fd8912a68b01dde2d39e5383d5c3c9be0 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Tue, 31 Mar 2026 13:43:03 -0700 Subject: [PATCH 6/7] Hide replays from share page --- .../websites/[websiteId]/sessions/SessionModal.tsx | 4 +++- .../websites/[websiteId]/sessions/SessionProfile.tsx | 12 ++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionModal.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionModal.tsx index a387ec56e..dd9ce4690 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/SessionModal.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/SessionModal.tsx @@ -10,9 +10,11 @@ export interface SessionModalProps extends ModalProps { export function SessionModal({ websiteId, ...props }: SessionModalProps) { const { router, + pathname, query: { session }, updateParams, } = useNavigation(); + const isSharePage = pathname.includes('/share/'); const handleOpenChange = (isOpen: boolean) => { if (!isOpen) { router.push(updateParams({ session: undefined })); @@ -32,7 +34,7 @@ export function SessionModal({ websiteId, ...props }: SessionModalProps) { {({ close }) => ( - close()} /> + close()} /> )} diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionProfile.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionProfile.tsx index 5f94defe5..9671c995e 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/SessionProfile.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/SessionProfile.tsx @@ -23,10 +23,12 @@ import { SessionStats } from './SessionStats'; export function SessionProfile({ websiteId, sessionId, + showReplays = true, onClose, }: { websiteId: string; sessionId: string; + showReplays?: boolean; onClose?: () => void; }) { const { data, isLoading, error } = useWebsiteSessionQuery(websiteId, sessionId); @@ -65,7 +67,7 @@ export function SessionProfile({ {t(labels.activity)} {t(labels.properties)} - {t(labels.replays)} + {showReplays && {t(labels.replays)}} - - - + {showReplays && ( + + + + )} From edbb291628cfc5e0e2e628b5f5a3294f39154fd1 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Tue, 31 Mar 2026 15:15:39 -0700 Subject: [PATCH 7/7] fix undefined share params allowing access to pages --- src/app/share/ShareProvider.tsx | 3 ++- src/app/share/[slug]/[[...path]]/SharePage.tsx | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/app/share/ShareProvider.tsx b/src/app/share/ShareProvider.tsx index a09a3776e..60e989014 100644 --- a/src/app/share/ShareProvider.tsx +++ b/src/app/share/ShareProvider.tsx @@ -27,6 +27,7 @@ const ALL_SECTION_IDS = [ 'events', 'sessions', 'realtime', + 'performance', 'compare', 'breakdown', 'goals', @@ -59,7 +60,7 @@ export function ShareProvider({ slug, children }: { slug: string; children: Reac const isWebsiteShare = share?.shareType === ENTITY_TYPE.website; const allowedSections = isWebsiteShare && share?.parameters - ? ALL_SECTION_IDS.filter(id => share.parameters[id] !== false) + ? ALL_SECTION_IDS.filter(id => share.parameters[id] === true) : []; const shouldRedirect = isWebsiteShare && diff --git a/src/app/share/[slug]/[[...path]]/SharePage.tsx b/src/app/share/[slug]/[[...path]]/SharePage.tsx index a1103ffd9..750097aa1 100644 --- a/src/app/share/[slug]/[[...path]]/SharePage.tsx +++ b/src/app/share/[slug]/[[...path]]/SharePage.tsx @@ -23,7 +23,7 @@ import { useShare } from '@/components/hooks'; import { MobileMenuButton } from '@/components/input/MobileMenuButton'; import { ENTITY_TYPE } from '@/lib/constants'; import { Column, Grid, Row, useTheme } from '@umami/react-zen'; -import { usePathname } from 'next/navigation'; +import { usePathname, useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { ShareFooter } from './ShareFooter'; import { ShareNav } from './ShareNav'; @@ -69,9 +69,10 @@ export function SharePage() { }; const share = useShare(); const { setTheme } = useTheme(); + const router = useRouter(); const pathname = usePathname(); const path = getSharePath(pathname); - const { websiteId, boardId, pixelId, linkId, parameters = {}, shareType } = share; + const { slug, websiteId, boardId, pixelId, linkId, parameters = {}, shareType } = share; useEffect(() => { const url = new URL(window?.location?.href); @@ -102,9 +103,10 @@ export function SharePage() { // Check if the requested path is allowed const pageKey = path || ''; - const isAllowed = pageKey === '' || pageKey === 'overview' || parameters[pageKey] !== false; + const isAllowed = pageKey === '' || parameters[pageKey] === true; if (!isAllowed) { + router.replace(`/share/${slug}`); return null; }