fix broken profile page #22
This commit is contained in:
@@ -1,31 +1,25 @@
|
||||
import { Suspense } from 'react';
|
||||
import { start } from 'repl';
|
||||
import PageLayout from '@/app/(app)/[organizationSlug]/[projectId]/page-layout';
|
||||
import ClickToCopy from '@/components/click-to-copy';
|
||||
import { ListPropertiesIcon } from '@/components/events/list-properties-icon';
|
||||
import { ProfileAvatar } from '@/components/profiles/profile-avatar';
|
||||
import { ChartSwitch } from '@/components/report/chart';
|
||||
import { Tooltiper } from '@/components/ui/tooltip';
|
||||
import { Widget, WidgetBody, WidgetHead } from '@/components/widget';
|
||||
import {
|
||||
eventQueryFiltersParser,
|
||||
eventQueryNamesFilter,
|
||||
} from '@/hooks/useEventQueryFilters';
|
||||
import { clipboard } from '@/utils/clipboard';
|
||||
import { getProfileName } from '@/utils/getters';
|
||||
import { CopyIcon } from 'lucide-react';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { parseAsInteger, parseAsString } from 'nuqs';
|
||||
import { toast } from 'sonner';
|
||||
import { parseAsInteger } from 'nuqs';
|
||||
|
||||
import type { GetEventListOptions } from '@openpanel/db';
|
||||
import { getEventList, getEventsCount, getProfileById } from '@openpanel/db';
|
||||
import type { IChartInput } from '@openpanel/validation';
|
||||
import { getProfileById } from '@openpanel/db';
|
||||
|
||||
import { EventList } from '../../events/event-list';
|
||||
import EventListServer from '../../events/event-list';
|
||||
import { StickyBelowHeader } from '../../layout-sticky-below-header';
|
||||
import MostEventsServer from './most-events';
|
||||
import PopularRoutesServer from './popular-routes';
|
||||
import ProfileActivityServer from './profile-activity';
|
||||
import ProfileCharts from './profile-charts';
|
||||
import ProfileMetrics from './profile-metrics';
|
||||
|
||||
interface PageProps {
|
||||
@@ -58,80 +52,8 @@ export default async function Page({
|
||||
eventQueryFiltersParser.parseServerSide(searchParams.f ?? '') ??
|
||||
undefined,
|
||||
};
|
||||
const startDate = parseAsString.parseServerSide(searchParams.startDate);
|
||||
const endDate = parseAsString.parseServerSide(searchParams.endDate);
|
||||
const profile = await getProfileById(profileId, projectId);
|
||||
|
||||
const pageViewsChart: IChartInput = {
|
||||
projectId,
|
||||
startDate,
|
||||
endDate,
|
||||
chartType: 'linear',
|
||||
events: [
|
||||
{
|
||||
segment: 'event',
|
||||
filters: [
|
||||
{
|
||||
id: 'profile_id',
|
||||
name: 'profile_id',
|
||||
operator: 'is',
|
||||
value: [profileId],
|
||||
},
|
||||
],
|
||||
id: 'A',
|
||||
name: '*',
|
||||
displayName: 'Events',
|
||||
},
|
||||
],
|
||||
breakdowns: [
|
||||
{
|
||||
id: 'path',
|
||||
name: 'path',
|
||||
},
|
||||
],
|
||||
lineType: 'monotone',
|
||||
interval: 'day',
|
||||
name: 'Events',
|
||||
range: '30d',
|
||||
previous: false,
|
||||
metric: 'sum',
|
||||
};
|
||||
|
||||
const eventsChart: IChartInput = {
|
||||
projectId,
|
||||
startDate,
|
||||
endDate,
|
||||
chartType: 'linear',
|
||||
events: [
|
||||
{
|
||||
segment: 'event',
|
||||
filters: [
|
||||
{
|
||||
id: 'profile_id',
|
||||
name: 'profile_id',
|
||||
operator: 'is',
|
||||
value: [profileId],
|
||||
},
|
||||
],
|
||||
id: 'A',
|
||||
name: '*',
|
||||
displayName: 'Events',
|
||||
},
|
||||
],
|
||||
breakdowns: [
|
||||
{
|
||||
id: 'name',
|
||||
name: 'name',
|
||||
},
|
||||
],
|
||||
lineType: 'monotone',
|
||||
interval: 'day',
|
||||
name: 'Events',
|
||||
range: '30d',
|
||||
previous: false,
|
||||
metric: 'sum',
|
||||
};
|
||||
|
||||
if (!profile) {
|
||||
return notFound();
|
||||
}
|
||||
@@ -169,37 +91,13 @@ export default async function Page({
|
||||
<div className="col-span-2">
|
||||
<PopularRoutesServer profileId={profileId} projectId={projectId} />
|
||||
</div>
|
||||
<Widget className="col-span-3 w-full">
|
||||
<WidgetHead>
|
||||
<span className="title">Page views</span>
|
||||
</WidgetHead>
|
||||
<WidgetBody className="flex gap-2">
|
||||
<ChartSwitch {...pageViewsChart} />
|
||||
</WidgetBody>
|
||||
</Widget>
|
||||
<Widget className="col-span-3 w-full">
|
||||
<WidgetHead>
|
||||
<span className="title">Events per day</span>
|
||||
</WidgetHead>
|
||||
<WidgetBody className="flex gap-2">
|
||||
<ChartSwitch {...eventsChart} />
|
||||
</WidgetBody>
|
||||
</Widget>
|
||||
|
||||
<ProfileCharts profileId={profileId} projectId={projectId} />
|
||||
</div>
|
||||
<div className="mt-8">
|
||||
<Suspense fallback={<div />}>
|
||||
<EventListServer {...eventListOptions} />
|
||||
</Suspense>
|
||||
<EventListServer {...eventListOptions} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
async function EventListServer(props: GetEventListOptions) {
|
||||
const [events, count] = await Promise.all([
|
||||
getEventList(props),
|
||||
getEventsCount(props),
|
||||
]);
|
||||
return <EventList data={events} count={count} />;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
'use client';
|
||||
|
||||
import { memo } from 'react';
|
||||
import { ChartSwitch } from '@/components/report/chart';
|
||||
import { Widget, WidgetBody, WidgetHead } from '@/components/widget';
|
||||
|
||||
import type { IChartInput } from '@openpanel/validation';
|
||||
|
||||
type Props = {
|
||||
profileId: string;
|
||||
projectId: string;
|
||||
};
|
||||
|
||||
const ProfileCharts = ({ profileId, projectId }: Props) => {
|
||||
const pageViewsChart: IChartInput = {
|
||||
projectId,
|
||||
chartType: 'linear',
|
||||
events: [
|
||||
{
|
||||
segment: 'event',
|
||||
filters: [
|
||||
{
|
||||
id: 'profile_id',
|
||||
name: 'profile_id',
|
||||
operator: 'is',
|
||||
value: [profileId],
|
||||
},
|
||||
],
|
||||
id: 'A',
|
||||
name: '*',
|
||||
displayName: 'Events',
|
||||
},
|
||||
],
|
||||
breakdowns: [
|
||||
{
|
||||
id: 'path',
|
||||
name: 'path',
|
||||
},
|
||||
],
|
||||
lineType: 'monotone',
|
||||
interval: 'day',
|
||||
name: 'Events',
|
||||
range: '30d',
|
||||
previous: false,
|
||||
metric: 'sum',
|
||||
};
|
||||
|
||||
const eventsChart: IChartInput = {
|
||||
projectId,
|
||||
chartType: 'linear',
|
||||
events: [
|
||||
{
|
||||
segment: 'event',
|
||||
filters: [
|
||||
{
|
||||
id: 'profile_id',
|
||||
name: 'profile_id',
|
||||
operator: 'is',
|
||||
value: [profileId],
|
||||
},
|
||||
],
|
||||
id: 'A',
|
||||
name: '*',
|
||||
displayName: 'Events',
|
||||
},
|
||||
],
|
||||
breakdowns: [
|
||||
{
|
||||
id: 'name',
|
||||
name: 'name',
|
||||
},
|
||||
],
|
||||
lineType: 'monotone',
|
||||
interval: 'day',
|
||||
name: 'Events',
|
||||
range: '30d',
|
||||
previous: false,
|
||||
metric: 'sum',
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Widget className="col-span-3 w-full">
|
||||
<WidgetHead>
|
||||
<span className="title">Page views</span>
|
||||
</WidgetHead>
|
||||
<WidgetBody className="flex gap-2">
|
||||
<ChartSwitch {...pageViewsChart} />
|
||||
</WidgetBody>
|
||||
</Widget>
|
||||
<Widget className="col-span-3 w-full">
|
||||
<WidgetHead>
|
||||
<span className="title">Events per day</span>
|
||||
</WidgetHead>
|
||||
<WidgetBody className="flex gap-2">
|
||||
<ChartSwitch {...eventsChart} />
|
||||
</WidgetBody>
|
||||
</Widget>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
// No clue why I need to check for equality here
|
||||
export default memo(ProfileCharts, (a, b) => {
|
||||
return a.profileId === b.profileId && a.projectId === b.projectId;
|
||||
});
|
||||
Reference in New Issue
Block a user