✨ feat(App): add page tracking

This commit is contained in:
2025-05-28 10:29:48 +00:00
parent bf6d945c61
commit e0f90d5d87
6 changed files with 77 additions and 41 deletions
+7
View File
@@ -1,7 +1,14 @@
import { render, screen } from '@testing-library/react'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { useAnalytics } from 'use-analytics'
import App from './App'
// Mock the analytics module
vi.mock('use-analytics', () => ({
useAnalytics: () => ({ plugins: { enable: vi.fn(), disable: vi.fn() }, page: vi.fn() }),
}))
describe('App component', () => {
test('renders MainPage without crashing', async () => {
render(<App />)
+37 -31
View File
@@ -1,8 +1,8 @@
import React from 'react'
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
import { Backdrop, CircularProgress } from '@mui/material'
import { ErrorPage } from 'components/pages'
import ErrorPage from 'components/pages/ErrorPage/index.js'
import RootLayout from 'components/templates/RouteTracker/index.js'
const MainPage = React.lazy(() => import('components/pages/MainPage'))
const ProjectsPage = React.lazy(() => import('components/pages/ProjectsPage'))
@@ -18,36 +18,42 @@ const Loading = () => (
const router = createBrowserRouter([
{
path: '/',
element: (
<React.Suspense fallback={<Loading />}>
<MainPage />
</React.Suspense>
),
element: <RootLayout />,
errorElement: <ErrorPage />,
},
{
path: '/projects',
element: (
<React.Suspense fallback={<Loading />}>
<ProjectsPage />
</React.Suspense>
),
},
{
path: '/curriculum',
element: (
<React.Suspense fallback={<Loading />}>
<CurriculumPage />
</React.Suspense>
),
},
{
path: '/contacts',
element: (
<React.Suspense fallback={<Loading />}>
<ContactPage />
</React.Suspense>
),
children: [
{
index: true,
element: (
<React.Suspense fallback={<Loading />}>
<MainPage />
</React.Suspense>
),
},
{
path: 'projects',
element: (
<React.Suspense fallback={<Loading />}>
<ProjectsPage />
</React.Suspense>
),
},
{
path: 'curriculum',
element: (
<React.Suspense fallback={<Loading />}>
<CurriculumPage />
</React.Suspense>
),
},
{
path: 'contacts',
element: (
<React.Suspense fallback={<Loading />}>
<ContactPage />
</React.Suspense>
),
},
],
},
])
+1 -1
View File
@@ -100,7 +100,7 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
sx={{
display: 'flex',
// maxWidth: '100%',
// [theme.breakpoints.up('md')]: { width: '80em', mx: 'auto' },
// [theme.breakpoints.up('md')]: { width: theme => theme.breakpoints.values.lg, mx: 'auto' },
}}>
<IconButton
color="primary"
@@ -0,0 +1,19 @@
import { useEffect } from 'react'
import { useAnalytics } from 'use-analytics'
import { Outlet, useLocation } from 'react-router-dom'
/**
* Route tracking component that wraps all routes and includes analytics page tracking
*/
const RouteTracker = () => {
const location = useLocation()
const analytics = useAnalytics()
useEffect(() => {
analytics.page()
}, [analytics, location])
return <Outlet />
}
export default RouteTracker
+2 -1
View File
@@ -1 +1,2 @@
export { default as Page } from './Page'
export { default as Page } from './Page/index.js'
export { default as RouteTracker } from './RouteTracker/index.js'
+11 -8
View File
@@ -1,19 +1,22 @@
/* istanbul ignore file */
import React from 'react'
import ReactDOM from 'react-dom/client'
import { ThemeProvider } from '@mui/material/styles'
import { CssBaseline } from '@mui/material'
import { AnalyticsProvider } from 'use-analytics'
import { ThemeProvider, CssBaseline } from '@mui/material'
import App from './App.tsx'
import theme from 'style/theme.ts'
import analytics from 'components/utils/analytics/index.js'
import theme from 'style/theme.js'
import App from './App.js'
import './index.css'
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(
<React.StrictMode>
<ThemeProvider theme={theme}>
<CssBaseline />
<App />
</ThemeProvider>
<AnalyticsProvider instance={analytics}>
<ThemeProvider theme={theme}>
<CssBaseline />
<App />
</ThemeProvider>
</AnalyticsProvider>
</React.StrictMode>
)