feat: add others metrics in website detail
This commit is contained in:
parent
0e71e073fc
commit
086c8ee3df
@ -3,7 +3,7 @@ import type { AppRouter } from '../../server/trpc/routers';
|
||||
import { httpBatchLink, TRPCClientErrorLike } from '@trpc/client';
|
||||
import { getJWT } from './auth';
|
||||
import { message } from 'antd';
|
||||
import { inferRouterInputs, inferRouterOutputs } from '@trpc/server';
|
||||
import type { inferRouterInputs, inferRouterOutputs } from '@trpc/server';
|
||||
|
||||
export const trpc = createTRPCReact<AppRouter>();
|
||||
|
||||
|
@ -1,11 +1,13 @@
|
||||
import { Table } from 'antd';
|
||||
import { ColumnsType } from 'antd/es/table/interface';
|
||||
import React from 'react';
|
||||
import { trpc } from '../../api/trpc';
|
||||
import { RouterOutput, trpc } from '../../api/trpc';
|
||||
import { useCurrentWorkspaceId } from '../../store/user';
|
||||
import { sum } from 'lodash-es';
|
||||
import millify from 'millify';
|
||||
|
||||
type MetricsItemType = RouterOutput['website']['metrics'][number];
|
||||
|
||||
interface MetricsTableProps {
|
||||
websiteId: string;
|
||||
title: [string, string];
|
||||
@ -35,10 +37,11 @@ export const MetricsTable: React.FC<MetricsTableProps> = React.memo((props) => {
|
||||
|
||||
const total = sum(metrics.map((m) => m.y));
|
||||
|
||||
const columns: ColumnsType<{ x: string; y: number }> = [
|
||||
const columns: ColumnsType<MetricsItemType> = [
|
||||
{
|
||||
title: title[0],
|
||||
dataIndex: 'x',
|
||||
render: (val) => val ?? <span className="italic">(None)</span>,
|
||||
},
|
||||
{
|
||||
title: title[1],
|
||||
@ -55,7 +58,7 @@ export const MetricsTable: React.FC<MetricsTableProps> = React.memo((props) => {
|
||||
lowercase: true,
|
||||
})}
|
||||
</div>
|
||||
<div className="inline-block w-10 relative border-l ml-1 pl-1">
|
||||
<div className="inline-block w-12 relative border-l ml-1 px-1">
|
||||
<div
|
||||
className="bg-blue-300 absolute h-full bg-opacity-25 left-0 top-0 pointer-events-none"
|
||||
style={{ width: `${percent}%` }}
|
||||
|
@ -1,12 +0,0 @@
|
||||
import React from 'react';
|
||||
import { MetricsTable } from './MetricsTable';
|
||||
|
||||
interface PagesTableProps {
|
||||
websiteId: string;
|
||||
startAt: number;
|
||||
endAt: number;
|
||||
}
|
||||
export const PagesTable: React.FC<PagesTableProps> = React.memo((props) => {
|
||||
return <MetricsTable {...props} type="url" title={['Pages', 'Views']} />;
|
||||
});
|
||||
PagesTable.displayName = 'PagesTable';
|
@ -6,7 +6,7 @@ import { trpc } from '../../api/trpc';
|
||||
import { ErrorTip } from '../../components/ErrorTip';
|
||||
import { Loading } from '../../components/Loading';
|
||||
import { NotFoundTip } from '../../components/NotFoundTip';
|
||||
import { PagesTable } from '../../components/website/PagesTable';
|
||||
import { MetricsTable } from '../../components/website/MetricsTable';
|
||||
import { WebsiteOverview } from '../../components/website/WebsiteOverview';
|
||||
import { useCurrentWorkspaceId } from '../../store/user';
|
||||
|
||||
@ -30,21 +30,83 @@ export const WebsiteDetail: React.FC = React.memo(() => {
|
||||
return <NotFoundTip />;
|
||||
}
|
||||
|
||||
const startAt = dayjs().subtract(1, 'day').unix() * 1000;
|
||||
const endAt = dayjs().unix() * 1000;
|
||||
|
||||
return (
|
||||
<div className="py-6">
|
||||
<Card>
|
||||
<Card.Grid hoverable={false} className="!w-full">
|
||||
<WebsiteOverview website={website} />
|
||||
</Card.Grid>
|
||||
<Card.Grid hoverable={false} className="!w-1/2">
|
||||
<PagesTable
|
||||
<Card.Grid hoverable={false} className="!w-1/2 min-h-[470px]">
|
||||
<MetricsTable
|
||||
websiteId={websiteId}
|
||||
startAt={dayjs().subtract(1, 'day').unix() * 1000}
|
||||
endAt={dayjs().unix() * 1000}
|
||||
type="url"
|
||||
title={['Pages', 'Views']}
|
||||
startAt={startAt}
|
||||
endAt={endAt}
|
||||
/>
|
||||
</Card.Grid>
|
||||
<Card.Grid hoverable={false} className="!w-1/2">
|
||||
right
|
||||
<Card.Grid hoverable={false} className="!w-1/2 min-h-[470px]">
|
||||
<MetricsTable
|
||||
websiteId={websiteId}
|
||||
type="referrer"
|
||||
title={['Referrers', 'Views']}
|
||||
startAt={startAt}
|
||||
endAt={endAt}
|
||||
/>
|
||||
</Card.Grid>
|
||||
<Card.Grid hoverable={false} className="!w-1/3 min-h-[470px]">
|
||||
<MetricsTable
|
||||
websiteId={websiteId}
|
||||
type="browser"
|
||||
title={['Browser', 'Visitors']}
|
||||
startAt={startAt}
|
||||
endAt={endAt}
|
||||
/>
|
||||
</Card.Grid>
|
||||
<Card.Grid hoverable={false} className="!w-1/3 min-h-[470px]">
|
||||
<MetricsTable
|
||||
websiteId={websiteId}
|
||||
type="os"
|
||||
title={['OS', 'Visitors']}
|
||||
startAt={startAt}
|
||||
endAt={endAt}
|
||||
/>
|
||||
</Card.Grid>
|
||||
<Card.Grid hoverable={false} className="!w-1/3 min-h-[470px]">
|
||||
<MetricsTable
|
||||
websiteId={websiteId}
|
||||
type="device"
|
||||
title={['Devices', 'Visitors']}
|
||||
startAt={startAt}
|
||||
endAt={endAt}
|
||||
/>
|
||||
</Card.Grid>
|
||||
<Card.Grid hoverable={false} className="!w-2/3 min-h-[470px]">
|
||||
{/* Map */}
|
||||
</Card.Grid>
|
||||
<Card.Grid hoverable={false} className="!w-1/3 min-h-[470px]">
|
||||
<MetricsTable
|
||||
websiteId={websiteId}
|
||||
type="country"
|
||||
title={['Countries', 'Visitors']}
|
||||
startAt={startAt}
|
||||
endAt={endAt}
|
||||
/>
|
||||
</Card.Grid>
|
||||
<Card.Grid hoverable={false} className="!w-1/3 min-h-[470px]">
|
||||
<MetricsTable
|
||||
websiteId={websiteId}
|
||||
type="event"
|
||||
title={['Events', 'Actions']}
|
||||
startAt={startAt}
|
||||
endAt={endAt}
|
||||
/>
|
||||
</Card.Grid>
|
||||
<Card.Grid hoverable={false} className="!w-2/3 min-h-[470px]">
|
||||
{/* Events */}
|
||||
</Card.Grid>
|
||||
</Card>
|
||||
</div>
|
||||
|
@ -292,7 +292,7 @@ export async function getSessionMetrics(
|
||||
const includeCountry = column === 'city' || column === 'subdivision1';
|
||||
|
||||
return prisma.$queryRaw`select
|
||||
${column} x,
|
||||
${Prisma.sql([`"${column}"`])} x,
|
||||
count(distinct "WebsiteEvent"."sessionId") y
|
||||
${includeCountry ? Prisma.sql([', country']) : Prisma.empty}
|
||||
from "WebsiteEvent"
|
||||
|
@ -73,8 +73,8 @@ export const websiteRouter = router({
|
||||
.output(
|
||||
z.array(
|
||||
z.object({
|
||||
x: z.string(),
|
||||
y: z.bigint(),
|
||||
x: z.string().nullable(),
|
||||
y: z.number(),
|
||||
})
|
||||
)
|
||||
)
|
||||
@ -137,16 +137,19 @@ export const websiteRouter = router({
|
||||
}
|
||||
}
|
||||
|
||||
return Object.values(combined);
|
||||
return Object.values(combined).map((d) => ({
|
||||
x: d.x,
|
||||
y: Number(d.y),
|
||||
}));
|
||||
}
|
||||
|
||||
return data;
|
||||
return data.map((d) => ({ x: d.x, y: Number(d.y) }));
|
||||
}
|
||||
|
||||
if (EVENT_COLUMNS.includes(type)) {
|
||||
const data = await getPageviewMetrics(websiteId, column, filters);
|
||||
|
||||
return data;
|
||||
return data.map((d) => ({ x: d.x, y: Number(d.y) }));
|
||||
}
|
||||
|
||||
return [];
|
||||
|
Loading…
Reference in New Issue
Block a user