@explorins/pers-sdk-react-native 2.1.3 → 2.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/dist/hooks/index.d.ts +6 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useAnalytics.d.ts +37 -14
- package/dist/hooks/useAnalytics.d.ts.map +1 -1
- package/dist/hooks/useAnalytics.js +239 -19
- package/dist/hooks/useCampaigns.d.ts +14 -6
- package/dist/hooks/useCampaigns.d.ts.map +1 -1
- package/dist/hooks/useCampaigns.js +144 -10
- package/dist/hooks/useRedemptions.d.ts +5 -2
- package/dist/hooks/useRedemptions.d.ts.map +1 -1
- package/dist/hooks/useRedemptions.js +53 -2
- package/dist/hooks/useTransactions.d.ts +8 -5
- package/dist/hooks/useTransactions.d.ts.map +1 -1
- package/dist/hooks/useTransactions.js +70 -27
- package/dist/hooks/useTriggerSources.d.ts +76 -0
- package/dist/hooks/useTriggerSources.d.ts.map +1 -0
- package/dist/hooks/useTriggerSources.js +272 -0
- package/dist/index.d.ts +12 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2459 -393
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/hooks/index.ts +17 -1
- package/src/hooks/useAnalytics.ts +268 -21
- package/src/hooks/useCampaigns.ts +176 -14
- package/src/hooks/useRedemptions.ts +66 -3
- package/src/hooks/useTransactions.ts +84 -29
- package/src/hooks/useTriggerSources.ts +301 -0
- package/src/index.ts +33 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@explorins/pers-sdk-react-native",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.5",
|
|
4
4
|
"description": "React Native SDK for PERS Platform - Tourism Loyalty System with Blockchain Transaction Signing and WebAuthn Authentication",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"author": "eXplorins",
|
|
38
38
|
"license": "MIT",
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@explorins/pers-sdk": "^2.1.
|
|
40
|
+
"@explorins/pers-sdk": "^2.1.6",
|
|
41
41
|
"@explorins/pers-signer": "^1.0.33",
|
|
42
42
|
"buffer": "^6.0.3",
|
|
43
43
|
"ethers": "^6.15.0",
|
package/src/hooks/index.ts
CHANGED
|
@@ -16,6 +16,7 @@ export { useFiles } from './useFiles';
|
|
|
16
16
|
export { useAnalytics } from './useAnalytics';
|
|
17
17
|
export { useDonations } from './useDonations';
|
|
18
18
|
export { useEvents } from './useEvents';
|
|
19
|
+
export { useTriggerSources } from './useTriggerSources';
|
|
19
20
|
|
|
20
21
|
// Re-export auth-related types for convenience
|
|
21
22
|
export type { RawUserData } from './useAuth';
|
|
@@ -34,4 +35,19 @@ export type {
|
|
|
34
35
|
TokenBalanceWithToken,
|
|
35
36
|
UseTokenBalancesOptions,
|
|
36
37
|
UseTokenBalancesResult
|
|
37
|
-
} from './useTokenBalances';
|
|
38
|
+
} from './useTokenBalances';
|
|
39
|
+
|
|
40
|
+
// Export campaign-related types
|
|
41
|
+
export type { CampaignClaimFilters, CampaignHook } from './useCampaigns';
|
|
42
|
+
|
|
43
|
+
// Export redemption-related types
|
|
44
|
+
export type { RedemptionRedeemFilters, RedemptionHook } from './useRedemptions';
|
|
45
|
+
|
|
46
|
+
// Export transaction-related types
|
|
47
|
+
export type { TransactionQueryOptions, TransactionHook } from './useTransactions';
|
|
48
|
+
|
|
49
|
+
// Export trigger source-related types
|
|
50
|
+
export type { TriggerSourceQueryOptions, TriggerSourceHook } from './useTriggerSources';
|
|
51
|
+
|
|
52
|
+
// Export analytics-related types
|
|
53
|
+
export type { AnalyticsHook } from './useAnalytics';
|
|
@@ -2,35 +2,63 @@ import { useCallback } from 'react';
|
|
|
2
2
|
import { usePersSDK } from '../providers/PersSDKProvider';
|
|
3
3
|
import {
|
|
4
4
|
TransactionAnalyticsRequestDTO,
|
|
5
|
-
TransactionAnalyticsResponseDTO
|
|
5
|
+
TransactionAnalyticsResponseDTO,
|
|
6
|
+
CampaignClaimAnalyticsRequestDTO,
|
|
7
|
+
CampaignClaimAnalyticsResponseDTO,
|
|
8
|
+
UserAnalyticsRequestDTO,
|
|
9
|
+
UserAnalyticsResponseDTO,
|
|
10
|
+
UserRankingAnalyticsRequestDTO,
|
|
11
|
+
UserRankingAnalyticsResponseDTO,
|
|
12
|
+
BusinessRankingAnalyticsRequestDTO,
|
|
13
|
+
BusinessRankingAnalyticsResponseDTO,
|
|
14
|
+
RetentionAnalyticsRequestDTO,
|
|
15
|
+
RetentionAnalyticsResponseDTO
|
|
6
16
|
} from '@explorins/pers-shared';
|
|
7
17
|
|
|
8
18
|
/**
|
|
9
19
|
* React hook for analytics operations in the PERS SDK
|
|
10
20
|
*
|
|
11
|
-
* Provides
|
|
12
|
-
*
|
|
21
|
+
* Provides comprehensive analytics and business intelligence capabilities:
|
|
22
|
+
* - **Transaction Analytics**: Volume, trends, business performance
|
|
23
|
+
* - **Campaign Claim Analytics**: Campaign performance and claim patterns
|
|
24
|
+
* - **User Analytics**: Engagement metrics with per-active-user averages
|
|
25
|
+
* - **User Ranking**: Leaderboards with full user details
|
|
26
|
+
* - **Business Ranking**: Business performance rankings
|
|
27
|
+
* - **Retention Analytics**: Monthly retention metrics
|
|
13
28
|
*
|
|
14
29
|
* @returns Analytics hook with methods for data analysis
|
|
15
30
|
*
|
|
16
|
-
* @example
|
|
31
|
+
* @example Basic Transaction Analytics
|
|
17
32
|
* ```typescript
|
|
18
33
|
* function AnalyticsComponent() {
|
|
19
34
|
* const { getTransactionAnalytics } = useAnalytics();
|
|
20
35
|
*
|
|
21
36
|
* const loadAnalytics = async () => {
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* } catch (error) {
|
|
29
|
-
* console.error('Failed to load analytics:', error);
|
|
30
|
-
* }
|
|
37
|
+
* const analytics = await getTransactionAnalytics({
|
|
38
|
+
* startDate: '2024-01-01',
|
|
39
|
+
* endDate: '2024-01-31',
|
|
40
|
+
* groupBy: 'day'
|
|
41
|
+
* });
|
|
42
|
+
* console.log('Transaction analytics:', analytics);
|
|
31
43
|
* };
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
32
46
|
*
|
|
33
|
-
*
|
|
47
|
+
* @example User Leaderboard
|
|
48
|
+
* ```typescript
|
|
49
|
+
* function LeaderboardScreen() {
|
|
50
|
+
* const { getUserRanking } = useAnalytics();
|
|
51
|
+
*
|
|
52
|
+
* const loadLeaderboard = async () => {
|
|
53
|
+
* const ranking = await getUserRanking({
|
|
54
|
+
* sortBy: 'totalTransactions',
|
|
55
|
+
* sortOrder: 'DESC',
|
|
56
|
+
* limit: 50
|
|
57
|
+
* });
|
|
58
|
+
* ranking.results.forEach((user, i) => {
|
|
59
|
+
* console.log(`#${i + 1}: ${user.email} - ${user.totalTransactions} txns`);
|
|
60
|
+
* });
|
|
61
|
+
* };
|
|
34
62
|
* }
|
|
35
63
|
* ```
|
|
36
64
|
*/
|
|
@@ -46,19 +74,17 @@ export const useAnalytics = () => {
|
|
|
46
74
|
*
|
|
47
75
|
* @example
|
|
48
76
|
* ```typescript
|
|
49
|
-
* const { getTransactionAnalytics } = useAnalytics();
|
|
50
77
|
* const analytics = await getTransactionAnalytics({
|
|
51
|
-
* groupBy: ['day'],
|
|
52
|
-
* metrics: ['count', 'sum'],
|
|
53
78
|
* startDate: '2024-01-01',
|
|
54
79
|
* endDate: '2024-01-31',
|
|
55
|
-
*
|
|
80
|
+
* groupBy: 'day',
|
|
81
|
+
* metrics: ['count', 'sum']
|
|
56
82
|
* });
|
|
57
|
-
* console.log('Daily transaction analytics:', analytics.results);
|
|
58
|
-
* console.log('Execution time:', analytics.metadata.executionTime);
|
|
59
83
|
* ```
|
|
60
84
|
*/
|
|
61
|
-
const getTransactionAnalytics = useCallback(async (
|
|
85
|
+
const getTransactionAnalytics = useCallback(async (
|
|
86
|
+
request: TransactionAnalyticsRequestDTO
|
|
87
|
+
): Promise<TransactionAnalyticsResponseDTO> => {
|
|
62
88
|
if (!isInitialized || !sdk) {
|
|
63
89
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
64
90
|
}
|
|
@@ -72,8 +98,229 @@ export const useAnalytics = () => {
|
|
|
72
98
|
}
|
|
73
99
|
}, [sdk, isInitialized]);
|
|
74
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Retrieves campaign claim analytics with aggregation
|
|
103
|
+
*
|
|
104
|
+
* Provides insights into campaign performance, claim patterns, and user engagement.
|
|
105
|
+
*
|
|
106
|
+
* @param request - Analytics request with filters, groupBy, and metrics
|
|
107
|
+
* @returns Promise resolving to campaign claim analytics data
|
|
108
|
+
*
|
|
109
|
+
* @example Claims per campaign
|
|
110
|
+
* ```typescript
|
|
111
|
+
* const analytics = await getCampaignClaimAnalytics({
|
|
112
|
+
* filters: { status: 'COMPLETED' },
|
|
113
|
+
* groupBy: ['campaignId'],
|
|
114
|
+
* metrics: ['count'],
|
|
115
|
+
* sortBy: 'count',
|
|
116
|
+
* sortOrder: 'DESC',
|
|
117
|
+
* limit: 10
|
|
118
|
+
* });
|
|
119
|
+
* console.log('Top campaigns:', analytics.results);
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
const getCampaignClaimAnalytics = useCallback(async (
|
|
123
|
+
request: CampaignClaimAnalyticsRequestDTO
|
|
124
|
+
): Promise<CampaignClaimAnalyticsResponseDTO> => {
|
|
125
|
+
if (!isInitialized || !sdk) {
|
|
126
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
const result = await sdk.analytics.getCampaignClaimAnalytics(request);
|
|
131
|
+
return result;
|
|
132
|
+
} catch (error) {
|
|
133
|
+
console.error('Failed to fetch campaign claim analytics:', error);
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
}, [sdk, isInitialized]);
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Retrieves user analytics with engagement metrics
|
|
140
|
+
*
|
|
141
|
+
* Includes both per-user and per-active-user metrics for accurate engagement insights.
|
|
142
|
+
* Per-active-user metrics show concentrated engagement among active users.
|
|
143
|
+
*
|
|
144
|
+
* @param request - Analytics request with optional filters and date range
|
|
145
|
+
* @returns Promise resolving to user analytics data
|
|
146
|
+
*
|
|
147
|
+
* @example Compare per-user vs per-active-user metrics
|
|
148
|
+
* ```typescript
|
|
149
|
+
* const analytics = await getUserAnalytics({
|
|
150
|
+
* startDate: new Date('2026-02-01'),
|
|
151
|
+
* endDate: new Date('2026-02-28')
|
|
152
|
+
* });
|
|
153
|
+
*
|
|
154
|
+
* console.log(`Active users: ${analytics.activeUsers} / ${analytics.totalUsers}`);
|
|
155
|
+
* console.log(`Engagement rate: ${analytics.engagementRate.toFixed(1)}%`);
|
|
156
|
+
*
|
|
157
|
+
* // Per-active-user metrics (more meaningful)
|
|
158
|
+
* console.log(`Avg transactions per active user: ${analytics.averageTransactionsPerActiveUser}`);
|
|
159
|
+
* ```
|
|
160
|
+
*
|
|
161
|
+
* @example Business-specific analytics
|
|
162
|
+
* ```typescript
|
|
163
|
+
* const analytics = await getUserAnalytics({
|
|
164
|
+
* filters: { businessId: 'business-123' },
|
|
165
|
+
* startDate: new Date('2026-01-01'),
|
|
166
|
+
* endDate: new Date('2026-12-31')
|
|
167
|
+
* });
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
const getUserAnalytics = useCallback(async (
|
|
171
|
+
request: UserAnalyticsRequestDTO = {}
|
|
172
|
+
): Promise<UserAnalyticsResponseDTO> => {
|
|
173
|
+
if (!isInitialized || !sdk) {
|
|
174
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
const result = await sdk.analytics.getUserAnalytics(request);
|
|
179
|
+
return result;
|
|
180
|
+
} catch (error) {
|
|
181
|
+
console.error('Failed to fetch user analytics:', error);
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
}, [sdk, isInitialized]);
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Retrieves user transaction ranking with enriched user data
|
|
188
|
+
*
|
|
189
|
+
* Returns ranked list of users with full user details (email, externalUserId)
|
|
190
|
+
* and transaction metrics. Ideal for leaderboards, engagement analysis,
|
|
191
|
+
* and identifying power users.
|
|
192
|
+
*
|
|
193
|
+
* @param request - Ranking request with filters, sorting, and limit
|
|
194
|
+
* @returns Promise resolving to ranked user list with transaction metrics
|
|
195
|
+
*
|
|
196
|
+
* @example Top 50 users by transaction count
|
|
197
|
+
* ```typescript
|
|
198
|
+
* const ranking = await getUserRanking({
|
|
199
|
+
* sortBy: 'totalTransactions',
|
|
200
|
+
* sortOrder: 'DESC',
|
|
201
|
+
* limit: 50
|
|
202
|
+
* });
|
|
203
|
+
*
|
|
204
|
+
* ranking.results.forEach((user, index) => {
|
|
205
|
+
* console.log(`#${index + 1}: ${user.email || user.externalUserId}`);
|
|
206
|
+
* console.log(` Transactions: ${user.totalTransactions}`);
|
|
207
|
+
* console.log(` Token spent: ${user.tokenSpent}`);
|
|
208
|
+
* });
|
|
209
|
+
* ```
|
|
210
|
+
*
|
|
211
|
+
* @example Top STAMP spenders
|
|
212
|
+
* ```typescript
|
|
213
|
+
* const ranking = await getUserRanking({
|
|
214
|
+
* filters: { tokenType: 'STAMP' },
|
|
215
|
+
* sortBy: 'tokenSpent',
|
|
216
|
+
* sortOrder: 'DESC',
|
|
217
|
+
* limit: 20
|
|
218
|
+
* });
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
const getUserRanking = useCallback(async (
|
|
222
|
+
request: UserRankingAnalyticsRequestDTO = {}
|
|
223
|
+
): Promise<UserRankingAnalyticsResponseDTO> => {
|
|
224
|
+
if (!isInitialized || !sdk) {
|
|
225
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
try {
|
|
229
|
+
const result = await sdk.analytics.getUserRanking(request);
|
|
230
|
+
return result;
|
|
231
|
+
} catch (error) {
|
|
232
|
+
console.error('Failed to fetch user ranking:', error);
|
|
233
|
+
throw error;
|
|
234
|
+
}
|
|
235
|
+
}, [sdk, isInitialized]);
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Retrieves business transaction ranking with enriched business data
|
|
239
|
+
*
|
|
240
|
+
* Returns ranked list of businesses with transaction metrics for
|
|
241
|
+
* partner analytics and performance dashboards.
|
|
242
|
+
*
|
|
243
|
+
* @param request - Ranking request with filters, sorting, and limit
|
|
244
|
+
* @returns Promise resolving to ranked business list
|
|
245
|
+
*
|
|
246
|
+
* @example Top businesses by transaction count
|
|
247
|
+
* ```typescript
|
|
248
|
+
* const ranking = await getBusinessRanking({
|
|
249
|
+
* sortBy: 'totalTransactions',
|
|
250
|
+
* sortOrder: 'DESC',
|
|
251
|
+
* limit: 20
|
|
252
|
+
* });
|
|
253
|
+
*
|
|
254
|
+
* ranking.results.forEach((business, index) => {
|
|
255
|
+
* console.log(`#${index + 1}: ${business.businessId}`);
|
|
256
|
+
* console.log(` Transactions: ${business.totalTransactions}`);
|
|
257
|
+
* console.log(` Token spent: ${business.tokenSpent}`);
|
|
258
|
+
* });
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
const getBusinessRanking = useCallback(async (
|
|
262
|
+
request: BusinessRankingAnalyticsRequestDTO = {}
|
|
263
|
+
): Promise<BusinessRankingAnalyticsResponseDTO> => {
|
|
264
|
+
if (!isInitialized || !sdk) {
|
|
265
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
try {
|
|
269
|
+
const result = await sdk.analytics.getBusinessRanking(request);
|
|
270
|
+
return result;
|
|
271
|
+
} catch (error) {
|
|
272
|
+
console.error('Failed to fetch business ranking:', error);
|
|
273
|
+
throw error;
|
|
274
|
+
}
|
|
275
|
+
}, [sdk, isInitialized]);
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Retrieves monthly user retention analytics
|
|
279
|
+
*
|
|
280
|
+
* Returns monthly retention data with active, new, and returning users
|
|
281
|
+
* along with retention rates. Useful for churn analysis and engagement trends.
|
|
282
|
+
*
|
|
283
|
+
* @param request - Retention request with monthsBack and filters
|
|
284
|
+
* @returns Promise resolving to monthly retention data
|
|
285
|
+
*
|
|
286
|
+
* @example Get 12 months of retention data
|
|
287
|
+
* ```typescript
|
|
288
|
+
* const retention = await getRetentionAnalytics({
|
|
289
|
+
* monthsBack: 12
|
|
290
|
+
* });
|
|
291
|
+
*
|
|
292
|
+
* retention.results.forEach(month => {
|
|
293
|
+
* console.log(`${month.month}:`);
|
|
294
|
+
* console.log(` Active: ${month.activeUsers}`);
|
|
295
|
+
* console.log(` New: ${month.newUsers}`);
|
|
296
|
+
* console.log(` Returning: ${month.returningUsers}`);
|
|
297
|
+
* console.log(` Retention Rate: ${month.retentionRate.toFixed(1)}%`);
|
|
298
|
+
* });
|
|
299
|
+
* ```
|
|
300
|
+
*/
|
|
301
|
+
const getRetentionAnalytics = useCallback(async (
|
|
302
|
+
request: RetentionAnalyticsRequestDTO = {}
|
|
303
|
+
): Promise<RetentionAnalyticsResponseDTO> => {
|
|
304
|
+
if (!isInitialized || !sdk) {
|
|
305
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
try {
|
|
309
|
+
const result = await sdk.analytics.getRetentionAnalytics(request);
|
|
310
|
+
return result;
|
|
311
|
+
} catch (error) {
|
|
312
|
+
console.error('Failed to fetch retention analytics:', error);
|
|
313
|
+
throw error;
|
|
314
|
+
}
|
|
315
|
+
}, [sdk, isInitialized]);
|
|
316
|
+
|
|
75
317
|
return {
|
|
76
318
|
getTransactionAnalytics,
|
|
319
|
+
getCampaignClaimAnalytics,
|
|
320
|
+
getUserAnalytics,
|
|
321
|
+
getUserRanking,
|
|
322
|
+
getBusinessRanking,
|
|
323
|
+
getRetentionAnalytics,
|
|
77
324
|
isAvailable: isInitialized && !!sdk?.analytics,
|
|
78
325
|
};
|
|
79
326
|
};
|
|
@@ -5,11 +5,14 @@ import type {
|
|
|
5
5
|
CampaignDTO,
|
|
6
6
|
CampaignClaimDTO,
|
|
7
7
|
CampaignTriggerDTO,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
PaginatedResponseDTO
|
|
8
|
+
PaginatedResponseDTO,
|
|
9
|
+
CampaignClaimIncludeRelation,
|
|
10
|
+
CampaignIncludeRelation
|
|
12
11
|
} from '@explorins/pers-shared';
|
|
12
|
+
import type { CampaignClaimFilters } from '@explorins/pers-sdk/campaign';
|
|
13
|
+
|
|
14
|
+
// Re-export for consumers
|
|
15
|
+
export type { CampaignClaimFilters } from '@explorins/pers-sdk/campaign';
|
|
13
16
|
|
|
14
17
|
export const useCampaigns = () => {
|
|
15
18
|
const { sdk, isInitialized, isAuthenticated } = usePersSDK();
|
|
@@ -28,13 +31,30 @@ export const useCampaigns = () => {
|
|
|
28
31
|
}
|
|
29
32
|
}, [sdk, isInitialized]);
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Get campaign by ID with optional include relations
|
|
36
|
+
*
|
|
37
|
+
* @param campaignId - The campaign ID
|
|
38
|
+
* @param include - Relations to include: 'triggerSources', 'businesses'
|
|
39
|
+
* @returns Promise resolving to campaign data
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* // Get campaign with all related data
|
|
44
|
+
* const campaign = await getCampaignById('campaign-123', ['triggerSources', 'businesses']);
|
|
45
|
+
* console.log('Trigger sources:', campaign.included?.triggerSources);
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
const getCampaignById = useCallback(async (
|
|
49
|
+
campaignId: string,
|
|
50
|
+
include?: CampaignIncludeRelation[]
|
|
51
|
+
): Promise<CampaignDTO | null> => {
|
|
32
52
|
if (!isInitialized || !sdk) {
|
|
33
53
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
34
54
|
}
|
|
35
55
|
|
|
36
56
|
try {
|
|
37
|
-
const result = await sdk.campaigns.getCampaignById(campaignId);
|
|
57
|
+
const result = await sdk.campaigns.getCampaignById(campaignId, include);
|
|
38
58
|
return result;
|
|
39
59
|
} catch (error) {
|
|
40
60
|
console.error('Failed to fetch campaign:', error);
|
|
@@ -59,7 +79,29 @@ export const useCampaigns = () => {
|
|
|
59
79
|
}
|
|
60
80
|
}, [sdk, isInitialized, isAuthenticated]);
|
|
61
81
|
|
|
62
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Get user's campaign claims with optional pagination and include relations
|
|
84
|
+
*
|
|
85
|
+
* @param options - Optional options including pagination and include relations
|
|
86
|
+
* @returns Promise resolving to paginated campaign claims
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* // Get user's claims with campaign details
|
|
91
|
+
* const { data: claims } = await getUserClaims({ include: ['campaign', 'business'] });
|
|
92
|
+
* claims.forEach(claim => {
|
|
93
|
+
* console.log('Campaign:', claim.included?.campaign?.title);
|
|
94
|
+
* });
|
|
95
|
+
*
|
|
96
|
+
* // With pagination
|
|
97
|
+
* const { data } = await getUserClaims({ page: 1, limit: 10, include: ['campaign'] });
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
const getUserClaims = useCallback(async (options?: {
|
|
101
|
+
page?: number;
|
|
102
|
+
limit?: number;
|
|
103
|
+
include?: CampaignClaimIncludeRelation[];
|
|
104
|
+
}): Promise<PaginatedResponseDTO<CampaignClaimDTO>> => {
|
|
63
105
|
if (!isInitialized || !sdk) {
|
|
64
106
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
65
107
|
}
|
|
@@ -69,7 +111,7 @@ export const useCampaigns = () => {
|
|
|
69
111
|
}
|
|
70
112
|
|
|
71
113
|
try {
|
|
72
|
-
const result = await sdk.campaigns.getUserClaims();
|
|
114
|
+
const result = await sdk.campaigns.getUserClaims(options);
|
|
73
115
|
return result;
|
|
74
116
|
} catch (error) {
|
|
75
117
|
console.error('Failed to fetch user claims:', error);
|
|
@@ -106,13 +148,32 @@ export const useCampaigns = () => {
|
|
|
106
148
|
}
|
|
107
149
|
}, [sdk, isInitialized]);
|
|
108
150
|
|
|
109
|
-
|
|
151
|
+
/**
|
|
152
|
+
* Admin: Get campaign claims with optional filters and include relations
|
|
153
|
+
*
|
|
154
|
+
* @param filters - Optional filters for campaign, user, or business
|
|
155
|
+
* @param include - Relations to include: 'campaign', 'user', 'business'
|
|
156
|
+
* @returns Promise resolving to paginated campaign claims
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* // Get all claims with user details
|
|
161
|
+
* const { data: claims } = await getCampaignClaims({}, ['user']);
|
|
162
|
+
*
|
|
163
|
+
* // Get claims for a specific campaign
|
|
164
|
+
* const { data } = await getCampaignClaims({ campaignId: 'campaign-123' }, ['user', 'business']);
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
const getCampaignClaims = useCallback(async (
|
|
168
|
+
filters?: CampaignClaimFilters,
|
|
169
|
+
include?: CampaignClaimIncludeRelation[]
|
|
170
|
+
): Promise<PaginatedResponseDTO<CampaignClaimDTO>> => {
|
|
110
171
|
if (!isInitialized || !sdk) {
|
|
111
172
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
112
173
|
}
|
|
113
174
|
|
|
114
175
|
try {
|
|
115
|
-
const result = await sdk.campaigns.getCampaignClaims();
|
|
176
|
+
const result = await sdk.campaigns.getCampaignClaims(filters, include);
|
|
116
177
|
return result;
|
|
117
178
|
} catch (error) {
|
|
118
179
|
console.error('Failed to fetch campaign claims:', error);
|
|
@@ -120,13 +181,23 @@ export const useCampaigns = () => {
|
|
|
120
181
|
}
|
|
121
182
|
}, [sdk, isInitialized]);
|
|
122
183
|
|
|
123
|
-
|
|
184
|
+
/**
|
|
185
|
+
* Admin: Get campaign claims by user ID with optional include relations
|
|
186
|
+
*
|
|
187
|
+
* @param userId - The user ID
|
|
188
|
+
* @param include - Relations to include: 'campaign', 'user', 'business'
|
|
189
|
+
* @returns Promise resolving to paginated campaign claims
|
|
190
|
+
*/
|
|
191
|
+
const getCampaignClaimsByUserId = useCallback(async (
|
|
192
|
+
userId: string,
|
|
193
|
+
include?: CampaignClaimIncludeRelation[]
|
|
194
|
+
): Promise<PaginatedResponseDTO<CampaignClaimDTO>> => {
|
|
124
195
|
if (!isInitialized || !sdk) {
|
|
125
196
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
126
197
|
}
|
|
127
198
|
|
|
128
199
|
try {
|
|
129
|
-
const result = await sdk.campaigns.getCampaignClaimsByUserId(userId);
|
|
200
|
+
const result = await sdk.campaigns.getCampaignClaimsByUserId(userId, undefined, include);
|
|
130
201
|
return result;
|
|
131
202
|
} catch (error) {
|
|
132
203
|
console.error('Failed to fetch campaign claims by user ID:', error);
|
|
@@ -134,13 +205,23 @@ export const useCampaigns = () => {
|
|
|
134
205
|
}
|
|
135
206
|
}, [sdk, isInitialized]);
|
|
136
207
|
|
|
137
|
-
|
|
208
|
+
/**
|
|
209
|
+
* Admin: Get campaign claims by business ID with optional include relations
|
|
210
|
+
*
|
|
211
|
+
* @param businessId - The business ID
|
|
212
|
+
* @param include - Relations to include: 'campaign', 'user', 'business'
|
|
213
|
+
* @returns Promise resolving to paginated campaign claims
|
|
214
|
+
*/
|
|
215
|
+
const getCampaignClaimsByBusinessId = useCallback(async (
|
|
216
|
+
businessId: string,
|
|
217
|
+
include?: CampaignClaimIncludeRelation[]
|
|
218
|
+
): Promise<PaginatedResponseDTO<CampaignClaimDTO>> => {
|
|
138
219
|
if (!isInitialized || !sdk) {
|
|
139
220
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
140
221
|
}
|
|
141
222
|
|
|
142
223
|
try {
|
|
143
|
-
const result = await sdk.campaigns.getCampaignClaimsByBusinessId(businessId);
|
|
224
|
+
const result = await sdk.campaigns.getCampaignClaimsByBusinessId(businessId, undefined, include);
|
|
144
225
|
return result;
|
|
145
226
|
} catch (error) {
|
|
146
227
|
console.error('Failed to fetch campaign claims by business ID:', error);
|
|
@@ -148,6 +229,85 @@ export const useCampaigns = () => {
|
|
|
148
229
|
}
|
|
149
230
|
}, [sdk, isInitialized]);
|
|
150
231
|
|
|
232
|
+
// ==========================================
|
|
233
|
+
// TRIGGER SOURCE ASSIGNMENT (Admin)
|
|
234
|
+
// Note: TriggerSource CRUD is in useTriggerSources hook
|
|
235
|
+
// ==========================================
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Admin: Assign a trigger source to a campaign
|
|
239
|
+
*
|
|
240
|
+
* Associates a trigger source (QR code, NFC tag, etc.) with a campaign.
|
|
241
|
+
* A campaign can have multiple trigger sources.
|
|
242
|
+
*
|
|
243
|
+
* Note: To create/update/delete trigger sources, use `useTriggerSources` hook.
|
|
244
|
+
*
|
|
245
|
+
* @param campaignId - Campaign UUID
|
|
246
|
+
* @param triggerSourceId - Trigger source UUID
|
|
247
|
+
* @returns Promise resolving to updated campaign
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```typescript
|
|
251
|
+
* const { create } = useTriggerSources();
|
|
252
|
+
* const { assignTriggerSource } = useCampaigns();
|
|
253
|
+
*
|
|
254
|
+
* // Create trigger source first
|
|
255
|
+
* const source = await create({ type: 'QR_CODE', name: 'Store QR' });
|
|
256
|
+
*
|
|
257
|
+
* // Then assign to campaign
|
|
258
|
+
* const updated = await assignTriggerSource('campaign-123', source.id);
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
const assignTriggerSource = useCallback(async (
|
|
262
|
+
campaignId: string,
|
|
263
|
+
triggerSourceId: string
|
|
264
|
+
): Promise<CampaignDTO> => {
|
|
265
|
+
if (!isInitialized || !sdk) {
|
|
266
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
267
|
+
}
|
|
268
|
+
if (!isAuthenticated) {
|
|
269
|
+
throw new Error('SDK not authenticated. assignTriggerSource requires admin authentication.');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
try {
|
|
273
|
+
const result = await sdk.campaigns.assignTriggerSource(campaignId, triggerSourceId);
|
|
274
|
+
return result;
|
|
275
|
+
} catch (error) {
|
|
276
|
+
console.error('Failed to assign trigger source:', error);
|
|
277
|
+
throw error;
|
|
278
|
+
}
|
|
279
|
+
}, [sdk, isInitialized, isAuthenticated]);
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Admin: Remove a trigger source from a campaign
|
|
283
|
+
*
|
|
284
|
+
* Removes the association between a trigger source and a campaign.
|
|
285
|
+
* The trigger source itself is not deleted.
|
|
286
|
+
*
|
|
287
|
+
* @param campaignId - Campaign UUID
|
|
288
|
+
* @param triggerSourceId - Trigger source UUID
|
|
289
|
+
* @returns Promise resolving to updated campaign
|
|
290
|
+
*/
|
|
291
|
+
const removeTriggerSource = useCallback(async (
|
|
292
|
+
campaignId: string,
|
|
293
|
+
triggerSourceId: string
|
|
294
|
+
): Promise<CampaignDTO> => {
|
|
295
|
+
if (!isInitialized || !sdk) {
|
|
296
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
297
|
+
}
|
|
298
|
+
if (!isAuthenticated) {
|
|
299
|
+
throw new Error('SDK not authenticated. removeTriggerSource requires admin authentication.');
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
try {
|
|
303
|
+
const result = await sdk.campaigns.removeTriggerSource(campaignId, triggerSourceId);
|
|
304
|
+
return result;
|
|
305
|
+
} catch (error) {
|
|
306
|
+
console.error('Failed to remove trigger source:', error);
|
|
307
|
+
throw error;
|
|
308
|
+
}
|
|
309
|
+
}, [sdk, isInitialized, isAuthenticated]);
|
|
310
|
+
|
|
151
311
|
return {
|
|
152
312
|
getActiveCampaigns,
|
|
153
313
|
getCampaignById,
|
|
@@ -158,6 +318,8 @@ export const useCampaigns = () => {
|
|
|
158
318
|
getCampaignClaims,
|
|
159
319
|
getCampaignClaimsByUserId,
|
|
160
320
|
getCampaignClaimsByBusinessId,
|
|
321
|
+
assignTriggerSource,
|
|
322
|
+
removeTriggerSource,
|
|
161
323
|
isAvailable: isInitialized && !!sdk?.campaigns,
|
|
162
324
|
};
|
|
163
325
|
};
|