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 && } 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/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)} 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, }); 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} diff --git a/src/lib/request.ts b/src/lib/request.ts index da247e20b..97086c2f4 100644 --- a/src/lib/request.ts +++ b/src/lib/request.ts @@ -83,7 +83,7 @@ export function getRequestFilters(query: Record) { export async function setWebsiteDate(websiteId: string, data: Record) { const website = await fetchWebsite(websiteId); - if (website) { + if (website?.resetAt) { data.startDate = maxDate(data.startDate, new Date(website?.resetAt)); } 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; } 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} 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}