* esm * wip * wip * wip * wip * wip * wip * subscription notice * wip * wip * wip * fix envs * fix: update docker build * fix * esm/types * delete dashboard :D * add patches to dockerfiles * update packages + catalogs + ts * wip * remove native libs * ts * improvements * fix redirects and fetching session * try fix favicon * fixes * fix * order and resize reportds within a dashboard * improvements * wip * added userjot to dashboard * fix * add op * wip * different cache key * improve date picker * fix table * event details loading * redo onboarding completely * fix login * fix * fix * extend session, billing and improve bars * fix * reduce price on 10M
141 lines
4.0 KiB
TypeScript
141 lines
4.0 KiB
TypeScript
import FullPageLoadingState from '@/components/full-page-loading-state';
|
|
import { LatestEvents } from '@/components/profiles/latest-events';
|
|
import { MostEvents } from '@/components/profiles/most-events';
|
|
import { PopularRoutes } from '@/components/profiles/popular-routes';
|
|
import { ProfileActivity } from '@/components/profiles/profile-activity';
|
|
import { ProfileCharts } from '@/components/profiles/profile-charts';
|
|
import { ProfileMetrics } from '@/components/profiles/profile-metrics';
|
|
import { ProfileProperties } from '@/components/profiles/profile-properties';
|
|
import { useTRPC } from '@/integrations/trpc/react';
|
|
import { useSuspenseQuery } from '@tanstack/react-query';
|
|
import { createFileRoute } from '@tanstack/react-router';
|
|
|
|
export const Route = createFileRoute(
|
|
'/_app/$organizationId/$projectId_/profiles/$profileId/_tabs/',
|
|
)({
|
|
component: Component,
|
|
loader: async ({ context, params }) => {
|
|
// Prefetch all profile data
|
|
await Promise.all([
|
|
context.queryClient.prefetchQuery(
|
|
context.trpc.profile.metrics.queryOptions({
|
|
profileId: params.profileId,
|
|
projectId: params.projectId,
|
|
}),
|
|
),
|
|
context.queryClient.prefetchQuery(
|
|
context.trpc.profile.activity.queryOptions({
|
|
profileId: params.profileId,
|
|
projectId: params.projectId,
|
|
}),
|
|
),
|
|
context.queryClient.prefetchQuery(
|
|
context.trpc.profile.mostEvents.queryOptions({
|
|
profileId: params.profileId,
|
|
projectId: params.projectId,
|
|
}),
|
|
),
|
|
context.queryClient.prefetchQuery(
|
|
context.trpc.profile.popularRoutes.queryOptions({
|
|
profileId: params.profileId,
|
|
projectId: params.projectId,
|
|
}),
|
|
),
|
|
context.queryClient.prefetchQuery(
|
|
context.trpc.event.events.queryOptions({
|
|
profileId: params.profileId,
|
|
projectId: params.projectId,
|
|
}),
|
|
),
|
|
]);
|
|
},
|
|
pendingComponent: FullPageLoadingState,
|
|
});
|
|
|
|
function Component() {
|
|
const { profileId, projectId, organizationId } = Route.useParams();
|
|
const trpc = useTRPC();
|
|
|
|
// Get profile data from parent route
|
|
const profile = useSuspenseQuery(
|
|
trpc.profile.byId.queryOptions({
|
|
profileId,
|
|
projectId,
|
|
}),
|
|
);
|
|
|
|
const metrics = useSuspenseQuery(
|
|
trpc.profile.metrics.queryOptions({
|
|
profileId,
|
|
projectId,
|
|
}),
|
|
);
|
|
|
|
const activity = useSuspenseQuery(
|
|
trpc.profile.activity.queryOptions({
|
|
profileId,
|
|
projectId,
|
|
}),
|
|
);
|
|
|
|
const mostEvents = useSuspenseQuery(
|
|
trpc.profile.mostEvents.queryOptions({
|
|
profileId,
|
|
projectId,
|
|
}),
|
|
);
|
|
|
|
const popularRoutes = useSuspenseQuery(
|
|
trpc.profile.popularRoutes.queryOptions({
|
|
profileId,
|
|
projectId,
|
|
}),
|
|
);
|
|
|
|
return (
|
|
<>
|
|
{/* Main content grid */}
|
|
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
<div className="col-span-1 md:col-span-2">
|
|
<ProfileMetrics data={metrics.data} />
|
|
</div>
|
|
{/* Profile properties - full width */}
|
|
<div className="col-span-1 md:col-span-2">
|
|
<ProfileProperties profile={profile.data!} />
|
|
</div>
|
|
|
|
{/* Heatmap / Activity */}
|
|
<div className="col-span-1">
|
|
<ProfileActivity data={activity.data} />
|
|
</div>
|
|
|
|
{/* Latest events */}
|
|
<div className="col-span-1">
|
|
<LatestEvents
|
|
profileId={profileId}
|
|
projectId={projectId}
|
|
organizationId={organizationId}
|
|
/>
|
|
</div>
|
|
|
|
{/* Most events */}
|
|
<div className="col-span-1">
|
|
<MostEvents data={mostEvents.data} />
|
|
</div>
|
|
|
|
{/* Popular routes */}
|
|
<div className="col-span-1">
|
|
<PopularRoutes data={popularRoutes.data} />
|
|
</div>
|
|
|
|
{/* Charts - spans both columns */}
|
|
<div className="col-span-1 md:col-span-2">
|
|
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
<ProfileCharts profileId={profileId} projectId={projectId} />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|