Skip to content

Commit 4737bd7

Browse files
committed
Add user traits endpoints and refactor analytics API structure
- Introduced new user traits endpoints: `fetchUserTraitKeys`, `fetchUserTraitValues`, and `fetchUserTraitValueUsers` to enhance user data retrieval capabilities. - Updated the analytics API structure by moving user-related functions to a dedicated `users` directory for better organization. - Removed deprecated `getUserInfo`, `getUsers`, and `getUserSessionCount` files, streamlining the codebase. - Enhanced the `UsersPage` component with a new tabbed interface for better user experience in viewing user data and traits.
1 parent 531751a commit 4737bd7

File tree

11 files changed

+771
-109
lines changed

11 files changed

+771
-109
lines changed

client/src/api/analytics/endpoints/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,19 @@ export type {
142142
SessionReplaysParams,
143143
} from "./sessionReplay";
144144

145+
// User Traits endpoints
146+
export { fetchUserTraitKeys, fetchUserTraitValues, fetchUserTraitValueUsers } from "./userTraits";
147+
export type {
148+
TraitKey,
149+
TraitKeysResponse,
150+
TraitValue,
151+
TraitValuesResponse,
152+
TraitValuesParams,
153+
TraitValueUser,
154+
TraitValueUsersResponse,
155+
TraitValueUsersParams,
156+
} from "./userTraits";
157+
145158
// Export endpoints
146159
export { exportPdfReport } from "./export";
147160
export type { ExportPdfParams } from "./export";
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { authedFetch } from "../../utils";
2+
3+
export interface TraitKey {
4+
key: string;
5+
userCount: number;
6+
}
7+
8+
export interface TraitKeysResponse {
9+
keys: TraitKey[];
10+
}
11+
12+
export interface TraitValue {
13+
value: string;
14+
userCount: number;
15+
}
16+
17+
export interface TraitValuesResponse {
18+
values: TraitValue[];
19+
total: number;
20+
hasMore: boolean;
21+
}
22+
23+
export interface TraitValuesParams {
24+
key: string;
25+
limit?: number;
26+
offset?: number;
27+
}
28+
29+
/**
30+
* Fetch all trait keys for a site
31+
* GET /api/sites/:siteId/user-traits/keys
32+
*/
33+
export async function fetchUserTraitKeys(site: string | number): Promise<TraitKeysResponse> {
34+
return authedFetch<TraitKeysResponse>(`/sites/${site}/user-traits/keys`);
35+
}
36+
37+
/**
38+
* Fetch trait values for a given key
39+
* GET /api/sites/:siteId/user-traits/values
40+
*/
41+
export async function fetchUserTraitValues(
42+
site: string | number,
43+
params: TraitValuesParams
44+
): Promise<TraitValuesResponse> {
45+
return authedFetch<TraitValuesResponse>(`/sites/${site}/user-traits/values`, {
46+
key: params.key,
47+
limit: params.limit,
48+
offset: params.offset,
49+
});
50+
}
51+
52+
export interface TraitValueUser {
53+
user_id: string;
54+
identified_user_id: string;
55+
traits: Record<string, unknown> | null;
56+
country: string;
57+
region: string;
58+
city: string;
59+
browser: string;
60+
operating_system: string;
61+
device_type: string;
62+
sessions: number;
63+
}
64+
65+
export interface TraitValueUsersResponse {
66+
users: TraitValueUser[];
67+
total: number;
68+
hasMore: boolean;
69+
}
70+
71+
export interface TraitValueUsersParams {
72+
key: string;
73+
value: string;
74+
limit?: number;
75+
offset?: number;
76+
}
77+
78+
/**
79+
* Fetch users that have a specific trait key+value
80+
* GET /api/sites/:siteId/user-traits/users
81+
*/
82+
export async function fetchUserTraitValueUsers(
83+
site: string | number,
84+
params: TraitValueUsersParams
85+
): Promise<TraitValueUsersResponse> {
86+
return authedFetch<TraitValueUsersResponse>(`/sites/${site}/user-traits/users`, {
87+
key: params.key,
88+
value: params.value,
89+
limit: params.limit,
90+
offset: params.offset,
91+
});
92+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { useInfiniteQuery, useQuery } from "@tanstack/react-query";
2+
import { useStore } from "../../../lib/store";
3+
import {
4+
fetchUserTraitKeys,
5+
fetchUserTraitValues,
6+
fetchUserTraitValueUsers,
7+
TraitKeysResponse,
8+
TraitValuesResponse,
9+
TraitValueUsersResponse,
10+
} from "../endpoints";
11+
12+
export function useGetUserTraitKeys() {
13+
const { site } = useStore();
14+
15+
return useQuery<TraitKeysResponse>({
16+
queryKey: ["user-trait-keys", site],
17+
queryFn: () => fetchUserTraitKeys(site),
18+
enabled: !!site,
19+
});
20+
}
21+
22+
export function useGetUserTraitValues(key: string | null) {
23+
const { site } = useStore();
24+
const limit = 1000;
25+
26+
return useInfiniteQuery<TraitValuesResponse>({
27+
queryKey: ["user-trait-values", site, key],
28+
queryFn: async ({ pageParam = 0 }) => {
29+
return fetchUserTraitValues(site, {
30+
key: key!,
31+
limit,
32+
offset: pageParam as number,
33+
});
34+
},
35+
initialPageParam: 0,
36+
getNextPageParam: (lastPage, allPages) => {
37+
const totalFetched = allPages.reduce((acc, page) => acc + page.values.length, 0);
38+
return lastPage.hasMore ? totalFetched : undefined;
39+
},
40+
enabled: !!site && !!key,
41+
});
42+
}
43+
44+
export function useGetUserTraitValueUsers(key: string | null, value: string | null) {
45+
const { site } = useStore();
46+
const limit = 50;
47+
48+
return useInfiniteQuery<TraitValueUsersResponse>({
49+
queryKey: ["user-trait-value-users", site, key, value],
50+
queryFn: async ({ pageParam = 0 }) => {
51+
return fetchUserTraitValueUsers(site, {
52+
key: key!,
53+
value: value!,
54+
limit,
55+
offset: pageParam as number,
56+
});
57+
},
58+
initialPageParam: 0,
59+
getNextPageParam: (lastPage, allPages) => {
60+
const totalFetched = allPages.reduce((acc, page) => acc + page.users.length, 0);
61+
return lastPage.hasMore ? totalFetched : undefined;
62+
},
63+
enabled: !!site && !!key && value !== null,
64+
});
65+
}

0 commit comments

Comments
 (0)