diff --git a/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionActivity.tsx b/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionActivity.tsx
index def3f0ba..3b0ad008 100644
--- a/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionActivity.tsx
+++ b/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionActivity.tsx
@@ -7,16 +7,12 @@ import styles from './SessionActivity.module.css';
export function SessionActivity({
websiteId,
sessionId,
- startDate,
- endDate,
}: {
websiteId: string;
sessionId: string;
- startDate: string;
- endDate: string;
}) {
const { formatDate } = useTimezone();
- const { data, isLoading } = useSessionActivity(websiteId, sessionId, startDate, endDate);
+ const { data, isLoading } = useSessionActivity(websiteId, sessionId);
if (isLoading) {
return ;
diff --git a/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionDetailsPage.tsx b/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionDetailsPage.tsx
index d6a07edc..212f8533 100644
--- a/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionDetailsPage.tsx
+++ b/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionDetailsPage.tsx
@@ -28,12 +28,7 @@ export default function SessionDetailsPage({
-
+
diff --git a/src/components/hooks/queries/useSessionActivity.ts b/src/components/hooks/queries/useSessionActivity.ts
index 94676a99..e6d7ffa0 100644
--- a/src/components/hooks/queries/useSessionActivity.ts
+++ b/src/components/hooks/queries/useSessionActivity.ts
@@ -1,17 +1,12 @@
import { useApi } from './useApi';
-export function useSessionActivity(
- websiteId: string,
- sessionId: string,
- startDate: string,
- endDate: string,
-) {
+export function useSessionActivity(websiteId: string, sessionId: string) {
const { get, useQuery } = useApi();
return useQuery({
queryKey: ['session:activity', { websiteId, sessionId }],
queryFn: () => {
- return get(`/websites/${websiteId}/sessions/${sessionId}/activity`, { startDate, endDate });
+ return get(`/websites/${websiteId}/sessions/${sessionId}/activity`);
},
});
}
diff --git a/src/components/hooks/useFilterParams.ts b/src/components/hooks/useFilterParams.ts
index 343aea9f..525f3492 100644
--- a/src/components/hooks/useFilterParams.ts
+++ b/src/components/hooks/useFilterParams.ts
@@ -1,19 +1,18 @@
import { useNavigation } from './useNavigation';
import { useDateRange } from './useDateRange';
import { useTimezone } from './useTimezone';
-import { zonedTimeToUtc } from 'date-fns-tz';
export function useFilterParams(websiteId: string) {
const { dateRange } = useDateRange(websiteId);
const { startDate, endDate, unit } = dateRange;
- const { timezone } = useTimezone();
+ const { timezone, toUtc } = useTimezone();
const {
query: { url, referrer, title, query, host, os, browser, device, country, region, city, event },
} = useNavigation();
return {
- startAt: +zonedTimeToUtc(startDate, timezone),
- endAt: +zonedTimeToUtc(endDate, timezone),
+ startAt: +toUtc(startDate),
+ endAt: +toUtc(endDate),
unit,
timezone,
url,
diff --git a/src/components/hooks/useTimezone.ts b/src/components/hooks/useTimezone.ts
index b5e58ea9..24cef02c 100644
--- a/src/components/hooks/useTimezone.ts
+++ b/src/components/hooks/useTimezone.ts
@@ -1,6 +1,6 @@
import { setItem } from 'next-basics';
import { TIMEZONE_CONFIG } from 'lib/constants';
-import { formatInTimeZone } from 'date-fns-tz';
+import { formatInTimeZone, zonedTimeToUtc, utcToZonedTime } from 'date-fns-tz';
import useStore, { setTimezone } from 'store/app';
const selector = (state: { timezone: string }) => state.timezone;
@@ -23,7 +23,15 @@ export function useTimezone() {
);
};
- return { timezone, saveTimezone, formatDate };
+ const toUtc = (date: Date | string | number) => {
+ return zonedTimeToUtc(date, timezone);
+ };
+
+ const fromUtc = (date: Date | string | number) => {
+ return utcToZonedTime(date, timezone);
+ };
+
+ return { timezone, saveTimezone, formatDate, toUtc, fromUtc };
}
export default useTimezone;
diff --git a/src/lib/clickhouse.ts b/src/lib/clickhouse.ts
index 78f0323e..63027d75 100644
--- a/src/lib/clickhouse.ts
+++ b/src/lib/clickhouse.ts
@@ -8,6 +8,7 @@ import { filtersToArray } from './params';
import { PageParams, QueryFilters, QueryOptions } from './types';
export const CLICKHOUSE_DATE_FORMATS = {
+ utc: '%Y-%m-%dT%H:%i:%SZ',
second: '%Y-%m-%d %H:%i:%S',
minute: '%Y-%m-%d %H:%i:00',
hour: '%Y-%m-%d %H:00:00',
@@ -47,7 +48,7 @@ function getClient() {
return client;
}
-function getDateStringSQL(data: any, unit: string | number, timezone?: string) {
+function getDateStringSQL(data: any, unit: string = 'utc', timezone?: string) {
if (timezone) {
return `formatDateTime(${data}, '${CLICKHOUSE_DATE_FORMATS[unit]}', '${timezone}')`;
}
diff --git a/src/pages/api/websites/[websiteId]/sessions/[sessionId]/activity.ts b/src/pages/api/websites/[websiteId]/sessions/[sessionId]/activity.ts
index d1a763fb..8d1b2346 100644
--- a/src/pages/api/websites/[websiteId]/sessions/[sessionId]/activity.ts
+++ b/src/pages/api/websites/[websiteId]/sessions/[sessionId]/activity.ts
@@ -9,16 +9,12 @@ import { getSessionActivity } from 'queries';
export interface SessionActivityRequestQuery extends PageParams {
websiteId: string;
sessionId: string;
- startDate: string;
- endDate: string;
}
const schema = {
GET: yup.object().shape({
websiteId: yup.string().uuid().required(),
sessionId: yup.string().uuid().required(),
- startDate: yup.string().required(),
- endDate: yup.string().required(),
}),
};
@@ -30,19 +26,14 @@ export default async (
await useAuth(req, res);
await useValidate(schema, req, res);
- const { websiteId, sessionId, startDate, endDate } = req.query;
+ const { websiteId, sessionId } = req.query;
if (req.method === 'GET') {
if (!(await canViewWebsite(req.auth, websiteId))) {
return unauthorized(res);
}
- const data = await getSessionActivity(
- websiteId,
- sessionId,
- new Date(startDate + 'Z'),
- new Date(endDate + 'Z'),
- );
+ const data = await getSessionActivity(websiteId, sessionId);
return ok(res, data);
}
diff --git a/src/queries/analytics/sessions/getSessionActivity.ts b/src/queries/analytics/sessions/getSessionActivity.ts
index bb7c141c..47c5f590 100644
--- a/src/queries/analytics/sessions/getSessionActivity.ts
+++ b/src/queries/analytics/sessions/getSessionActivity.ts
@@ -2,44 +2,32 @@ import clickhouse from 'lib/clickhouse';
import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db';
import prisma from 'lib/prisma';
-export async function getSessionActivity(
- ...args: [websiteId: string, sessionId: string, startDate: Date, endDate: Date]
-) {
+export async function getSessionActivity(...args: [websiteId: string, sessionId: string]) {
return runQuery({
[PRISMA]: () => relationalQuery(...args),
[CLICKHOUSE]: () => clickhouseQuery(...args),
});
}
-async function relationalQuery(
- websiteId: string,
- sessionId: string,
- startDate: Date,
- endDate: Date,
-) {
+async function relationalQuery(websiteId: string, sessionId: string) {
return prisma.client.websiteEvent.findMany({
where: {
id: sessionId,
websiteId,
- createdAt: { gte: startDate, lte: endDate },
},
+ take: 500,
});
}
-async function clickhouseQuery(
- websiteId: string,
- sessionId: string,
- startDate: Date,
- endDate: Date,
-) {
- const { rawQuery } = clickhouse;
+async function clickhouseQuery(websiteId: string, sessionId: string) {
+ const { rawQuery, getDateStringSQL } = clickhouse;
return rawQuery(
`
select
session_id as id,
website_id as websiteId,
- created_at as createdAt,
+ ${getDateStringSQL('created_at')} as createdAt,
url_path as urlPath,
url_query as urlQuery,
referrer_domain as referrerDomain,
@@ -50,9 +38,9 @@ async function clickhouseQuery(
from website_event
where website_id = {websiteId:UUID}
and session_id = {sessionId:UUID}
- and created_at between {startDate:DateTime64} and {endDate:DateTime64}
order by created_at desc
+ limit 500
`,
- { websiteId, sessionId, startDate, endDate },
+ { websiteId, sessionId },
);
}
diff --git a/src/queries/analytics/sessions/getWebsiteSession.ts b/src/queries/analytics/sessions/getWebsiteSession.ts
index 22c18642..6f672e7d 100644
--- a/src/queries/analytics/sessions/getWebsiteSession.ts
+++ b/src/queries/analytics/sessions/getWebsiteSession.ts
@@ -19,7 +19,7 @@ async function relationalQuery(websiteId: string, sessionId: string) {
}
async function clickhouseQuery(websiteId: string, sessionId: string) {
- const { rawQuery } = clickhouse;
+ const { rawQuery, getDateStringSQL } = clickhouse;
return rawQuery(
`
@@ -34,8 +34,8 @@ async function clickhouseQuery(websiteId: string, sessionId: string) {
country,
subdivision1,
city,
- min(min_time) as firstAt,
- max(max_time) as lastAt,
+ ${getDateStringSQL('min(min_time)')} as firstAt,
+ ${getDateStringSQL('max(max_time)')} as lastAt,
uniq(visit_id) visits,
sum(views) as views,
sum(events) as events,
diff --git a/src/queries/analytics/sessions/getWebsiteSessions.ts b/src/queries/analytics/sessions/getWebsiteSessions.ts
index 60f30b6b..1ea3ef49 100644
--- a/src/queries/analytics/sessions/getWebsiteSessions.ts
+++ b/src/queries/analytics/sessions/getWebsiteSessions.ts
@@ -24,7 +24,7 @@ async function relationalQuery(websiteId: string, filters: QueryFilters, pagePar
}
async function clickhouseQuery(websiteId: string, filters: QueryFilters, pageParams?: PageParams) {
- const { pagedQuery, parseFilters } = clickhouse;
+ const { pagedQuery, parseFilters, getDateStringSQL } = clickhouse;
const { params, dateQuery, filterQuery } = await parseFilters(websiteId, filters);
return pagedQuery(
@@ -42,8 +42,8 @@ async function clickhouseQuery(websiteId: string, filters: QueryFilters, pagePar
country,
subdivision1,
city,
- min(min_time) as firstAt,
- max(max_time) as lastAt,
+ ${getDateStringSQL('min(min_time)')} as firstAt,
+ ${getDateStringSQL('max(max_time)')} as lastAt,
uniq(visit_id) as visits,
sumIf(views, event_type = 1) as views
from website_event_stats_hourly