@elqnt/admin 2.1.0 → 2.2.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.
@@ -2,12 +2,18 @@
2
2
  import { useState, useCallback } from "react";
3
3
 
4
4
  // api/index.ts
5
- import { browserApiRequest as browserApiRequest4, clearGatewayTokenCache } from "@elqnt/api-client/browser";
5
+ import { browserApiRequest as browserApiRequest6, clearGatewayTokenCache } from "@elqnt/api-client/browser";
6
6
 
7
7
  // api/orgs.ts
8
8
  import { browserApiRequest } from "@elqnt/api-client/browser";
9
- async function listOrgsApi(options) {
10
- return browserApiRequest("/api/v1/admin/orgs", {
9
+ async function listOrgsApi(filter, options) {
10
+ const params = new URLSearchParams();
11
+ if (filter?.product) params.set("product", filter.product);
12
+ if (filter?.status) params.set("status", filter.status);
13
+ if (filter?.type) params.set("type", filter.type);
14
+ const queryString = params.toString();
15
+ const url = queryString ? `/api/v1/admin/orgs?${queryString}` : "/api/v1/admin/orgs";
16
+ return browserApiRequest(url, {
11
17
  method: "GET",
12
18
  ...options
13
19
  });
@@ -44,6 +50,13 @@ async function getOrgInfoApi(orgId, options) {
44
50
  ...options
45
51
  });
46
52
  }
53
+ async function createOrgWithSchemasApi(org, schemas, options) {
54
+ return browserApiRequest("/api/v1/admin/orgs/with-schemas", {
55
+ method: "POST",
56
+ body: { org, schemas },
57
+ ...options
58
+ });
59
+ }
47
60
 
48
61
  // api/users.ts
49
62
  import { browserApiRequest as browserApiRequest2 } from "@elqnt/api-client/browser";
@@ -72,6 +85,12 @@ async function getUserByEmailApi(email, options) {
72
85
  ...options
73
86
  });
74
87
  }
88
+ async function getUserByPhoneApi(phone, options) {
89
+ return browserApiRequest2(`/api/v1/admin/users/by-phone?phone=${encodeURIComponent(phone)}`, {
90
+ method: "GET",
91
+ ...options
92
+ });
93
+ }
75
94
  async function updateUserApi(userId, updates, options) {
76
95
  return browserApiRequest2(`/api/v1/admin/users/${userId}`, {
77
96
  method: "PUT",
@@ -146,22 +165,208 @@ async function acceptInviteApi(inviteId, options) {
146
165
  });
147
166
  }
148
167
 
168
+ // api/analytics.ts
169
+ import { browserApiRequest as browserApiRequest4 } from "@elqnt/api-client/browser";
170
+ function buildDateFilterParams(filter) {
171
+ if (!filter) return "";
172
+ const params = new URLSearchParams();
173
+ if (filter.from) params.set("from", filter.from);
174
+ if (filter.to) params.set("to", filter.to);
175
+ const queryString = params.toString();
176
+ return queryString ? `?${queryString}` : "";
177
+ }
178
+ async function getAnalyticsSummaryApi(filter, options) {
179
+ const queryString = buildDateFilterParams(filter);
180
+ return browserApiRequest4(`/api/v1/analytics/summary${queryString}`, {
181
+ method: "GET",
182
+ ...options
183
+ });
184
+ }
185
+ async function getChatsAnalyticsApi(filter, agentId, options) {
186
+ const params = new URLSearchParams();
187
+ if (filter?.from) params.set("from", filter.from);
188
+ if (filter?.to) params.set("to", filter.to);
189
+ if (agentId) params.set("agent_id", agentId);
190
+ const queryString = params.toString();
191
+ return browserApiRequest4(`/api/v1/analytics/chats${queryString ? `?${queryString}` : ""}`, {
192
+ method: "GET",
193
+ ...options
194
+ });
195
+ }
196
+ async function getAgentsAnalyticsApi(filter, options) {
197
+ const queryString = buildDateFilterParams(filter);
198
+ return browserApiRequest4(`/api/v1/analytics/agents${queryString}`, {
199
+ method: "GET",
200
+ ...options
201
+ });
202
+ }
203
+ async function getUsageAnalyticsApi(filter, options) {
204
+ const queryString = buildDateFilterParams(filter);
205
+ return browserApiRequest4(`/api/v1/analytics/usage${queryString}`, {
206
+ method: "GET",
207
+ ...options
208
+ });
209
+ }
210
+ async function getDailyAnalyticsApi(filter, options) {
211
+ const queryString = buildDateFilterParams(filter);
212
+ return browserApiRequest4(`/api/v1/analytics/daily${queryString}`, {
213
+ method: "GET",
214
+ ...options
215
+ });
216
+ }
217
+ async function getAnalyticsEventsApi(filter, options) {
218
+ const queryString = buildDateFilterParams(filter);
219
+ return browserApiRequest4(`/api/v1/analytics/events${queryString}`, {
220
+ method: "GET",
221
+ ...options
222
+ });
223
+ }
224
+ async function logAnalyticsEventApi(event, options) {
225
+ return browserApiRequest4("/api/v1/analytics/events", {
226
+ method: "POST",
227
+ body: event,
228
+ ...options
229
+ });
230
+ }
231
+ async function getGlobalSummaryApi(filter, options) {
232
+ const queryString = buildDateFilterParams(filter);
233
+ return browserApiRequest4(`/api/v1/analytics/global/summary${queryString}`, {
234
+ method: "GET",
235
+ ...options
236
+ });
237
+ }
238
+ async function getGlobalOrgsAnalyticsApi(filter, options) {
239
+ const queryString = buildDateFilterParams(filter);
240
+ return browserApiRequest4(`/api/v1/analytics/global/orgs${queryString}`, {
241
+ method: "GET",
242
+ ...options
243
+ });
244
+ }
245
+
246
+ // api/provisioning.ts
247
+ import { browserApiRequest as browserApiRequest5 } from "@elqnt/api-client/browser";
248
+ async function createOrgWithProvisioningApi(request, options) {
249
+ return browserApiRequest5("/api/v1/admin/provisioning/orgs", {
250
+ method: "POST",
251
+ body: request,
252
+ ...options
253
+ });
254
+ }
255
+ async function getProvisioningStatusApi(orgId, options) {
256
+ return browserApiRequest5(`/api/v1/admin/orgs/${orgId}/provisioning`, {
257
+ method: "GET",
258
+ ...options
259
+ });
260
+ }
261
+ async function retryProvisioningApi(orgId, request, options) {
262
+ return browserApiRequest5(`/api/v1/admin/orgs/${orgId}/provisioning/retry`, {
263
+ method: "POST",
264
+ body: request || {},
265
+ ...options
266
+ });
267
+ }
268
+ async function validateProvisioningApi(orgId, options) {
269
+ return browserApiRequest5(
270
+ `/api/v1/admin/orgs/${orgId}/provisioning/validate`,
271
+ {
272
+ method: "POST",
273
+ ...options
274
+ }
275
+ );
276
+ }
277
+ async function cancelProvisioningApi(orgId, options) {
278
+ return browserApiRequest5(
279
+ `/api/v1/admin/orgs/${orgId}/provisioning/cancel`,
280
+ {
281
+ method: "POST",
282
+ ...options
283
+ }
284
+ );
285
+ }
286
+ async function cleanupProvisioningApi(orgId, options) {
287
+ return browserApiRequest5(`/api/v1/admin/orgs/${orgId}/provisioning`, {
288
+ method: "DELETE",
289
+ ...options
290
+ });
291
+ }
292
+ function streamProvisioningProgress(orgId, callbacks, options) {
293
+ const url = new URL(
294
+ `/api/v1/admin/orgs/${orgId}/provisioning/stream`,
295
+ options.baseUrl
296
+ );
297
+ if (options.token) {
298
+ url.searchParams.set("token", options.token);
299
+ }
300
+ const eventSource = new EventSource(url.toString());
301
+ eventSource.addEventListener("connected", (event) => {
302
+ try {
303
+ const data = JSON.parse(event.data);
304
+ callbacks.onConnected?.(data.orgId);
305
+ } catch (e) {
306
+ console.error("Failed to parse connected event", e);
307
+ }
308
+ });
309
+ eventSource.addEventListener("progress", (event) => {
310
+ try {
311
+ const progress = JSON.parse(event.data);
312
+ callbacks.onProgress?.(progress);
313
+ } catch (e) {
314
+ console.error("Failed to parse progress event", e);
315
+ }
316
+ });
317
+ eventSource.addEventListener("done", () => {
318
+ callbacks.onDone?.();
319
+ eventSource.close();
320
+ });
321
+ eventSource.addEventListener("timeout", () => {
322
+ callbacks.onTimeout?.();
323
+ eventSource.close();
324
+ });
325
+ eventSource.onerror = (error) => {
326
+ callbacks.onError?.(new Error("SSE connection error"));
327
+ eventSource.close();
328
+ };
329
+ return () => {
330
+ eventSource.close();
331
+ };
332
+ }
333
+ function calculateProgressPercentage(progress) {
334
+ if (progress.totalArtifacts === 0) return 0;
335
+ return Math.round(
336
+ progress.completedArtifacts / progress.totalArtifacts * 100
337
+ );
338
+ }
339
+ function isProvisioningComplete(progress) {
340
+ return progress.status === "completed" || progress.status === "failed" || progress.status === "partial";
341
+ }
342
+ function isProvisioningSuccessful(progress) {
343
+ return progress.status === "completed";
344
+ }
345
+ function getFailedArtifacts(progress) {
346
+ return progress.artifacts.filter((a) => a.status === "failed");
347
+ }
348
+ function hasCriticalFailures(progress) {
349
+ return progress.artifacts.some(
350
+ (a) => a.status === "failed" && a.critical
351
+ );
352
+ }
353
+
149
354
  // api/index.ts
150
355
  async function getOrgSettingsApi(options) {
151
- return browserApiRequest4("/api/v1/org/settings", {
356
+ return browserApiRequest6("/api/v1/org/settings", {
152
357
  method: "GET",
153
358
  ...options
154
359
  });
155
360
  }
156
361
  async function createOrgSettingsApi(settings, options) {
157
- return browserApiRequest4("/api/v1/org/settings", {
362
+ return browserApiRequest6("/api/v1/org/settings", {
158
363
  method: "POST",
159
364
  body: settings,
160
365
  ...options
161
366
  });
162
367
  }
163
368
  async function updateOrgSettingsApi(settings, options) {
164
- return browserApiRequest4("/api/v1/org/settings", {
369
+ return browserApiRequest6("/api/v1/org/settings", {
165
370
  method: "PUT",
166
371
  body: settings,
167
372
  ...options
@@ -172,11 +377,11 @@ async function updateOrgSettingsApi(settings, options) {
172
377
  function useOrgAdmin(options) {
173
378
  const [loading, setLoading] = useState(false);
174
379
  const [error, setError] = useState(null);
175
- const listOrgs = useCallback(async () => {
380
+ const listOrgs = useCallback(async (filter) => {
176
381
  setLoading(true);
177
382
  setError(null);
178
383
  try {
179
- const response = await listOrgsApi(options);
384
+ const response = await listOrgsApi(filter, options);
180
385
  if (response.error) {
181
386
  setError(response.error);
182
387
  return [];
@@ -253,6 +458,27 @@ function useOrgAdmin(options) {
253
458
  },
254
459
  [options]
255
460
  );
461
+ const createOrgWithSchemas = useCallback(
462
+ async (org, schemas) => {
463
+ setLoading(true);
464
+ setError(null);
465
+ try {
466
+ const response = await createOrgWithSchemasApi(org, schemas, options);
467
+ if (response.error) {
468
+ setError(response.error);
469
+ return null;
470
+ }
471
+ return response.data || null;
472
+ } catch (err) {
473
+ const message = err instanceof Error ? err.message : "Failed to create organization with schemas";
474
+ setError(message);
475
+ return null;
476
+ } finally {
477
+ setLoading(false);
478
+ }
479
+ },
480
+ [options]
481
+ );
256
482
  const updateOrg = useCallback(
257
483
  async (orgId, updates) => {
258
484
  setLoading(true);
@@ -302,6 +528,7 @@ function useOrgAdmin(options) {
302
528
  getOrg,
303
529
  getOrgInfo,
304
530
  createOrg,
531
+ createOrgWithSchemas,
305
532
  updateOrg,
306
533
  deleteOrg
307
534
  };
@@ -372,6 +599,27 @@ function useUsersAdmin(options) {
372
599
  },
373
600
  [options]
374
601
  );
602
+ const getUserByPhone = useCallback2(
603
+ async (phone) => {
604
+ setLoading(true);
605
+ setError(null);
606
+ try {
607
+ const response = await getUserByPhoneApi(phone, options);
608
+ if (response.error) {
609
+ setError(response.error);
610
+ return null;
611
+ }
612
+ return response.data?.user || null;
613
+ } catch (err) {
614
+ const message = err instanceof Error ? err.message : "Failed to get user by phone";
615
+ setError(message);
616
+ return null;
617
+ } finally {
618
+ setLoading(false);
619
+ }
620
+ },
621
+ [options]
622
+ );
375
623
  const createUser = useCallback2(
376
624
  async (user) => {
377
625
  setLoading(true);
@@ -483,6 +731,7 @@ function useUsersAdmin(options) {
483
731
  listUsers,
484
732
  getUser,
485
733
  getUserByEmail,
734
+ getUserByPhone,
486
735
  createUser,
487
736
  updateUser,
488
737
  deleteUser,
@@ -726,10 +975,519 @@ function useOrgSettings(options) {
726
975
  updateSettings
727
976
  };
728
977
  }
978
+
979
+ // hooks/use-product-analytics.ts
980
+ import { useState as useState5, useCallback as useCallback5, useRef, useEffect } from "react";
981
+ function useProductAnalytics(options) {
982
+ const [state, setState] = useState5({
983
+ summary: null,
984
+ chats: [],
985
+ agents: [],
986
+ usage: [],
987
+ daily: [],
988
+ events: [],
989
+ loading: false,
990
+ error: null
991
+ });
992
+ const sessionIdRef = useRef("");
993
+ useEffect(() => {
994
+ if (typeof window !== "undefined") {
995
+ let sessionId = sessionStorage.getItem("analytics_session_id");
996
+ if (!sessionId) {
997
+ sessionId = crypto.randomUUID();
998
+ sessionStorage.setItem("analytics_session_id", sessionId);
999
+ }
1000
+ sessionIdRef.current = sessionId;
1001
+ }
1002
+ }, []);
1003
+ const getSummary = useCallback5(
1004
+ async (filter) => {
1005
+ setState((prev) => ({ ...prev, loading: true, error: null }));
1006
+ try {
1007
+ const response = await getAnalyticsSummaryApi(filter, options);
1008
+ if (response.error) {
1009
+ setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
1010
+ return null;
1011
+ }
1012
+ const summary = response.data?.data || null;
1013
+ setState((prev) => ({ ...prev, loading: false, summary }));
1014
+ return summary;
1015
+ } catch (err) {
1016
+ const message = err instanceof Error ? err.message : "Failed to get analytics summary";
1017
+ setState((prev) => ({ ...prev, loading: false, error: message }));
1018
+ return null;
1019
+ }
1020
+ },
1021
+ [options]
1022
+ );
1023
+ const getChats = useCallback5(
1024
+ async (filter, agentId) => {
1025
+ setState((prev) => ({ ...prev, loading: true, error: null }));
1026
+ try {
1027
+ const response = await getChatsAnalyticsApi(filter, agentId, options);
1028
+ if (response.error) {
1029
+ setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
1030
+ return [];
1031
+ }
1032
+ const chats = response.data?.data || [];
1033
+ setState((prev) => ({ ...prev, loading: false, chats }));
1034
+ return chats;
1035
+ } catch (err) {
1036
+ const message = err instanceof Error ? err.message : "Failed to get chat analytics";
1037
+ setState((prev) => ({ ...prev, loading: false, error: message }));
1038
+ return [];
1039
+ }
1040
+ },
1041
+ [options]
1042
+ );
1043
+ const getAgents = useCallback5(
1044
+ async (filter) => {
1045
+ setState((prev) => ({ ...prev, loading: true, error: null }));
1046
+ try {
1047
+ const response = await getAgentsAnalyticsApi(filter, options);
1048
+ if (response.error) {
1049
+ setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
1050
+ return [];
1051
+ }
1052
+ const agents = response.data?.data || [];
1053
+ setState((prev) => ({ ...prev, loading: false, agents }));
1054
+ return agents;
1055
+ } catch (err) {
1056
+ const message = err instanceof Error ? err.message : "Failed to get agent analytics";
1057
+ setState((prev) => ({ ...prev, loading: false, error: message }));
1058
+ return [];
1059
+ }
1060
+ },
1061
+ [options]
1062
+ );
1063
+ const getUsage = useCallback5(
1064
+ async (filter) => {
1065
+ setState((prev) => ({ ...prev, loading: true, error: null }));
1066
+ try {
1067
+ const response = await getUsageAnalyticsApi(filter, options);
1068
+ if (response.error) {
1069
+ setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
1070
+ return [];
1071
+ }
1072
+ const usage = response.data?.data || [];
1073
+ setState((prev) => ({ ...prev, loading: false, usage }));
1074
+ return usage;
1075
+ } catch (err) {
1076
+ const message = err instanceof Error ? err.message : "Failed to get usage analytics";
1077
+ setState((prev) => ({ ...prev, loading: false, error: message }));
1078
+ return [];
1079
+ }
1080
+ },
1081
+ [options]
1082
+ );
1083
+ const getDaily = useCallback5(
1084
+ async (filter) => {
1085
+ setState((prev) => ({ ...prev, loading: true, error: null }));
1086
+ try {
1087
+ const response = await getDailyAnalyticsApi(filter, options);
1088
+ if (response.error) {
1089
+ setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
1090
+ return [];
1091
+ }
1092
+ const daily = response.data?.data || [];
1093
+ setState((prev) => ({ ...prev, loading: false, daily }));
1094
+ return daily;
1095
+ } catch (err) {
1096
+ const message = err instanceof Error ? err.message : "Failed to get daily analytics";
1097
+ setState((prev) => ({ ...prev, loading: false, error: message }));
1098
+ return [];
1099
+ }
1100
+ },
1101
+ [options]
1102
+ );
1103
+ const getEvents = useCallback5(
1104
+ async (filter) => {
1105
+ setState((prev) => ({ ...prev, loading: true, error: null }));
1106
+ try {
1107
+ const response = await getAnalyticsEventsApi(filter, options);
1108
+ if (response.error) {
1109
+ setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
1110
+ return [];
1111
+ }
1112
+ const events = response.data?.data || [];
1113
+ setState((prev) => ({ ...prev, loading: false, events }));
1114
+ return events;
1115
+ } catch (err) {
1116
+ const message = err instanceof Error ? err.message : "Failed to get analytics events";
1117
+ setState((prev) => ({ ...prev, loading: false, error: message }));
1118
+ return [];
1119
+ }
1120
+ },
1121
+ [options]
1122
+ );
1123
+ const trackEvent = useCallback5(
1124
+ async (eventType, eventCategory, properties) => {
1125
+ try {
1126
+ const event = {
1127
+ sessionId: sessionIdRef.current,
1128
+ userId: options.userId || "",
1129
+ eventType,
1130
+ eventCategory,
1131
+ pagePath: typeof window !== "undefined" ? window.location.pathname : void 0,
1132
+ properties
1133
+ };
1134
+ await logAnalyticsEventApi(event, options);
1135
+ } catch {
1136
+ console.debug("Failed to track analytics event:", eventType);
1137
+ }
1138
+ },
1139
+ [options]
1140
+ );
1141
+ const trackPageView = useCallback5(
1142
+ async (pageName) => {
1143
+ await trackEvent("page_view", "navigation", {
1144
+ pageName: pageName || (typeof window !== "undefined" ? document.title : "")
1145
+ });
1146
+ },
1147
+ [trackEvent]
1148
+ );
1149
+ const getGlobalSummary = useCallback5(
1150
+ async (filter) => {
1151
+ setState((prev) => ({ ...prev, loading: true, error: null }));
1152
+ try {
1153
+ const response = await getGlobalSummaryApi(filter, options);
1154
+ if (response.error) {
1155
+ setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
1156
+ return null;
1157
+ }
1158
+ setState((prev) => ({ ...prev, loading: false }));
1159
+ return response.data?.data || null;
1160
+ } catch (err) {
1161
+ const message = err instanceof Error ? err.message : "Failed to get global summary";
1162
+ setState((prev) => ({ ...prev, loading: false, error: message }));
1163
+ return null;
1164
+ }
1165
+ },
1166
+ [options]
1167
+ );
1168
+ const getGlobalOrgs = useCallback5(
1169
+ async (filter) => {
1170
+ setState((prev) => ({ ...prev, loading: true, error: null }));
1171
+ try {
1172
+ const response = await getGlobalOrgsAnalyticsApi(filter, options);
1173
+ if (response.error) {
1174
+ setState((prev) => ({ ...prev, loading: false, error: response.error || null }));
1175
+ return [];
1176
+ }
1177
+ setState((prev) => ({ ...prev, loading: false }));
1178
+ return response.data?.data || [];
1179
+ } catch (err) {
1180
+ const message = err instanceof Error ? err.message : "Failed to get org analytics";
1181
+ setState((prev) => ({ ...prev, loading: false, error: message }));
1182
+ return [];
1183
+ }
1184
+ },
1185
+ [options]
1186
+ );
1187
+ return {
1188
+ // State
1189
+ ...state,
1190
+ // Query functions
1191
+ getSummary,
1192
+ getChats,
1193
+ getAgents,
1194
+ getUsage,
1195
+ getDaily,
1196
+ getEvents,
1197
+ // Event tracking
1198
+ trackEvent,
1199
+ trackPageView,
1200
+ // Global analytics (admin)
1201
+ getGlobalSummary,
1202
+ getGlobalOrgs
1203
+ };
1204
+ }
1205
+ var useAnalyticsContext = useProductAnalytics;
1206
+
1207
+ // hooks/use-org-provisioning.ts
1208
+ import { useState as useState6, useCallback as useCallback6, useEffect as useEffect2, useRef as useRef2 } from "react";
1209
+ function useOrgProvisioning(options) {
1210
+ const [state, setState] = useState6({
1211
+ status: "idle",
1212
+ progress: null,
1213
+ org: null,
1214
+ error: null,
1215
+ percentage: 0
1216
+ });
1217
+ const cleanupRef = useRef2(null);
1218
+ useEffect2(() => {
1219
+ return () => {
1220
+ if (cleanupRef.current) {
1221
+ cleanupRef.current();
1222
+ }
1223
+ };
1224
+ }, []);
1225
+ const createOrgWithProvisioning = useCallback6(
1226
+ async (request) => {
1227
+ setState((prev) => ({
1228
+ ...prev,
1229
+ status: "creating",
1230
+ error: null,
1231
+ progress: null,
1232
+ percentage: 0
1233
+ }));
1234
+ try {
1235
+ const response = await createOrgWithProvisioningApi(request, options);
1236
+ if (response.error) {
1237
+ setState((prev) => ({
1238
+ ...prev,
1239
+ status: "failed",
1240
+ error: response.error || "Failed to create organization"
1241
+ }));
1242
+ return null;
1243
+ }
1244
+ const org = response.data?.organization || response.data?.org;
1245
+ if (!org) {
1246
+ setState((prev) => ({
1247
+ ...prev,
1248
+ status: "failed",
1249
+ error: "No organization returned"
1250
+ }));
1251
+ return null;
1252
+ }
1253
+ setState((prev) => ({
1254
+ ...prev,
1255
+ status: "provisioning",
1256
+ org
1257
+ }));
1258
+ const cleanup = streamProvisioningProgress(
1259
+ org.id,
1260
+ {
1261
+ onProgress: (progress) => {
1262
+ const percentage = calculateProgressPercentage(progress);
1263
+ const status = isProvisioningComplete(progress) ? isProvisioningSuccessful(progress) ? "completed" : progress.status === "partial" ? "partial" : "failed" : "provisioning";
1264
+ setState((prev) => ({
1265
+ ...prev,
1266
+ status,
1267
+ progress,
1268
+ percentage,
1269
+ error: progress.error || null
1270
+ }));
1271
+ },
1272
+ onDone: () => {
1273
+ cleanupRef.current = null;
1274
+ },
1275
+ onError: (error) => {
1276
+ setState((prev) => ({
1277
+ ...prev,
1278
+ status: "failed",
1279
+ error: error.message
1280
+ }));
1281
+ cleanupRef.current = null;
1282
+ },
1283
+ onTimeout: () => {
1284
+ setState((prev) => ({
1285
+ ...prev,
1286
+ error: "Provisioning timed out"
1287
+ }));
1288
+ cleanupRef.current = null;
1289
+ }
1290
+ },
1291
+ { baseUrl: options.baseUrl }
1292
+ );
1293
+ cleanupRef.current = cleanup;
1294
+ return org;
1295
+ } catch (err) {
1296
+ const message = err instanceof Error ? err.message : "Failed to create organization";
1297
+ setState((prev) => ({
1298
+ ...prev,
1299
+ status: "failed",
1300
+ error: message
1301
+ }));
1302
+ return null;
1303
+ }
1304
+ },
1305
+ [options]
1306
+ );
1307
+ const getProvisioningStatus = useCallback6(
1308
+ async (orgId) => {
1309
+ try {
1310
+ const response = await getProvisioningStatusApi(orgId, options);
1311
+ if (response.error) {
1312
+ setState((prev) => ({ ...prev, error: response.error || null }));
1313
+ return null;
1314
+ }
1315
+ const progress = response.data?.progress || null;
1316
+ if (progress) {
1317
+ setState((prev) => ({
1318
+ ...prev,
1319
+ progress,
1320
+ percentage: calculateProgressPercentage(progress),
1321
+ status: isProvisioningComplete(progress) ? isProvisioningSuccessful(progress) ? "completed" : progress.status === "partial" ? "partial" : "failed" : "provisioning"
1322
+ }));
1323
+ }
1324
+ return progress;
1325
+ } catch (err) {
1326
+ const message = err instanceof Error ? err.message : "Failed to get provisioning status";
1327
+ setState((prev) => ({ ...prev, error: message }));
1328
+ return null;
1329
+ }
1330
+ },
1331
+ [options]
1332
+ );
1333
+ const retryProvisioning = useCallback6(
1334
+ async (orgId, artifacts) => {
1335
+ setState((prev) => ({
1336
+ ...prev,
1337
+ status: "provisioning",
1338
+ error: null
1339
+ }));
1340
+ try {
1341
+ const request = artifacts ? { artifacts } : void 0;
1342
+ const response = await retryProvisioningApi(orgId, request, options);
1343
+ if (response.error) {
1344
+ setState((prev) => ({
1345
+ ...prev,
1346
+ status: "failed",
1347
+ error: response.error || "Failed to retry provisioning"
1348
+ }));
1349
+ return false;
1350
+ }
1351
+ const cleanup = streamProvisioningProgress(
1352
+ orgId,
1353
+ {
1354
+ onProgress: (progress) => {
1355
+ const percentage = calculateProgressPercentage(progress);
1356
+ const status = isProvisioningComplete(progress) ? isProvisioningSuccessful(progress) ? "completed" : progress.status === "partial" ? "partial" : "failed" : "provisioning";
1357
+ setState((prev) => ({
1358
+ ...prev,
1359
+ status,
1360
+ progress,
1361
+ percentage,
1362
+ error: progress.error || null
1363
+ }));
1364
+ },
1365
+ onDone: () => {
1366
+ cleanupRef.current = null;
1367
+ },
1368
+ onError: (error) => {
1369
+ setState((prev) => ({
1370
+ ...prev,
1371
+ status: "failed",
1372
+ error: error.message
1373
+ }));
1374
+ cleanupRef.current = null;
1375
+ }
1376
+ },
1377
+ { baseUrl: options.baseUrl }
1378
+ );
1379
+ cleanupRef.current = cleanup;
1380
+ return true;
1381
+ } catch (err) {
1382
+ const message = err instanceof Error ? err.message : "Failed to retry provisioning";
1383
+ setState((prev) => ({
1384
+ ...prev,
1385
+ status: "failed",
1386
+ error: message
1387
+ }));
1388
+ return false;
1389
+ }
1390
+ },
1391
+ [options]
1392
+ );
1393
+ const validateProvisioning = useCallback6(
1394
+ async (orgId) => {
1395
+ try {
1396
+ const response = await validateProvisioningApi(orgId, options);
1397
+ if (response.error) {
1398
+ setState((prev) => ({ ...prev, error: response.error || null }));
1399
+ return null;
1400
+ }
1401
+ return response.data || null;
1402
+ } catch (err) {
1403
+ const message = err instanceof Error ? err.message : "Failed to validate provisioning";
1404
+ setState((prev) => ({ ...prev, error: message }));
1405
+ return null;
1406
+ }
1407
+ },
1408
+ [options]
1409
+ );
1410
+ const cancelProvisioning = useCallback6(
1411
+ async (orgId) => {
1412
+ try {
1413
+ if (cleanupRef.current) {
1414
+ cleanupRef.current();
1415
+ cleanupRef.current = null;
1416
+ }
1417
+ const response = await cancelProvisioningApi(orgId, options);
1418
+ if (response.error) {
1419
+ setState((prev) => ({ ...prev, error: response.error || null }));
1420
+ return false;
1421
+ }
1422
+ setState((prev) => ({
1423
+ ...prev,
1424
+ status: "failed",
1425
+ error: "Provisioning cancelled"
1426
+ }));
1427
+ return true;
1428
+ } catch (err) {
1429
+ const message = err instanceof Error ? err.message : "Failed to cancel provisioning";
1430
+ setState((prev) => ({ ...prev, error: message }));
1431
+ return false;
1432
+ }
1433
+ },
1434
+ [options]
1435
+ );
1436
+ const cleanupOrg = useCallback6(
1437
+ async (orgId) => {
1438
+ try {
1439
+ const response = await cleanupProvisioningApi(orgId, options);
1440
+ if (response.error) {
1441
+ setState((prev) => ({ ...prev, error: response.error || null }));
1442
+ return false;
1443
+ }
1444
+ return true;
1445
+ } catch (err) {
1446
+ const message = err instanceof Error ? err.message : "Failed to cleanup organization";
1447
+ setState((prev) => ({ ...prev, error: message }));
1448
+ return false;
1449
+ }
1450
+ },
1451
+ [options]
1452
+ );
1453
+ const reset = useCallback6(() => {
1454
+ if (cleanupRef.current) {
1455
+ cleanupRef.current();
1456
+ cleanupRef.current = null;
1457
+ }
1458
+ setState({
1459
+ status: "idle",
1460
+ progress: null,
1461
+ org: null,
1462
+ error: null,
1463
+ percentage: 0
1464
+ });
1465
+ }, []);
1466
+ return {
1467
+ state,
1468
+ createOrgWithProvisioning,
1469
+ getProvisioningStatus,
1470
+ retryProvisioning,
1471
+ validateProvisioning,
1472
+ cancelProvisioning,
1473
+ cleanupOrg,
1474
+ reset,
1475
+ // Helper functions
1476
+ isComplete: state.status === "completed",
1477
+ isFailed: state.status === "failed",
1478
+ isPartial: state.status === "partial",
1479
+ isProvisioning: state.status === "provisioning" || state.status === "creating",
1480
+ failedArtifacts: state.progress ? getFailedArtifacts(state.progress) : [],
1481
+ hasCriticalFailures: state.progress ? hasCriticalFailures(state.progress) : false
1482
+ };
1483
+ }
729
1484
  export {
1485
+ useAnalyticsContext,
730
1486
  useInvitesAdmin,
731
1487
  useOrgAdmin,
1488
+ useOrgProvisioning,
732
1489
  useOrgSettings,
1490
+ useProductAnalytics,
733
1491
  useUsersAdmin
734
1492
  };
735
1493
  //# sourceMappingURL=index.js.map