From 895b41cb783c871e576a0a62f1062dd71cb6daa5 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Mon, 6 Oct 2025 21:15:28 -0700 Subject: [PATCH 1/9] Updated login form. --- src/app/login/LoginForm.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/app/login/LoginForm.tsx b/src/app/login/LoginForm.tsx index 33a2ca711..c1c2c4311 100644 --- a/src/app/login/LoginForm.tsx +++ b/src/app/login/LoginForm.tsx @@ -55,7 +55,12 @@ export function LoginForm() { - + {formatMessage(labels.login)} From 5244d8608b7a46baa9b561fd1cf2e4b3cd6f7423 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Mon, 6 Oct 2025 22:08:33 -0700 Subject: [PATCH 2/9] Fixed links/pixel lookup. --- src/permissions/website.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/permissions/website.ts b/src/permissions/website.ts index 1a6f20341..8bd81517a 100644 --- a/src/permissions/website.ts +++ b/src/permissions/website.ts @@ -1,7 +1,7 @@ import { Auth } from '@/lib/types'; import { PERMISSIONS } from '@/lib/constants'; import { hasPermission } from '@/lib/auth'; -import { getTeamUser, getWebsite } from '@/queries/prisma'; +import { getLink, getPixel, getTeamUser, getWebsite } from '@/queries/prisma'; export async function canViewWebsite({ user, shareToken }: Auth, websiteId: string) { if (user?.isAdmin) { @@ -13,17 +13,21 @@ export async function canViewWebsite({ user, shareToken }: Auth, websiteId: stri } const website = await getWebsite(websiteId); + const link = await getLink(websiteId); + const pixel = await getPixel(websiteId); - if (!website) { + const entity = website || link || pixel; + + if (!entity) { return false; } - if (website.userId) { - return user.id === website.userId; + if (entity.userId) { + return user.id === entity.userId; } - if (website.teamId) { - const teamUser = await getTeamUser(website.teamId, user.id); + if (entity.teamId) { + const teamUser = await getTeamUser(entity.teamId, user.id); return !!teamUser; } From cc3710880c7ec3d2a1d3d7f5cc1c9c1831e78a94 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Mon, 6 Oct 2025 22:50:49 -0700 Subject: [PATCH 3/9] optimize getWebsiteEvent hasData --- src/queries/sql/events/getWebsiteEvents.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/queries/sql/events/getWebsiteEvents.ts b/src/queries/sql/events/getWebsiteEvents.ts index 371c45f66..d4625c2b2 100644 --- a/src/queries/sql/events/getWebsiteEvents.ts +++ b/src/queries/sql/events/getWebsiteEvents.ts @@ -96,7 +96,7 @@ async function clickhouseQuery(websiteId: string, filters: QueryFilters) { page_title as pageTitle, event_type as eventType, event_name as eventName, - event_id IN (SELECT event_id FROM event_data) as hasData + event_id IN (SELECT event_id FROM event_data where website_id = {websiteId:UUID}) as hasData from website_event ${cohortQuery} where website_id = {websiteId:UUID} From 0d67f1fdaa3bc4406caac9bfc2b7bfe42f1a9388 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Mon, 6 Oct 2025 22:56:34 -0700 Subject: [PATCH 4/9] optimize getSessionActivity hasData --- src/queries/sql/sessions/getSessionActivity.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/queries/sql/sessions/getSessionActivity.ts b/src/queries/sql/sessions/getSessionActivity.ts index 06b8a1372..9f1be24ad 100644 --- a/src/queries/sql/sessions/getSessionActivity.ts +++ b/src/queries/sql/sessions/getSessionActivity.ts @@ -57,7 +57,7 @@ async function clickhouseQuery(websiteId: string, sessionId: string, filters: Qu event_type as eventType, event_name as eventName, visit_id as visitId, - event_id IN (SELECT event_id FROM event_data) AS hasData + event_id IN (SELECT event_id FROM event_data where website_id = {websiteId:UUID} and session_id = {sessionId:UUID}) AS hasData from website_event e where e.website_id = {websiteId:UUID} and e.session_id = {sessionId:UUID} From d0aa266dce42f440c607f2f583d7281ab9dd55cc Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Tue, 7 Oct 2025 01:55:19 -0700 Subject: [PATCH 5/9] Fixed resetAt lookup. Added teams GET. --- src/app/api/teams/route.ts | 23 +++++++++++++++++++++-- src/lib/request.ts | 6 +++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/app/api/teams/route.ts b/src/app/api/teams/route.ts index 0d2be6249..2b9985ba4 100644 --- a/src/app/api/teams/route.ts +++ b/src/app/api/teams/route.ts @@ -3,8 +3,27 @@ import { getRandomChars } from '@/lib/generate'; import { unauthorized, json } from '@/lib/response'; import { canCreateTeam } from '@/permissions'; import { uuid } from '@/lib/crypto'; -import { parseRequest } from '@/lib/request'; -import { createTeam } from '@/queries/prisma'; +import { getQueryFilters, parseRequest } from '@/lib/request'; +import { createTeam, getUserTeams } from '@/queries/prisma'; +import { pagingParams } from '@/lib/schema'; + +export async function GET(request: Request) { + const schema = z.object({ + ...pagingParams, + }); + + const { auth, query, error } = await parseRequest(request, schema); + + if (error) { + return error(); + } + + const filters = await getQueryFilters(query); + + const teams = await getUserTeams(auth.user.id, filters); + + return json(teams); +} export async function POST(request: Request) { const schema = z.object({ diff --git a/src/lib/request.ts b/src/lib/request.ts index da247e20b..b48953b51 100644 --- a/src/lib/request.ts +++ b/src/lib/request.ts @@ -1,6 +1,6 @@ import { checkAuth } from '@/lib/auth'; import { DEFAULT_PAGE_SIZE, FILTER_COLUMNS } from '@/lib/constants'; -import { getAllowedUnits, getMinimumUnit, maxDate, parseDateRange } from '@/lib/date'; +import { getAllowedUnits, getMinimumUnit, parseDateRange } from '@/lib/date'; import { fetchWebsite } from '@/lib/load'; import { filtersArrayToObject } from '@/lib/params'; import { badRequest, unauthorized } from '@/lib/response'; @@ -83,8 +83,8 @@ export function getRequestFilters(query: Record) { export async function setWebsiteDate(websiteId: string, data: Record) { const website = await fetchWebsite(websiteId); - if (website) { - data.startDate = maxDate(data.startDate, new Date(website?.resetAt)); + if (website?.resetAt) { + data.startDate = new Date(website.resetAt); } return data; From d440a44d96e939c9b81b806068f2736cf2fcc4e4 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Tue, 7 Oct 2025 09:07:34 -0700 Subject: [PATCH 6/9] clean-up useWebsite query params --- .../hooks/queries/useWebsiteMetricsQuery.ts | 16 +++++++++++----- .../hooks/queries/useWebsitePageviewsQuery.ts | 17 ++++++++++++++--- .../hooks/queries/useWebsiteStatsQuery.ts | 7 ++++--- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/components/hooks/queries/useWebsiteMetricsQuery.ts b/src/components/hooks/queries/useWebsiteMetricsQuery.ts index 8370db8eb..a5ec7ac99 100644 --- a/src/components/hooks/queries/useWebsiteMetricsQuery.ts +++ b/src/components/hooks/queries/useWebsiteMetricsQuery.ts @@ -1,8 +1,8 @@ +import { ReactQueryOptions } from '@/lib/types'; import { keepPreviousData } from '@tanstack/react-query'; import { useApi } from '../useApi'; -import { useFilterParameters } from '../useFilterParameters'; import { useDateParameters } from '../useDateParameters'; -import { ReactQueryOptions } from '@/lib/types'; +import { useFilterParameters } from '../useFilterParameters'; export type WebsiteMetricsData = { x: string; @@ -15,7 +15,7 @@ export function useWebsiteMetricsQuery( options?: ReactQueryOptions, ) { const { get, useQuery } = useApi(); - const date = useDateParameters(); + const { startAt, endAt, unit, timezone } = useDateParameters(); const filters = useFilterParameters(); return useQuery({ @@ -23,14 +23,20 @@ export function useWebsiteMetricsQuery( 'websites:metrics', { websiteId, - ...date, + startAt, + endAt, + unit, + timezone, ...filters, ...params, }, ], queryFn: async () => get(`/websites/${websiteId}/metrics`, { - ...date, + startAt, + endAt, + unit, + timezone, ...filters, ...params, }), diff --git a/src/components/hooks/queries/useWebsitePageviewsQuery.ts b/src/components/hooks/queries/useWebsitePageviewsQuery.ts index 5784cae8e..6f471bab0 100644 --- a/src/components/hooks/queries/useWebsitePageviewsQuery.ts +++ b/src/components/hooks/queries/useWebsitePageviewsQuery.ts @@ -13,12 +13,23 @@ export function useWebsitePageviewsQuery( options?: ReactQueryOptions, ) { const { get, useQuery } = useApi(); - const date = useDateParameters(); + const { startAt, endAt, unit, timezone } = useDateParameters(); const queryParams = useFilterParameters(); return useQuery({ - queryKey: ['websites:pageviews', { websiteId, compare, ...date, ...queryParams }], - queryFn: () => get(`/websites/${websiteId}/pageviews`, { compare, ...date, ...queryParams }), + queryKey: [ + 'websites:pageviews', + { websiteId, compare, startAt, endAt, unit, timezone, ...queryParams }, + ], + queryFn: () => + get(`/websites/${websiteId}/pageviews`, { + compare, + startAt, + endAt, + unit, + timezone, + ...queryParams, + }), enabled: !!websiteId, ...options, }); diff --git a/src/components/hooks/queries/useWebsiteStatsQuery.ts b/src/components/hooks/queries/useWebsiteStatsQuery.ts index 98ae9d8ff..64304b1b9 100644 --- a/src/components/hooks/queries/useWebsiteStatsQuery.ts +++ b/src/components/hooks/queries/useWebsiteStatsQuery.ts @@ -23,12 +23,13 @@ export function useWebsiteStatsQuery( options?: UseQueryOptions, ) { const { get, useQuery } = useApi(); - const date = useDateParameters(); + const { startAt, endAt, unit, timezone } = useDateParameters(); const filters = useFilterParameters(); return useQuery({ - queryKey: ['websites:stats', { websiteId, ...date, ...filters }], - queryFn: () => get(`/websites/${websiteId}/stats`, { ...date, ...filters }), + queryKey: ['websites:stats', { websiteId, startAt, endAt, unit, timezone, ...filters }], + queryFn: () => + get(`/websites/${websiteId}/stats`, { startAt, endAt, unit, timezone, ...filters }), enabled: !!websiteId, ...options, }); From d948e122ea93563f8cc3a15260f99d8c4d457d4e Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Tue, 7 Oct 2025 09:44:59 -0700 Subject: [PATCH 7/9] fix resetAt logic --- src/lib/request.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/request.ts b/src/lib/request.ts index b48953b51..97086c2f4 100644 --- a/src/lib/request.ts +++ b/src/lib/request.ts @@ -1,6 +1,6 @@ import { checkAuth } from '@/lib/auth'; import { DEFAULT_PAGE_SIZE, FILTER_COLUMNS } from '@/lib/constants'; -import { getAllowedUnits, getMinimumUnit, parseDateRange } from '@/lib/date'; +import { getAllowedUnits, getMinimumUnit, maxDate, parseDateRange } from '@/lib/date'; import { fetchWebsite } from '@/lib/load'; import { filtersArrayToObject } from '@/lib/params'; import { badRequest, unauthorized } from '@/lib/response'; @@ -84,7 +84,7 @@ export async function setWebsiteDate(websiteId: string, data: Record Date: Tue, 7 Oct 2025 11:22:58 -0700 Subject: [PATCH 8/9] add max width to listtable label --- src/components/metrics/ListTable.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/metrics/ListTable.tsx b/src/components/metrics/ListTable.tsx index 4e9ee9044..4c98eb5dc 100644 --- a/src/components/metrics/ListTable.tsx +++ b/src/components/metrics/ListTable.tsx @@ -117,7 +117,9 @@ const AnimatedRow = ({ gap > - {label} + + {label} + {change} From bac3ab2c1a6ab1e8fc853b744b9d98e29930fd28 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Tue, 7 Oct 2025 11:35:28 -0700 Subject: [PATCH 9/9] add maxwidth on event/session activity --- src/app/(main)/websites/[websiteId]/events/EventsTable.tsx | 2 +- .../(main)/websites/[websiteId]/sessions/SessionActivity.tsx | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/(main)/websites/[websiteId]/events/EventsTable.tsx b/src/app/(main)/websites/[websiteId]/events/EventsTable.tsx index c36ee5e73..7cefdd274 100644 --- a/src/app/(main)/websites/[websiteId]/events/EventsTable.tsx +++ b/src/app/(main)/websites/[websiteId]/events/EventsTable.tsx @@ -30,7 +30,7 @@ export function EventsTable({ data = [] }) { {formatMessage(row.eventName ? labels.triggeredEvent : labels.viewedPage)} - + {row.eventName || row.urlPath} diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionActivity.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionActivity.tsx index 4dcf08b42..b9f34e485 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/SessionActivity.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/SessionActivity.tsx @@ -59,7 +59,9 @@ export function SessionActivity({ ? formatMessage(labels.triggeredEvent) : formatMessage(labels.viewedPage)} - {eventName || urlPath} + + {eventName || urlPath} + {hasData > 0 && }