feature(dashboard): refactor overview

fix(lint)
This commit is contained in:
Carl-Gerhard Lindesvärd
2025-03-20 09:28:54 +01:00
committed by Carl-Gerhard Lindesvärd
parent b035c0d586
commit a1eb4a296f
83 changed files with 59167 additions and 32403 deletions

View File

@@ -9,11 +9,12 @@ type Props = {
};
const Conversions = ({ projectId }: Props) => {
const query = api.event.conversions.useQuery(
const query = api.event.conversions.useInfiniteQuery(
{
projectId,
},
{
getNextPageParam: (lastPage) => lastPage.meta.next,
keepPreviousData: true,
},
);

View File

@@ -5,13 +5,13 @@ import EventListener from '@/components/events/event-listener';
import { EventsTable } from '@/components/events/table';
import { OverviewFiltersButtons } from '@/components/overview/filters/overview-filters-buttons';
import { OverviewFiltersDrawer } from '@/components/overview/filters/overview-filters-drawer';
import {
useEventQueryFilters,
useEventQueryNamesFilter,
} from '@/hooks/useEventQueryFilters';
import { Button } from '@/components/ui/button';
import { useEventQueryFilters } from '@/hooks/useEventQueryFilters';
import { pushModal } from '@/modals';
import { api } from '@/trpc/client';
import { Loader2Icon } from 'lucide-react';
import { parseAsInteger, useQueryState } from 'nuqs';
import { format } from 'date-fns';
import { CalendarIcon, Loader2Icon } from 'lucide-react';
import { parseAsIsoDateTime, useQueryState } from 'nuqs';
type Props = {
projectId: string;
@@ -20,21 +20,22 @@ type Props = {
const Events = ({ projectId, profileId }: Props) => {
const [filters] = useEventQueryFilters();
const [eventNames] = useEventQueryNamesFilter();
const [cursor, setCursor] = useQueryState(
'cursor',
parseAsInteger.withDefault(0),
const [startDate, setStartDate] = useQueryState(
'startDate',
parseAsIsoDateTime,
);
const query = api.event.events.useQuery(
const [endDate, setEndDate] = useQueryState('endDate', parseAsIsoDateTime);
const query = api.event.events.useInfiniteQuery(
{
cursor,
projectId,
take: 50,
events: eventNames,
filters,
profileId,
startDate: startDate || undefined,
endDate: endDate || undefined,
},
{
getNextPageParam: (lastPage) => lastPage.meta.next,
keepPreviousData: true,
},
);
@@ -43,6 +44,25 @@ const Events = ({ projectId, profileId }: Props) => {
<div>
<TableButtons>
<EventListener onRefresh={() => query.refetch()} />
<Button
variant="outline"
size="sm"
icon={CalendarIcon}
onClick={() => {
pushModal('DateRangerPicker', {
onChange: ({ startDate, endDate }) => {
setStartDate(startDate);
setEndDate(endDate);
},
startDate: startDate || undefined,
endDate: endDate || undefined,
});
}}
>
{startDate && endDate
? `${format(startDate, 'MMM d')} - ${format(endDate, 'MMM d')}`
: 'Date range'}
</Button>
<OverviewFiltersDrawer
mode="events"
projectId={projectId}
@@ -58,7 +78,7 @@ const Events = ({ projectId, profileId }: Props) => {
</div>
)}
</TableButtons>
<EventsTable query={query} cursor={cursor} setCursor={setCursor} />
<EventsTable query={query} />
</div>
);
};

View File

@@ -1,7 +1,6 @@
import { OverviewFiltersButtons } from '@/components/overview/filters/overview-filters-buttons';
import { OverviewFiltersDrawer } from '@/components/overview/filters/overview-filters-drawer';
import ServerLiveCounter from '@/components/overview/live-counter';
import OverviewMetrics from '@/components/overview/overview-metrics';
import OverviewShareServer from '@/components/overview/overview-share';
import OverviewTopDevices from '@/components/overview/overview-top-devices';
import OverviewTopEvents from '@/components/overview/overview-top-events';
@@ -10,6 +9,7 @@ import OverviewTopPages from '@/components/overview/overview-top-pages';
import OverviewTopSources from '@/components/overview/overview-top-sources';
import { OverviewInterval } from '@/components/overview/overview-interval';
import OverviewMetricsV2 from '@/components/overview/overview-metrics-v2';
import { OverviewRange } from '@/components/overview/overview-range';
interface PageProps {
@@ -36,7 +36,8 @@ export default function Page({ params: { projectId } }: PageProps) {
<OverviewFiltersButtons />
</div>
<div className="grid grid-cols-6 gap-4 p-4 pt-0">
<OverviewMetrics projectId={projectId} />
{/* <OverviewMetrics projectId={projectId} /> */}
<OverviewMetricsV2 projectId={projectId} />
<OverviewTopSources projectId={projectId} />
<OverviewTopPages projectId={projectId} />
<OverviewTopDevices projectId={projectId} />

View File

@@ -4,15 +4,9 @@ import { TableButtons } from '@/components/data-table';
import { EventsTable } from '@/components/events/table';
import { OverviewFiltersButtons } from '@/components/overview/filters/overview-filters-buttons';
import { OverviewFiltersDrawer } from '@/components/overview/filters/overview-filters-drawer';
import {
useEventQueryFilters,
useEventQueryNamesFilter,
} from '@/hooks/useEventQueryFilters';
import { useEventQueryFilters } from '@/hooks/useEventQueryFilters';
import { api } from '@/trpc/client';
import { Loader2Icon } from 'lucide-react';
import { parseAsInteger, useQueryState } from 'nuqs';
import { GetEventListOptions } from '@openpanel/db';
type Props = {
projectId: string;
@@ -21,21 +15,14 @@ type Props = {
const Events = ({ projectId, profileId }: Props) => {
const [filters] = useEventQueryFilters();
const [eventNames] = useEventQueryNamesFilter();
const [cursor, setCursor] = useQueryState(
'cursor',
parseAsInteger.withDefault(0),
);
const query = api.event.events.useQuery(
const query = api.event.events.useInfiniteQuery(
{
cursor,
projectId,
take: 50,
events: eventNames,
filters,
profileId,
},
{
getNextPageParam: (lastPage) => lastPage.meta.next,
keepPreviousData: true,
},
);
@@ -58,7 +45,7 @@ const Events = ({ projectId, profileId }: Props) => {
</div>
)}
</TableButtons>
<EventsTable query={query} cursor={cursor} setCursor={setCursor} />
<EventsTable query={query} />
</div>
);
};

View File

@@ -49,24 +49,13 @@ const Map = ({ markers }: Props) => {
const boundingBox = getBoundingBox(hull);
const [zoom] = useAnimatedState(
markers.length === 1
? 20
? 1
: determineZoom(boundingBox, size ? size?.height / size?.width : 1),
);
const [long] = useAnimatedState(center.long);
const [lat] = useAnimatedState(center.lat);
useEffect(() => {
requestAnimationFrame(() => {
if (ref.current) {
setSize({
width: ref.current.clientWidth,
height: ref.current.clientHeight,
});
}
});
}, [isFullscreen]);
useEffect(() => {
return bind(window, {
type: 'resize',
@@ -95,20 +84,12 @@ const Map = ({ markers }: Props) => {
const theme = useTheme();
return (
<div
className={cn(
'fixed bottom-0 left-0 right-0 top-0',
!isFullscreen && 'lg:left-72',
)}
ref={ref}
>
<div className={cn('absolute bottom-0 left-0 right-0 top-0')} ref={ref}>
{size === null ? (
<></>
) : (
<>
<ComposableMap
width={size?.width}
height={size?.height}
projection="geoMercator"
projectionConfig={{
rotate: [0, 0, 0],