@axcode/axcloud-sdk 0.1.0
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 +339 -0
- package/dist/index.d.mts +1473 -0
- package/dist/index.d.ts +1473 -0
- package/dist/index.js +1282 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1246 -0
- package/dist/index.mjs.map +1 -0
- package/dist/styles/linked-accounts.css +156 -0
- package/package.json +70 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1473 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
4
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
5
|
+
import { useAuth0, User as User$1 } from '@auth0/auth0-react';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* AxCloud API Client
|
|
9
|
+
*
|
|
10
|
+
* Fetch wrapper with authentication header injection and error handling.
|
|
11
|
+
*/
|
|
12
|
+
interface ClientConfig {
|
|
13
|
+
baseUrl: string;
|
|
14
|
+
getAccessToken?: () => Promise<string | undefined>;
|
|
15
|
+
/** API key for public content endpoints */
|
|
16
|
+
apiKey?: string;
|
|
17
|
+
/** Default request timeout in milliseconds (default: 30000) */
|
|
18
|
+
timeout?: number;
|
|
19
|
+
}
|
|
20
|
+
interface RequestOptions extends Omit<RequestInit, 'body'> {
|
|
21
|
+
body?: unknown;
|
|
22
|
+
params?: Record<string, string | number | boolean | undefined>;
|
|
23
|
+
/** Request timeout in milliseconds (overrides client default) */
|
|
24
|
+
timeout?: number;
|
|
25
|
+
}
|
|
26
|
+
declare class AxCloudClient {
|
|
27
|
+
private baseUrl;
|
|
28
|
+
private getAccessToken?;
|
|
29
|
+
private apiKey?;
|
|
30
|
+
private defaultTimeout;
|
|
31
|
+
constructor(config: ClientConfig);
|
|
32
|
+
/**
|
|
33
|
+
* Update the access token getter (used when auth state changes)
|
|
34
|
+
*/
|
|
35
|
+
setAccessTokenGetter(getter: () => Promise<string | undefined>): void;
|
|
36
|
+
/**
|
|
37
|
+
* Build URL with query parameters
|
|
38
|
+
*/
|
|
39
|
+
private buildUrl;
|
|
40
|
+
/**
|
|
41
|
+
* Make an authenticated request
|
|
42
|
+
*/
|
|
43
|
+
request<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
44
|
+
/**
|
|
45
|
+
* GET request
|
|
46
|
+
*/
|
|
47
|
+
get<T>(path: string, params?: Record<string, string | number | boolean | undefined>): Promise<T>;
|
|
48
|
+
/**
|
|
49
|
+
* POST request
|
|
50
|
+
*/
|
|
51
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
52
|
+
/**
|
|
53
|
+
* PUT request
|
|
54
|
+
*/
|
|
55
|
+
put<T>(path: string, body?: unknown): Promise<T>;
|
|
56
|
+
/**
|
|
57
|
+
* PATCH request
|
|
58
|
+
*/
|
|
59
|
+
patch<T>(path: string, body?: unknown): Promise<T>;
|
|
60
|
+
/**
|
|
61
|
+
* DELETE request
|
|
62
|
+
*/
|
|
63
|
+
delete<T>(path: string): Promise<T>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Create a client instance associated with a key (typically the provider instance)
|
|
67
|
+
* This allows multiple AxCloudProviders to coexist without conflicts
|
|
68
|
+
*/
|
|
69
|
+
declare function createClient(config: ClientConfig, key?: object): AxCloudClient;
|
|
70
|
+
/**
|
|
71
|
+
* Get a client instance by key
|
|
72
|
+
* @deprecated Use the client from useAxCloudContext() instead
|
|
73
|
+
*/
|
|
74
|
+
declare function getClient(key?: object): AxCloudClient;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* AxCloud SDK Error Types
|
|
78
|
+
*/
|
|
79
|
+
type AxCloudErrorCode = 'UNAUTHORIZED' | 'FORBIDDEN' | 'NOT_FOUND' | 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'TIMEOUT_ERROR' | 'SERVER_ERROR' | 'UNKNOWN_ERROR';
|
|
80
|
+
declare class AxCloudError extends Error {
|
|
81
|
+
readonly code: AxCloudErrorCode;
|
|
82
|
+
readonly status: number;
|
|
83
|
+
readonly details?: Record<string, unknown>;
|
|
84
|
+
constructor(message: string, code: AxCloudErrorCode, status: number, details?: Record<string, unknown>);
|
|
85
|
+
static fromResponse(status: number, body?: unknown): AxCloudError;
|
|
86
|
+
static networkError(originalError?: Error): AxCloudError;
|
|
87
|
+
static timeoutError(timeoutMs: number): AxCloudError;
|
|
88
|
+
}
|
|
89
|
+
declare function isAxCloudError(error: unknown): error is AxCloudError;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* AxCloud SDK Types
|
|
93
|
+
*
|
|
94
|
+
* Note: In the future, these types should be auto-generated from the OpenAPI spec.
|
|
95
|
+
* For now, they are manually defined based on the AxCloud API.
|
|
96
|
+
*/
|
|
97
|
+
type AxCloudModule = 'content' | 'members' | 'sections' | 'training' | 'ai' | 'documents' | 'voting';
|
|
98
|
+
type SystemRole = 'super_admin' | 'org_admin' | 'section_admin' | 'member' | 'viewer';
|
|
99
|
+
type UserRole = SystemRole | 'superadmin' | 'admin' | 'editor';
|
|
100
|
+
type BaseRole = 'org_admin' | 'section_admin' | 'member' | 'viewer';
|
|
101
|
+
/**
|
|
102
|
+
* Custom role definition
|
|
103
|
+
*/
|
|
104
|
+
interface CustomRole {
|
|
105
|
+
role_id: string;
|
|
106
|
+
org_id: string;
|
|
107
|
+
name: string;
|
|
108
|
+
description?: string;
|
|
109
|
+
baseRole: BaseRole;
|
|
110
|
+
permissions?: string[];
|
|
111
|
+
deniedPermissions?: string[];
|
|
112
|
+
effectivePermissions?: string[];
|
|
113
|
+
color?: string;
|
|
114
|
+
icon?: string;
|
|
115
|
+
hierarchy: number;
|
|
116
|
+
isSystem: false;
|
|
117
|
+
isActive: boolean;
|
|
118
|
+
createdAt: string;
|
|
119
|
+
updatedAt: string;
|
|
120
|
+
}
|
|
121
|
+
interface Organization {
|
|
122
|
+
id: string;
|
|
123
|
+
name: string;
|
|
124
|
+
slug: string;
|
|
125
|
+
description?: string;
|
|
126
|
+
modules: AxCloudModule[];
|
|
127
|
+
settings?: OrganizationSettings;
|
|
128
|
+
createdAt: string;
|
|
129
|
+
updatedAt: string;
|
|
130
|
+
}
|
|
131
|
+
interface OrganizationSettings {
|
|
132
|
+
allowPublicSignup?: boolean;
|
|
133
|
+
requireEmailVerification?: boolean;
|
|
134
|
+
defaultUserRole?: UserRole;
|
|
135
|
+
theme?: {
|
|
136
|
+
primaryColor?: string;
|
|
137
|
+
logo?: string;
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
interface Section {
|
|
141
|
+
id: string;
|
|
142
|
+
organizationId: string;
|
|
143
|
+
name: string;
|
|
144
|
+
description?: string;
|
|
145
|
+
slug: string;
|
|
146
|
+
parentId?: string;
|
|
147
|
+
permissions?: SectionPermissions;
|
|
148
|
+
createdAt: string;
|
|
149
|
+
updatedAt: string;
|
|
150
|
+
}
|
|
151
|
+
interface SectionPermissions {
|
|
152
|
+
canViewMembers?: boolean;
|
|
153
|
+
canEditContent?: boolean;
|
|
154
|
+
canManageMembers?: boolean;
|
|
155
|
+
}
|
|
156
|
+
interface User {
|
|
157
|
+
id: string;
|
|
158
|
+
email: string;
|
|
159
|
+
name: string;
|
|
160
|
+
firstName?: string;
|
|
161
|
+
lastName?: string;
|
|
162
|
+
avatar?: string;
|
|
163
|
+
organizationId: string;
|
|
164
|
+
sectionId?: string;
|
|
165
|
+
role: UserRole;
|
|
166
|
+
customRole?: CustomRole;
|
|
167
|
+
permissions?: string[];
|
|
168
|
+
metadata?: Record<string, unknown>;
|
|
169
|
+
createdAt: string;
|
|
170
|
+
updatedAt: string;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Check if user has a specific permission
|
|
174
|
+
*/
|
|
175
|
+
declare function userHasPermission(user: User, permission: string): boolean;
|
|
176
|
+
/**
|
|
177
|
+
* Check if user has any of the specified permissions
|
|
178
|
+
*/
|
|
179
|
+
declare function userHasAnyPermission(user: User, permissions: string[]): boolean;
|
|
180
|
+
/**
|
|
181
|
+
* Check if user has all of the specified permissions
|
|
182
|
+
*/
|
|
183
|
+
declare function userHasAllPermissions(user: User, permissions: string[]): boolean;
|
|
184
|
+
interface Membership {
|
|
185
|
+
userId: string;
|
|
186
|
+
organizationId: string;
|
|
187
|
+
sectionId?: string;
|
|
188
|
+
section?: Section;
|
|
189
|
+
role: UserRole;
|
|
190
|
+
status: 'active' | 'pending' | 'suspended' | 'expired';
|
|
191
|
+
joinedAt: string;
|
|
192
|
+
expiresAt?: string;
|
|
193
|
+
metadata?: Record<string, unknown>;
|
|
194
|
+
}
|
|
195
|
+
interface ContentItem {
|
|
196
|
+
id: string;
|
|
197
|
+
organizationId: string;
|
|
198
|
+
type: string;
|
|
199
|
+
title: string;
|
|
200
|
+
slug: string;
|
|
201
|
+
content: string;
|
|
202
|
+
excerpt?: string;
|
|
203
|
+
author?: {
|
|
204
|
+
id: string;
|
|
205
|
+
name: string;
|
|
206
|
+
};
|
|
207
|
+
status: 'draft' | 'published' | 'archived';
|
|
208
|
+
visibility: 'public' | 'members' | 'section';
|
|
209
|
+
sectionId?: string;
|
|
210
|
+
publishedAt?: string;
|
|
211
|
+
createdAt: string;
|
|
212
|
+
updatedAt: string;
|
|
213
|
+
}
|
|
214
|
+
interface NewsItem extends ContentItem {
|
|
215
|
+
type: 'news';
|
|
216
|
+
featuredImage?: string;
|
|
217
|
+
category?: string;
|
|
218
|
+
tags?: string[];
|
|
219
|
+
}
|
|
220
|
+
interface Page extends ContentItem {
|
|
221
|
+
type: 'page';
|
|
222
|
+
template?: string;
|
|
223
|
+
order?: number;
|
|
224
|
+
}
|
|
225
|
+
interface PaginatedResponse<T> {
|
|
226
|
+
items: T[];
|
|
227
|
+
total: number;
|
|
228
|
+
page: number;
|
|
229
|
+
pageSize: number;
|
|
230
|
+
hasMore: boolean;
|
|
231
|
+
}
|
|
232
|
+
interface AxCloudConfig {
|
|
233
|
+
orgId: string;
|
|
234
|
+
apiUrl: string;
|
|
235
|
+
/** API stage - defaults to 'dev'. Use 'prod' for production. */
|
|
236
|
+
stage: string;
|
|
237
|
+
/** API key for public content endpoints (optional - required for public API access) */
|
|
238
|
+
apiKey?: string;
|
|
239
|
+
auth0: {
|
|
240
|
+
domain: string;
|
|
241
|
+
clientId: string;
|
|
242
|
+
redirectUri: string;
|
|
243
|
+
audience?: string;
|
|
244
|
+
/** Database connection name for password operations. Defaults to 'Username-Password-Authentication' */
|
|
245
|
+
connection?: string;
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
interface ContentQueryOptions {
|
|
249
|
+
page?: number;
|
|
250
|
+
pageSize?: number;
|
|
251
|
+
status?: 'draft' | 'published' | 'archived';
|
|
252
|
+
visibility?: 'public' | 'members' | 'section';
|
|
253
|
+
sectionId?: string;
|
|
254
|
+
search?: string;
|
|
255
|
+
sortBy?: string;
|
|
256
|
+
sortOrder?: 'asc' | 'desc';
|
|
257
|
+
/** Force public endpoint even when authenticated (for public pages) */
|
|
258
|
+
publicOnly?: boolean;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Organization branding information
|
|
262
|
+
*/
|
|
263
|
+
interface OrganizationBranding {
|
|
264
|
+
organizationId: string;
|
|
265
|
+
name: string;
|
|
266
|
+
branding: {
|
|
267
|
+
/** Signed URL for logo (expires in 1 hour) */
|
|
268
|
+
logoUrl: string | null;
|
|
269
|
+
/** Seconds until logoUrl expires */
|
|
270
|
+
logoExpiresIn: number | null;
|
|
271
|
+
/** Primary brand color (hex) */
|
|
272
|
+
primaryColor: string | null;
|
|
273
|
+
/** Secondary brand color (hex) */
|
|
274
|
+
secondaryColor: string | null;
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Signed URL response for media assets
|
|
279
|
+
*/
|
|
280
|
+
interface SignedMediaUrl {
|
|
281
|
+
/** Signed S3 URL (expires in 1 hour) */
|
|
282
|
+
url: string;
|
|
283
|
+
/** Seconds until URL expires */
|
|
284
|
+
expiresIn: number;
|
|
285
|
+
/** S3 bucket name */
|
|
286
|
+
bucket: string;
|
|
287
|
+
/** S3 object key */
|
|
288
|
+
key: string;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Media list item
|
|
292
|
+
*/
|
|
293
|
+
interface MediaItem {
|
|
294
|
+
/** File key (filename) */
|
|
295
|
+
key: string;
|
|
296
|
+
/** File size in bytes */
|
|
297
|
+
size: number;
|
|
298
|
+
/** Last modified timestamp */
|
|
299
|
+
lastModified: string;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Media list response
|
|
303
|
+
*/
|
|
304
|
+
interface MediaListResponse {
|
|
305
|
+
items: MediaItem[];
|
|
306
|
+
count: number;
|
|
307
|
+
bucket: string;
|
|
308
|
+
prefix: string;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* AxCloud Forms Module
|
|
313
|
+
*
|
|
314
|
+
* Public functions for form submissions.
|
|
315
|
+
* Requires organization API key for authentication.
|
|
316
|
+
* Used by public websites like airene.io, theremoters.io, etc.
|
|
317
|
+
*/
|
|
318
|
+
/**
|
|
319
|
+
* Form submission request
|
|
320
|
+
*/
|
|
321
|
+
interface FormSubmission {
|
|
322
|
+
/** Organization API key (required for authentication) */
|
|
323
|
+
apiKey: string;
|
|
324
|
+
/** Site domain (e.g., 'airene.io') */
|
|
325
|
+
site: string;
|
|
326
|
+
/** Form type: 'waitlist', 'contact', or 'membership' */
|
|
327
|
+
formType: 'waitlist' | 'contact' | 'membership';
|
|
328
|
+
/** Email address */
|
|
329
|
+
email: string;
|
|
330
|
+
/** Additional form data */
|
|
331
|
+
data?: Record<string, unknown>;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Form submission response
|
|
335
|
+
*/
|
|
336
|
+
interface FormSubmissionResponse {
|
|
337
|
+
/** Whether the submission was successful */
|
|
338
|
+
success: boolean;
|
|
339
|
+
/** User-friendly message */
|
|
340
|
+
message: string;
|
|
341
|
+
/** Unique submission ID */
|
|
342
|
+
submissionId: string;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Form submission stored in database
|
|
346
|
+
*/
|
|
347
|
+
interface FormSubmissionRecord {
|
|
348
|
+
submission_id: string;
|
|
349
|
+
org_id: string;
|
|
350
|
+
site: string;
|
|
351
|
+
form_type: 'waitlist' | 'contact' | 'membership';
|
|
352
|
+
status: 'pending' | 'approved' | 'rejected' | 'converted';
|
|
353
|
+
email: string;
|
|
354
|
+
data: Record<string, unknown>;
|
|
355
|
+
created_at: string;
|
|
356
|
+
updated_at: string;
|
|
357
|
+
reviewed_by?: string;
|
|
358
|
+
reviewed_at?: string;
|
|
359
|
+
notes?: string;
|
|
360
|
+
user_id?: string;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Form stats response from API
|
|
364
|
+
*/
|
|
365
|
+
interface FormStatsResponse {
|
|
366
|
+
stats: {
|
|
367
|
+
total: number;
|
|
368
|
+
byStatus: Record<string, number>;
|
|
369
|
+
byType: Record<string, number>;
|
|
370
|
+
bySite: Record<string, number>;
|
|
371
|
+
recent: {
|
|
372
|
+
today: number;
|
|
373
|
+
last7Days: number;
|
|
374
|
+
last30Days: number;
|
|
375
|
+
};
|
|
376
|
+
};
|
|
377
|
+
summary: {
|
|
378
|
+
pending: number;
|
|
379
|
+
approved: number;
|
|
380
|
+
rejected: number;
|
|
381
|
+
conversionRate: string;
|
|
382
|
+
};
|
|
383
|
+
period: {
|
|
384
|
+
days: number;
|
|
385
|
+
from: string;
|
|
386
|
+
to: string;
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Paginated response for form submissions
|
|
391
|
+
*/
|
|
392
|
+
interface FormSubmissionsResponse {
|
|
393
|
+
items: FormSubmissionRecord[];
|
|
394
|
+
total: number;
|
|
395
|
+
cursor?: string;
|
|
396
|
+
hasMore: boolean;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Submit a form to AxCloud
|
|
400
|
+
*
|
|
401
|
+
* Requires organization API key for authentication.
|
|
402
|
+
*
|
|
403
|
+
* @param apiUrl - AxCloud Forms API base URL (e.g., 'https://api.axcloud.app/forms/dev')
|
|
404
|
+
* @param submission - Form submission data including API key
|
|
405
|
+
* @returns Submission response with ID
|
|
406
|
+
*
|
|
407
|
+
* @example
|
|
408
|
+
* ```tsx
|
|
409
|
+
* import { submitForm } from '@axcloud/sdk'
|
|
410
|
+
*
|
|
411
|
+
* const handleSubmit = async (email: string) => {
|
|
412
|
+
* const result = await submitForm(
|
|
413
|
+
* 'https://api.axcloud.app/forms/dev',
|
|
414
|
+
* {
|
|
415
|
+
* apiKey: 'your-org-api-key',
|
|
416
|
+
* site: 'airene.io',
|
|
417
|
+
* formType: 'waitlist',
|
|
418
|
+
* email,
|
|
419
|
+
* data: { name: 'John Doe' }
|
|
420
|
+
* }
|
|
421
|
+
* )
|
|
422
|
+
* console.log(result.message) // "Thanks! We'll notify you when we launch."
|
|
423
|
+
* }
|
|
424
|
+
* ```
|
|
425
|
+
*/
|
|
426
|
+
declare function submitForm(apiUrl: string, submission: FormSubmission): Promise<FormSubmissionResponse>;
|
|
427
|
+
/**
|
|
428
|
+
* Create a form submission helper with pre-configured API URL, API key, and site
|
|
429
|
+
*
|
|
430
|
+
* @param config - Configuration with apiUrl, apiKey, and site
|
|
431
|
+
* @returns Object with submit functions
|
|
432
|
+
*
|
|
433
|
+
* @example
|
|
434
|
+
* ```tsx
|
|
435
|
+
* import { createFormHelper } from '@axcloud/sdk'
|
|
436
|
+
*
|
|
437
|
+
* const forms = createFormHelper({
|
|
438
|
+
* apiUrl: 'https://api.axcloud.app/forms/dev',
|
|
439
|
+
* apiKey: 'your-org-api-key',
|
|
440
|
+
* site: 'airene.io'
|
|
441
|
+
* })
|
|
442
|
+
*
|
|
443
|
+
* // Now you can submit forms without repeating apiUrl, apiKey and site
|
|
444
|
+
* const result = await forms.submit('waitlist', 'user@example.com')
|
|
445
|
+
* ```
|
|
446
|
+
*/
|
|
447
|
+
declare function createFormHelper(config: {
|
|
448
|
+
apiUrl: string;
|
|
449
|
+
apiKey: string;
|
|
450
|
+
site: string;
|
|
451
|
+
}): {
|
|
452
|
+
/**
|
|
453
|
+
* Submit a waitlist form
|
|
454
|
+
*/
|
|
455
|
+
submitWaitlist: (email: string, data?: Record<string, unknown>) => Promise<FormSubmissionResponse>;
|
|
456
|
+
/**
|
|
457
|
+
* Submit a contact form
|
|
458
|
+
*/
|
|
459
|
+
submitContact: (email: string, data: {
|
|
460
|
+
name?: string;
|
|
461
|
+
message: string;
|
|
462
|
+
[key: string]: unknown;
|
|
463
|
+
}) => Promise<FormSubmissionResponse>;
|
|
464
|
+
/**
|
|
465
|
+
* Submit a membership application
|
|
466
|
+
*/
|
|
467
|
+
submitMembership: (email: string, data: {
|
|
468
|
+
firstName?: string;
|
|
469
|
+
lastName?: string;
|
|
470
|
+
phone?: string;
|
|
471
|
+
[key: string]: unknown;
|
|
472
|
+
}) => Promise<FormSubmissionResponse>;
|
|
473
|
+
/**
|
|
474
|
+
* Generic submit function
|
|
475
|
+
*/
|
|
476
|
+
submit: (formType: "waitlist" | "contact" | "membership", email: string, data?: Record<string, unknown>) => Promise<FormSubmissionResponse>;
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
interface AxCloudProviderProps {
|
|
480
|
+
children: React.ReactNode;
|
|
481
|
+
orgId: string;
|
|
482
|
+
apiUrl: string;
|
|
483
|
+
/** API stage - defaults to 'dev'. Use 'prod' for production. */
|
|
484
|
+
stage?: string;
|
|
485
|
+
/** API key for public content endpoints */
|
|
486
|
+
apiKey?: string;
|
|
487
|
+
auth0: {
|
|
488
|
+
domain: string;
|
|
489
|
+
clientId: string;
|
|
490
|
+
redirectUri: string;
|
|
491
|
+
audience?: string;
|
|
492
|
+
/** Database connection name for password operations. Defaults to 'Username-Password-Authentication' */
|
|
493
|
+
connection?: string;
|
|
494
|
+
};
|
|
495
|
+
queryClient?: QueryClient;
|
|
496
|
+
/** Default request timeout in milliseconds (default: 30000) */
|
|
497
|
+
timeout?: number;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* AxCloudProvider - Main provider for the SDK
|
|
501
|
+
*
|
|
502
|
+
* Combines Auth0Provider, QueryClientProvider, and AxCloud context.
|
|
503
|
+
*
|
|
504
|
+
* @example
|
|
505
|
+
* ```tsx
|
|
506
|
+
* <AxCloudProvider
|
|
507
|
+
* orgId="spf"
|
|
508
|
+
* apiUrl="https://api.axcloud.app"
|
|
509
|
+
* apiKey="your-api-key" // Required for public content access
|
|
510
|
+
* auth0={{
|
|
511
|
+
* domain: "auth.axcloud.app",
|
|
512
|
+
* clientId: "xxx",
|
|
513
|
+
* redirectUri: window.location.origin
|
|
514
|
+
* }}
|
|
515
|
+
* >
|
|
516
|
+
* <App />
|
|
517
|
+
* </AxCloudProvider>
|
|
518
|
+
* ```
|
|
519
|
+
*/
|
|
520
|
+
declare function AxCloudProvider({ children, orgId, apiUrl, stage, apiKey, auth0, queryClient, timeout, }: AxCloudProviderProps): react_jsx_runtime.JSX.Element;
|
|
521
|
+
|
|
522
|
+
interface AxCloudContextValue {
|
|
523
|
+
config: AxCloudConfig;
|
|
524
|
+
client: AxCloudClient;
|
|
525
|
+
orgId: string;
|
|
526
|
+
/** API stage (e.g., 'dev', 'prod') */
|
|
527
|
+
stage: string;
|
|
528
|
+
/** Whether using public API mode (API key, no auth) */
|
|
529
|
+
isPublicMode: boolean;
|
|
530
|
+
}
|
|
531
|
+
declare function useAxCloudContext(): AxCloudContextValue;
|
|
532
|
+
|
|
533
|
+
interface AuthUser {
|
|
534
|
+
id: string;
|
|
535
|
+
email: string;
|
|
536
|
+
name: string;
|
|
537
|
+
avatar?: string;
|
|
538
|
+
}
|
|
539
|
+
interface UseAuthReturn {
|
|
540
|
+
isAuthenticated: boolean;
|
|
541
|
+
isLoading: boolean;
|
|
542
|
+
error: Error | undefined;
|
|
543
|
+
user: AuthUser | null;
|
|
544
|
+
login: (options?: {
|
|
545
|
+
returnTo?: string;
|
|
546
|
+
}) => Promise<void>;
|
|
547
|
+
logout: (options?: {
|
|
548
|
+
returnTo?: string;
|
|
549
|
+
}) => Promise<void>;
|
|
550
|
+
getAccessToken: () => Promise<string | undefined>;
|
|
551
|
+
getAuth0Client: () => Auth0ClientState;
|
|
552
|
+
/** Request a password reset email for the current user or specified email */
|
|
553
|
+
requestPasswordReset: (email?: string) => Promise<{
|
|
554
|
+
success: boolean;
|
|
555
|
+
message: string;
|
|
556
|
+
}>;
|
|
557
|
+
}
|
|
558
|
+
interface Auth0ClientState {
|
|
559
|
+
loginWithRedirect: ReturnType<typeof useAuth0>['loginWithRedirect'];
|
|
560
|
+
logout: ReturnType<typeof useAuth0>['logout'];
|
|
561
|
+
getAccessTokenSilently: ReturnType<typeof useAuth0>['getAccessTokenSilently'];
|
|
562
|
+
getIdTokenClaims: ReturnType<typeof useAuth0>['getIdTokenClaims'];
|
|
563
|
+
user: User$1 | undefined;
|
|
564
|
+
isAuthenticated: boolean;
|
|
565
|
+
isLoading: boolean;
|
|
566
|
+
error: Error | undefined;
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* useAuth - Authentication hook with simplified API and escape hatch
|
|
570
|
+
*
|
|
571
|
+
* Provides easy login/logout methods while allowing access to the
|
|
572
|
+
* underlying Auth0 client for advanced use cases.
|
|
573
|
+
*
|
|
574
|
+
* @example
|
|
575
|
+
* ```tsx
|
|
576
|
+
* function Header() {
|
|
577
|
+
* const { isAuthenticated, login, logout, user } = useAuth()
|
|
578
|
+
*
|
|
579
|
+
* return isAuthenticated ? (
|
|
580
|
+
* <button onClick={logout}>Log out</button>
|
|
581
|
+
* ) : (
|
|
582
|
+
* <button onClick={login}>Log in</button>
|
|
583
|
+
* )
|
|
584
|
+
* }
|
|
585
|
+
* ```
|
|
586
|
+
*
|
|
587
|
+
* @example
|
|
588
|
+
* // Advanced: Get access token for manual API calls
|
|
589
|
+
* ```tsx
|
|
590
|
+
* function MyComponent() {
|
|
591
|
+
* const { getAccessToken } = useAuth()
|
|
592
|
+
*
|
|
593
|
+
* const fetchData = async () => {
|
|
594
|
+
* const token = await getAccessToken()
|
|
595
|
+
* // Use token for custom API calls
|
|
596
|
+
* }
|
|
597
|
+
* }
|
|
598
|
+
* ```
|
|
599
|
+
*/
|
|
600
|
+
declare function useAuth(): UseAuthReturn;
|
|
601
|
+
|
|
602
|
+
interface UserApiResponse extends User {
|
|
603
|
+
all_org_ids?: string[];
|
|
604
|
+
organization_memberships?: Record<string, {
|
|
605
|
+
role: string;
|
|
606
|
+
sections?: string[];
|
|
607
|
+
}>;
|
|
608
|
+
isSuperAdmin?: boolean;
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* useUser - Fetch the current authenticated user from AxCloud
|
|
612
|
+
*
|
|
613
|
+
* Returns the full user profile including organization membership,
|
|
614
|
+
* role, section, and permissions.
|
|
615
|
+
*
|
|
616
|
+
* Also validates that the user has access to the configured organization.
|
|
617
|
+
*
|
|
618
|
+
* @example
|
|
619
|
+
* ```tsx
|
|
620
|
+
* function Profile() {
|
|
621
|
+
* const { user, isLoading, isError, hasOrgAccess } = useUser()
|
|
622
|
+
*
|
|
623
|
+
* if (isLoading) return <Spinner />
|
|
624
|
+
* if (!hasOrgAccess) return <AccessDenied />
|
|
625
|
+
* if (!user) return <LoginPrompt />
|
|
626
|
+
*
|
|
627
|
+
* return (
|
|
628
|
+
* <div>
|
|
629
|
+
* <h1>Welcome, {user.name}!</h1>
|
|
630
|
+
* <p>Role: {user.role}</p>
|
|
631
|
+
* <p>Organization: {user.organizationId}</p>
|
|
632
|
+
* </div>
|
|
633
|
+
* )
|
|
634
|
+
* }
|
|
635
|
+
* ```
|
|
636
|
+
*/
|
|
637
|
+
declare function useUser(): {
|
|
638
|
+
user: UserApiResponse | null;
|
|
639
|
+
isLoading: boolean;
|
|
640
|
+
isError: boolean;
|
|
641
|
+
error: Error | null;
|
|
642
|
+
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<UserApiResponse, Error>>;
|
|
643
|
+
hasOrgAccess: boolean;
|
|
644
|
+
roleInOrg: string | null;
|
|
645
|
+
isAuthenticated: boolean;
|
|
646
|
+
role: UserRole | null;
|
|
647
|
+
organizationId: string | null;
|
|
648
|
+
sectionId: string | null;
|
|
649
|
+
permissions: string[];
|
|
650
|
+
isSuperAdmin: boolean;
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Public organization response from /content/public/{orgId}/org
|
|
655
|
+
*/
|
|
656
|
+
interface PublicOrganization {
|
|
657
|
+
org_id: string;
|
|
658
|
+
name: string;
|
|
659
|
+
description?: string;
|
|
660
|
+
branding?: {
|
|
661
|
+
logo?: string;
|
|
662
|
+
primaryColor?: string;
|
|
663
|
+
secondaryColor?: string;
|
|
664
|
+
};
|
|
665
|
+
modules?: string[];
|
|
666
|
+
contact?: {
|
|
667
|
+
email?: string;
|
|
668
|
+
phone?: string;
|
|
669
|
+
website?: string;
|
|
670
|
+
};
|
|
671
|
+
social?: {
|
|
672
|
+
facebook?: string;
|
|
673
|
+
twitter?: string;
|
|
674
|
+
linkedin?: string;
|
|
675
|
+
instagram?: string;
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* useOrg - Fetch organization info and check module availability
|
|
680
|
+
*
|
|
681
|
+
* Automatically uses the appropriate endpoint:
|
|
682
|
+
* - With API key (public): `/content/public/{orgId}/org`
|
|
683
|
+
* - With JWT auth: `/{stage}/api/organizations/{orgId}`
|
|
684
|
+
*
|
|
685
|
+
* @example
|
|
686
|
+
* ```tsx
|
|
687
|
+
* function Dashboard() {
|
|
688
|
+
* const { org, hasModule, isLoading } = useOrg()
|
|
689
|
+
*
|
|
690
|
+
* if (isLoading) return <Spinner />
|
|
691
|
+
*
|
|
692
|
+
* return (
|
|
693
|
+
* <div>
|
|
694
|
+
* <h1>{org.name}</h1>
|
|
695
|
+
* {org.branding?.logo && <img src={org.branding.logo} alt={org.name} />}
|
|
696
|
+
* {hasModule('training') && <TrainingSection />}
|
|
697
|
+
* {hasModule('ai') && <AIChatWidget />}
|
|
698
|
+
* </div>
|
|
699
|
+
* )
|
|
700
|
+
* }
|
|
701
|
+
* ```
|
|
702
|
+
*/
|
|
703
|
+
declare function useOrg(): {
|
|
704
|
+
org: {
|
|
705
|
+
id: string;
|
|
706
|
+
org_id: string;
|
|
707
|
+
name: string;
|
|
708
|
+
description: string | undefined;
|
|
709
|
+
branding: {
|
|
710
|
+
primaryColor?: string;
|
|
711
|
+
logo?: string;
|
|
712
|
+
} | undefined;
|
|
713
|
+
modules: string[];
|
|
714
|
+
contact: {
|
|
715
|
+
email?: string;
|
|
716
|
+
phone?: string;
|
|
717
|
+
website?: string;
|
|
718
|
+
} | undefined;
|
|
719
|
+
social: {
|
|
720
|
+
facebook?: string;
|
|
721
|
+
twitter?: string;
|
|
722
|
+
linkedin?: string;
|
|
723
|
+
instagram?: string;
|
|
724
|
+
} | undefined;
|
|
725
|
+
} | null;
|
|
726
|
+
orgId: string;
|
|
727
|
+
isLoading: boolean;
|
|
728
|
+
isError: boolean;
|
|
729
|
+
error: Error | null;
|
|
730
|
+
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<Organization | PublicOrganization, Error>>;
|
|
731
|
+
hasModule: (module: AxCloudModule) => boolean;
|
|
732
|
+
modules: string[];
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* useNews - Fetch news articles for the organization
|
|
737
|
+
*
|
|
738
|
+
* When authenticated (isPublicMode = false), fetches news visible to members
|
|
739
|
+
* including public, internal, and members-only content.
|
|
740
|
+
*
|
|
741
|
+
* When not authenticated (isPublicMode = true), fetches only public news.
|
|
742
|
+
*
|
|
743
|
+
* @example
|
|
744
|
+
* ```tsx
|
|
745
|
+
* function NewsPage() {
|
|
746
|
+
* const { data: news, isLoading, isError, error } = useNews()
|
|
747
|
+
*
|
|
748
|
+
* if (isLoading) return <Spinner />
|
|
749
|
+
* if (isError) return <Error message={error.message} />
|
|
750
|
+
*
|
|
751
|
+
* return (
|
|
752
|
+
* <ul>
|
|
753
|
+
* {news.map(item => (
|
|
754
|
+
* <li key={item.id}>{item.title}</li>
|
|
755
|
+
* ))}
|
|
756
|
+
* </ul>
|
|
757
|
+
* )
|
|
758
|
+
* }
|
|
759
|
+
* ```
|
|
760
|
+
*
|
|
761
|
+
* @example
|
|
762
|
+
* // With pagination
|
|
763
|
+
* ```tsx
|
|
764
|
+
* const { data, hasMore, fetchNextPage } = useNews({
|
|
765
|
+
* pageSize: 10,
|
|
766
|
+
* status: 'published'
|
|
767
|
+
* })
|
|
768
|
+
* ```
|
|
769
|
+
*/
|
|
770
|
+
declare function useNews(options?: ContentQueryOptions): {
|
|
771
|
+
data: NewsItem[];
|
|
772
|
+
total: number;
|
|
773
|
+
hasMore: boolean;
|
|
774
|
+
isLoading: boolean;
|
|
775
|
+
isError: boolean;
|
|
776
|
+
error: Error | null;
|
|
777
|
+
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<PaginatedResponse<NewsItem>, Error>>;
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* useContent - Generic content fetching hook
|
|
782
|
+
*
|
|
783
|
+
* When authenticated (isPublicMode = false), fetches content visible to members
|
|
784
|
+
* including public, internal, and members-only content (for supported types).
|
|
785
|
+
*
|
|
786
|
+
* When not authenticated (isPublicMode = true), fetches only public content.
|
|
787
|
+
*
|
|
788
|
+
* @param contentType - The type of content to fetch (e.g., 'news', 'pages', 'events')
|
|
789
|
+
* @param options - Query options for filtering and pagination
|
|
790
|
+
*
|
|
791
|
+
* @example
|
|
792
|
+
* ```tsx
|
|
793
|
+
* // Fetch pages
|
|
794
|
+
* const { data: pages } = useContent('pages')
|
|
795
|
+
*
|
|
796
|
+
* // Fetch custom content type
|
|
797
|
+
* const { data: events } = useContent('events', {
|
|
798
|
+
* status: 'published',
|
|
799
|
+
* sortBy: 'startDate'
|
|
800
|
+
* })
|
|
801
|
+
* ```
|
|
802
|
+
*/
|
|
803
|
+
declare function useContent<T extends ContentItem = ContentItem>(contentType: string, options?: ContentQueryOptions): {
|
|
804
|
+
data: T[];
|
|
805
|
+
total: number;
|
|
806
|
+
hasMore: boolean;
|
|
807
|
+
isLoading: boolean;
|
|
808
|
+
isError: boolean;
|
|
809
|
+
error: Error | null;
|
|
810
|
+
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<PaginatedResponse<T>, Error>>;
|
|
811
|
+
};
|
|
812
|
+
interface ContentItemOptions {
|
|
813
|
+
/** Force public endpoint even when authenticated */
|
|
814
|
+
publicOnly?: boolean;
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* useContentItem - Fetch a single content item by ID or slug
|
|
818
|
+
*
|
|
819
|
+
* When authenticated (isPublicMode = false), fetches from member endpoint
|
|
820
|
+
* which can return members-only content (for supported types).
|
|
821
|
+
*
|
|
822
|
+
* When not authenticated (isPublicMode = true), fetches only public content.
|
|
823
|
+
*
|
|
824
|
+
* @param contentType - The type of content (e.g., 'news', 'pages', 'events')
|
|
825
|
+
* @param idOrSlug - The content ID or slug
|
|
826
|
+
* @param options - Optional settings
|
|
827
|
+
*
|
|
828
|
+
* @example
|
|
829
|
+
* ```tsx
|
|
830
|
+
* // Fetch a page by slug
|
|
831
|
+
* const { data: page } = useContentItem('pages', 'about-us')
|
|
832
|
+
*
|
|
833
|
+
* // Force public endpoint
|
|
834
|
+
* const { data: page } = useContentItem('pages', 'about-us', { publicOnly: true })
|
|
835
|
+
* ```
|
|
836
|
+
*/
|
|
837
|
+
declare function useContentItem<T extends ContentItem = ContentItem>(contentType: string, idOrSlug: string, options?: ContentItemOptions): {
|
|
838
|
+
data: _tanstack_react_query.NoInfer<T> | null;
|
|
839
|
+
isLoading: boolean;
|
|
840
|
+
isError: boolean;
|
|
841
|
+
error: Error | null;
|
|
842
|
+
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<_tanstack_react_query.NoInfer<T>, Error>>;
|
|
843
|
+
};
|
|
844
|
+
|
|
845
|
+
interface SectionWithMembers extends Section {
|
|
846
|
+
members?: User[];
|
|
847
|
+
memberCount?: number;
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* useMySection - Fetch the current user's section
|
|
851
|
+
*
|
|
852
|
+
* Returns the section the authenticated user belongs to,
|
|
853
|
+
* along with optional member list if the user has permission to view.
|
|
854
|
+
*
|
|
855
|
+
* @example
|
|
856
|
+
* ```tsx
|
|
857
|
+
* function MySectionPage() {
|
|
858
|
+
* const { section, members, isLoading } = useMySection()
|
|
859
|
+
*
|
|
860
|
+
* if (isLoading) return <Spinner />
|
|
861
|
+
* if (!section) return <p>You are not assigned to a section</p>
|
|
862
|
+
*
|
|
863
|
+
* return (
|
|
864
|
+
* <div>
|
|
865
|
+
* <h1>{section.name}</h1>
|
|
866
|
+
* <p>{section.description}</p>
|
|
867
|
+
* <h2>Members ({members.length})</h2>
|
|
868
|
+
* <ul>
|
|
869
|
+
* {members.map(m => <li key={m.id}>{m.name}</li>)}
|
|
870
|
+
* </ul>
|
|
871
|
+
* </div>
|
|
872
|
+
* )
|
|
873
|
+
* }
|
|
874
|
+
* ```
|
|
875
|
+
*/
|
|
876
|
+
declare function useMySection(options?: {
|
|
877
|
+
includeMembers?: boolean;
|
|
878
|
+
}): {
|
|
879
|
+
section: SectionWithMembers | null;
|
|
880
|
+
sectionId: string | null;
|
|
881
|
+
members: User[];
|
|
882
|
+
memberCount: number;
|
|
883
|
+
isLoading: boolean;
|
|
884
|
+
isError: boolean;
|
|
885
|
+
error: Error | null;
|
|
886
|
+
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<SectionWithMembers, Error>>;
|
|
887
|
+
hasSection: boolean;
|
|
888
|
+
user: UserApiResponse | null;
|
|
889
|
+
};
|
|
890
|
+
/**
|
|
891
|
+
* useSections - Fetch all sections for the organization
|
|
892
|
+
*
|
|
893
|
+
* @example
|
|
894
|
+
* ```tsx
|
|
895
|
+
* const { sections } = useSections()
|
|
896
|
+
* ```
|
|
897
|
+
*/
|
|
898
|
+
declare function useSections(): {
|
|
899
|
+
sections: Section[];
|
|
900
|
+
isLoading: boolean;
|
|
901
|
+
isError: boolean;
|
|
902
|
+
error: Error | null;
|
|
903
|
+
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<Section[], Error>>;
|
|
904
|
+
};
|
|
905
|
+
|
|
906
|
+
interface UseFormsOptions {
|
|
907
|
+
/** Filter by form type */
|
|
908
|
+
formType?: 'waitlist' | 'contact' | 'membership';
|
|
909
|
+
/** Filter by status */
|
|
910
|
+
status?: 'pending' | 'approved' | 'rejected' | 'converted';
|
|
911
|
+
/** Number of items per page (default 50, max 100) */
|
|
912
|
+
limit?: number;
|
|
913
|
+
/** Pagination cursor */
|
|
914
|
+
cursor?: string;
|
|
915
|
+
}
|
|
916
|
+
interface UseFormStatsOptions {
|
|
917
|
+
/** Number of days to include (default 30, max 365) */
|
|
918
|
+
days?: number;
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* useForms - Fetch form submissions for the organization (admin only)
|
|
922
|
+
*
|
|
923
|
+
* @example
|
|
924
|
+
* ```tsx
|
|
925
|
+
* function FormSubmissions() {
|
|
926
|
+
* const { data, isLoading, hasMore, refetch } = useForms({
|
|
927
|
+
* status: 'pending'
|
|
928
|
+
* })
|
|
929
|
+
*
|
|
930
|
+
* if (isLoading) return <Spinner />
|
|
931
|
+
*
|
|
932
|
+
* return (
|
|
933
|
+
* <ul>
|
|
934
|
+
* {data.map(submission => (
|
|
935
|
+
* <li key={submission.submission_id}>{submission.email}</li>
|
|
936
|
+
* ))}
|
|
937
|
+
* </ul>
|
|
938
|
+
* )
|
|
939
|
+
* }
|
|
940
|
+
* ```
|
|
941
|
+
*/
|
|
942
|
+
declare function useForms(options?: UseFormsOptions): {
|
|
943
|
+
data: FormSubmissionRecord[];
|
|
944
|
+
total: number;
|
|
945
|
+
hasMore: boolean;
|
|
946
|
+
cursor: string | undefined;
|
|
947
|
+
isLoading: boolean;
|
|
948
|
+
isError: boolean;
|
|
949
|
+
error: Error | null;
|
|
950
|
+
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<FormSubmissionsResponse, Error>>;
|
|
951
|
+
};
|
|
952
|
+
/**
|
|
953
|
+
* useFormStats - Fetch form submission statistics (admin only)
|
|
954
|
+
*
|
|
955
|
+
* @example
|
|
956
|
+
* ```tsx
|
|
957
|
+
* function FormDashboard() {
|
|
958
|
+
* const { stats, summary, isLoading } = useFormStats({ days: 30 })
|
|
959
|
+
*
|
|
960
|
+
* if (isLoading) return <Spinner />
|
|
961
|
+
*
|
|
962
|
+
* return (
|
|
963
|
+
* <div>
|
|
964
|
+
* <p>Pending: {summary.pending}</p>
|
|
965
|
+
* <p>Approved: {summary.approved}</p>
|
|
966
|
+
* <p>Conversion Rate: {summary.conversionRate}</p>
|
|
967
|
+
* </div>
|
|
968
|
+
* )
|
|
969
|
+
* }
|
|
970
|
+
* ```
|
|
971
|
+
*/
|
|
972
|
+
declare function useFormStats(options?: UseFormStatsOptions): {
|
|
973
|
+
stats: {
|
|
974
|
+
total: number;
|
|
975
|
+
byStatus: Record<string, number>;
|
|
976
|
+
byType: Record<string, number>;
|
|
977
|
+
bySite: Record<string, number>;
|
|
978
|
+
recent: {
|
|
979
|
+
today: number;
|
|
980
|
+
last7Days: number;
|
|
981
|
+
last30Days: number;
|
|
982
|
+
};
|
|
983
|
+
} | undefined;
|
|
984
|
+
summary: {
|
|
985
|
+
pending: number;
|
|
986
|
+
approved: number;
|
|
987
|
+
rejected: number;
|
|
988
|
+
conversionRate: string;
|
|
989
|
+
} | undefined;
|
|
990
|
+
period: {
|
|
991
|
+
days: number;
|
|
992
|
+
from: string;
|
|
993
|
+
to: string;
|
|
994
|
+
} | undefined;
|
|
995
|
+
isLoading: boolean;
|
|
996
|
+
isError: boolean;
|
|
997
|
+
error: Error | null;
|
|
998
|
+
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<FormStatsResponse, Error>>;
|
|
999
|
+
};
|
|
1000
|
+
/**
|
|
1001
|
+
* useUpdateFormSubmission - Mutation hook for updating submission status
|
|
1002
|
+
*
|
|
1003
|
+
* @example
|
|
1004
|
+
* ```tsx
|
|
1005
|
+
* function SubmissionRow({ submission }) {
|
|
1006
|
+
* const { mutate: updateSubmission, isLoading } = useUpdateFormSubmission()
|
|
1007
|
+
*
|
|
1008
|
+
* const handleApprove = () => {
|
|
1009
|
+
* updateSubmission({
|
|
1010
|
+
* submissionId: submission.submission_id,
|
|
1011
|
+
* status: 'approved',
|
|
1012
|
+
* notes: 'Approved by admin'
|
|
1013
|
+
* })
|
|
1014
|
+
* }
|
|
1015
|
+
*
|
|
1016
|
+
* return (
|
|
1017
|
+
* <button onClick={handleApprove} disabled={isLoading}>
|
|
1018
|
+
* Approve
|
|
1019
|
+
* </button>
|
|
1020
|
+
* )
|
|
1021
|
+
* }
|
|
1022
|
+
* ```
|
|
1023
|
+
*/
|
|
1024
|
+
declare function useUpdateFormSubmission(): _tanstack_react_query.UseMutationResult<{
|
|
1025
|
+
success: boolean;
|
|
1026
|
+
message: string;
|
|
1027
|
+
submission: FormSubmissionRecord;
|
|
1028
|
+
user_created?: boolean;
|
|
1029
|
+
user_id?: string;
|
|
1030
|
+
}, Error, {
|
|
1031
|
+
submissionId: string;
|
|
1032
|
+
status: "approved" | "rejected";
|
|
1033
|
+
notes?: string;
|
|
1034
|
+
}, unknown>;
|
|
1035
|
+
|
|
1036
|
+
/**
|
|
1037
|
+
* useLinkedAccounts Hook
|
|
1038
|
+
*
|
|
1039
|
+
* Manages linked social accounts (identities) for the current user.
|
|
1040
|
+
* Supports Google, Microsoft, and Apple OAuth providers.
|
|
1041
|
+
*
|
|
1042
|
+
* Uses React-Query for caching, background refresh, and automatic refetch.
|
|
1043
|
+
*
|
|
1044
|
+
* @example
|
|
1045
|
+
* ```tsx
|
|
1046
|
+
* function AccountSettings() {
|
|
1047
|
+
* const {
|
|
1048
|
+
* identities,
|
|
1049
|
+
* availableProviders,
|
|
1050
|
+
* isLoading,
|
|
1051
|
+
* linkAccount,
|
|
1052
|
+
* unlinkAccount,
|
|
1053
|
+
* canUnlink
|
|
1054
|
+
* } = useLinkedAccounts()
|
|
1055
|
+
*
|
|
1056
|
+
* return (
|
|
1057
|
+
* <div>
|
|
1058
|
+
* {identities.map(identity => (
|
|
1059
|
+
* <div key={identity.provider}>
|
|
1060
|
+
* {identity.provider_display_name}
|
|
1061
|
+
* {canUnlink && !identity.is_primary && (
|
|
1062
|
+
* <button onClick={() => unlinkAccount(identity.provider)}>
|
|
1063
|
+
* Disconnect
|
|
1064
|
+
* </button>
|
|
1065
|
+
* )}
|
|
1066
|
+
* </div>
|
|
1067
|
+
* ))}
|
|
1068
|
+
* {availableProviders.map(provider => (
|
|
1069
|
+
* <button key={provider.provider} onClick={() => linkAccount(provider.provider)}>
|
|
1070
|
+
* Connect {provider.display_name}
|
|
1071
|
+
* </button>
|
|
1072
|
+
* ))}
|
|
1073
|
+
* </div>
|
|
1074
|
+
* )
|
|
1075
|
+
* }
|
|
1076
|
+
* ```
|
|
1077
|
+
*/
|
|
1078
|
+
interface LinkedIdentity {
|
|
1079
|
+
provider: string;
|
|
1080
|
+
provider_display_name: string;
|
|
1081
|
+
provider_icon: string;
|
|
1082
|
+
user_id: string;
|
|
1083
|
+
connection: string;
|
|
1084
|
+
is_social: boolean;
|
|
1085
|
+
is_primary: boolean;
|
|
1086
|
+
profile_data?: {
|
|
1087
|
+
email?: string;
|
|
1088
|
+
name?: string;
|
|
1089
|
+
picture?: string;
|
|
1090
|
+
};
|
|
1091
|
+
}
|
|
1092
|
+
interface AvailableProvider {
|
|
1093
|
+
provider: string;
|
|
1094
|
+
display_name: string;
|
|
1095
|
+
icon: string;
|
|
1096
|
+
}
|
|
1097
|
+
interface UseLinkedAccountsReturn {
|
|
1098
|
+
/** List of linked identities/accounts */
|
|
1099
|
+
identities: LinkedIdentity[];
|
|
1100
|
+
/** List of providers available for linking */
|
|
1101
|
+
availableProviders: AvailableProvider[];
|
|
1102
|
+
/** Whether the user can unlink accounts (must have >1) */
|
|
1103
|
+
canUnlink: boolean;
|
|
1104
|
+
/** Loading state */
|
|
1105
|
+
isLoading: boolean;
|
|
1106
|
+
/** Error state */
|
|
1107
|
+
error: Error | null;
|
|
1108
|
+
/** Initiate linking a new account - redirects to OAuth flow */
|
|
1109
|
+
linkAccount: (provider: 'google' | 'microsoft' | 'apple') => void;
|
|
1110
|
+
/** Unlink an account */
|
|
1111
|
+
unlinkAccount: (provider: string) => void;
|
|
1112
|
+
/** Whether a link operation is in progress */
|
|
1113
|
+
isLinking: boolean;
|
|
1114
|
+
/** Whether an unlink operation is in progress */
|
|
1115
|
+
isUnlinking: boolean;
|
|
1116
|
+
/** Refresh the identities list */
|
|
1117
|
+
refetch: () => Promise<unknown>;
|
|
1118
|
+
}
|
|
1119
|
+
/**
|
|
1120
|
+
* useLinkedAccounts - Manage social login accounts
|
|
1121
|
+
*
|
|
1122
|
+
* Provides functionality to view, link, and unlink social accounts
|
|
1123
|
+
* (Google, Microsoft, Apple) from the user's profile.
|
|
1124
|
+
*
|
|
1125
|
+
* Uses React-Query for caching and automatic state management.
|
|
1126
|
+
*/
|
|
1127
|
+
declare function useLinkedAccounts(): UseLinkedAccountsReturn;
|
|
1128
|
+
|
|
1129
|
+
/**
|
|
1130
|
+
* useBranding - Fetch organization branding (logo, colors)
|
|
1131
|
+
*
|
|
1132
|
+
* Returns branding information including a signed URL for the logo.
|
|
1133
|
+
* The logo URL expires after 1 hour and will be refreshed automatically.
|
|
1134
|
+
*
|
|
1135
|
+
* @example
|
|
1136
|
+
* ```tsx
|
|
1137
|
+
* const { branding, logoUrl, isLoading } = useBranding()
|
|
1138
|
+
*
|
|
1139
|
+
* return (
|
|
1140
|
+
* <header>
|
|
1141
|
+
* {logoUrl && <img src={logoUrl} alt="Logo" />}
|
|
1142
|
+
* <h1 style={{ color: branding?.primaryColor }}>Welcome</h1>
|
|
1143
|
+
* </header>
|
|
1144
|
+
* )
|
|
1145
|
+
* ```
|
|
1146
|
+
*/
|
|
1147
|
+
declare function useBranding(): {
|
|
1148
|
+
branding: {
|
|
1149
|
+
logoUrl: string | null;
|
|
1150
|
+
logoExpiresIn: number | null;
|
|
1151
|
+
primaryColor: string | null;
|
|
1152
|
+
secondaryColor: string | null;
|
|
1153
|
+
} | null;
|
|
1154
|
+
logoUrl: string | null;
|
|
1155
|
+
organizationName: string | null;
|
|
1156
|
+
isLoading: boolean;
|
|
1157
|
+
isError: boolean;
|
|
1158
|
+
error: Error | null;
|
|
1159
|
+
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<OrganizationBranding, Error>>;
|
|
1160
|
+
};
|
|
1161
|
+
/**
|
|
1162
|
+
* useLogo - Fetch organization logo URL
|
|
1163
|
+
*
|
|
1164
|
+
* Returns a signed URL for the organization logo.
|
|
1165
|
+
* Use this when you only need the logo, not full branding info.
|
|
1166
|
+
*
|
|
1167
|
+
* @example
|
|
1168
|
+
* ```tsx
|
|
1169
|
+
* const { logoUrl, isLoading } = useLogo()
|
|
1170
|
+
*
|
|
1171
|
+
* if (isLoading) return <Skeleton />
|
|
1172
|
+
* return logoUrl ? <img src={logoUrl} alt="Logo" /> : <DefaultLogo />
|
|
1173
|
+
* ```
|
|
1174
|
+
*/
|
|
1175
|
+
declare function useLogo(): {
|
|
1176
|
+
logoUrl: string | null;
|
|
1177
|
+
expiresIn: number | null;
|
|
1178
|
+
isLoading: boolean;
|
|
1179
|
+
isError: boolean;
|
|
1180
|
+
error: Error | null;
|
|
1181
|
+
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<SignedMediaUrl, Error>>;
|
|
1182
|
+
};
|
|
1183
|
+
/**
|
|
1184
|
+
* useAvatar - Fetch user avatar URL
|
|
1185
|
+
*
|
|
1186
|
+
* @param userId - The user ID to fetch avatar for
|
|
1187
|
+
*
|
|
1188
|
+
* @example
|
|
1189
|
+
* ```tsx
|
|
1190
|
+
* const { avatarUrl } = useAvatar(user.id)
|
|
1191
|
+
* return <img src={avatarUrl || defaultAvatar} alt={user.name} />
|
|
1192
|
+
* ```
|
|
1193
|
+
*/
|
|
1194
|
+
declare function useAvatar(userId: string): {
|
|
1195
|
+
avatarUrl: string | null;
|
|
1196
|
+
isLoading: boolean;
|
|
1197
|
+
isError: boolean;
|
|
1198
|
+
error: Error | null;
|
|
1199
|
+
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<SignedMediaUrl, Error>>;
|
|
1200
|
+
};
|
|
1201
|
+
/**
|
|
1202
|
+
* useMediaList - List media files in organization's library
|
|
1203
|
+
*
|
|
1204
|
+
* @param type - Media type to list ('media', 'logos', 'avatars')
|
|
1205
|
+
* @param limit - Maximum number of items to return (default: 50)
|
|
1206
|
+
*
|
|
1207
|
+
* @example
|
|
1208
|
+
* ```tsx
|
|
1209
|
+
* const { items, isLoading } = useMediaList('media', 20)
|
|
1210
|
+
*
|
|
1211
|
+
* return (
|
|
1212
|
+
* <div className="grid">
|
|
1213
|
+
* {items.map(item => (
|
|
1214
|
+
* <MediaThumbnail key={item.key} item={item} />
|
|
1215
|
+
* ))}
|
|
1216
|
+
* </div>
|
|
1217
|
+
* )
|
|
1218
|
+
* ```
|
|
1219
|
+
*/
|
|
1220
|
+
declare function useMediaList(type?: 'media' | 'logos' | 'avatars', limit?: number): {
|
|
1221
|
+
items: MediaItem[];
|
|
1222
|
+
count: number;
|
|
1223
|
+
isLoading: boolean;
|
|
1224
|
+
isError: boolean;
|
|
1225
|
+
error: Error | null;
|
|
1226
|
+
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<MediaListResponse, Error>>;
|
|
1227
|
+
};
|
|
1228
|
+
/**
|
|
1229
|
+
* useMedia - Fetch a specific media file by ID
|
|
1230
|
+
*
|
|
1231
|
+
* @param mediaId - The media ID (filename including extension)
|
|
1232
|
+
*
|
|
1233
|
+
* @example
|
|
1234
|
+
* ```tsx
|
|
1235
|
+
* const { mediaUrl } = useMedia('hero-image.jpg')
|
|
1236
|
+
* return <img src={mediaUrl} alt="Hero" />
|
|
1237
|
+
* ```
|
|
1238
|
+
*/
|
|
1239
|
+
declare function useMedia(mediaId: string): {
|
|
1240
|
+
mediaUrl: string | null;
|
|
1241
|
+
expiresIn: number | null;
|
|
1242
|
+
isLoading: boolean;
|
|
1243
|
+
isError: boolean;
|
|
1244
|
+
error: Error | null;
|
|
1245
|
+
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<SignedMediaUrl, Error>>;
|
|
1246
|
+
};
|
|
1247
|
+
|
|
1248
|
+
interface LoginButtonProps {
|
|
1249
|
+
/**
|
|
1250
|
+
* Button text when not authenticated
|
|
1251
|
+
*/
|
|
1252
|
+
children?: React.ReactNode;
|
|
1253
|
+
/**
|
|
1254
|
+
* URL to return to after login
|
|
1255
|
+
*/
|
|
1256
|
+
returnTo?: string;
|
|
1257
|
+
/**
|
|
1258
|
+
* Additional CSS class names
|
|
1259
|
+
*/
|
|
1260
|
+
className?: string;
|
|
1261
|
+
/**
|
|
1262
|
+
* Inline styles
|
|
1263
|
+
*/
|
|
1264
|
+
style?: React.CSSProperties;
|
|
1265
|
+
}
|
|
1266
|
+
/**
|
|
1267
|
+
* LoginButton - Trigger Auth0 Universal Login
|
|
1268
|
+
*
|
|
1269
|
+
* @example
|
|
1270
|
+
* ```tsx
|
|
1271
|
+
* <LoginButton>Sign In</LoginButton>
|
|
1272
|
+
*
|
|
1273
|
+
* // With custom return URL
|
|
1274
|
+
* <LoginButton returnTo="/dashboard">Sign In</LoginButton>
|
|
1275
|
+
*
|
|
1276
|
+
* // With styling
|
|
1277
|
+
* <LoginButton className="btn btn-primary">Sign In</LoginButton>
|
|
1278
|
+
* ```
|
|
1279
|
+
*/
|
|
1280
|
+
declare function LoginButton({ children, returnTo, className, style, }: LoginButtonProps): react_jsx_runtime.JSX.Element;
|
|
1281
|
+
interface LogoutButtonProps {
|
|
1282
|
+
/**
|
|
1283
|
+
* Button text
|
|
1284
|
+
*/
|
|
1285
|
+
children?: React.ReactNode;
|
|
1286
|
+
/**
|
|
1287
|
+
* URL to return to after logout
|
|
1288
|
+
*/
|
|
1289
|
+
returnTo?: string;
|
|
1290
|
+
/**
|
|
1291
|
+
* Additional CSS class names
|
|
1292
|
+
*/
|
|
1293
|
+
className?: string;
|
|
1294
|
+
/**
|
|
1295
|
+
* Inline styles
|
|
1296
|
+
*/
|
|
1297
|
+
style?: React.CSSProperties;
|
|
1298
|
+
}
|
|
1299
|
+
/**
|
|
1300
|
+
* LogoutButton - Trigger logout
|
|
1301
|
+
*
|
|
1302
|
+
* @example
|
|
1303
|
+
* ```tsx
|
|
1304
|
+
* <LogoutButton>Sign Out</LogoutButton>
|
|
1305
|
+
* ```
|
|
1306
|
+
*/
|
|
1307
|
+
declare function LogoutButton({ children, returnTo, className, style, }: LogoutButtonProps): react_jsx_runtime.JSX.Element;
|
|
1308
|
+
|
|
1309
|
+
interface ProtectedRouteProps {
|
|
1310
|
+
/**
|
|
1311
|
+
* Content to render when authenticated
|
|
1312
|
+
*/
|
|
1313
|
+
children: React.ReactNode;
|
|
1314
|
+
/**
|
|
1315
|
+
* Required role(s) to access this route
|
|
1316
|
+
*/
|
|
1317
|
+
roles?: UserRole | UserRole[];
|
|
1318
|
+
/**
|
|
1319
|
+
* Component to render while loading
|
|
1320
|
+
*/
|
|
1321
|
+
loadingComponent?: React.ReactNode;
|
|
1322
|
+
/**
|
|
1323
|
+
* Component to render when not authenticated
|
|
1324
|
+
*/
|
|
1325
|
+
unauthenticatedComponent?: React.ReactNode;
|
|
1326
|
+
/**
|
|
1327
|
+
* Component to render when authenticated but lacking required role
|
|
1328
|
+
*/
|
|
1329
|
+
unauthorizedComponent?: React.ReactNode;
|
|
1330
|
+
/**
|
|
1331
|
+
* Whether to automatically redirect to login when not authenticated
|
|
1332
|
+
* @default false
|
|
1333
|
+
*/
|
|
1334
|
+
redirectToLogin?: boolean;
|
|
1335
|
+
/**
|
|
1336
|
+
* Return URL after login (only used with redirectToLogin)
|
|
1337
|
+
*/
|
|
1338
|
+
returnTo?: string;
|
|
1339
|
+
}
|
|
1340
|
+
/**
|
|
1341
|
+
* ProtectedRoute - Require authentication to view content
|
|
1342
|
+
*
|
|
1343
|
+
* @example
|
|
1344
|
+
* ```tsx
|
|
1345
|
+
* // Basic usage
|
|
1346
|
+
* <ProtectedRoute>
|
|
1347
|
+
* <MemberContent />
|
|
1348
|
+
* </ProtectedRoute>
|
|
1349
|
+
*
|
|
1350
|
+
* // With role requirement
|
|
1351
|
+
* <ProtectedRoute roles="admin">
|
|
1352
|
+
* <AdminDashboard />
|
|
1353
|
+
* </ProtectedRoute>
|
|
1354
|
+
*
|
|
1355
|
+
* // With multiple allowed roles
|
|
1356
|
+
* <ProtectedRoute roles={['admin', 'editor']}>
|
|
1357
|
+
* <ContentEditor />
|
|
1358
|
+
* </ProtectedRoute>
|
|
1359
|
+
*
|
|
1360
|
+
* // With custom fallbacks
|
|
1361
|
+
* <ProtectedRoute
|
|
1362
|
+
* loadingComponent={<Spinner />}
|
|
1363
|
+
* unauthenticatedComponent={<LoginPrompt />}
|
|
1364
|
+
* unauthorizedComponent={<AccessDenied />}
|
|
1365
|
+
* >
|
|
1366
|
+
* <ProtectedContent />
|
|
1367
|
+
* </ProtectedRoute>
|
|
1368
|
+
*
|
|
1369
|
+
* // Auto-redirect to login
|
|
1370
|
+
* <ProtectedRoute redirectToLogin>
|
|
1371
|
+
* <MemberArea />
|
|
1372
|
+
* </ProtectedRoute>
|
|
1373
|
+
* ```
|
|
1374
|
+
*/
|
|
1375
|
+
declare function ProtectedRoute({ children, roles, loadingComponent, unauthenticatedComponent, unauthorizedComponent, redirectToLogin, returnTo, }: ProtectedRouteProps): react_jsx_runtime.JSX.Element;
|
|
1376
|
+
|
|
1377
|
+
interface ModuleGateProps {
|
|
1378
|
+
/**
|
|
1379
|
+
* Required module(s) to render children
|
|
1380
|
+
*/
|
|
1381
|
+
module: AxCloudModule | AxCloudModule[];
|
|
1382
|
+
/**
|
|
1383
|
+
* Content to render when module is enabled
|
|
1384
|
+
*/
|
|
1385
|
+
children: React.ReactNode;
|
|
1386
|
+
/**
|
|
1387
|
+
* Content to render when module is NOT enabled
|
|
1388
|
+
*/
|
|
1389
|
+
fallback?: React.ReactNode;
|
|
1390
|
+
/**
|
|
1391
|
+
* Whether ALL modules are required (true) or ANY module (false)
|
|
1392
|
+
* @default false (any)
|
|
1393
|
+
*/
|
|
1394
|
+
requireAll?: boolean;
|
|
1395
|
+
}
|
|
1396
|
+
/**
|
|
1397
|
+
* ModuleGate - Conditionally render based on organization modules
|
|
1398
|
+
*
|
|
1399
|
+
* Only renders children if the organization has the required module(s) enabled.
|
|
1400
|
+
*
|
|
1401
|
+
* @example
|
|
1402
|
+
* ```tsx
|
|
1403
|
+
* // Single module
|
|
1404
|
+
* <ModuleGate module="training">
|
|
1405
|
+
* <TrainingSection />
|
|
1406
|
+
* </ModuleGate>
|
|
1407
|
+
*
|
|
1408
|
+
* // With fallback
|
|
1409
|
+
* <ModuleGate module="ai" fallback={<UpgradePrompt />}>
|
|
1410
|
+
* <AIChatWidget />
|
|
1411
|
+
* </ModuleGate>
|
|
1412
|
+
*
|
|
1413
|
+
* // Multiple modules (any)
|
|
1414
|
+
* <ModuleGate module={['training', 'documents']}>
|
|
1415
|
+
* <LearningCenter />
|
|
1416
|
+
* </ModuleGate>
|
|
1417
|
+
*
|
|
1418
|
+
* // Multiple modules (all required)
|
|
1419
|
+
* <ModuleGate module={['training', 'ai']} requireAll>
|
|
1420
|
+
* <AITrainingAssistant />
|
|
1421
|
+
* </ModuleGate>
|
|
1422
|
+
* ```
|
|
1423
|
+
*/
|
|
1424
|
+
declare function ModuleGate({ module, children, fallback, requireAll, }: ModuleGateProps): react_jsx_runtime.JSX.Element | null;
|
|
1425
|
+
/**
|
|
1426
|
+
* useModuleAccess - Hook for programmatic module checks
|
|
1427
|
+
*
|
|
1428
|
+
* @example
|
|
1429
|
+
* ```tsx
|
|
1430
|
+
* function Dashboard() {
|
|
1431
|
+
* const { hasModule, modules } = useModuleAccess()
|
|
1432
|
+
*
|
|
1433
|
+
* return (
|
|
1434
|
+
* <nav>
|
|
1435
|
+
* <Link to="/news">News</Link>
|
|
1436
|
+
* {hasModule('training') && <Link to="/training">Training</Link>}
|
|
1437
|
+
* {hasModule('ai') && <Link to="/chat">AI Chat</Link>}
|
|
1438
|
+
* </nav>
|
|
1439
|
+
* )
|
|
1440
|
+
* }
|
|
1441
|
+
* ```
|
|
1442
|
+
*/
|
|
1443
|
+
declare function useModuleAccess(): {
|
|
1444
|
+
hasModule: (module: AxCloudModule) => boolean;
|
|
1445
|
+
modules: string[];
|
|
1446
|
+
isLoading: boolean;
|
|
1447
|
+
};
|
|
1448
|
+
|
|
1449
|
+
interface LinkedAccountsListProps {
|
|
1450
|
+
/** Which providers to show (default: all available) */
|
|
1451
|
+
providers?: ('google' | 'microsoft' | 'apple')[];
|
|
1452
|
+
/** Show connect buttons for unlinked providers */
|
|
1453
|
+
showConnectButtons?: boolean;
|
|
1454
|
+
/** Custom class name for the container */
|
|
1455
|
+
className?: string;
|
|
1456
|
+
/** Callback when an account is successfully unlinked */
|
|
1457
|
+
onUnlink?: (provider: string) => void;
|
|
1458
|
+
/** Callback when link flow is initiated */
|
|
1459
|
+
onLinkInitiated?: (provider: string) => void;
|
|
1460
|
+
/** Custom render for identity items */
|
|
1461
|
+
renderIdentity?: (identity: LinkedIdentity, onUnlink: () => void) => React.ReactNode;
|
|
1462
|
+
/** Custom render for available provider items */
|
|
1463
|
+
renderAvailableProvider?: (provider: AvailableProvider, onLink: () => void) => React.ReactNode;
|
|
1464
|
+
}
|
|
1465
|
+
/**
|
|
1466
|
+
* LinkedAccountsList - Ready-to-use component for managing linked accounts
|
|
1467
|
+
*
|
|
1468
|
+
* Uses CSS classes for styling. Import the CSS file for default styles:
|
|
1469
|
+
* import '@axcode/axcloud-sdk/styles/linked-accounts.css'
|
|
1470
|
+
*/
|
|
1471
|
+
declare function LinkedAccountsList({ providers, showConnectButtons, className, onUnlink, onLinkInitiated, renderIdentity, renderAvailableProvider, }: LinkedAccountsListProps): react_jsx_runtime.JSX.Element;
|
|
1472
|
+
|
|
1473
|
+
export { type AvailableProvider, AxCloudClient, type AxCloudConfig, AxCloudError, type AxCloudErrorCode, type AxCloudModule, AxCloudProvider, type BaseRole, type ContentItem, type ContentQueryOptions, type CustomRole, type FormStatsResponse, type FormSubmission, type FormSubmissionRecord, type FormSubmissionResponse, type FormSubmissionsResponse, LinkedAccountsList, type LinkedAccountsListProps, type LinkedIdentity, LoginButton, LogoutButton, type MediaItem, type MediaListResponse, type Membership, ModuleGate, type NewsItem, type Organization, type OrganizationBranding, type OrganizationSettings, type Page, type PaginatedResponse, ProtectedRoute, type Section, type SectionPermissions, type SignedMediaUrl, type SystemRole, type UseLinkedAccountsReturn, type User, type UserRole, createClient, createFormHelper, getClient, isAxCloudError, submitForm, useAuth, useAvatar, useAxCloudContext, useBranding, useContent, useContentItem, useFormStats, useForms, useLinkedAccounts, useLogo, useMedia, useMediaList, useModuleAccess, useMySection, useNews, useOrg, useSections, useUpdateFormSubmission, useUser, userHasAllPermissions, userHasAnyPermission, userHasPermission };
|