feat: add session count
This commit is contained in:
parent
90166346e8
commit
d5acf872a9
@ -140,5 +140,9 @@ export function useWorkspaceWebsitePageview(
|
||||
}
|
||||
);
|
||||
|
||||
return { stats: data?.stats ?? [], isLoading };
|
||||
return {
|
||||
pageviews: data?.pageviews ?? [],
|
||||
sessions: data?.sessions ?? [],
|
||||
isLoading,
|
||||
};
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ const WebsiteOverviewItem: React.FC<{
|
||||
const startDate = dayjs().subtract(1, 'day').add(1, unit).startOf(unit);
|
||||
const endDate = dayjs().endOf(unit);
|
||||
|
||||
const { stats, isLoading } = useWorkspaceWebsitePageview(
|
||||
const { pageviews, sessions, isLoading } = useWorkspaceWebsitePageview(
|
||||
props.website.workspaceId,
|
||||
props.website.id,
|
||||
startDate.unix() * 1000,
|
||||
@ -55,8 +55,14 @@ const WebsiteOverviewItem: React.FC<{
|
||||
);
|
||||
|
||||
const chartData = useMemo(() => {
|
||||
return getDateArray(stats, startDate, endDate, unit);
|
||||
}, [stats, unit]);
|
||||
const pageviewsArr = getDateArray(pageviews, startDate, endDate, unit);
|
||||
const sessionsArr = getDateArray(sessions, startDate, endDate, unit);
|
||||
|
||||
return [
|
||||
...pageviewsArr.map((item) => ({ ...item, type: 'pageview' })),
|
||||
...sessionsArr.map((item) => ({ ...item, type: 'session' })),
|
||||
];
|
||||
}, [pageviews, sessions, unit]);
|
||||
|
||||
if (isLoading) {
|
||||
return <Loading />;
|
||||
@ -138,14 +144,16 @@ const MetricCard: React.FC<{
|
||||
MetricCard.displayName = 'MetricCard';
|
||||
|
||||
export const StatsChart: React.FC<{
|
||||
data: { x: string; y: number }[];
|
||||
data: { x: string; y: number; type: string }[];
|
||||
unit: DateUnit;
|
||||
}> = React.memo((props) => {
|
||||
const config: ColumnConfig = useMemo(
|
||||
() => ({
|
||||
data: props.data,
|
||||
isStack: true,
|
||||
xField: 'x',
|
||||
yField: 'y',
|
||||
seriesField: 'type',
|
||||
label: {
|
||||
position: 'middle' as const,
|
||||
style: {
|
||||
|
@ -104,32 +104,6 @@ export async function deleteWorkspaceWebsite(
|
||||
return website;
|
||||
}
|
||||
|
||||
export async function getWorkspaceWebsitePageviewStats(
|
||||
websiteId: string,
|
||||
filters: QueryFilters
|
||||
) {
|
||||
const { timezone = 'utc', unit = 'day' } = filters;
|
||||
const { filterQuery, joinSession, params } = await parseFilters(websiteId, {
|
||||
...filters,
|
||||
eventType: EVENT_TYPE.pageView,
|
||||
});
|
||||
|
||||
return prisma.$queryRaw`
|
||||
select
|
||||
${getDateQuery('"WebsiteEvent"."createdAt"', unit, timezone)} x,
|
||||
count(1) y
|
||||
from "WebsiteEvent"
|
||||
${joinSession ? Prisma.sql([joinSession]) : Prisma.empty}
|
||||
where "WebsiteEvent"."websiteId" = ${params.websiteId}::uuid
|
||||
and "WebsiteEvent"."createdAt" between ${
|
||||
params.startDate
|
||||
}::timestamptz and ${params.endDate}::timestamptz
|
||||
and "WebsiteEvent"."eventType" = ${EVENT_TYPE.pageView}
|
||||
${filterQuery}
|
||||
group by 1
|
||||
`;
|
||||
}
|
||||
|
||||
export async function getWorkspaceWebsiteDateRange(websiteId: string) {
|
||||
const { params } = await parseFilters(websiteId, {
|
||||
startDate: new Date(DEFAULT_RESET_DATE),
|
||||
@ -155,3 +129,53 @@ export async function getWorkspaceWebsiteDateRange(websiteId: string) {
|
||||
min: res._min.createdAt,
|
||||
};
|
||||
}
|
||||
|
||||
export async function getWorkspaceWebsitePageviewStats(
|
||||
websiteId: string,
|
||||
filters: QueryFilters
|
||||
) {
|
||||
const { timezone = 'utc', unit = 'day' } = filters;
|
||||
const { filterQuery, joinSession, params } = await parseFilters(websiteId, {
|
||||
...filters,
|
||||
});
|
||||
|
||||
return prisma.$queryRaw`
|
||||
select
|
||||
${getDateQuery('"WebsiteEvent"."createdAt"', unit, timezone)} x,
|
||||
count(1) y
|
||||
from "WebsiteEvent"
|
||||
${joinSession}
|
||||
where "WebsiteEvent"."websiteId" = ${params.websiteId}::uuid
|
||||
and "WebsiteEvent"."createdAt" between ${
|
||||
params.startDate
|
||||
}::timestamptz and ${params.endDate}::timestamptz
|
||||
and "WebsiteEvent"."eventType" = ${EVENT_TYPE.pageView}
|
||||
${filterQuery}
|
||||
group by 1
|
||||
`;
|
||||
}
|
||||
|
||||
export async function getWorkspaceWebsiteSessionStats(
|
||||
websiteId: string,
|
||||
filters: QueryFilters
|
||||
) {
|
||||
const { timezone = 'utc', unit = 'day' } = filters;
|
||||
const { filterQuery, joinSession, params } = await parseFilters(websiteId, {
|
||||
...filters,
|
||||
});
|
||||
|
||||
return prisma.$queryRaw`
|
||||
select
|
||||
${getDateQuery('"WebsiteEvent"."createdAt"', unit, timezone)} x,
|
||||
count(distinct "WebsiteEvent"."sessionId") y
|
||||
from "WebsiteEvent"
|
||||
${joinSession}
|
||||
where "WebsiteEvent"."websiteId" = ${params.websiteId}::uuid
|
||||
and "WebsiteEvent"."createdAt" between ${
|
||||
params.startDate
|
||||
}::timestamptz and ${params.endDate}::timestamptz
|
||||
and "WebsiteEvent"."eventType" = ${EVENT_TYPE.pageView}
|
||||
${filterQuery}
|
||||
group by 1
|
||||
`;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
getWorkspaceWebsiteInfo,
|
||||
getWorkspaceWebsitePageviewStats,
|
||||
getWorkspaceWebsites,
|
||||
getWorkspaceWebsiteSessionStats,
|
||||
updateWorkspaceWebsiteInfo,
|
||||
} from '../model/workspace';
|
||||
import { parseDateRange } from '../utils/common';
|
||||
@ -186,11 +187,11 @@ workspaceRouter.get(
|
||||
city,
|
||||
};
|
||||
|
||||
const stats = await getWorkspaceWebsitePageviewStats(
|
||||
websiteId,
|
||||
filters as QueryFilters
|
||||
);
|
||||
const [pageviews, sessions] = await Promise.all([
|
||||
getWorkspaceWebsitePageviewStats(websiteId, filters as QueryFilters),
|
||||
getWorkspaceWebsiteSessionStats(websiteId, filters as QueryFilters),
|
||||
]);
|
||||
|
||||
res.json({ stats });
|
||||
res.json({ pageviews, sessions });
|
||||
}
|
||||
);
|
||||
|
@ -58,8 +58,10 @@ export async function parseFilters(
|
||||
([key, value]) =>
|
||||
typeof value !== 'undefined' && SESSION_COLUMNS.includes(key)
|
||||
)
|
||||
? `inner join "WebsiteSession" on "WebsiteEvent"."sessionId" = "WebsiteSession"."id"`
|
||||
: '',
|
||||
? Prisma.sql([
|
||||
`inner join "WebsiteSession" on "WebsiteEvent"."sessionId" = "WebsiteSession"."id"`,
|
||||
])
|
||||
: Prisma.empty,
|
||||
filterQuery: getFilterQuery(filters, options, websiteDomain),
|
||||
params: {
|
||||
...normalizeFilters(filters),
|
||||
|
Loading…
Reference in New Issue
Block a user