-
-
Notifications
You must be signed in to change notification settings - Fork 373
Expand file tree
/
Copy pathuseContacts.ts
More file actions
86 lines (76 loc) · 2.34 KB
/
Copy pathuseContacts.ts
File metadata and controls
86 lines (76 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import type {Contact} from '@plunk/db';
import type {CursorPaginatedResponse, PaginatedResponse} from '@plunk/types';
import useSWR from 'swr';
interface UseContactsOptions {
limit?: number;
search?: string;
}
/**
* Hook to fetch contacts with optional search
*/
export function useContacts(options: UseContactsOptions = {}) {
const {limit = 50, search} = options;
const params = new URLSearchParams();
params.set('limit', limit.toString());
if (search) {
params.set('search', search);
}
const {data, error, mutate, isLoading} = useSWR<CursorPaginatedResponse<Contact>>(`/contacts?${params.toString()}`, {
revalidateOnFocus: false,
dedupingInterval: 10000, // Prevent duplicate requests within 10 seconds
});
return {
contacts: data?.data || [],
total: data?.total || 0,
error,
isLoading,
mutate,
};
}
/**
* Hook to fetch the contacts belonging to a specific segment.
*
* Backed by `GET /segments/:id/contacts`, which resolves both STATIC
* (via SegmentMembership) and DYNAMIC (via condition) segments. Used by the
* email editor to scope the "Preview as" dropdown to the campaign's selected
* audience instead of every contact in the project.
*
* When `segmentId` is undefined/empty the SWR key is null, so no request is
* made and an empty list is returned (callers fall back to all contacts).
*/
export function useSegmentContacts(segmentId?: string, pageSize = 50) {
const {data, error, mutate, isLoading} = useSWR<PaginatedResponse<Contact>>(
segmentId ? `/segments/${segmentId}/contacts?page=1&pageSize=${pageSize}` : null,
{
revalidateOnFocus: false,
dedupingInterval: 10000, // Prevent duplicate requests within 10 seconds
},
);
return {
contacts: data?.data ?? [],
total: data?.total ?? 0,
error,
isLoading,
mutate,
};
}
/**
* Hook to fetch available contact fields for variable usage
*/
export function useContactFields() {
const {data, error, mutate, isLoading} = useSWR<{fields: {field: string; type: string}[]; count: number}>(
'/contacts/fields',
{
revalidateOnFocus: false,
// Cache fields for longer since they don't change often
dedupingInterval: 60000, // 1 minute
},
);
const fieldNames = (data?.fields || []).map(f => f.field);
return {
fields: fieldNames,
error,
isLoading,
mutate,
};
}