diff --git a/src/app/share/ShareProvider.tsx b/src/app/share/ShareProvider.tsx index fe4b5b3a..5b0ca12e 100644 --- a/src/app/share/ShareProvider.tsx +++ b/src/app/share/ShareProvider.tsx @@ -1,6 +1,7 @@ 'use client'; import { Loading } from '@umami/react-zen'; -import { createContext, type ReactNode } from 'react'; +import { usePathname, useRouter } from 'next/navigation'; +import { createContext, type ReactNode, useEffect } from 'react'; import { useShareTokenQuery } from '@/components/hooks'; import type { WhiteLabel } from '@/lib/types'; @@ -14,14 +15,48 @@ export interface ShareData { export const ShareContext = createContext(null); +const ALL_SECTION_IDS = [ + 'overview', + 'events', + 'sessions', + 'realtime', + 'compare', + 'breakdown', + 'goals', + 'funnels', + 'journeys', + 'retention', + 'utm', + 'revenue', + 'attribution', +]; + export function ShareProvider({ shareId, children }: { shareId: string; children: ReactNode }) { const { share, isLoading, isFetching } = useShareTokenQuery(shareId); + const router = useRouter(); + const pathname = usePathname(); + const path = pathname.split('/')[3]; + + const allowedSections = share?.parameters + ? ALL_SECTION_IDS.filter(id => share.parameters[id] !== false) + : []; + + const shouldRedirect = + allowedSections.length === 1 && + allowedSections[0] !== 'overview' && + (path === undefined || path === '' || path === 'overview'); + + useEffect(() => { + if (shouldRedirect) { + router.replace(`/share/${shareId}/${allowedSections[0]}`); + } + }, [shouldRedirect, shareId, allowedSections, router]); if (isFetching && isLoading) { return ; } - if (!share) { + if (!share || shouldRedirect) { return null; } diff --git a/src/app/share/[...shareId]/SharePage.tsx b/src/app/share/[...shareId]/SharePage.tsx index aa0361c6..5d93fd96 100644 --- a/src/app/share/[...shareId]/SharePage.tsx +++ b/src/app/share/[...shareId]/SharePage.tsx @@ -1,7 +1,7 @@ 'use client'; import { Column, Grid, Row, useTheme } from '@umami/react-zen'; -import { usePathname, useRouter } from 'next/navigation'; -import { useEffect, useMemo } from 'react'; +import { usePathname } from 'next/navigation'; +import { useEffect } from 'react'; import { AttributionPage } from '@/app/(main)/websites/[websiteId]/(reports)/attribution/AttributionPage'; import { BreakdownPage } from '@/app/(main)/websites/[websiteId]/(reports)/breakdown/BreakdownPage'; import { FunnelsPage } from '@/app/(main)/websites/[websiteId]/(reports)/funnels/FunnelsPage'; @@ -39,38 +39,13 @@ const PAGE_COMPONENTS: Record attribution: AttributionPage, }; -// All section IDs that can be enabled/disabled via parameters -const ALL_SECTION_IDS = [ - 'overview', - 'events', - 'sessions', - 'realtime', - 'compare', - 'breakdown', - 'goals', - 'funnels', - 'journeys', - 'retention', - 'utm', - 'revenue', - 'attribution', -]; - -export function SharePage({ shareId }: { shareId: string }) { +export function SharePage() { const share = useShare(); const { setTheme } = useTheme(); - const router = useRouter(); const pathname = usePathname(); const path = pathname.split('/')[3]; const { websiteId, parameters = {} } = share; - // Calculate allowed sections - const allowedSections = useMemo(() => { - if (!share?.parameters) return []; - const params = share.parameters; - return ALL_SECTION_IDS.filter(id => params[id] !== false); - }, [share?.parameters]); - useEffect(() => { const url = new URL(window?.location?.href); const theme = url.searchParams.get('theme'); @@ -80,26 +55,6 @@ export function SharePage({ shareId }: { shareId: string }) { } }, []); - // Redirect to the only allowed section if there's just one and we're on the base path - useEffect(() => { - if ( - allowedSections.length === 1 && - allowedSections[0] !== 'overview' && - (path === '' || path === 'overview') - ) { - router.replace(`/share/${shareId}/${allowedSections[0]}`); - } - }, [allowedSections, shareId, path, router]); - - // Redirect to only allowed section - return null while redirecting - if ( - allowedSections.length === 1 && - allowedSections[0] !== 'overview' && - (path === '' || path === 'overview') - ) { - return null; - } - // Check if the requested path is allowed const pageKey = path || ''; const isAllowed = pageKey === '' || pageKey === 'overview' || parameters[pageKey] !== false; diff --git a/src/app/share/[...shareId]/page.tsx b/src/app/share/[...shareId]/page.tsx index 7d080fe5..f21e1979 100644 --- a/src/app/share/[...shareId]/page.tsx +++ b/src/app/share/[...shareId]/page.tsx @@ -7,7 +7,7 @@ export default async function ({ params }: { params: Promise<{ shareId: string[] return ( - + ); }