'use client'; import { useOverviewOptions } from '@/components/overview/useOverviewOptions'; import { useEventQueryFilters } from '@/hooks/useEventQueryFilters'; import { cn } from '@/utils/cn'; import { useFormatDateInterval } from '@/hooks/useFormatDateInterval'; import { useNumber } from '@/hooks/useNumerFormatter'; import { type RouterOutputs, api } from '@/trpc/client'; import { getChartColor } from '@/utils/theme'; import { getPreviousMetric } from '@openpanel/common'; import React from 'react'; import { CartesianGrid, Line, LineChart, ResponsiveContainer, XAxis, YAxis, } from 'recharts'; import { createChartTooltip } from '../charts/chart-tooltip'; import { useXAxisProps, useYAxisProps } from '../report-chart/common/axis'; import { PreviousDiffIndicatorPure } from '../report-chart/common/previous-diff-indicator'; import { Skeleton } from '../skeleton'; import { OverviewLiveHistogram } from './overview-live-histogram'; import { OverviewMetricCard } from './overview-metric-card'; interface OverviewMetricsProps { projectId: string; } const TITLES = [ { title: 'Unique Visitors', key: 'unique_visitors', unit: '', inverted: false, }, { title: 'Sessions', key: 'total_sessions', unit: '', inverted: false, }, { title: 'Pageviews', key: 'total_screen_views', unit: '', inverted: false, }, { title: 'Pages per session', key: 'views_per_session', unit: '', inverted: false, }, { title: 'Bounce Rate', key: 'bounce_rate', unit: '%', inverted: true, }, { title: 'Session Duration', key: 'avg_session_duration', unit: 'min', inverted: false, }, ] as const; export default function OverviewMetricsV2({ projectId }: OverviewMetricsProps) { const { range, interval, metric, setMetric, startDate, endDate } = useOverviewOptions(); const [filters] = useEventQueryFilters(); const activeMetric = TITLES[metric]!; const overviewQuery = api.overview.stats.useQuery({ projectId, range, interval, filters, startDate, endDate, }); const data = overviewQuery.data?.series?.map((item) => ({ ...item, timestamp: new Date(item.date).getTime(), })) || []; const xAxisProps = useXAxisProps({ interval: 'day' }); const yAxisProps = useYAxisProps(); return ( <>
{TITLES.map((title, index) => ( setMetric(index)} label={title.title} metric={{ current: overviewQuery.data?.metrics[title.key] ?? 0, previous: overviewQuery.data?.metrics[`prev_${title.key}`], }} unit={title.unit} data={data.map((item) => ({ current: item[title.key], previous: item[`prev_${title.key}`], }))} active={metric === index} isLoading={overviewQuery.isLoading} /> ))}
{activeMetric.title}
{overviewQuery.isLoading && } 90 ? false : { stroke: 'hsl(var(--foreground) / 0.2)', fill: 'hsl(var(--def-100))', strokeWidth: 1.5, r: 3, } } activeDot={{ stroke: 'hsl(var(--foreground) / 0.2)', fill: 'hsl(var(--def-100))', strokeWidth: 2, r: 4, }} /> 90 ? false : { stroke: getChartColor(0), fill: 'hsl(var(--def-100))', strokeWidth: 1.5, r: 3, } } activeDot={{ stroke: getChartColor(0), fill: 'hsl(var(--def-100))', strokeWidth: 2, r: 4, }} />
); } const { Tooltip, TooltipProvider } = createChartTooltip< RouterOutputs['overview']['stats']['series'][number], { metric: (typeof TITLES)[number]; } >(({ context: { metric }, data }) => { const formatDate = useFormatDateInterval('day'); const number = useNumber(); return ( <>
{formatDate(new Date(data.date))}
{metric.title}
{number.formatWithUnit(data[metric.key])} {!!data[`prev_${metric.key}`] && ( ({number.formatWithUnit(data[`prev_${metric.key}`])}) )}
); });