Skip to content

Commit 74f5eba

Browse files
committed
fix: web vitals
1 parent a2f421c commit 74f5eba

File tree

282 files changed

+686
-10853
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

282 files changed

+686
-10853
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@
1414
"editor.codeActionsOnSave": {
1515
"source.fixAll.biome": "explicit",
1616
"source.organizeImports.biome": "explicit"
17-
}
17+
},
18+
"typescript.experimental.useTsgo": false
1819
}

apps/dashboard/app/(main)/websites/[id]/_components/tabs/performance/_components/web-vitals-chart.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ export function WebVitalsChart({
183183
description={`${WEB_VITALS_METRICS.find((m) => m.key === selectedMetric)?.desc || 'Performance metric'} showing percentile distributions over time`}
184184
height={400}
185185
isLoading={isLoading || isRefreshing}
186+
metricsFilter={(metric) =>
187+
metric.category === 'performance' ||
188+
metric.category === 'core_web_vitals'
189+
}
190+
showLegend={false}
186191
title={`${WEB_VITALS_METRICS.find((m) => m.key === selectedMetric)?.label || 'Core Web Vitals'} Performance`}
187192
/>
188193
) : (

apps/dashboard/app/(main)/websites/[id]/flags/page.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ export default function FlagsPage() {
6060
const { data: website } = useWebsite(websiteId);
6161
const { isEnabled } = useFlags();
6262
const experimentFlag = isEnabled('experiment-50');
63-
6463
const {
6564
data: flags,
6665
isLoading,

apps/dashboard/components/charts/metrics-chart.tsx

Lines changed: 101 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@ import {
1818
CardTitle,
1919
} from '@/components/ui/card';
2020
import { cn } from '@/lib/utils';
21-
import { type ChartDataRow, METRIC_COLORS, METRICS } from './metrics-constants';
21+
import {
22+
type ChartDataRow,
23+
METRIC_COLORS,
24+
METRICS,
25+
type MetricConfig,
26+
} from './metrics-constants';
2227
import { SkeletonChart } from './skeleton-chart';
2328

2429
const CustomTooltip = ({
@@ -97,6 +102,8 @@ interface MetricsChartProps {
97102
className?: string;
98103
hiddenMetrics?: Record<string, boolean>;
99104
onToggleMetric?: (metricKey: string) => void;
105+
metricsFilter?: (metric: MetricConfig) => boolean;
106+
showLegend?: boolean;
100107
}
101108

102109
export function MetricsChart({
@@ -108,6 +115,8 @@ export function MetricsChart({
108115
className,
109116
hiddenMetrics = {},
110117
onToggleMetric,
118+
metricsFilter,
119+
showLegend = true,
111120
}: MetricsChartProps) {
112121
const chartData = useMemo(() => data || [], [data]);
113122

@@ -174,15 +183,17 @@ export function MetricsChart({
174183
);
175184
}
176185

177-
const analyticsMetrics = METRICS.filter((metric) =>
178-
[
179-
'pageviews',
180-
'visitors',
181-
'sessions',
182-
'bounce_rate',
183-
'avg_session_duration',
184-
].includes(metric.key)
185-
);
186+
const displayMetrics = metricsFilter
187+
? METRICS.filter(metricsFilter)
188+
: METRICS.filter((metric) =>
189+
[
190+
'pageviews',
191+
'visitors',
192+
'sessions',
193+
'bounce_rate',
194+
'avg_session_duration',
195+
].includes(metric.key)
196+
);
186197

187198
return (
188199
<Card className={cn('w-full overflow-hidden rounded-none p-0', className)}>
@@ -268,85 +279,89 @@ export function MetricsChart({
268279
}}
269280
wrapperStyle={{ outline: 'none' }}
270281
/>
271-
<Legend
272-
align="center"
273-
formatter={(value) => {
274-
const metric = analyticsMetrics.find(
275-
(m) => m.label === value || m.key === value
276-
);
277-
if (!metric) {
278-
// Fallback for unknown metrics
279-
return (
280-
<span className="inline-flex cursor-pointer select-none items-center font-medium text-muted-foreground text-xs capitalize leading-none opacity-100 transition-all duration-200 hover:text-foreground">
281-
{String(value).replace(/_/g, ' ')}
282-
</span>
282+
{showLegend && (
283+
<Legend
284+
align="center"
285+
formatter={(value) => {
286+
const metric = displayMetrics.find(
287+
(m) => m.label === value || m.key === value
283288
);
284-
}
289+
if (!metric) {
290+
// Fallback for unknown metrics
291+
return (
292+
<span className="inline-flex cursor-pointer select-none items-center font-medium text-muted-foreground text-xs capitalize leading-none opacity-100 transition-all duration-200 hover:text-foreground">
293+
{String(value).replace(/_/g, ' ')}
294+
</span>
295+
);
296+
}
285297

286-
const hasData = chartData.some(
287-
(item) =>
288-
metric.key in item &&
289-
item[metric.key] !== undefined &&
290-
item[metric.key] !== null
291-
);
292-
const isHidden = hiddenMetrics[metric.key];
298+
const hasData = chartData.some(
299+
(item) =>
300+
metric.key in item &&
301+
item[metric.key] !== undefined &&
302+
item[metric.key] !== null
303+
);
304+
const isHidden = hiddenMetrics[metric.key];
293305

294-
return (
295-
<span
296-
className={`inline-flex cursor-pointer select-none items-center font-medium text-xs capitalize leading-none transition-all duration-200 ${
297-
isHidden
298-
? 'text-slate-600 line-through decoration-1 opacity-40'
299-
: hasData
300-
? 'text-muted-foreground opacity-100 hover:text-foreground'
301-
: 'text-muted-foreground/60 opacity-60 hover:text-foreground'
302-
}`}
303-
>
304-
{metric.label}
305-
</span>
306-
);
307-
}}
308-
iconSize={10}
309-
iconType="circle"
310-
layout="horizontal"
311-
onClick={(payload) => {
312-
const anyPayload = payload as unknown as {
313-
dataKey?: string | number;
314-
value?: string | number;
315-
id?: string | number;
316-
};
317-
const raw =
318-
anyPayload?.dataKey ?? anyPayload?.value ?? anyPayload?.id;
319-
if (raw == null || !onToggleMetric) {
320-
return;
321-
}
322-
const key = String(raw);
323-
const metric = analyticsMetrics.find(
324-
(m) => m.label === key || m.key === key
325-
);
326-
if (metric) {
327-
onToggleMetric(metric.key);
328-
}
329-
}}
330-
payload={analyticsMetrics.map((metric) => ({
331-
value: metric.label,
332-
type: 'circle',
333-
color: metric.color,
334-
id: metric.key,
335-
dataKey: metric.key,
336-
}))}
337-
verticalAlign="bottom"
338-
wrapperStyle={{
339-
display: 'flex',
340-
justifyContent: 'center',
341-
gap: 12,
342-
fontSize: '12px',
343-
paddingTop: '20px',
344-
bottom: chartData.length > 5 ? 35 : 5,
345-
fontWeight: 500,
346-
cursor: 'pointer',
347-
}}
348-
/>
349-
{analyticsMetrics.map((metric) => {
306+
return (
307+
<span
308+
className={`inline-flex cursor-pointer select-none items-center font-medium text-xs capitalize leading-none transition-all duration-200 ${
309+
isHidden
310+
? 'text-slate-600 line-through decoration-1 opacity-40'
311+
: hasData
312+
? 'text-muted-foreground opacity-100 hover:text-foreground'
313+
: 'text-muted-foreground/60 opacity-60 hover:text-foreground'
314+
}`}
315+
>
316+
{metric.label}
317+
</span>
318+
);
319+
}}
320+
iconSize={10}
321+
iconType="circle"
322+
layout="horizontal"
323+
onClick={(payload) => {
324+
const anyPayload = payload as unknown as {
325+
dataKey?: string | number;
326+
value?: string | number;
327+
id?: string | number;
328+
};
329+
const raw =
330+
anyPayload?.dataKey ??
331+
anyPayload?.value ??
332+
anyPayload?.id;
333+
if (raw == null || !onToggleMetric) {
334+
return;
335+
}
336+
const key = String(raw);
337+
const metric = displayMetrics.find(
338+
(m) => m.label === key || m.key === key
339+
);
340+
if (metric) {
341+
onToggleMetric(metric.key);
342+
}
343+
}}
344+
payload={displayMetrics.map((metric) => ({
345+
value: metric.label,
346+
type: 'circle',
347+
color: metric.color,
348+
id: metric.key,
349+
dataKey: metric.key,
350+
}))}
351+
verticalAlign="bottom"
352+
wrapperStyle={{
353+
display: 'flex',
354+
justifyContent: 'center',
355+
gap: 12,
356+
fontSize: '12px',
357+
paddingTop: '20px',
358+
bottom: chartData.length > 5 ? 35 : 5,
359+
fontWeight: 500,
360+
cursor: 'pointer',
361+
}}
362+
/>
363+
)}
364+
{displayMetrics.map((metric) => {
350365
const hasData = chartData.some(
351366
(item) =>
352367
metric.key in item &&

apps/dashboard/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"dev": "next dev --turbopack -p 3000",
77
"build": "next build --turbopack",
88
"start": "next start -p 3000",
9-
"typecheck": "tsc --noEmit",
9+
"typecheck": "tsgo --noEmit",
1010
"build:script": "bun build ./public/databuddy.ts --outfile ./public/databuddy.js --minify"
1111
},
1212
"dependencies": {

0 commit comments

Comments
 (0)