kaafil-react-uikit 0.1.0-beta.1

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.
Files changed (79) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/LICENSE +21 -0
  3. package/README.md +187 -0
  4. package/dist/OfflineFallbackScreen-B5dfaJBN.d.ts +37 -0
  5. package/dist/OfflineFallbackScreen-Ctm7nBa-.d.cts +37 -0
  6. package/dist/SessionExpiredScreen-CytQNuak.d.cts +50 -0
  7. package/dist/SessionExpiredScreen-D8GHyZc3.d.ts +50 -0
  8. package/dist/admin/index.cjs +23779 -0
  9. package/dist/admin/index.cjs.map +1 -0
  10. package/dist/admin/index.d.cts +1157 -0
  11. package/dist/admin/index.d.ts +1157 -0
  12. package/dist/admin/index.js +23724 -0
  13. package/dist/admin/index.js.map +1 -0
  14. package/dist/chunk-6FPAGGFL.js +6028 -0
  15. package/dist/chunk-6FPAGGFL.js.map +1 -0
  16. package/dist/chunk-ACVU55PZ.cjs +294 -0
  17. package/dist/chunk-ACVU55PZ.cjs.map +1 -0
  18. package/dist/chunk-EM7JV3D7.cjs +6051 -0
  19. package/dist/chunk-EM7JV3D7.cjs.map +1 -0
  20. package/dist/chunk-IIPQ4JNC.js +287 -0
  21. package/dist/chunk-IIPQ4JNC.js.map +1 -0
  22. package/dist/chunk-LL243STJ.cjs +2195 -0
  23. package/dist/chunk-LL243STJ.cjs.map +1 -0
  24. package/dist/chunk-PJRZCOFF.cjs +958 -0
  25. package/dist/chunk-PJRZCOFF.cjs.map +1 -0
  26. package/dist/chunk-PTQ2CJKE.cjs +40 -0
  27. package/dist/chunk-PTQ2CJKE.cjs.map +1 -0
  28. package/dist/chunk-PZKXLQSU.js +10 -0
  29. package/dist/chunk-PZKXLQSU.js.map +1 -0
  30. package/dist/chunk-QHUDOVKW.cjs +111 -0
  31. package/dist/chunk-QHUDOVKW.cjs.map +1 -0
  32. package/dist/chunk-TOBZFADB.cjs +12 -0
  33. package/dist/chunk-TOBZFADB.cjs.map +1 -0
  34. package/dist/chunk-UUGMNP27.js +936 -0
  35. package/dist/chunk-UUGMNP27.js.map +1 -0
  36. package/dist/chunk-UYJ6LIWP.js +2154 -0
  37. package/dist/chunk-UYJ6LIWP.js.map +1 -0
  38. package/dist/chunk-VHTSTUCJ.cjs +346 -0
  39. package/dist/chunk-VHTSTUCJ.cjs.map +1 -0
  40. package/dist/chunk-WUAFL77X.js +340 -0
  41. package/dist/chunk-WUAFL77X.js.map +1 -0
  42. package/dist/chunk-XI7MK4Y7.js +38 -0
  43. package/dist/chunk-XI7MK4Y7.js.map +1 -0
  44. package/dist/chunk-YDGR7JSY.js +107 -0
  45. package/dist/chunk-YDGR7JSY.js.map +1 -0
  46. package/dist/core/index.cjs +1254 -0
  47. package/dist/core/index.cjs.map +1 -0
  48. package/dist/core/index.d.cts +1267 -0
  49. package/dist/core/index.d.ts +1267 -0
  50. package/dist/core/index.js +995 -0
  51. package/dist/core/index.js.map +1 -0
  52. package/dist/index.css +1 -0
  53. package/dist/manager/index.cjs +13562 -0
  54. package/dist/manager/index.cjs.map +1 -0
  55. package/dist/manager/index.d.cts +1054 -0
  56. package/dist/manager/index.d.ts +1054 -0
  57. package/dist/manager/index.js +13518 -0
  58. package/dist/manager/index.js.map +1 -0
  59. package/dist/testing/index.cjs +221 -0
  60. package/dist/testing/index.cjs.map +1 -0
  61. package/dist/testing/index.d.cts +269 -0
  62. package/dist/testing/index.d.ts +269 -0
  63. package/dist/testing/index.js +208 -0
  64. package/dist/testing/index.js.map +1 -0
  65. package/dist/tokenStyle-CToG5oOS.d.cts +3 -0
  66. package/dist/tokenStyle-CToG5oOS.d.ts +3 -0
  67. package/dist/traveller/index.cjs +1799 -0
  68. package/dist/traveller/index.cjs.map +1 -0
  69. package/dist/traveller/index.d.cts +58 -0
  70. package/dist/traveller/index.d.ts +58 -0
  71. package/dist/traveller/index.js +1789 -0
  72. package/dist/traveller/index.js.map +1 -0
  73. package/dist/useAgencyTrip-BUYSIaC2.d.cts +454 -0
  74. package/dist/useAgencyTrip-BzyJB1D9.d.ts +454 -0
  75. package/dist/useNotifications-BZW1Z_ur.d.cts +356 -0
  76. package/dist/useNotifications-D262i5BQ.d.ts +356 -0
  77. package/dist/useVendors-DXOuZWhZ.d.cts +784 -0
  78. package/dist/useVendors-DXOuZWhZ.d.ts +784 -0
  79. package/package.json +95 -0
@@ -0,0 +1,936 @@
1
+ import { createDomainHook, useSnapshotList, classifyError } from './chunk-UYJ6LIWP.js';
2
+ import { useServerTime } from './chunk-XI7MK4Y7.js';
3
+ import { useOfflineMutation, useKaafilClient, useCapabilityRows, deriveCapabilityTriple } from './chunk-6FPAGGFL.js';
4
+ import { useCallback, useState, useEffect, useRef, useMemo } from 'react';
5
+ import { SyncOpMethod } from 'kaafil-js/client';
6
+
7
+ function useAgencyAdminMe() {
8
+ const client = useKaafilClient();
9
+ const [result, setResult] = useState({ status: "loading" });
10
+ useEffect(() => {
11
+ let cancelled = false;
12
+ setResult({ status: "loading" });
13
+ client.agencyAdminMe.read().then((response) => {
14
+ if (cancelled) {
15
+ return;
16
+ }
17
+ setResult({ status: "ready", agencyAdmin: response.agencyAdmin });
18
+ }).catch(() => {
19
+ if (!cancelled) {
20
+ setResult({ status: "error" });
21
+ }
22
+ });
23
+ return () => {
24
+ cancelled = true;
25
+ };
26
+ }, [client]);
27
+ return result;
28
+ }
29
+ function useAgencyChecklistTemplates() {
30
+ const client = useKaafilClient();
31
+ const [templates, setTemplates] = useState([]);
32
+ const [loaded, setLoaded] = useState(false);
33
+ const [lastFetchFailed, setLastFetchFailed] = useState(false);
34
+ const refresh = useCallback(async () => {
35
+ try {
36
+ const response = await client.checklists.agencyTemplates.list({});
37
+ setTemplates(response.templates);
38
+ setLoaded(true);
39
+ setLastFetchFailed(false);
40
+ } catch {
41
+ setLastFetchFailed(true);
42
+ }
43
+ }, [client]);
44
+ useEffect(() => {
45
+ void refresh();
46
+ }, [refresh]);
47
+ const createTemplate = useCallback(
48
+ async (input) => {
49
+ const response = await client.checklists.agencyTemplates.create(input);
50
+ void refresh();
51
+ return response;
52
+ },
53
+ [client, refresh]
54
+ );
55
+ const patchTemplate = useCallback(
56
+ async (input) => {
57
+ const response = await client.checklists.agencyTemplates.patch(input);
58
+ void refresh();
59
+ return response;
60
+ },
61
+ [client, refresh]
62
+ );
63
+ const removeTemplate = useCallback(
64
+ async (input) => {
65
+ await client.checklists.agencyTemplates.remove(input);
66
+ void refresh();
67
+ },
68
+ [client, refresh]
69
+ );
70
+ const publishTemplate = useCallback(
71
+ async (input) => {
72
+ const response = await client.checklists.agencyTemplates.publish(input);
73
+ void refresh();
74
+ return response;
75
+ },
76
+ [client, refresh]
77
+ );
78
+ return {
79
+ templates,
80
+ loaded,
81
+ lastFetchFailed,
82
+ refresh,
83
+ createTemplate,
84
+ patchTemplate,
85
+ removeTemplate,
86
+ publishTemplate
87
+ };
88
+ }
89
+ function useAgencyForms() {
90
+ const client = useKaafilClient();
91
+ const [forms, setForms] = useState([]);
92
+ const [loaded, setLoaded] = useState(false);
93
+ const [lastFetchFailed, setLastFetchFailed] = useState(false);
94
+ const refresh = useCallback(async () => {
95
+ try {
96
+ const response = await client.forms.list({});
97
+ setForms(response.items);
98
+ setLoaded(true);
99
+ setLastFetchFailed(false);
100
+ } catch {
101
+ setLastFetchFailed(true);
102
+ }
103
+ }, [client]);
104
+ useEffect(() => {
105
+ void refresh();
106
+ }, [refresh]);
107
+ const createForm = useCallback(
108
+ async (input) => {
109
+ const response = await client.forms.create(input);
110
+ void refresh();
111
+ return response;
112
+ },
113
+ [client, refresh]
114
+ );
115
+ const getForm = useCallback(
116
+ async (formId) => client.forms.get({ formId }),
117
+ [client]
118
+ );
119
+ const patchForm = useCallback(
120
+ async (input) => {
121
+ const response = await client.forms.patch(input);
122
+ void refresh();
123
+ return response;
124
+ },
125
+ [client, refresh]
126
+ );
127
+ const deleteForm = useCallback(
128
+ async (input) => {
129
+ await client.forms.delete(input);
130
+ void refresh();
131
+ },
132
+ [client, refresh]
133
+ );
134
+ const archiveForm = useCallback(
135
+ async (formId) => {
136
+ const response = await client.forms.archive({ formId });
137
+ void refresh();
138
+ return response;
139
+ },
140
+ [client, refresh]
141
+ );
142
+ const unarchiveForm = useCallback(
143
+ async (formId) => {
144
+ const response = await client.forms.unarchive({ formId });
145
+ void refresh();
146
+ return response;
147
+ },
148
+ [client, refresh]
149
+ );
150
+ const publishForm = useCallback(
151
+ async (formId) => {
152
+ const response = await client.forms.publish({ formId });
153
+ void refresh();
154
+ return response;
155
+ },
156
+ [client, refresh]
157
+ );
158
+ const closeForm = useCallback(
159
+ async (formId) => {
160
+ const response = await client.forms.close({ formId });
161
+ void refresh();
162
+ return response;
163
+ },
164
+ [client, refresh]
165
+ );
166
+ const reopenForm = useCallback(
167
+ async (formId) => {
168
+ const response = await client.forms.reopen({ formId });
169
+ void refresh();
170
+ return response;
171
+ },
172
+ [client, refresh]
173
+ );
174
+ const cloneForm = useCallback(
175
+ async (input) => {
176
+ const response = await client.forms.clone(input);
177
+ void refresh();
178
+ return response;
179
+ },
180
+ [client, refresh]
181
+ );
182
+ const reorderForm = useCallback(
183
+ async (input) => {
184
+ await client.forms.reorder(input);
185
+ },
186
+ [client]
187
+ );
188
+ const createSection = useCallback(
189
+ async (input) => client.forms.sections.create(input),
190
+ [client]
191
+ );
192
+ const patchSection = useCallback(
193
+ async (input) => client.forms.sections.patch(input),
194
+ [client]
195
+ );
196
+ const deleteSection = useCallback(
197
+ async (input) => {
198
+ await client.forms.sections.delete(input);
199
+ },
200
+ [client]
201
+ );
202
+ const createField = useCallback(
203
+ async (input) => client.forms.fields.create(input),
204
+ [client]
205
+ );
206
+ const patchField = useCallback(
207
+ async (input) => client.forms.fields.patch(input),
208
+ [client]
209
+ );
210
+ const deleteField = useCallback(
211
+ async (input) => {
212
+ await client.forms.fields.delete(input);
213
+ },
214
+ [client]
215
+ );
216
+ const listBindings = useCallback(async () => {
217
+ const response = await client.forms.bindings.list();
218
+ return response.items;
219
+ }, [client]);
220
+ return {
221
+ forms,
222
+ loaded,
223
+ lastFetchFailed,
224
+ refresh,
225
+ createForm,
226
+ getForm,
227
+ patchForm,
228
+ deleteForm,
229
+ archiveForm,
230
+ unarchiveForm,
231
+ publishForm,
232
+ closeForm,
233
+ reopenForm,
234
+ cloneForm,
235
+ reorderForm,
236
+ createSection,
237
+ patchSection,
238
+ deleteSection,
239
+ createField,
240
+ patchField,
241
+ deleteField,
242
+ listBindings
243
+ };
244
+ }
245
+ function useAgencyJourneyTriggers() {
246
+ const client = useKaafilClient();
247
+ const [triggers, setTriggers] = useState([]);
248
+ const [loaded, setLoaded] = useState(false);
249
+ const [lastFetchFailed, setLastFetchFailed] = useState(false);
250
+ const refresh = useCallback(async () => {
251
+ try {
252
+ const response = await client.journey.triggers.list({});
253
+ setTriggers(response);
254
+ setLoaded(true);
255
+ setLastFetchFailed(false);
256
+ } catch {
257
+ setLastFetchFailed(true);
258
+ }
259
+ }, [client]);
260
+ useEffect(() => {
261
+ void refresh();
262
+ }, [refresh]);
263
+ const patchTrigger = useCallback(
264
+ async (input) => {
265
+ const response = await client.journey.triggers.patch(input);
266
+ void refresh();
267
+ return response;
268
+ },
269
+ [client, refresh]
270
+ );
271
+ return { triggers, loaded, lastFetchFailed, refresh, patchTrigger };
272
+ }
273
+ function useAgencyManagerProfile(managerRef) {
274
+ const client = useKaafilClient();
275
+ const [read, setRead] = useState(void 0);
276
+ const [readFailed, setReadFailed] = useState(false);
277
+ const refresh = useCallback(async () => {
278
+ try {
279
+ const response = await client.agencies.managers.get({ managerRef });
280
+ setRead(response);
281
+ setReadFailed(false);
282
+ } catch {
283
+ setReadFailed(true);
284
+ }
285
+ }, [client, managerRef]);
286
+ useEffect(() => {
287
+ void refresh();
288
+ }, [refresh]);
289
+ return { read, readFailed, refresh };
290
+ }
291
+ function useAgencySettings() {
292
+ const client = useKaafilClient();
293
+ const [document, setDocument] = useState(void 0);
294
+ const [loaded, setLoaded] = useState(false);
295
+ const [lastFetchFailed, setLastFetchFailed] = useState(false);
296
+ const refresh = useCallback(async () => {
297
+ try {
298
+ const response = await client.agencies.settings.get({});
299
+ setDocument(response);
300
+ setLoaded(true);
301
+ setLastFetchFailed(false);
302
+ } catch {
303
+ setLastFetchFailed(true);
304
+ }
305
+ }, [client]);
306
+ useEffect(() => {
307
+ void refresh();
308
+ }, [refresh]);
309
+ const patchSettings = useCallback(
310
+ async (input) => {
311
+ const response = await client.agencies.settings.patch(input);
312
+ void refresh();
313
+ return response;
314
+ },
315
+ [client, refresh]
316
+ );
317
+ return { document, loaded, lastFetchFailed, refresh, patchSettings };
318
+ }
319
+ function useAgencyTrip(tripRef) {
320
+ const client = useKaafilClient();
321
+ const [read, setRead] = useState(void 0);
322
+ const [readFailed, setReadFailed] = useState(false);
323
+ const refresh = useCallback(async () => {
324
+ try {
325
+ const response = await client.agencies.trips.get({ tripRef });
326
+ setRead(response);
327
+ setReadFailed(false);
328
+ } catch {
329
+ setReadFailed(true);
330
+ }
331
+ }, [client, tripRef]);
332
+ useEffect(() => {
333
+ void refresh();
334
+ }, [refresh]);
335
+ return { read, readFailed, refresh };
336
+ }
337
+ var DEFAULT_PAGE_LIMIT = 20;
338
+ var GROUPED_PAGE_LIMIT = 200;
339
+ function useAgencyTripManifest(tripRef) {
340
+ const client = useKaafilClient();
341
+ const [facets, setFacets] = useState(void 0);
342
+ const mountedRef = useRef(true);
343
+ useEffect(() => {
344
+ mountedRef.current = true;
345
+ return () => {
346
+ mountedRef.current = false;
347
+ };
348
+ }, []);
349
+ const makeManifestFetch = useCallback(
350
+ (filters, pageSize) => async (cursor) => {
351
+ const page = await client.agencies.trips.manifest.listPage({
352
+ tripRef,
353
+ ...filters,
354
+ cursor,
355
+ limit: pageSize ?? DEFAULT_PAGE_LIMIT
356
+ });
357
+ if (mountedRef.current) {
358
+ setFacets(page.facets);
359
+ }
360
+ return {
361
+ rows: page,
362
+ nextCursor: page.meta.page.hasNext ? page.meta.page.cursor ?? void 0 : void 0
363
+ };
364
+ },
365
+ [client, tripRef]
366
+ );
367
+ return { makeManifestFetch, facets, groupedPageSize: GROUPED_PAGE_LIMIT };
368
+ }
369
+ var DEFAULT_PAGE_LIMIT2 = 20;
370
+ function useAgencyTrips() {
371
+ const client = useKaafilClient();
372
+ const [segmentCounts, setSegmentCounts] = useState(
373
+ void 0
374
+ );
375
+ const mountedRef = useRef(true);
376
+ useEffect(() => {
377
+ mountedRef.current = true;
378
+ return () => {
379
+ mountedRef.current = false;
380
+ };
381
+ }, []);
382
+ const makeTripsFetch = useCallback(
383
+ (filters) => async (cursor) => {
384
+ const page = await client.agencies.trips.listPage({
385
+ ...filters,
386
+ cursor,
387
+ limit: DEFAULT_PAGE_LIMIT2
388
+ });
389
+ if (mountedRef.current) {
390
+ setSegmentCounts(page.facets.segments);
391
+ }
392
+ return {
393
+ rows: page,
394
+ nextCursor: page.meta.page.hasNext ? page.meta.page.cursor ?? void 0 : void 0
395
+ };
396
+ },
397
+ [client]
398
+ );
399
+ return { makeTripsFetch, segmentCounts };
400
+ }
401
+ var useBookingsInternal = createDomainHook("bookings", (tripRef) => {
402
+ const {
403
+ rows: bookings,
404
+ syncedAt,
405
+ refreshLive
406
+ } = useSnapshotList(tripRef, "bookings", {
407
+ live: async (liveClient, ref) => {
408
+ const response = await liveClient.bookings.list({ tripRef: ref });
409
+ return { rows: [...response], syncedAt: response.meta.serverTime };
410
+ }
411
+ });
412
+ const vouchersMutation = useOfflineMutation({
413
+ tripRef,
414
+ enqueue: (engine, input) => engine.enqueue({
415
+ tripRef,
416
+ method: SyncOpMethod.Patch,
417
+ path: `/api/v1/trips/${tripRef}/bookings/${input.bookingRef}/vouchers`,
418
+ // Hardcoded literal, not imported: `OperationId` is not exported from
419
+ // `kaafil-js/client`'s public surface (the reasoning `useRooming.ts`
420
+ // documents). Verified against `kaafil-js/src/generated/security.ts`:
421
+ // `OperationId.ReplaceBookingVouchers === 'replaceBookingVouchers'`.
422
+ operationId: "replaceBookingVouchers",
423
+ body: { voucherFileKeys: [...input.voucherFileKeys] }
424
+ }),
425
+ // THE DESK LANE, and the only lane that matters in practice: filing a
426
+ // voucher is desk work and a desk console mounts no `OfflineShell`. The
427
+ // outbox lane above exists because this hook cannot know which shell it
428
+ // is under, not because a manager can call this route — they cannot.
429
+ direct: (liveClient, input) => liveClient.bookings.vouchers.replace({
430
+ tripRef,
431
+ bookingRef: input.bookingRef,
432
+ voucherFileKeys: [...input.voucherFileKeys]
433
+ })
434
+ });
435
+ const mutate = vouchersMutation.mutate;
436
+ const replaceVouchers = useCallback(
437
+ async (input) => {
438
+ await mutate(input);
439
+ await refreshLive();
440
+ },
441
+ [mutate, refreshLive]
442
+ );
443
+ return { bookings, syncedAt, refreshLive, replaceVouchers };
444
+ });
445
+ function useBookings(tripRef) {
446
+ return useBookingsInternal(tripRef);
447
+ }
448
+ function useCapabilityStatuses(tripRef) {
449
+ const { rows, loaded } = useCapabilityRows(tripRef);
450
+ const statuses = useMemo(() => {
451
+ const map = /* @__PURE__ */ new Map();
452
+ for (const row of rows) map.set(row.capability, deriveCapabilityTriple(row).status);
453
+ return map;
454
+ }, [rows]);
455
+ return { statuses, loaded };
456
+ }
457
+ var DEFAULT_PAGE_LIMIT3 = 20;
458
+ var DirectoriesWriteError = class _DirectoriesWriteError extends Error {
459
+ classification;
460
+ constructor(classification) {
461
+ super(
462
+ classification.cause instanceof Error ? classification.cause.message : "The directory write failed."
463
+ );
464
+ this.name = "DirectoriesWriteError";
465
+ Object.setPrototypeOf(this, _DirectoriesWriteError.prototype);
466
+ this.classification = classification;
467
+ }
468
+ };
469
+ function useDirectories(agencyRef) {
470
+ const client = useKaafilClient();
471
+ const serverTime = useServerTime();
472
+ const makeManagersFetch = useCallback(
473
+ (filters) => async (cursor) => {
474
+ const page = await client.agencies.managers.listPage({
475
+ ...filters,
476
+ cursor,
477
+ limit: DEFAULT_PAGE_LIMIT3
478
+ });
479
+ return {
480
+ rows: page,
481
+ nextCursor: page.meta.page.hasNext ? page.meta.page.cursor ?? void 0 : void 0
482
+ };
483
+ },
484
+ [client]
485
+ );
486
+ const makeTravellersFetch = useCallback(
487
+ (filters) => async (cursor) => {
488
+ const page = await client.travellers.listForAgencyPage({
489
+ ...filters,
490
+ cursor,
491
+ limit: DEFAULT_PAGE_LIMIT3
492
+ });
493
+ return {
494
+ rows: page,
495
+ nextCursor: page.meta.page.hasNext ? page.meta.page.cursor ?? void 0 : void 0
496
+ };
497
+ },
498
+ [client]
499
+ );
500
+ const listTripManifest = useCallback(
501
+ async (tripRef) => {
502
+ const response = await client.travellers.listForTrip({ tripRef });
503
+ return response;
504
+ },
505
+ [client]
506
+ );
507
+ const promoteManager = useCallback(
508
+ async (input) => {
509
+ try {
510
+ return await client.trips.managers.patch({
511
+ tripRef: input.tripRef,
512
+ managerRef: input.managerRef,
513
+ version: input.version,
514
+ role: input.role,
515
+ isLead: input.isLead
516
+ });
517
+ } catch (error) {
518
+ throw new DirectoriesWriteError(classifyError(error));
519
+ }
520
+ },
521
+ [client]
522
+ );
523
+ const assignManager = useCallback(
524
+ async (input) => {
525
+ try {
526
+ await client.trips.managers.assign({
527
+ tripRef: input.tripRef,
528
+ managerRef: input.managerRef,
529
+ ...input.role === void 0 ? {} : { role: input.role },
530
+ ...input.isLead === void 0 ? {} : { isLead: input.isLead }
531
+ });
532
+ } catch (error) {
533
+ throw new DirectoriesWriteError(classifyError(error));
534
+ }
535
+ },
536
+ [client]
537
+ );
538
+ const unassignManager = useCallback(
539
+ async (input) => {
540
+ try {
541
+ await client.trips.managers.unassign({
542
+ tripRef: input.tripRef,
543
+ managerRef: input.managerRef
544
+ });
545
+ } catch (error) {
546
+ throw new DirectoriesWriteError(classifyError(error));
547
+ }
548
+ },
549
+ [client]
550
+ );
551
+ const addTraveller = useCallback(
552
+ async (input) => {
553
+ try {
554
+ const response = await client.trips.travellers.pushManifest({
555
+ tripRef: input.tripRef,
556
+ travellers: [
557
+ {
558
+ externalTravellerId: input.externalTravellerId,
559
+ fullName: input.fullName,
560
+ phone: input.phone,
561
+ sourceUpdatedAt: serverTime.now()
562
+ }
563
+ ]
564
+ });
565
+ const item = response.items.find(
566
+ (entry) => entry.externalTravellerId === input.externalTravellerId
567
+ );
568
+ if (item === void 0 || item.verdict !== "applied") {
569
+ throw new DirectoriesWriteError({
570
+ path: "surface-to-user",
571
+ code: item?.verdict === "rejected" ? "BUSINESS_RULE_VIOLATION" : void 0,
572
+ status: void 0,
573
+ unsatisfiableScheme: false,
574
+ cause: void 0
575
+ });
576
+ }
577
+ return item.externalTravellerId;
578
+ } catch (error) {
579
+ if (error instanceof DirectoriesWriteError) {
580
+ throw error;
581
+ }
582
+ throw new DirectoriesWriteError(classifyError(error));
583
+ }
584
+ },
585
+ [client, serverTime]
586
+ );
587
+ const createAgencyTraveller = useCallback(
588
+ async (input) => {
589
+ try {
590
+ return await client.travellers.create({
591
+ fullName: input.fullName,
592
+ phone: input.phone,
593
+ email: input.email,
594
+ locale: input.locale,
595
+ externalTravellerId: input.externalTravellerId
596
+ });
597
+ } catch (error) {
598
+ throw new DirectoriesWriteError(classifyError(error));
599
+ }
600
+ },
601
+ [client]
602
+ );
603
+ const removeFromManifest = useCallback(
604
+ async (input) => {
605
+ try {
606
+ await client.trips.travellers.remove({
607
+ tripRef: input.tripRef,
608
+ travellerRef: input.travellerRef
609
+ });
610
+ } catch (error) {
611
+ throw new DirectoriesWriteError(classifyError(error));
612
+ }
613
+ },
614
+ [client]
615
+ );
616
+ const createParty = useCallback(
617
+ async (input) => {
618
+ try {
619
+ return await client.trips.parties.add({
620
+ tripRef: input.tripRef,
621
+ kind: input.kind,
622
+ ...input.label !== void 0 ? { label: input.label } : {},
623
+ travellerRefs: [...input.travellerRefs]
624
+ });
625
+ } catch (error) {
626
+ throw new DirectoriesWriteError(classifyError(error));
627
+ }
628
+ },
629
+ [client]
630
+ );
631
+ const patchParty = useCallback(
632
+ async (input) => {
633
+ try {
634
+ return await client.trips.parties.patch({
635
+ tripRef: input.tripRef,
636
+ partyId: input.partyId,
637
+ version: input.version,
638
+ ...input.kind !== void 0 ? { kind: input.kind } : {},
639
+ ...input.label !== void 0 ? { label: input.label } : {},
640
+ ...input.travellerRefs !== void 0 ? { travellerRefs: [...input.travellerRefs] } : {}
641
+ });
642
+ } catch (error) {
643
+ throw new DirectoriesWriteError(classifyError(error));
644
+ }
645
+ },
646
+ [client]
647
+ );
648
+ const deleteParty = useCallback(
649
+ async (input) => {
650
+ try {
651
+ await client.trips.parties.remove({ tripRef: input.tripRef, partyId: input.partyId });
652
+ } catch (error) {
653
+ throw new DirectoriesWriteError(classifyError(error));
654
+ }
655
+ },
656
+ [client]
657
+ );
658
+ const addTravellerNote = useCallback(
659
+ async (input) => {
660
+ try {
661
+ await client.travellers.addNote({
662
+ tripRef: input.tripRef,
663
+ travellerRef: input.travellerRef,
664
+ body: input.body
665
+ });
666
+ } catch (error) {
667
+ throw new DirectoriesWriteError(classifyError(error));
668
+ }
669
+ },
670
+ [client]
671
+ );
672
+ return {
673
+ makeManagersFetch,
674
+ makeTravellersFetch,
675
+ listTripManifest,
676
+ promoteManager,
677
+ assignManager,
678
+ unassignManager,
679
+ addTraveller,
680
+ createAgencyTraveller,
681
+ removeFromManifest,
682
+ createParty,
683
+ patchParty,
684
+ deleteParty,
685
+ addTravellerNote
686
+ };
687
+ }
688
+ function usePaginatedList(fetch, options) {
689
+ const [rows, setRows] = useState([]);
690
+ const [hasNext, setHasNext] = useState(false);
691
+ const [pageIndex, setPageIndex] = useState(0);
692
+ const fetchRef = useRef(fetch);
693
+ fetchRef.current = fetch;
694
+ const cursorsRef = useRef([void 0]);
695
+ const loadPage = useCallback(async (index) => {
696
+ const cursor = cursorsRef.current[index];
697
+ const result = await fetchRef.current(cursor);
698
+ cursorsRef.current = cursorsRef.current.slice(0, index + 1);
699
+ if (result.nextCursor !== void 0) {
700
+ cursorsRef.current[index + 1] = result.nextCursor;
701
+ }
702
+ setRows(result.rows);
703
+ setHasNext(result.nextCursor !== void 0);
704
+ setPageIndex(index);
705
+ }, []);
706
+ useEffect(() => {
707
+ void loadPage(0);
708
+ }, [loadPage]);
709
+ const loadNext = useCallback(async () => {
710
+ if (!hasNext) {
711
+ return;
712
+ }
713
+ await loadPage(pageIndex + 1);
714
+ }, [hasNext, pageIndex, loadPage]);
715
+ const loadPrev = useCallback(async () => {
716
+ if (pageIndex === 0) {
717
+ return;
718
+ }
719
+ await loadPage(pageIndex - 1);
720
+ }, [pageIndex, loadPage]);
721
+ return { rows, hasNext, hasPrev: pageIndex > 0, loadNext, loadPrev };
722
+ }
723
+ var SHARE_SECTION_KEYS = [
724
+ "itinerary",
725
+ "rooming",
726
+ "seating",
727
+ "checklists",
728
+ "pickup",
729
+ "accommodation",
730
+ "transport",
731
+ "activities",
732
+ "documents",
733
+ "money",
734
+ "managerContact",
735
+ "agencyContact",
736
+ "household",
737
+ "forms"
738
+ ];
739
+ function familySafeSections(isFamilyLink) {
740
+ return isFamilyLink ? SHARE_SECTION_KEYS.filter((key) => key !== "money") : SHARE_SECTION_KEYS;
741
+ }
742
+ var ShareLinkWriteError = class extends Error {
743
+ classification;
744
+ constructor(classification) {
745
+ super("Share-link write failed");
746
+ this.name = "ShareLinkWriteError";
747
+ this.classification = classification;
748
+ }
749
+ };
750
+ function useShareLinks(tripRef, travellerRef) {
751
+ const client = useKaafilClient();
752
+ const [links, setLinks] = useState(void 0);
753
+ const [readFailed, setReadFailed] = useState(false);
754
+ const refresh = useCallback(async () => {
755
+ try {
756
+ const response = await client.shareTokens.list({
757
+ tripRef,
758
+ ...travellerRef !== null ? { travellerRef } : {}
759
+ });
760
+ setLinks(response);
761
+ setReadFailed(false);
762
+ } catch (error) {
763
+ setReadFailed(true);
764
+ }
765
+ }, [client, tripRef, travellerRef]);
766
+ useEffect(() => {
767
+ void refresh();
768
+ }, [refresh]);
769
+ const mint = useCallback(
770
+ async (input) => {
771
+ try {
772
+ const minted = await client.shareTokens.create({
773
+ tripRef,
774
+ ...input.travellerRef !== void 0 ? { travellerRef: input.travellerRef } : {},
775
+ ...input.sections !== void 0 ? { config: { sections: input.sections } } : {},
776
+ ...input.ttlDays !== void 0 ? { ttlDays: input.ttlDays } : {},
777
+ ...input.expiresAt !== void 0 ? { expiresAt: input.expiresAt } : {}
778
+ });
779
+ await refresh();
780
+ return minted;
781
+ } catch (error) {
782
+ throw new ShareLinkWriteError(classifyError(error));
783
+ }
784
+ },
785
+ [client, tripRef, refresh]
786
+ );
787
+ const revoke = useCallback(
788
+ async (id) => {
789
+ try {
790
+ await client.shareTokens.revoke({ id });
791
+ await refresh();
792
+ } catch (error) {
793
+ throw new ShareLinkWriteError(classifyError(error));
794
+ }
795
+ },
796
+ [client, refresh]
797
+ );
798
+ const patch = useCallback(
799
+ async (input) => {
800
+ try {
801
+ await client.shareTokens.patch({
802
+ id: input.id,
803
+ version: input.version,
804
+ ...input.sections !== void 0 ? { config: { sections: input.sections } } : {},
805
+ ...input.expiresAt !== void 0 ? { expiresAt: input.expiresAt } : {}
806
+ });
807
+ await refresh();
808
+ } catch (error) {
809
+ throw new ShareLinkWriteError(classifyError(error));
810
+ }
811
+ },
812
+ [client, refresh]
813
+ );
814
+ const regenerate = useCallback(
815
+ async (id) => {
816
+ try {
817
+ const minted = await client.shareTokens.regenerate({ id });
818
+ await refresh();
819
+ return minted;
820
+ } catch (error) {
821
+ throw new ShareLinkWriteError(classifyError(error));
822
+ }
823
+ },
824
+ [client, refresh]
825
+ );
826
+ return { links, readFailed, refresh, mint, revoke, patch, regenerate };
827
+ }
828
+ function useTravellerFormResponses(tripRef, travellerRef) {
829
+ const client = useKaafilClient();
830
+ const [responses, setResponses] = useState(
831
+ void 0
832
+ );
833
+ const [readFailed, setReadFailed] = useState(false);
834
+ const refresh = useCallback(async () => {
835
+ if (travellerRef === null) {
836
+ setResponses(void 0);
837
+ setReadFailed(false);
838
+ return;
839
+ }
840
+ try {
841
+ const response = await client.forms.trip.travellerResponses.list({ tripRef, travellerRef });
842
+ setResponses(response.items);
843
+ setReadFailed(false);
844
+ } catch {
845
+ setReadFailed(true);
846
+ }
847
+ }, [client, tripRef, travellerRef]);
848
+ useEffect(() => {
849
+ void refresh();
850
+ }, [refresh]);
851
+ return { responses, readFailed, refresh };
852
+ }
853
+
854
+ // src/core/routing/deepLinks.ts
855
+ var CLOSEOUT_ACTION_TAB = {
856
+ open_collections: "payments",
857
+ open_expenses: "expenses",
858
+ open_float: "float",
859
+ open_checklist: "checklist",
860
+ open_mandatory_checklist: "checklist",
861
+ open_forms: "forms",
862
+ open_rooming: "rooming",
863
+ open_seating: "vehicles",
864
+ open_pickups: "pickups",
865
+ open_itinerary: "itinerary",
866
+ open_past_itinerary: "itinerary",
867
+ open_vendors: "vendors"
868
+ };
869
+ var BLOCKER_PRESET_FILTER = {
870
+ balance_due: "outstanding",
871
+ missing_receipt: "missing-receipt",
872
+ open_mandatory_checklist: "open-mandatory",
873
+ required_form_gap: "outstanding-respondents",
874
+ unassigned_rooming: "unassigned",
875
+ // Mirrors `unassigned_rooming` — the spec gives seating the identical
876
+ // arrival contract, pointed at the seating pool instead of the bed pool.
877
+ unseated_travellers: "unassigned"
878
+ // DELIBERATELY ABSENT, each for its own reason:
879
+ // `float_not_returned`, `pickup_no_show`, `open_past_itinerary` — these
880
+ // arrive by `highlightId` on a single row, not by narrowing a list.
881
+ // `reimbursements_pending` — see this map's header; filtering the
882
+ // expense ledger to missing receipts would be actively wrong here.
883
+ // `unrated_vendors` — see `resolveBlockerDeepLink`.
884
+ };
885
+ function resolveBlockerDeepLink(input) {
886
+ const tab = CLOSEOUT_ACTION_TAB[input.actionKey];
887
+ if (tab === void 0) return null;
888
+ const presetFilter = input.key === void 0 ? void 0 : BLOCKER_PRESET_FILTER[input.key];
889
+ return {
890
+ tab,
891
+ ...presetFilter !== void 0 ? { presetFilter } : {},
892
+ ...input.highlightId !== void 0 ? { highlightId: input.highlightId } : {}
893
+ };
894
+ }
895
+ var PARAM_TAB = "kfTab";
896
+ var PARAM_HIGHLIGHT = "kfHighlight";
897
+ var PARAM_FILTER = "kfFilter";
898
+ function toSearchParams(link) {
899
+ const params = new URLSearchParams();
900
+ if (link.tab !== void 0) params.set(PARAM_TAB, link.tab);
901
+ if (link.highlightId !== void 0) params.set(PARAM_HIGHLIGHT, link.highlightId);
902
+ if (link.presetFilter !== void 0) params.set(PARAM_FILTER, link.presetFilter);
903
+ return params;
904
+ }
905
+ function fromSearchParams(params) {
906
+ const rawTab = params.get(PARAM_TAB);
907
+ const highlightId = params.get(PARAM_HIGHLIGHT);
908
+ const presetFilter = params.get(PARAM_FILTER);
909
+ if (rawTab === null && highlightId === null && presetFilter === null) return null;
910
+ const initialTab = isTripTabKey(rawTab) ? rawTab : void 0;
911
+ return {
912
+ ...initialTab !== void 0 ? { initialTab } : {},
913
+ ...highlightId !== null ? { highlightId } : {},
914
+ ...presetFilter !== null ? { presetFilter } : {}
915
+ };
916
+ }
917
+ function isTripTabKey(value) {
918
+ if (value === null || value === void 0) return false;
919
+ return Object.hasOwn(TRIP_TAB_KEY_SET, value);
920
+ }
921
+ var TRIP_TAB_KEY_SET = {
922
+ itinerary: true,
923
+ pickups: true,
924
+ rooming: true,
925
+ vehicles: true,
926
+ vendors: true,
927
+ payments: true,
928
+ expenses: true,
929
+ float: true,
930
+ checklist: true,
931
+ forms: true
932
+ };
933
+
934
+ export { CLOSEOUT_ACTION_TAB, familySafeSections, fromSearchParams, isTripTabKey, resolveBlockerDeepLink, toSearchParams, useAgencyAdminMe, useAgencyChecklistTemplates, useAgencyForms, useAgencyJourneyTriggers, useAgencyManagerProfile, useAgencySettings, useAgencyTrip, useAgencyTripManifest, useAgencyTrips, useBookings, useCapabilityStatuses, useDirectories, usePaginatedList, useShareLinks, useTravellerFormResponses };
935
+ //# sourceMappingURL=chunk-UUGMNP27.js.map
936
+ //# sourceMappingURL=chunk-UUGMNP27.js.map