@burdenoff/microfe-movethewheels 2026.1012.1 → 2026.1013.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.
@@ -3,23 +3,32 @@ import { RefreshCw as t } from "../node_modules/lucide-react/dist/esm/icons/refr
3
3
  import { useMoveTheWheels as n } from "../providers/MoveTheWheelsProvider.js";
4
4
  import { Button as r, Input as i, Label as a } from "../components/ui.js";
5
5
  import { PageLayout as o } from "../components/PageLayout.js";
6
- import { CONTAINER_EVENT_TYPES as s, EQUIPMENT_TYPES as c, useContainerLifecycle as l } from "../hooks/useContainerLifecycle.js";
7
- import { useState as u } from "react";
8
- import { Fragment as d, jsx as f, jsxs as p } from "react/jsx-runtime";
6
+ import { useShipmentPermissions as s } from "../hooks/useShipmentPermissions.js";
7
+ import { CONTAINER_EVENT_TYPES as c, EQUIPMENT_TYPES as l, useContainerLifecycle as u } from "../hooks/useContainerLifecycle.js";
8
+ import { useState as d } from "react";
9
+ import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
10
+ import { PermissionProvider as h } from "@burdenoff/fe-libs/shared/providers/shell";
9
11
  //#region src/movethewheels/pages/ContainersPage.tsx
10
- function m(e) {
12
+ function g(e) {
11
13
  return e.replaceAll("_", " ");
12
14
  }
13
- function h(e) {
15
+ function _(e) {
14
16
  return new Date(e).toLocaleString();
15
17
  }
16
- var g = "w-full rounded-md border bg-bg-surface p-2 text-sm", _ = "rounded-xl border bg-bg-surface p-5 space-y-4";
17
- function v() {
18
- let { workspaceId: e, currentUser: t } = n();
19
- return /* @__PURE__ */ f(y, {}, `${e ?? ""}:${t?.id ?? ""}`);
18
+ var v = "w-full rounded-md border bg-bg-surface p-2 text-sm", y = "rounded-xl border bg-bg-surface p-5 space-y-4";
19
+ function b() {
20
+ let { workspaceId: e, tenantId: t, currentUser: r, apiGatewayUrl: i } = n();
21
+ return /* @__PURE__ */ p(h, {
22
+ scopeId: e ?? null,
23
+ gateway: "workspace",
24
+ children: /* @__PURE__ */ p(x, {})
25
+ }, `${e}:${t}:${r?.id}:${i}`);
20
26
  }
21
- function y() {
22
- let n = l(), [v, y] = u(""), [x, S] = u("DRY_20"), [C, w] = u(""), [T, E] = u(""), [D, O] = u(""), [k, A] = u(""), [j, M] = u("GATE_OUT"), [N, P] = u("ACTUAL"), [F, I] = u(""), [L, R] = u(""), [z, B] = u(""), [V, H] = u(""), [U, W] = u(""), [G, K] = u(!1), [q, J] = u(null), [Y, X] = u(null), Z = n.containers.find((e) => e.id === n.containerId), Q = n.cycles.find((e) => e.id === n.cycleId), $ = async (e, t) => {
27
+ function x() {
28
+ return /* @__PURE__ */ p(S, { access: s() });
29
+ }
30
+ function S({ access: n }) {
31
+ let s = u(n.canRead), [h, b] = d(""), [x, S] = d("DRY_20"), [w, T] = d(""), [E, ee] = d(""), [D, O] = d(""), [k, A] = d(""), [j, M] = d("GATE_OUT"), [N, P] = d("ACTUAL"), [F, I] = d(""), [L, R] = d(""), [z, B] = d(""), [V, H] = d(""), [U, W] = d(""), [G, K] = d(!1), [q, J] = d(null), [Y, X] = d(null), Z = s.containers.find((e) => e.id === s.containerId), Q = s.cycles.find((e) => e.id === s.cycleId), $ = async (e, t) => {
23
32
  K(!0), J(null), X(null);
24
33
  try {
25
34
  await e(), X(t);
@@ -29,81 +38,81 @@ function y() {
29
38
  K(!1);
30
39
  }
31
40
  };
32
- return /* @__PURE__ */ p(o, {
41
+ return n.canRead ? /* @__PURE__ */ m(o, {
33
42
  title: "Containers",
34
43
  subtitle: "Physical equipment, usage cycles and sourced movement history",
35
- icon: /* @__PURE__ */ f(e, { size: 24 }),
36
- headerActions: /* @__PURE__ */ p(r, {
44
+ icon: /* @__PURE__ */ p(e, { size: 24 }),
45
+ headerActions: /* @__PURE__ */ m(r, {
37
46
  variant: "outline",
38
- onClick: n.refresh,
47
+ onClick: s.refresh,
39
48
  disabled: G,
40
- children: [/* @__PURE__ */ f(t, {
49
+ children: [/* @__PURE__ */ p(t, {
41
50
  size: 16,
42
51
  className: "mr-2"
43
52
  }), "Refresh"]
44
53
  }),
45
54
  children: [
46
- /* @__PURE__ */ f("p", {
55
+ /* @__PURE__ */ p("p", {
47
56
  className: "mb-5 text-sm text-text-secondary",
48
57
  children: "Shipment delivery and equipment return are separate obligations. Close a cycle only after an actual empty return and recorded return acceptance."
49
58
  }),
50
- q && /* @__PURE__ */ f("p", {
59
+ q && /* @__PURE__ */ p("p", {
51
60
  role: "alert",
52
61
  className: "mb-4 rounded-md border border-red-400 p-3",
53
62
  children: q
54
63
  }),
55
- Y && /* @__PURE__ */ f("p", {
64
+ Y && /* @__PURE__ */ p("p", {
56
65
  role: "status",
57
66
  className: "mb-4 rounded-md border p-3",
58
67
  children: Y
59
68
  }),
60
- /* @__PURE__ */ p("div", {
69
+ /* @__PURE__ */ m("div", {
61
70
  className: "grid gap-5 xl:grid-cols-3",
62
71
  children: [
63
- /* @__PURE__ */ p("section", {
64
- className: _,
72
+ /* @__PURE__ */ m("section", {
73
+ className: y,
65
74
  children: [
66
- /* @__PURE__ */ f("h2", {
75
+ /* @__PURE__ */ p("h2", {
67
76
  className: "text-lg font-semibold",
68
77
  children: "Equipment registry"
69
78
  }),
70
- n.loading && /* @__PURE__ */ f("p", {
79
+ s.loading && /* @__PURE__ */ p("p", {
71
80
  role: "status",
72
81
  children: "Loading containers…"
73
82
  }),
74
- n.error && /* @__PURE__ */ p("p", {
83
+ s.error && /* @__PURE__ */ m("p", {
75
84
  role: "alert",
76
85
  children: [
77
- n.error,
86
+ s.error,
78
87
  " ",
79
- /* @__PURE__ */ f(r, {
88
+ /* @__PURE__ */ p(r, {
80
89
  variant: "outline",
81
- onClick: n.refresh,
90
+ onClick: s.refresh,
82
91
  children: "Retry"
83
92
  })
84
93
  ]
85
94
  }),
86
- !n.loading && !n.error && n.containers.length === 0 && /* @__PURE__ */ f("p", { children: "No containers on this page. Register equipment to start tracking its lifecycle." }),
87
- /* @__PURE__ */ f("ul", {
95
+ !s.loading && !s.error && s.containers.length === 0 && /* @__PURE__ */ p("p", { children: "No containers on this page. Register equipment to start tracking its lifecycle." }),
96
+ /* @__PURE__ */ p("ul", {
88
97
  className: "space-y-2",
89
- children: n.containers.map((e) => /* @__PURE__ */ f("li", { children: /* @__PURE__ */ p("button", {
98
+ children: s.containers.map((e) => /* @__PURE__ */ p("li", { children: /* @__PURE__ */ m("button", {
90
99
  type: "button",
91
- "aria-pressed": e.id === n.containerId,
100
+ "aria-pressed": e.id === s.containerId,
92
101
  disabled: G,
93
102
  onClick: () => {
94
- n.selectContainer(e.id), J(null), X(null);
103
+ s.selectContainer(e.id), J(null), X(null);
95
104
  },
96
- className: `w-full rounded-md border p-3 text-left ${e.id === n.containerId ? "border-blue-500" : ""}`,
105
+ className: `w-full rounded-md border p-3 text-left ${e.id === s.containerId ? "border-blue-500" : ""}`,
97
106
  children: [
98
- /* @__PURE__ */ f("span", {
107
+ /* @__PURE__ */ p("span", {
99
108
  className: "font-semibold",
100
109
  children: e.containerNumber
101
110
  }),
102
- /* @__PURE__ */ f("br", {}),
103
- /* @__PURE__ */ p("span", {
111
+ /* @__PURE__ */ p("br", {}),
112
+ /* @__PURE__ */ m("span", {
104
113
  className: "text-sm",
105
114
  children: [
106
- m(e.equipmentType),
115
+ g(e.equipmentType),
107
116
  " · ",
108
117
  e.ownerName || "Owner not recorded"
109
118
  ]
@@ -111,97 +120,97 @@ function y() {
111
120
  ]
112
121
  }) }, e.id))
113
122
  }),
114
- /* @__PURE__ */ f(b, {
115
- page: n.page,
116
- more: n.hasMore,
117
- disabled: n.loading || G,
123
+ /* @__PURE__ */ p(C, {
124
+ page: s.page,
125
+ more: s.hasMore,
126
+ disabled: s.loading || G,
118
127
  onChange: (e) => {
119
- n.selectContainer(""), n.setPage(e);
128
+ s.selectContainer(""), s.setPage(e);
120
129
  }
121
130
  }),
122
- /* @__PURE__ */ p("form", {
131
+ n.canCreate && /* @__PURE__ */ m("form", {
123
132
  onSubmit: (e) => {
124
- e.preventDefault(), $(async () => {
125
- await n.register({
126
- containerNumber: v.trim(),
133
+ e.preventDefault(), n.allows("create") && $(async () => {
134
+ await s.register({
135
+ containerNumber: h.trim(),
127
136
  equipmentType: x,
128
- ownerName: C.trim() || void 0,
129
- source: T.trim()
130
- }), y("");
137
+ ownerName: w.trim() || void 0,
138
+ source: E.trim()
139
+ }), b("");
131
140
  }, "Container registered. Record its usage cycle next.");
132
141
  },
133
142
  className: "space-y-3 border-t pt-4",
134
143
  children: [
135
- /* @__PURE__ */ f("h3", {
144
+ /* @__PURE__ */ p("h3", {
136
145
  className: "font-semibold",
137
146
  children: "Register container"
138
147
  }),
139
- /* @__PURE__ */ f(a, {
148
+ /* @__PURE__ */ p(a, {
140
149
  htmlFor: "container-number",
141
150
  children: "ISO container number"
142
151
  }),
143
- /* @__PURE__ */ f(i, {
152
+ /* @__PURE__ */ p(i, {
144
153
  id: "container-number",
145
- value: v,
146
- onChange: (e) => y(e.target.value),
154
+ value: h,
155
+ onChange: (e) => b(e.target.value),
147
156
  required: !0,
148
157
  maxLength: 20,
149
158
  placeholder: "Four letters and seven digits"
150
159
  }),
151
- /* @__PURE__ */ f(a, {
160
+ /* @__PURE__ */ p(a, {
152
161
  htmlFor: "equipment-type",
153
162
  children: "Physical equipment type"
154
163
  }),
155
- /* @__PURE__ */ f("select", {
164
+ /* @__PURE__ */ p("select", {
156
165
  id: "equipment-type",
157
- className: g,
166
+ className: v,
158
167
  value: x,
159
- onChange: (e) => S(c.find((t) => t === e.target.value) ?? "OTHER"),
160
- children: c.map((e) => /* @__PURE__ */ f("option", {
168
+ onChange: (e) => S(l.find((t) => t === e.target.value) ?? "OTHER"),
169
+ children: l.map((e) => /* @__PURE__ */ p("option", {
161
170
  value: e,
162
- children: m(e)
171
+ children: g(e)
163
172
  }, e))
164
173
  }),
165
- /* @__PURE__ */ f(a, {
174
+ /* @__PURE__ */ p(a, {
166
175
  htmlFor: "container-owner",
167
176
  children: "Owner (optional)"
168
177
  }),
169
- /* @__PURE__ */ f(i, {
178
+ /* @__PURE__ */ p(i, {
170
179
  id: "container-owner",
171
- value: C,
172
- onChange: (e) => w(e.target.value),
180
+ value: w,
181
+ onChange: (e) => T(e.target.value),
173
182
  maxLength: 200
174
183
  }),
175
- /* @__PURE__ */ f(a, {
184
+ /* @__PURE__ */ p(a, {
176
185
  htmlFor: "container-source",
177
186
  children: "Information source"
178
187
  }),
179
- /* @__PURE__ */ f(i, {
188
+ /* @__PURE__ */ p(i, {
180
189
  id: "container-source",
181
- value: T,
182
- onChange: (e) => E(e.target.value),
190
+ value: E,
191
+ onChange: (e) => ee(e.target.value),
183
192
  required: !0,
184
193
  maxLength: 120,
185
194
  placeholder: "Equipment release document or carrier portal"
186
195
  }),
187
- /* @__PURE__ */ f(r, {
196
+ /* @__PURE__ */ p(r, {
188
197
  type: "submit",
189
- disabled: G || !v.trim() || !T.trim(),
198
+ disabled: G || !h.trim() || !E.trim(),
190
199
  children: "Register container"
191
200
  })
192
201
  ]
193
202
  })
194
203
  ]
195
204
  }),
196
- /* @__PURE__ */ p("section", {
197
- className: _,
205
+ /* @__PURE__ */ m("section", {
206
+ className: y,
198
207
  children: [
199
- /* @__PURE__ */ f("h2", {
208
+ /* @__PURE__ */ p("h2", {
200
209
  className: "text-lg font-semibold",
201
210
  children: "Usage cycles"
202
211
  }),
203
- !n.containerId && /* @__PURE__ */ f("p", { children: "Select a container to view its cycles." }),
204
- Z && /* @__PURE__ */ p("p", {
212
+ !s.containerId && /* @__PURE__ */ p("p", { children: "Select a container to view its cycles." }),
213
+ Z && /* @__PURE__ */ m("p", {
205
214
  className: "text-sm",
206
215
  children: [
207
216
  Z.containerNumber,
@@ -209,27 +218,27 @@ function y() {
209
218
  Z.source
210
219
  ]
211
220
  }),
212
- n.cyclesLoading && /* @__PURE__ */ f("p", {
221
+ s.cyclesLoading && /* @__PURE__ */ p("p", {
213
222
  role: "status",
214
223
  children: "Loading cycles…"
215
224
  }),
216
- n.cycleError && /* @__PURE__ */ f("p", {
225
+ s.cycleError && /* @__PURE__ */ p("p", {
217
226
  role: "alert",
218
- children: n.cycleError
227
+ children: s.cycleError
219
228
  }),
220
- n.containerId && !n.cyclesLoading && !n.cycleError && !n.cycles.length && /* @__PURE__ */ f("p", { children: "No usage cycles on this page." }),
221
- /* @__PURE__ */ f("ul", {
229
+ s.containerId && !s.cyclesLoading && !s.cycleError && !s.cycles.length && /* @__PURE__ */ p("p", { children: "No usage cycles on this page." }),
230
+ /* @__PURE__ */ p("ul", {
222
231
  className: "space-y-2",
223
- children: n.cycles.map((e) => /* @__PURE__ */ f("li", { children: /* @__PURE__ */ p("button", {
232
+ children: s.cycles.map((e) => /* @__PURE__ */ p("li", { children: /* @__PURE__ */ m("button", {
224
233
  type: "button",
225
- "aria-pressed": e.id === n.cycleId,
234
+ "aria-pressed": e.id === s.cycleId,
226
235
  disabled: G,
227
- className: `w-full rounded-md border p-3 text-left ${e.id === n.cycleId ? "border-blue-500" : ""}`,
236
+ className: `w-full rounded-md border p-3 text-left ${e.id === s.cycleId ? "border-blue-500" : ""}`,
228
237
  onClick: () => {
229
- n.selectCycle(e.id), J(null), X(null);
238
+ s.selectCycle(e.id), J(null), X(null);
230
239
  },
231
240
  children: [
232
- /* @__PURE__ */ p("span", {
241
+ /* @__PURE__ */ m("span", {
233
242
  className: "font-semibold",
234
243
  children: [
235
244
  e.bookingReference || "Unlinked booking",
@@ -237,55 +246,55 @@ function y() {
237
246
  e.status
238
247
  ]
239
248
  }),
240
- /* @__PURE__ */ f("br", {}),
241
- /* @__PURE__ */ p("span", {
249
+ /* @__PURE__ */ p("br", {}),
250
+ /* @__PURE__ */ m("span", {
242
251
  className: "text-sm",
243
- children: ["Opened ", h(e.openedAt)]
252
+ children: ["Opened ", _(e.openedAt)]
244
253
  }),
245
- e.closedAt && /* @__PURE__ */ p("span", {
254
+ e.closedAt && /* @__PURE__ */ m("span", {
246
255
  className: "block text-sm",
247
- children: ["Closed ", h(e.closedAt)]
256
+ children: ["Closed ", _(e.closedAt)]
248
257
  })
249
258
  ]
250
259
  }) }, e.id))
251
260
  }),
252
- n.containerId && /* @__PURE__ */ f(b, {
253
- page: n.cyclePage,
254
- more: n.hasMoreCycles,
255
- disabled: n.cyclesLoading || G,
261
+ s.containerId && /* @__PURE__ */ p(C, {
262
+ page: s.cyclePage,
263
+ more: s.hasMoreCycles,
264
+ disabled: s.cyclesLoading || G,
256
265
  onChange: (e) => {
257
- n.selectCycle(""), n.setCyclePage(e);
266
+ s.selectCycle(""), s.setCyclePage(e);
258
267
  }
259
268
  }),
260
- n.containerId && /* @__PURE__ */ p("form", {
269
+ s.containerId && n.canCreate && /* @__PURE__ */ m("form", {
261
270
  className: "space-y-3 border-t pt-4",
262
271
  onSubmit: (e) => {
263
- e.preventDefault(), $(async () => {
272
+ e.preventDefault(), n.allows("create") && $(async () => {
264
273
  let e = new Date(k);
265
274
  if (!Number.isFinite(e.getTime())) throw Error("Enter a valid cycle opening time.");
266
- await n.openCycle({
267
- containerId: n.containerId,
275
+ await s.openCycle({
276
+ containerId: s.containerId,
268
277
  bookingReference: D.trim() || void 0,
269
278
  openedAt: e.toISOString()
270
279
  });
271
280
  }, "Usage cycle opened.");
272
281
  },
273
282
  children: [
274
- /* @__PURE__ */ f(a, {
283
+ /* @__PURE__ */ p(a, {
275
284
  htmlFor: "booking-reference",
276
285
  children: "Booking reference (optional)"
277
286
  }),
278
- /* @__PURE__ */ f(i, {
287
+ /* @__PURE__ */ p(i, {
279
288
  id: "booking-reference",
280
289
  value: D,
281
290
  onChange: (e) => O(e.target.value),
282
291
  maxLength: 120
283
292
  }),
284
- /* @__PURE__ */ f(a, {
293
+ /* @__PURE__ */ p(a, {
285
294
  htmlFor: "cycle-opening-time",
286
295
  children: "Cycle opening time (your local timezone)"
287
296
  }),
288
- /* @__PURE__ */ f(i, {
297
+ /* @__PURE__ */ p(i, {
289
298
  id: "cycle-opening-time",
290
299
  type: "datetime-local",
291
300
  step: 1,
@@ -293,12 +302,12 @@ function y() {
293
302
  onChange: (e) => A(e.target.value),
294
303
  required: !0
295
304
  }),
296
- /* @__PURE__ */ f(r, {
305
+ /* @__PURE__ */ p(r, {
297
306
  type: "submit",
298
- disabled: G || n.cyclesLoading,
307
+ disabled: G || s.cyclesLoading,
299
308
  children: "Open usage cycle"
300
309
  }),
301
- /* @__PURE__ */ f("p", {
310
+ /* @__PURE__ */ p("p", {
302
311
  className: "text-sm text-text-secondary",
303
312
  children: "Only one cycle may be open for this container. Use its actual start time so earlier movements can be recorded. Times are stored in UTC."
304
313
  })
@@ -306,60 +315,60 @@ function y() {
306
315
  })
307
316
  ]
308
317
  }),
309
- /* @__PURE__ */ p("section", {
310
- className: _,
318
+ /* @__PURE__ */ m("section", {
319
+ className: y,
311
320
  children: [
312
- /* @__PURE__ */ f("h2", {
321
+ /* @__PURE__ */ p("h2", {
313
322
  className: "text-lg font-semibold",
314
323
  children: "Movement and return history"
315
324
  }),
316
- !n.cycleId && /* @__PURE__ */ f("p", { children: "Select a usage cycle to view and record events." }),
317
- n.eventsLoading && /* @__PURE__ */ f("p", {
325
+ !s.cycleId && /* @__PURE__ */ p("p", { children: "Select a usage cycle to view and record events." }),
326
+ s.eventsLoading && /* @__PURE__ */ p("p", {
318
327
  role: "status",
319
328
  children: "Loading events…"
320
329
  }),
321
- n.eventError && /* @__PURE__ */ f("p", {
330
+ s.eventError && /* @__PURE__ */ p("p", {
322
331
  role: "alert",
323
- children: n.eventError
332
+ children: s.eventError
324
333
  }),
325
- n.cycleId && !n.eventsLoading && !n.eventError && !n.events.length && /* @__PURE__ */ f("p", { children: "No events on this page. Record actual movements with their source." }),
326
- /* @__PURE__ */ f("ol", {
334
+ s.cycleId && !s.eventsLoading && !s.eventError && !s.events.length && /* @__PURE__ */ p("p", { children: "No events on this page. Record actual movements with their source." }),
335
+ /* @__PURE__ */ p("ol", {
327
336
  className: "space-y-3",
328
- children: n.events.map((e) => /* @__PURE__ */ p("li", {
337
+ children: s.events.map((e) => /* @__PURE__ */ m("li", {
329
338
  className: "rounded-md border p-3 text-sm",
330
339
  children: [
331
- /* @__PURE__ */ p("p", {
340
+ /* @__PURE__ */ m("p", {
332
341
  className: "font-semibold",
333
342
  children: [
334
- m(e.eventType),
343
+ g(e.eventType),
335
344
  " · ",
336
345
  e.kind
337
346
  ]
338
347
  }),
339
- /* @__PURE__ */ p("p", { children: ["Occurred: ", h(e.occurredAt)] }),
340
- /* @__PURE__ */ p("p", { children: ["Received: ", h(e.receivedAt)] }),
341
- /* @__PURE__ */ p("p", { children: [
348
+ /* @__PURE__ */ m("p", { children: ["Occurred: ", _(e.occurredAt)] }),
349
+ /* @__PURE__ */ m("p", { children: ["Received: ", _(e.receivedAt)] }),
350
+ /* @__PURE__ */ m("p", { children: [
342
351
  "Source: ",
343
352
  e.source,
344
353
  e.sourceReference ? ` · ${e.sourceReference}` : ""
345
354
  ] }),
346
- e.location && /* @__PURE__ */ p("p", { children: ["Location: ", e.location] }),
347
- e.evidenceNote && /* @__PURE__ */ p("p", { children: ["Evidence: ", e.evidenceNote] })
355
+ e.location && /* @__PURE__ */ m("p", { children: ["Location: ", e.location] }),
356
+ e.evidenceNote && /* @__PURE__ */ m("p", { children: ["Evidence: ", e.evidenceNote] })
348
357
  ]
349
358
  }, e.id))
350
359
  }),
351
- n.cycleId && /* @__PURE__ */ f(b, {
352
- page: n.eventPage,
353
- more: n.hasMoreEvents,
354
- disabled: n.eventsLoading || G,
355
- onChange: n.setEventPage
360
+ s.cycleId && /* @__PURE__ */ p(C, {
361
+ page: s.eventPage,
362
+ more: s.hasMoreEvents,
363
+ disabled: s.eventsLoading || G,
364
+ onChange: s.setEventPage
356
365
  }),
357
- Q?.status === "OPEN" && /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ p("form", {
366
+ Q?.status === "OPEN" && /* @__PURE__ */ m(f, { children: [n.canUpdate && /* @__PURE__ */ m("form", {
358
367
  onSubmit: (e) => {
359
- e.preventDefault(), Q && $(async () => {
368
+ e.preventDefault(), !(!Q || !n.allows("update")) && $(async () => {
360
369
  let e = new Date(F);
361
370
  if (!Number.isFinite(e.getTime())) throw Error("Enter a valid event time.");
362
- await n.recordEvent({
371
+ await s.recordEvent({
363
372
  cycleId: Q.id,
364
373
  eventType: j,
365
374
  kind: N,
@@ -373,53 +382,53 @@ function y() {
373
382
  },
374
383
  className: "space-y-3 border-t pt-4",
375
384
  children: [
376
- /* @__PURE__ */ f("h3", {
385
+ /* @__PURE__ */ p("h3", {
377
386
  className: "font-semibold",
378
387
  children: "Record event"
379
388
  }),
380
- /* @__PURE__ */ f(a, {
389
+ /* @__PURE__ */ p(a, {
381
390
  htmlFor: "container-event",
382
391
  children: "Event"
383
392
  }),
384
- /* @__PURE__ */ f("select", {
393
+ /* @__PURE__ */ p("select", {
385
394
  id: "container-event",
386
- className: g,
395
+ className: v,
387
396
  value: j,
388
- onChange: (e) => M(s.find((t) => t === e.target.value) ?? "POSITION_UPDATE"),
389
- children: s.map((e) => /* @__PURE__ */ f("option", {
397
+ onChange: (e) => M(c.find((t) => t === e.target.value) ?? "POSITION_UPDATE"),
398
+ children: c.map((e) => /* @__PURE__ */ p("option", {
390
399
  value: e,
391
- children: m(e)
400
+ children: g(e)
392
401
  }, e))
393
402
  }),
394
- /* @__PURE__ */ f(a, {
403
+ /* @__PURE__ */ p(a, {
395
404
  htmlFor: "event-kind",
396
405
  children: "Event certainty"
397
406
  }),
398
- /* @__PURE__ */ p("select", {
407
+ /* @__PURE__ */ m("select", {
399
408
  id: "event-kind",
400
- className: g,
409
+ className: v,
401
410
  value: N,
402
411
  onChange: (e) => P(e.target.value === "PLANNED" ? "PLANNED" : e.target.value === "ESTIMATED" ? "ESTIMATED" : "ACTUAL"),
403
412
  children: [
404
- /* @__PURE__ */ f("option", {
413
+ /* @__PURE__ */ p("option", {
405
414
  value: "ACTUAL",
406
415
  children: "Actual"
407
416
  }),
408
- /* @__PURE__ */ f("option", {
417
+ /* @__PURE__ */ p("option", {
409
418
  value: "PLANNED",
410
419
  children: "Planned"
411
420
  }),
412
- /* @__PURE__ */ f("option", {
421
+ /* @__PURE__ */ p("option", {
413
422
  value: "ESTIMATED",
414
423
  children: "Estimated"
415
424
  })
416
425
  ]
417
426
  }),
418
- /* @__PURE__ */ f(a, {
427
+ /* @__PURE__ */ p(a, {
419
428
  htmlFor: "event-time",
420
429
  children: "Event time (your local timezone)"
421
430
  }),
422
- /* @__PURE__ */ f(i, {
431
+ /* @__PURE__ */ p(i, {
423
432
  id: "event-time",
424
433
  type: "datetime-local",
425
434
  step: 1,
@@ -427,89 +436,96 @@ function y() {
427
436
  onChange: (e) => I(e.target.value),
428
437
  required: !0
429
438
  }),
430
- /* @__PURE__ */ f(a, {
439
+ /* @__PURE__ */ p(a, {
431
440
  htmlFor: "event-source",
432
441
  children: "Event source"
433
442
  }),
434
- /* @__PURE__ */ f(i, {
443
+ /* @__PURE__ */ p(i, {
435
444
  id: "event-source",
436
445
  value: L,
437
446
  onChange: (e) => R(e.target.value),
438
447
  required: !0,
439
448
  maxLength: 120
440
449
  }),
441
- /* @__PURE__ */ f(a, {
450
+ /* @__PURE__ */ p(a, {
442
451
  htmlFor: "source-reference",
443
452
  children: "Source reference (optional)"
444
453
  }),
445
- /* @__PURE__ */ f(i, {
454
+ /* @__PURE__ */ p(i, {
446
455
  id: "source-reference",
447
456
  value: z,
448
457
  onChange: (e) => B(e.target.value),
449
458
  maxLength: 200
450
459
  }),
451
- /* @__PURE__ */ f(a, {
460
+ /* @__PURE__ */ p(a, {
452
461
  htmlFor: "event-location",
453
462
  children: "Location (optional)"
454
463
  }),
455
- /* @__PURE__ */ f(i, {
464
+ /* @__PURE__ */ p(i, {
456
465
  id: "event-location",
457
466
  value: U,
458
467
  onChange: (e) => W(e.target.value),
459
468
  maxLength: 200
460
469
  }),
461
- /* @__PURE__ */ p(a, {
470
+ /* @__PURE__ */ m(a, {
462
471
  htmlFor: "event-evidence",
463
472
  children: ["Evidence note", j === "RETURN_ACCEPTED" && N === "ACTUAL" ? " (required for acceptance)" : " (optional)"]
464
473
  }),
465
- /* @__PURE__ */ f(i, {
474
+ /* @__PURE__ */ p(i, {
466
475
  id: "event-evidence",
467
476
  value: V,
468
477
  onChange: (e) => H(e.target.value),
469
478
  maxLength: 2e3,
470
479
  required: j === "RETURN_ACCEPTED" && N === "ACTUAL"
471
480
  }),
472
- /* @__PURE__ */ f(r, {
481
+ /* @__PURE__ */ p(r, {
473
482
  type: "submit",
474
483
  disabled: G || !L.trim(),
475
484
  children: "Record event"
476
485
  })
477
486
  ]
478
- }), /* @__PURE__ */ p("div", {
487
+ }), n.canUpdate && /* @__PURE__ */ m("div", {
479
488
  className: "space-y-3 border-t pt-4",
480
- children: [/* @__PURE__ */ f("p", {
489
+ children: [/* @__PURE__ */ p("p", {
481
490
  className: "text-sm text-text-secondary",
482
491
  children: "Closure checks the complete recorded history for actual empty return and acceptance. A planned return or delivered shipment is insufficient."
483
- }), /* @__PURE__ */ f(r, {
492
+ }), /* @__PURE__ */ p(r, {
484
493
  variant: "outline",
485
- disabled: G || n.cyclesLoading || n.eventsLoading,
486
- onClick: () => void $(() => n.closeCycle(Q), "Cycle closed after accepted empty return."),
494
+ disabled: G || s.cyclesLoading || s.eventsLoading,
495
+ onClick: () => n.allows("update") && void $(() => s.closeCycle(Q), "Cycle closed after accepted empty return."),
487
496
  children: "Close cycle"
488
497
  })]
489
498
  })] }),
490
- Q?.status === "CLOSED" && /* @__PURE__ */ f("p", { children: "This cycle is closed. Its recorded history remains available." })
499
+ Q?.status === "CLOSED" && /* @__PURE__ */ p("p", { children: "This cycle is closed. Its recorded history remains available." })
491
500
  ]
492
501
  })
493
502
  ]
494
503
  })
495
504
  ]
505
+ }) : /* @__PURE__ */ p(o, {
506
+ title: "Containers",
507
+ subtitle: "Physical equipment, usage cycles and sourced movement history",
508
+ children: /* @__PURE__ */ p("p", {
509
+ role: n.failed ? "alert" : "status",
510
+ children: n.loading ? "Checking shipment permissions…" : n.failed ? "Shipment permissions are unavailable. Reload to retry." : "Shipment read permission is required."
511
+ })
496
512
  });
497
513
  }
498
- function b({ page: e, more: t, disabled: n, onChange: i }) {
499
- return /* @__PURE__ */ p("div", {
514
+ function C({ page: e, more: t, disabled: n, onChange: i }) {
515
+ return /* @__PURE__ */ m("div", {
500
516
  className: "flex items-center justify-between gap-2",
501
517
  children: [
502
- /* @__PURE__ */ f(r, {
518
+ /* @__PURE__ */ p(r, {
503
519
  variant: "outline",
504
520
  disabled: n || e === 0,
505
521
  onClick: () => i(e - 1),
506
522
  children: "Previous"
507
523
  }),
508
- /* @__PURE__ */ p("span", {
524
+ /* @__PURE__ */ m("span", {
509
525
  className: "text-sm",
510
526
  children: ["Page ", e + 1]
511
527
  }),
512
- /* @__PURE__ */ f(r, {
528
+ /* @__PURE__ */ p(r, {
513
529
  variant: "outline",
514
530
  disabled: n || !t,
515
531
  onClick: () => i(e + 1),
@@ -519,4 +535,4 @@ function b({ page: e, more: t, disabled: n, onChange: i }) {
519
535
  });
520
536
  }
521
537
  //#endregion
522
- export { v as default };
538
+ export { b as default };