@burdenoff/microfe-movethewheels 2026.1031.6 → 2026.1101.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.
@@ -0,0 +1,616 @@
1
+ import { Activity as e } from "../node_modules/lucide-react/dist/esm/icons/activity.js";
2
+ import { Check as t } from "../node_modules/lucide-react/dist/esm/icons/check.js";
3
+ import { ChevronDown as n } from "../node_modules/lucide-react/dist/esm/icons/chevron-down.js";
4
+ import { ChevronUp as r } from "../node_modules/lucide-react/dist/esm/icons/chevron-up.js";
5
+ import { Copy as i } from "../node_modules/lucide-react/dist/esm/icons/copy.js";
6
+ import { KeyRound as a } from "../node_modules/lucide-react/dist/esm/icons/key-round.js";
7
+ import { Pause as o } from "../node_modules/lucide-react/dist/esm/icons/pause.js";
8
+ import { Play as s } from "../node_modules/lucide-react/dist/esm/icons/play.js";
9
+ import { Plug as c } from "../node_modules/lucide-react/dist/esm/icons/plug.js";
10
+ import { Plus as l } from "../node_modules/lucide-react/dist/esm/icons/plus.js";
11
+ import { RefreshCw as u } from "../node_modules/lucide-react/dist/esm/icons/refresh-cw.js";
12
+ import { ShieldCheck as d } from "../node_modules/lucide-react/dist/esm/icons/shield-check.js";
13
+ import { Trash2 as f } from "../node_modules/lucide-react/dist/esm/icons/trash-2.js";
14
+ import { useMoveTheWheels as p } from "../providers/MoveTheWheelsProvider.js";
15
+ import { formatDateTime as m } from "../utils/formatters.js";
16
+ import { Badge as h, Button as g, Card as _, CardContent as v, Input as y, Label as b, Select as ee, SelectContent as te, SelectItem as x, SelectTrigger as ne, SelectValue as re, Skeleton as S } from "../components/ui.js";
17
+ import { PageLayout as ie } from "../components/PageLayout.js";
18
+ import { MetricCard as C, MetricGrid as ae } from "../components/MetricCard.js";
19
+ import { FormError as w } from "../components/FormError.js";
20
+ import { Notice as oe, useNotice as se } from "../components/Notice.js";
21
+ import { INTEGRATION_STATUSES as ce, ROADMAP_PROVIDERS as T, SIGNATURE_HEADER as le, TRACKING_EVENT_TYPES as ue, curlExample as E, eventStatusTone as D, examplePayload as O, generateSigningSecret as k, humanize as A, integrationNameError as j, integrationStatusTone as M, signingSecretError as N, statusExplanation as P, webhookUrl as de } from "../utils/carrierIntegrations.js";
22
+ import { useCarrierIntegrationActions as F, useCarrierIntegrationCounts as fe, useCarrierIntegrationEvents as I, useCarrierIntegrations as pe } from "../hooks/useCarrierIntegrations.js";
23
+ import { useEffect as me, useRef as he, useState as L } from "react";
24
+ import { jsx as R, jsxs as z } from "react/jsx-runtime";
25
+ import { CTAOverflowMenu as ge, PagePurpose as _e, ResponsiveDialog as B, ResponsiveDialogContent as V, ResponsiveDialogDescription as H, ResponsiveDialogFooter as U, ResponsiveDialogHeader as W, ResponsiveDialogTitle as G } from "@burdenoff/fe-libs/ui";
26
+ //#region src/movethewheels/pages/IntegrationsPage.tsx
27
+ var K = 20, q = "ALL";
28
+ function J(e, t) {
29
+ return e instanceof Error && e.message ? e.message : t;
30
+ }
31
+ function Y({ label: e, value: n, multiline: r }) {
32
+ let [a, o] = L(!1), s = async () => {
33
+ try {
34
+ await navigator.clipboard.writeText(n), o(!0), window.setTimeout(() => o(!1), 2e3);
35
+ } catch {
36
+ o(!1);
37
+ }
38
+ };
39
+ return /* @__PURE__ */ z("div", {
40
+ className: "space-y-1",
41
+ children: [/* @__PURE__ */ z("div", {
42
+ className: "flex items-center justify-between gap-2",
43
+ children: [/* @__PURE__ */ R("span", {
44
+ className: "text-xs font-medium text-text-secondary",
45
+ children: e
46
+ }), /* @__PURE__ */ z(g, {
47
+ type: "button",
48
+ size: "sm",
49
+ variant: "ghost",
50
+ onClick: () => void s(),
51
+ "aria-label": `Copy ${e.toLowerCase()}`,
52
+ children: [R(a ? t : i, {
53
+ size: 14,
54
+ className: "mr-1"
55
+ }), a ? "Copied" : "Copy"]
56
+ })]
57
+ }), r ? /* @__PURE__ */ R("pre", {
58
+ className: "max-h-64 overflow-auto whitespace-pre-wrap break-all rounded-lg bg-bg-sunken px-3 py-2 font-mono text-xs text-text-primary",
59
+ children: n
60
+ }) : /* @__PURE__ */ R("code", {
61
+ className: "block break-all rounded-lg bg-bg-sunken px-3 py-2 font-mono text-xs text-text-primary",
62
+ children: n
63
+ })]
64
+ });
65
+ }
66
+ function ve({ secret: e, integrationName: t, onClose: n }) {
67
+ return /* @__PURE__ */ R(B, {
68
+ open: e !== null,
69
+ onOpenChange: (e) => !e && n(),
70
+ children: /* @__PURE__ */ z(V, { children: [
71
+ /* @__PURE__ */ z(W, { children: [/* @__PURE__ */ z(G, { children: ["Signing secret for ", t] }), /* @__PURE__ */ R(H, { children: "Copy it into the sending system now. MoveTheWheels stores it to verify deliveries but will not show it again; rotate it if it is lost." })] }),
72
+ e ? /* @__PURE__ */ R(Y, {
73
+ label: "Signing secret",
74
+ value: e
75
+ }, e) : null,
76
+ /* @__PURE__ */ R(U, { children: /* @__PURE__ */ R(g, {
77
+ onClick: n,
78
+ children: "I have saved it"
79
+ }) })
80
+ ] })
81
+ });
82
+ }
83
+ function ye({ open: e, onOpenChange: t, onCreated: n }) {
84
+ let r = F(), [i, a] = L(""), [o, s] = L(() => k()), [c, l] = L(null), [d, f] = L(!1), p = () => {
85
+ a(""), s(k()), l(null);
86
+ }, m = async (e) => {
87
+ e.preventDefault();
88
+ let a = j(i) ?? N(o);
89
+ if (a) {
90
+ l(a);
91
+ return;
92
+ }
93
+ f(!0), l(null);
94
+ try {
95
+ n(await r.create({
96
+ provider: "GENERIC_WEBHOOK",
97
+ name: i,
98
+ apiSecret: o
99
+ }), o), p(), t(!1);
100
+ } catch (e) {
101
+ l(J(e, "Could not create the integration."));
102
+ } finally {
103
+ f(!1);
104
+ }
105
+ };
106
+ return /* @__PURE__ */ R(B, {
107
+ open: e,
108
+ onOpenChange: (e) => {
109
+ e || p(), t(e);
110
+ },
111
+ children: /* @__PURE__ */ R(V, { children: /* @__PURE__ */ z("form", {
112
+ onSubmit: (e) => void m(e),
113
+ className: "space-y-4",
114
+ children: [
115
+ /* @__PURE__ */ z(W, { children: [/* @__PURE__ */ R(G, { children: "Connect a tracking feed" }), /* @__PURE__ */ R(H, { children: "A signed webhook for a carrier, ELD or GPS provider. Updates it sends become tracking events on the matching shipments." })] }),
116
+ /* @__PURE__ */ z("div", {
117
+ className: "space-y-1.5",
118
+ children: [/* @__PURE__ */ R(b, {
119
+ htmlFor: "integration-name",
120
+ children: "Name"
121
+ }), /* @__PURE__ */ R(y, {
122
+ id: "integration-name",
123
+ value: i,
124
+ maxLength: 120,
125
+ placeholder: "e.g. Fleet GPS feed",
126
+ onChange: (e) => a(e.target.value),
127
+ autoFocus: !0
128
+ })]
129
+ }),
130
+ /* @__PURE__ */ z("div", {
131
+ className: "space-y-1.5",
132
+ children: [/* @__PURE__ */ R(b, { children: "Type" }), /* @__PURE__ */ R("p", {
133
+ className: "rounded-lg border border-border-default px-3 py-2 text-sm",
134
+ children: "Signed webhook (any carrier, ELD or GPS system that can send HTTPS POSTs)"
135
+ })]
136
+ }),
137
+ /* @__PURE__ */ z("div", {
138
+ className: "space-y-1.5",
139
+ children: [
140
+ /* @__PURE__ */ z("div", {
141
+ className: "flex items-center justify-between",
142
+ children: [/* @__PURE__ */ R(b, { children: "Signing secret" }), /* @__PURE__ */ z(g, {
143
+ type: "button",
144
+ size: "sm",
145
+ variant: "ghost",
146
+ onClick: () => s(k()),
147
+ children: [/* @__PURE__ */ R(u, {
148
+ size: 14,
149
+ className: "mr-1"
150
+ }), "Generate another"]
151
+ })]
152
+ }),
153
+ /* @__PURE__ */ R("code", {
154
+ className: "block break-all rounded-lg bg-bg-sunken px-3 py-2 font-mono text-xs",
155
+ children: o
156
+ }),
157
+ /* @__PURE__ */ R("p", {
158
+ className: "text-xs text-text-secondary",
159
+ children: "Generated in your browser. You can copy it on the next step."
160
+ })
161
+ ]
162
+ }),
163
+ /* @__PURE__ */ R(w, { message: c }),
164
+ /* @__PURE__ */ z(U, { children: [/* @__PURE__ */ R(g, {
165
+ type: "button",
166
+ variant: "outline",
167
+ onClick: () => t(!1),
168
+ children: "Cancel"
169
+ }), /* @__PURE__ */ R(g, {
170
+ type: "submit",
171
+ disabled: d,
172
+ children: d ? "Connecting…" : "Connect"
173
+ })] })
174
+ ]
175
+ }) })
176
+ });
177
+ }
178
+ function X({ integrationId: e, refreshKey: t }) {
179
+ let { events: n, isLoading: r, error: i } = I(e, t);
180
+ return /* @__PURE__ */ z("div", {
181
+ className: "space-y-2",
182
+ children: [
183
+ /* @__PURE__ */ R("p", {
184
+ className: "text-sm font-medium",
185
+ children: "Recent deliveries"
186
+ }),
187
+ /* @__PURE__ */ R(w, { message: i?.message }),
188
+ r && n.length === 0 ? /* @__PURE__ */ R(S, { className: "h-12 w-full" }) : n.length === 0 ? /* @__PURE__ */ R("p", {
189
+ className: "text-sm text-text-secondary",
190
+ children: "No deliveries yet. Send a signed test update with the example below."
191
+ }) : /* @__PURE__ */ R("ul", {
192
+ className: "space-y-2",
193
+ children: n.map((e) => /* @__PURE__ */ z("li", {
194
+ className: "flex flex-wrap items-start justify-between gap-3 rounded-lg bg-bg-sunken px-3 py-2",
195
+ children: [/* @__PURE__ */ z("div", {
196
+ className: "min-w-0",
197
+ children: [
198
+ /* @__PURE__ */ z("p", {
199
+ className: "text-sm font-medium",
200
+ children: [e.eventType ? A(e.eventType) : "Delivery", e.externalEventId ? /* @__PURE__ */ R("span", {
201
+ className: "ml-2 font-mono text-xs text-text-tertiary",
202
+ children: e.externalEventId
203
+ }) : null]
204
+ }),
205
+ /* @__PURE__ */ R("p", {
206
+ className: "text-xs text-text-secondary",
207
+ children: m(e.receivedAt)
208
+ }),
209
+ e.errorMessage ? /* @__PURE__ */ R("p", {
210
+ className: "mt-1 break-words text-xs text-status-error-text",
211
+ children: e.errorMessage
212
+ }) : null
213
+ ]
214
+ }), /* @__PURE__ */ R(h, {
215
+ variant: D(e.status),
216
+ children: A(e.status)
217
+ })]
218
+ }, e.id))
219
+ })
220
+ ]
221
+ });
222
+ }
223
+ function be({ url: e }) {
224
+ return /* @__PURE__ */ z("div", {
225
+ className: "space-y-3",
226
+ children: [
227
+ /* @__PURE__ */ R("p", {
228
+ className: "text-sm font-medium",
229
+ children: "How to send updates"
230
+ }),
231
+ /* @__PURE__ */ R(Y, {
232
+ label: "Webhook URL",
233
+ value: e
234
+ }),
235
+ /* @__PURE__ */ z("ul", {
236
+ className: "list-disc space-y-1 pl-5 text-xs text-text-secondary",
237
+ children: [
238
+ /* @__PURE__ */ z("li", { children: [
239
+ "POST JSON: one update object, or an array of up to ",
240
+ 5,
241
+ "."
242
+ ] }),
243
+ /* @__PURE__ */ z("li", { children: [
244
+ "Sign the exact raw body with HMAC-SHA256 using the signing secret and send the hex digest in the ",
245
+ /* @__PURE__ */ R("code", {
246
+ className: "font-mono",
247
+ children: le
248
+ }),
249
+ " header (a",
250
+ " ",
251
+ /* @__PURE__ */ R("code", {
252
+ className: "font-mono",
253
+ children: "sha256="
254
+ }),
255
+ " prefix is accepted)."
256
+ ] }),
257
+ /* @__PURE__ */ z("li", { children: [
258
+ "Identify the shipment with ",
259
+ /* @__PURE__ */ R("code", {
260
+ className: "font-mono",
261
+ children: "trackingNumber"
262
+ }),
263
+ " or its",
264
+ " ",
265
+ /* @__PURE__ */ R("code", {
266
+ className: "font-mono",
267
+ children: "shipmentId"
268
+ }),
269
+ ". Event types:",
270
+ " ",
271
+ ue.join(", "),
272
+ "."
273
+ ] }),
274
+ /* @__PURE__ */ z("li", { children: [
275
+ "Send a stable ",
276
+ /* @__PURE__ */ R("code", {
277
+ className: "font-mono",
278
+ children: "externalEventId"
279
+ }),
280
+ " so retries are recorded once instead of twice."
281
+ ] })
282
+ ]
283
+ }),
284
+ /* @__PURE__ */ R(Y, {
285
+ label: "Example body",
286
+ value: O(),
287
+ multiline: !0
288
+ }),
289
+ /* @__PURE__ */ R(Y, {
290
+ label: "Example request",
291
+ value: E(e),
292
+ multiline: !0
293
+ })
294
+ ]
295
+ });
296
+ }
297
+ function xe({ integration: e, url: t, expanded: i, refreshKey: c, busy: l, onToggle: u, onSetStatus: d, onRotate: p, onDelete: y }) {
298
+ let b = e.status === "ACTIVE";
299
+ return /* @__PURE__ */ R(_, { children: /* @__PURE__ */ z(v, {
300
+ className: "p-5",
301
+ children: [/* @__PURE__ */ z("div", {
302
+ className: "flex flex-wrap items-start justify-between gap-3",
303
+ children: [/* @__PURE__ */ z("div", {
304
+ className: "min-w-0 space-y-1",
305
+ children: [
306
+ /* @__PURE__ */ z("div", {
307
+ className: "flex flex-wrap items-center gap-2",
308
+ children: [/* @__PURE__ */ R("p", {
309
+ className: "text-base font-semibold",
310
+ children: e.name
311
+ }), /* @__PURE__ */ R(h, {
312
+ variant: M(e.status),
313
+ children: A(e.status)
314
+ })]
315
+ }),
316
+ /* @__PURE__ */ z("p", {
317
+ className: "text-xs text-text-secondary",
318
+ children: ["Signed webhook · ", P(e.status)]
319
+ }),
320
+ /* @__PURE__ */ z("p", {
321
+ className: "text-xs text-text-secondary",
322
+ children: [
323
+ "Last accepted update:",
324
+ " ",
325
+ e.lastSyncAt ? m(e.lastSyncAt) : "none yet",
326
+ e.lastErrorAt ? ` · Last error ${m(e.lastErrorAt)}` : ""
327
+ ]
328
+ }),
329
+ e.lastErrorMessage ? /* @__PURE__ */ R("p", {
330
+ className: "break-words text-xs text-status-error-text",
331
+ children: e.lastErrorMessage
332
+ }) : null
333
+ ]
334
+ }), /* @__PURE__ */ z("div", {
335
+ className: "flex flex-wrap items-center gap-2",
336
+ children: [
337
+ /* @__PURE__ */ z(g, {
338
+ size: "sm",
339
+ variant: "outline",
340
+ disabled: l,
341
+ onClick: () => d(b ? "PAUSED" : "ACTIVE"),
342
+ children: [R(b ? o : s, {
343
+ size: 14,
344
+ className: "mr-1"
345
+ }), b ? "Pause" : "Resume"]
346
+ }),
347
+ /* @__PURE__ */ z(g, {
348
+ size: "sm",
349
+ variant: "outline",
350
+ disabled: l,
351
+ onClick: p,
352
+ children: [/* @__PURE__ */ R(a, {
353
+ size: 14,
354
+ className: "mr-1"
355
+ }), "Rotate secret"]
356
+ }),
357
+ /* @__PURE__ */ R(g, {
358
+ size: "sm",
359
+ variant: "ghost",
360
+ disabled: l,
361
+ onClick: y,
362
+ "aria-label": `Delete ${e.name}`,
363
+ children: /* @__PURE__ */ R(f, { size: 14 })
364
+ }),
365
+ /* @__PURE__ */ R(g, {
366
+ size: "sm",
367
+ variant: "ghost",
368
+ onClick: u,
369
+ "aria-expanded": i,
370
+ "aria-label": i ? "Hide details" : "Show details",
371
+ children: R(i ? r : n, { size: 16 })
372
+ })
373
+ ]
374
+ })]
375
+ }), i ? /* @__PURE__ */ z("div", {
376
+ className: "mt-4 grid gap-6 border-t border-border-subtle pt-4 lg:grid-cols-2",
377
+ children: [/* @__PURE__ */ R(be, { url: t }), /* @__PURE__ */ R(X, {
378
+ integrationId: e.id,
379
+ refreshKey: c
380
+ })]
381
+ }) : null]
382
+ }) });
383
+ }
384
+ function Se() {
385
+ let { tenantId: e, workspaceId: t } = p();
386
+ return /* @__PURE__ */ R(Ce, {}, `${e ?? ""}:${t ?? ""}`);
387
+ }
388
+ function Ce() {
389
+ let { apiGatewayUrl: t } = p(), n = F(), { message: r, notify: i } = se(), [a, o] = L(null), [s, f] = L(q), [y, b] = L(0), [le, ue] = L(0), [E, D] = L(null), [O, j] = L(!1), [M, N] = L([]), P = M[0] ?? null, I = (e, t) => N((n) => [...n, {
390
+ name: e,
391
+ secret: t
392
+ }]), B = he(/* @__PURE__ */ new Set()), [V, H] = L(() => /* @__PURE__ */ new Set()), U = async (e, t) => {
393
+ if (!B.current.has(e)) {
394
+ B.current.add(e), H(new Set(B.current));
395
+ try {
396
+ await t();
397
+ } finally {
398
+ B.current.delete(e), H(new Set(B.current));
399
+ }
400
+ }
401
+ }, { integrations: W, total: G, isLoading: Y, error: X, refetch: be } = pe({
402
+ status: s === q ? void 0 : s,
403
+ limit: K,
404
+ offset: y * K
405
+ }), { all: Se, active: Ce, refetch: we } = fe(), Z = Math.max(1, Math.ceil(G / K));
406
+ me(() => {
407
+ !Y && y > 0 && y >= Z && b(Z - 1);
408
+ }, [
409
+ Y,
410
+ y,
411
+ Z
412
+ ]);
413
+ let Q = W.map((e) => e.lastSyncAt).filter((e) => !!e).sort(), Te = Q.length > 0 ? Q[Q.length - 1] : void 0, Ee = (e) => de(t, e.workspaceId, e.id, window.location.origin), De = () => {
414
+ ue((e) => e + 1), be(), we();
415
+ }, $ = (e) => {
416
+ o(null), i(e), De();
417
+ }, Oe = async (e, t) => {
418
+ try {
419
+ await n.update(e.id, { status: t }), $(t === "ACTIVE" ? `Resumed ${e.name}.` : `Paused ${e.name}.`);
420
+ } catch (e) {
421
+ o(J(e, "Could not change the integration status."));
422
+ }
423
+ }, ke = async (e) => {
424
+ if (!window.confirm(`Rotate the signing secret for ${e.name}? Deliveries signed with the old secret are refused as soon as it changes.`)) return;
425
+ let t = k();
426
+ try {
427
+ await n.update(e.id, { apiSecret: t }), I(e.name, t), $(`Rotated the signing secret for ${e.name}.`);
428
+ } catch (e) {
429
+ o(J(e, "Could not rotate the signing secret."));
430
+ }
431
+ }, Ae = async (e) => {
432
+ if (window.confirm(`Delete ${e.name}? Its webhook URL stops working; tracking events it already created stay on their shipments.`)) try {
433
+ await n.remove(e.id), E === e.id && D(null), $(`Deleted ${e.name}.`);
434
+ } catch (e) {
435
+ o(J(e, "Could not delete the integration."));
436
+ }
437
+ };
438
+ return /* @__PURE__ */ z(ie, {
439
+ title: "Integrations",
440
+ subtitle: "Carrier, ELD and GPS tracking feeds",
441
+ icon: /* @__PURE__ */ R(c, { size: 24 }),
442
+ headerActions: /* @__PURE__ */ R(ge, {
443
+ primary: {
444
+ label: "Connect feed",
445
+ icon: /* @__PURE__ */ R(l, { size: 16 }),
446
+ onSelect: () => j(!0)
447
+ },
448
+ actions: [{
449
+ label: "Refresh",
450
+ icon: /* @__PURE__ */ R(u, { size: 16 }),
451
+ onSelect: De
452
+ }]
453
+ }),
454
+ children: [
455
+ /* @__PURE__ */ R(_e, {
456
+ icon: /* @__PURE__ */ R(c, { size: 18 }),
457
+ children: "Connect the systems that already know where your freight is. Each feed gets its own signed webhook; every update it sends becomes a tracking event on the matching shipment, so status and ETA stay current without manual entry."
458
+ }),
459
+ /* @__PURE__ */ R(oe, { message: r }),
460
+ /* @__PURE__ */ R(w, { message: a }),
461
+ /* @__PURE__ */ z(ae, {
462
+ columns: 3,
463
+ children: [
464
+ /* @__PURE__ */ R(C, {
465
+ label: "Feeds",
466
+ value: Se,
467
+ icon: /* @__PURE__ */ R(c, { size: 20 }),
468
+ accent: "brand"
469
+ }),
470
+ /* @__PURE__ */ R(C, {
471
+ label: "Active",
472
+ value: Ce,
473
+ icon: /* @__PURE__ */ R(d, { size: 20 }),
474
+ accent: "success"
475
+ }),
476
+ /* @__PURE__ */ R(C, {
477
+ label: "Last accepted update (shown)",
478
+ value: Te ? m(Te) : "—",
479
+ icon: /* @__PURE__ */ R(e, { size: 20 }),
480
+ accent: "blue"
481
+ })
482
+ ]
483
+ }),
484
+ /* @__PURE__ */ R("div", {
485
+ className: "flex flex-col gap-3 sm:flex-row sm:items-center",
486
+ children: /* @__PURE__ */ z(ee, {
487
+ value: s,
488
+ onValueChange: (e) => {
489
+ f(e), b(0);
490
+ },
491
+ children: [/* @__PURE__ */ R(ne, {
492
+ "aria-label": "Status",
493
+ className: "sm:w-56",
494
+ children: /* @__PURE__ */ R(re, {})
495
+ }), /* @__PURE__ */ z(te, { children: [/* @__PURE__ */ R(x, {
496
+ value: q,
497
+ children: "All statuses"
498
+ }), ce.map((e) => /* @__PURE__ */ R(x, {
499
+ value: e,
500
+ children: A(e)
501
+ }, e))] })]
502
+ })
503
+ }),
504
+ /* @__PURE__ */ R(w, { message: X?.message }),
505
+ Y && W.length === 0 ? /* @__PURE__ */ z("div", {
506
+ className: "grid gap-4",
507
+ children: [/* @__PURE__ */ R(S, { className: "h-28 w-full" }), /* @__PURE__ */ R(S, { className: "h-28 w-full" })]
508
+ }) : W.length === 0 && !X ? /* @__PURE__ */ R(_, { children: /* @__PURE__ */ z(v, {
509
+ className: "flex flex-col items-center gap-3 p-10 text-center",
510
+ children: [
511
+ /* @__PURE__ */ R(c, {
512
+ size: 32,
513
+ className: "text-text-tertiary"
514
+ }),
515
+ /* @__PURE__ */ R("p", {
516
+ className: "font-medium",
517
+ children: s === q ? "No tracking feeds connected" : "No feeds with this status"
518
+ }),
519
+ /* @__PURE__ */ R("p", {
520
+ className: "max-w-md text-sm text-text-secondary",
521
+ children: s === q ? "Connect a carrier portal, ELD or GPS tracker so shipment updates arrive on their own." : "Choose another status to see the rest of your feeds."
522
+ }),
523
+ s === q ? /* @__PURE__ */ z(g, {
524
+ onClick: () => j(!0),
525
+ children: [/* @__PURE__ */ R(l, {
526
+ size: 16,
527
+ className: "mr-1.5"
528
+ }), "Connect feed"]
529
+ }) : null
530
+ ]
531
+ }) }) : /* @__PURE__ */ R("div", {
532
+ className: "grid gap-4",
533
+ children: W.map((e) => /* @__PURE__ */ R(xe, {
534
+ integration: e,
535
+ url: Ee(e),
536
+ expanded: E === e.id,
537
+ refreshKey: le,
538
+ busy: V.has(e.id),
539
+ onToggle: () => D((t) => t === e.id ? null : e.id),
540
+ onSetStatus: (t) => void U(e.id, () => Oe(e, t)),
541
+ onRotate: () => void U(e.id, () => ke(e)),
542
+ onDelete: () => void U(e.id, () => Ae(e))
543
+ }, e.id))
544
+ }),
545
+ G > K ? /* @__PURE__ */ z("div", {
546
+ className: "flex items-center justify-between text-sm",
547
+ children: [/* @__PURE__ */ z("span", {
548
+ className: "text-text-secondary",
549
+ children: [
550
+ "Page ",
551
+ y + 1,
552
+ " of ",
553
+ Z,
554
+ " · ",
555
+ G,
556
+ " feeds"
557
+ ]
558
+ }), /* @__PURE__ */ z("div", {
559
+ className: "flex gap-2",
560
+ children: [/* @__PURE__ */ R(g, {
561
+ variant: "outline",
562
+ size: "sm",
563
+ disabled: y === 0,
564
+ onClick: () => b((e) => e - 1),
565
+ children: "Previous"
566
+ }), /* @__PURE__ */ R(g, {
567
+ variant: "outline",
568
+ size: "sm",
569
+ disabled: y + 1 >= Z,
570
+ onClick: () => b((e) => e + 1),
571
+ children: "Next"
572
+ })]
573
+ })]
574
+ }) : null,
575
+ /* @__PURE__ */ R(_, { children: /* @__PURE__ */ z(v, {
576
+ className: "space-y-2 p-5",
577
+ children: [
578
+ /* @__PURE__ */ R("p", {
579
+ className: "text-sm font-medium",
580
+ children: "Carrier networks"
581
+ }),
582
+ /* @__PURE__ */ z("p", {
583
+ className: "text-sm text-text-secondary",
584
+ children: [
585
+ "Direct connections to ",
586
+ T.map((e) => e.label).join(", "),
587
+ " ",
588
+ "are not available yet. Until they are, any carrier or telematics system that can send HTTPS webhooks connects through a signed feed above."
589
+ ]
590
+ }),
591
+ /* @__PURE__ */ R("div", {
592
+ className: "flex flex-wrap gap-2",
593
+ children: T.map((e) => /* @__PURE__ */ z(h, {
594
+ variant: "outline",
595
+ children: [e.label, " · not available yet"]
596
+ }, e.id))
597
+ })
598
+ ]
599
+ }) }),
600
+ /* @__PURE__ */ R(ye, {
601
+ open: O,
602
+ onOpenChange: j,
603
+ onCreated: (e, t) => {
604
+ D(e.id), I(e.name, t), $(`Connected ${e.name}.`);
605
+ }
606
+ }),
607
+ /* @__PURE__ */ R(ve, {
608
+ secret: P?.secret ?? null,
609
+ integrationName: P?.name ?? "",
610
+ onClose: () => N((e) => e.slice(1))
611
+ })
612
+ ]
613
+ });
614
+ }
615
+ //#endregion
616
+ export { Se as default };