@burdenoff/microfe-movethewheels 2026.930.4 → 2026.1010.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 (377) hide show
  1. package/dist/MoveTheWheelsRoot.js +177 -102
  2. package/dist/MoveTheWheelsRoutes.js +55 -11
  3. package/dist/_virtual/_rolldown/runtime.js +1 -1
  4. package/dist/components/ContainerEvidencePicker.js +143 -0
  5. package/dist/components/FreeTimeAgreementForm.js +496 -0
  6. package/dist/components/ReturnInstructionForm.js +108 -0
  7. package/dist/components/ReuseControls.js +91 -0
  8. package/dist/components/ReusePermissionForm.js +114 -0
  9. package/dist/components/ReuseProposalForm.js +455 -0
  10. package/dist/components/ReuseSourceFields.js +78 -0
  11. package/dist/components/consolidation/ConsolidationHistory.js +244 -0
  12. package/dist/components/consolidation/ConsolidationLotEditor.js +133 -0
  13. package/dist/components/consolidation/ConsolidationManifestWorkbench.js +143 -0
  14. package/dist/components/consolidation/ConsolidationPlanForm.js +172 -0
  15. package/dist/components/consolidation/ConsolidationPlanWorkbench.js +321 -0
  16. package/dist/components/consolidation/ConsolidationReportForm.js +94 -0
  17. package/dist/components/consolidation/ConsolidationReportsWorkbench.js +195 -0
  18. package/dist/components/consolidation/ConsolidationSummary.js +76 -0
  19. package/dist/components/consolidation/OriginalConsolidationHistory.js +112 -0
  20. package/dist/components/freight-cost/FreightDraftForm.js +213 -0
  21. package/dist/components/freight-cost/FreightFields.js +70 -0
  22. package/dist/components/freight-cost/FreightFxEditor.js +90 -0
  23. package/dist/components/freight-cost/FreightHistory.js +164 -0
  24. package/dist/components/freight-cost/FreightLineEditor.js +191 -0
  25. package/dist/components/freight-cost/FreightScopeEditor.js +72 -0
  26. package/dist/components/freight-cost/FreightTotals.js +66 -0
  27. package/dist/components/logistics-procedure/ProcedureDecisionForm.js +197 -0
  28. package/dist/components/logistics-procedure/ProcedureFields.js +31 -0
  29. package/dist/components/logistics-procedure/ProcedureHistory.js +177 -0
  30. package/dist/components/logistics-procedure/ProcedurePolicyForm.js +227 -0
  31. package/dist/components/logistics-procedure/ProcedurePolicyWorkbench.js +155 -0
  32. package/dist/components/logistics-procedure/ProcedureReviewWorkbench.js +221 -0
  33. package/dist/components/logistics-procedure/ProcedureRunWorkbench.js +190 -0
  34. package/dist/components/logistics-procedure/ProcedureSubjectPicker.js +130 -0
  35. package/dist/components/pending-pick/PendingPickDraft.js +84 -0
  36. package/dist/components/pending-pick/PendingPickHistory.js +113 -0
  37. package/dist/components/pending-pick/PickCapture.js +166 -0
  38. package/dist/components/pending-pick/PickLineSelection.js +111 -0
  39. package/dist/components/stock-binding/StockAssessmentDraft.js +48 -0
  40. package/dist/components/stock-binding/StockAssessmentHistory.js +61 -0
  41. package/dist/components/stock-binding/StockAssessmentSummary.js +199 -0
  42. package/dist/components/stock-binding/StockFactForm.js +232 -0
  43. package/dist/components/stock-observation/StockIssueForm.js +148 -0
  44. package/dist/components/stock-observation/StockIssueHistory.js +116 -0
  45. package/dist/components/stock-observation/StockIssueReadPanel.js +70 -0
  46. package/dist/components/trip-utilization/TripReportForm.js +118 -0
  47. package/dist/components/trip-utilization/TripReportHistory.js +54 -0
  48. package/dist/components/trip-utilization/TripReportSummary.js +216 -0
  49. package/dist/components/trip-utilization/TripSegmentFields.js +166 -0
  50. package/dist/generated/consolidation-operations.d.ts +1060 -0
  51. package/dist/generated/container-condition-operations.d.ts +868 -0
  52. package/dist/generated/container-operations.d.ts +356 -0
  53. package/dist/generated/empty-reuse-operations.d.ts +1578 -0
  54. package/dist/generated/free-time-operations.d.ts +938 -0
  55. package/dist/generated/freight-cost-operations.d.ts +716 -0
  56. package/dist/generated/logistics-procedure-operations.d.ts +938 -0
  57. package/dist/generated/pending-pick-operations.d.ts +1969 -0
  58. package/dist/generated/stock-binding-operations.d.ts +930 -0
  59. package/dist/generated/stock-observation-operations.d.ts +476 -0
  60. package/dist/generated/trip-utilization-operations.d.ts +651 -0
  61. package/dist/generated/wspace-operations.d.ts +143 -50
  62. package/dist/hooks/useConsolidationAction.js +119 -0
  63. package/dist/hooks/useContainerCondition.js +105 -0
  64. package/dist/hooks/useContainerLifecycle.js +192 -0
  65. package/dist/hooks/useEmptyReuseAction.js +45 -0
  66. package/dist/hooks/useFreightRecoveryAction.js +117 -0
  67. package/dist/hooks/useInventory.js +12 -1
  68. package/dist/hooks/useProcedureAction.js +119 -0
  69. package/dist/hooks/useProcedureSelection.js +53 -0
  70. package/dist/hooks/useReuseRecoveryAction.js +116 -0
  71. package/dist/movethewheels/components/ContainerEvidencePicker.d.ts +10 -0
  72. package/dist/movethewheels/components/FreeTimeAgreementForm.d.ts +14 -0
  73. package/dist/movethewheels/components/ReturnInstructionForm.d.ts +8 -0
  74. package/dist/movethewheels/components/ReuseControls.d.ts +42 -0
  75. package/dist/movethewheels/components/ReusePermissionForm.d.ts +9 -0
  76. package/dist/movethewheels/components/ReuseProposalForm.d.ts +11 -0
  77. package/dist/movethewheels/components/ReuseSourceFields.d.ts +9 -0
  78. package/dist/movethewheels/components/consolidation/ConsolidationHistory.d.ts +13 -0
  79. package/dist/movethewheels/components/consolidation/ConsolidationLotEditor.d.ts +6 -0
  80. package/dist/movethewheels/components/consolidation/ConsolidationManifestWorkbench.d.ts +8 -0
  81. package/dist/movethewheels/components/consolidation/ConsolidationPlanForm.d.ts +8 -0
  82. package/dist/movethewheels/components/consolidation/ConsolidationPlanWorkbench.d.ts +5 -0
  83. package/dist/movethewheels/components/consolidation/ConsolidationReportForm.d.ts +9 -0
  84. package/dist/movethewheels/components/consolidation/ConsolidationReportsWorkbench.d.ts +7 -0
  85. package/dist/movethewheels/components/consolidation/ConsolidationSummary.d.ts +6 -0
  86. package/dist/movethewheels/components/consolidation/OriginalConsolidationHistory.d.ts +8 -0
  87. package/dist/movethewheels/components/freight-cost/FreightDraftForm.d.ts +8 -0
  88. package/dist/movethewheels/components/freight-cost/FreightFields.d.ts +23 -0
  89. package/dist/movethewheels/components/freight-cost/FreightFxEditor.d.ts +6 -0
  90. package/dist/movethewheels/components/freight-cost/FreightHistory.d.ts +5 -0
  91. package/dist/movethewheels/components/freight-cost/FreightLineEditor.d.ts +8 -0
  92. package/dist/movethewheels/components/freight-cost/FreightScopeEditor.d.ts +6 -0
  93. package/dist/movethewheels/components/freight-cost/FreightTotals.d.ts +6 -0
  94. package/dist/movethewheels/components/logistics-procedure/ProcedureDecisionForm.d.ts +20 -0
  95. package/dist/movethewheels/components/logistics-procedure/ProcedureFields.d.ts +17 -0
  96. package/dist/movethewheels/components/logistics-procedure/ProcedureHistory.d.ts +7 -0
  97. package/dist/movethewheels/components/logistics-procedure/ProcedurePolicyForm.d.ts +10 -0
  98. package/dist/movethewheels/components/logistics-procedure/ProcedurePolicyWorkbench.d.ts +5 -0
  99. package/dist/movethewheels/components/logistics-procedure/ProcedureReviewWorkbench.d.ts +5 -0
  100. package/dist/movethewheels/components/logistics-procedure/ProcedureRunWorkbench.d.ts +6 -0
  101. package/dist/movethewheels/components/logistics-procedure/ProcedureSubjectPicker.d.ts +7 -0
  102. package/dist/movethewheels/components/pending-pick/PendingPickDraft.d.ts +16 -0
  103. package/dist/movethewheels/components/pending-pick/PendingPickHistory.d.ts +5 -0
  104. package/dist/movethewheels/components/pending-pick/PickCapture.d.ts +6 -0
  105. package/dist/movethewheels/components/pending-pick/PickLineSelection.d.ts +17 -0
  106. package/dist/movethewheels/components/stock-binding/StockAssessmentDraft.d.ts +13 -0
  107. package/dist/movethewheels/components/stock-binding/StockAssessmentHistory.d.ts +18 -0
  108. package/dist/movethewheels/components/stock-binding/StockAssessmentSummary.d.ts +9 -0
  109. package/dist/movethewheels/components/stock-binding/StockFactForm.d.ts +6 -0
  110. package/dist/movethewheels/components/stock-observation/StockIssueForm.d.ts +7 -0
  111. package/dist/movethewheels/components/stock-observation/StockIssueHistory.d.ts +7 -0
  112. package/dist/movethewheels/components/stock-observation/StockIssueReadPanel.d.ts +5 -0
  113. package/dist/movethewheels/components/trip-utilization/TripReportForm.d.ts +6 -0
  114. package/dist/movethewheels/components/trip-utilization/TripReportHistory.d.ts +14 -0
  115. package/dist/movethewheels/components/trip-utilization/TripReportSummary.d.ts +5 -0
  116. package/dist/movethewheels/components/trip-utilization/TripSegmentFields.d.ts +9 -0
  117. package/dist/movethewheels/hooks/useConsolidationAction.d.ts +19 -0
  118. package/dist/movethewheels/hooks/useContainerCondition.d.ts +21 -0
  119. package/dist/movethewheels/hooks/useContainerLifecycle.d.ts +40 -0
  120. package/dist/movethewheels/hooks/useEmptyReuseAction.d.ts +14 -0
  121. package/dist/movethewheels/hooks/useFreightRecoveryAction.d.ts +23 -0
  122. package/dist/movethewheels/hooks/useProcedureAction.d.ts +18 -0
  123. package/dist/movethewheels/hooks/useProcedureSelection.d.ts +51 -0
  124. package/dist/movethewheels/hooks/useReuseRecoveryAction.d.ts +18 -0
  125. package/dist/movethewheels/pages/ConsolidationPage.d.ts +1 -0
  126. package/dist/movethewheels/pages/ContainerConditionPage.d.ts +1 -0
  127. package/dist/movethewheels/pages/ContainersPage.d.ts +2 -0
  128. package/dist/movethewheels/pages/EmptyReusePage.d.ts +1 -0
  129. package/dist/movethewheels/pages/FreeTimePage.d.ts +1 -0
  130. package/dist/movethewheels/pages/FreightEstimatePage.d.ts +1 -0
  131. package/dist/movethewheels/pages/LogisticsProceduresPage.d.ts +1 -0
  132. package/dist/movethewheels/pages/PendingPickPage.d.ts +1 -0
  133. package/dist/movethewheels/pages/StockBindingPage.d.ts +1 -0
  134. package/dist/movethewheels/pages/StockObservationsPage.d.ts +1 -0
  135. package/dist/movethewheels/pages/TripUtilizationPage.d.ts +1 -0
  136. package/dist/movethewheels/utils/consolidationHistoryTarget.d.ts +12 -0
  137. package/dist/movethewheels/utils/consolidationInput.d.ts +15 -0
  138. package/dist/movethewheels/utils/consolidationLot.d.ts +3 -0
  139. package/dist/movethewheels/utils/consolidationPins.d.ts +20 -0
  140. package/dist/movethewheels/utils/consolidationRecovery.d.ts +5 -0
  141. package/dist/movethewheels/utils/consolidationReportHead.d.ts +5 -0
  142. package/dist/movethewheels/utils/freeTimeDate.d.ts +1 -0
  143. package/dist/movethewheels/utils/freightAcknowledgement.d.ts +2 -0
  144. package/dist/movethewheels/utils/freightDraft.d.ts +36 -0
  145. package/dist/movethewheels/utils/freightRecovery.d.ts +5 -0
  146. package/dist/movethewheels/utils/graphqlClient.d.ts +2 -1
  147. package/dist/movethewheels/utils/pendingPickDraft.d.ts +8 -0
  148. package/dist/movethewheels/utils/procedureInput.d.ts +18 -0
  149. package/dist/movethewheels/utils/procedureRecovery.d.ts +5 -0
  150. package/dist/movethewheels/utils/reuseAttempt.d.ts +7 -0
  151. package/dist/movethewheels/utils/reuseForm.d.ts +6 -0
  152. package/dist/movethewheels/utils/reuseRecovery.d.ts +26 -0
  153. package/dist/movethewheels/utils/stockBindingForm.d.ts +23 -0
  154. package/dist/movethewheels/utils/stockBindingLabels.d.ts +10 -0
  155. package/dist/movethewheels/utils/stockObservationForm.d.ts +5 -0
  156. package/dist/movethewheels/utils/tripDraftContext.d.ts +25 -0
  157. package/dist/movethewheels/utils/tripUtilizationForm.d.ts +6 -0
  158. package/dist/node_modules/@react-leaflet/core/lib/component.js +5 -5
  159. package/dist/node_modules/fast-equals/dist/es/index.js +87 -74
  160. package/dist/node_modules/leaflet/dist/leaflet-src.js +8 -5
  161. package/dist/node_modules/lodash/_Stack.js +2 -1
  162. package/dist/node_modules/lucide-react/dist/esm/icons/clipboard-list.js +35 -0
  163. package/dist/node_modules/lucide-react/dist/esm/icons/repeat-2.js +22 -0
  164. package/dist/node_modules/react-leaflet/lib/MapContainer.js +3 -3
  165. package/dist/node_modules/react-smooth/es6/Animate.js +2 -2
  166. package/dist/node_modules/recharts/es6/cartesian/Area.js +13 -13
  167. package/dist/node_modules/recharts/es6/cartesian/Bar.js +9 -9
  168. package/dist/node_modules/recharts/es6/cartesian/Brush.js +12 -12
  169. package/dist/node_modules/recharts/es6/cartesian/CartesianAxis.js +7 -7
  170. package/dist/node_modules/recharts/es6/cartesian/CartesianGrid.js +13 -13
  171. package/dist/node_modules/recharts/es6/cartesian/ErrorBar.js +4 -4
  172. package/dist/node_modules/recharts/es6/cartesian/Line.js +10 -10
  173. package/dist/node_modules/recharts/es6/cartesian/ReferenceArea.js +3 -3
  174. package/dist/node_modules/recharts/es6/cartesian/ReferenceDot.js +3 -3
  175. package/dist/node_modules/recharts/es6/cartesian/ReferenceLine.js +4 -4
  176. package/dist/node_modules/recharts/es6/cartesian/XAxis.js +3 -3
  177. package/dist/node_modules/recharts/es6/cartesian/YAxis.js +3 -3
  178. package/dist/node_modules/recharts/es6/chart/AccessibilityManager.js +1 -1
  179. package/dist/node_modules/recharts/es6/chart/generateCategoricalChart.js +22 -22
  180. package/dist/node_modules/recharts/es6/component/Cursor.js +1 -1
  181. package/dist/node_modules/recharts/es6/component/DefaultLegendContent.js +11 -11
  182. package/dist/node_modules/recharts/es6/component/DefaultTooltipContent.js +6 -6
  183. package/dist/node_modules/recharts/es6/component/Label.js +14 -14
  184. package/dist/node_modules/recharts/es6/component/LabelList.js +6 -6
  185. package/dist/node_modules/recharts/es6/component/Legend.js +5 -5
  186. package/dist/node_modules/recharts/es6/component/ResponsiveContainer.js +3 -3
  187. package/dist/node_modules/recharts/es6/component/Text.js +2 -2
  188. package/dist/node_modules/recharts/es6/component/Tooltip.js +3 -3
  189. package/dist/node_modules/recharts/es6/component/TooltipBoundingBox.js +2 -2
  190. package/dist/node_modules/recharts/es6/container/Layer.js +2 -2
  191. package/dist/node_modules/recharts/es6/container/Surface.js +2 -2
  192. package/dist/node_modules/recharts/es6/context/chartLayoutContext.js +2 -2
  193. package/dist/node_modules/recharts/es6/polar/Pie.js +13 -13
  194. package/dist/node_modules/recharts/es6/polar/PolarAngleAxis.js +8 -8
  195. package/dist/node_modules/recharts/es6/polar/PolarRadiusAxis.js +6 -6
  196. package/dist/node_modules/recharts/es6/shape/Cross.js +1 -1
  197. package/dist/node_modules/recharts/es6/shape/Curve.js +1 -1
  198. package/dist/node_modules/recharts/es6/shape/Dot.js +1 -1
  199. package/dist/node_modules/recharts/es6/shape/Polygon.js +4 -4
  200. package/dist/node_modules/recharts/es6/shape/Rectangle.js +4 -4
  201. package/dist/node_modules/recharts/es6/shape/Sector.js +1 -1
  202. package/dist/node_modules/recharts/es6/shape/Symbols.js +1 -1
  203. package/dist/node_modules/recharts/es6/shape/Trapezoid.js +4 -4
  204. package/dist/node_modules/recharts/es6/util/ActiveShapeUtils.js +9 -9
  205. package/dist/node_modules/recharts/es6/util/BarUtils.js +1 -1
  206. package/dist/node_modules/recharts/es6/util/CartesianUtils.js +1 -1
  207. package/dist/node_modules/recharts/es6/util/PolarUtils.js +1 -1
  208. package/dist/node_modules/recharts/es6/util/ReactUtils.js +2 -2
  209. package/dist/node_modules/recharts/es6/util/ReduceCSSCalc.js +1 -1
  210. package/dist/node_modules/recharts/es6/util/types.js +1 -1
  211. package/dist/node_modules/{react-is → recharts/node_modules/react-is}/cjs/react-is.development.js +2 -2
  212. package/dist/node_modules/{react-is → recharts/node_modules/react-is}/cjs/react-is.production.min.js +2 -2
  213. package/dist/node_modules/{react-is → recharts/node_modules/react-is}/index.js +2 -2
  214. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +97 -18
  215. package/dist/node_modules/zustand/esm/middleware.js +2 -2
  216. package/dist/pages/ConsolidationPage.js +76 -0
  217. package/dist/pages/ContainerConditionPage.js +972 -0
  218. package/dist/pages/ContainersPage.js +522 -0
  219. package/dist/pages/EmptyReusePage.js +777 -0
  220. package/dist/pages/FreeTimePage.js +657 -0
  221. package/dist/pages/FreightEstimatePage.js +284 -0
  222. package/dist/pages/InventoryPage.js +77 -73
  223. package/dist/pages/LogisticsProceduresPage.js +100 -0
  224. package/dist/pages/PendingPickPage.js +155 -0
  225. package/dist/pages/StockBindingPage.js +236 -0
  226. package/dist/pages/StockObservationsPage.js +168 -0
  227. package/dist/pages/TripUtilizationPage.js +227 -0
  228. package/dist/src/generated/consolidation-operations.js +505 -0
  229. package/dist/src/generated/container-condition-operations.js +208 -0
  230. package/dist/src/generated/container-operations.js +101 -0
  231. package/dist/src/generated/empty-reuse-operations.js +749 -0
  232. package/dist/src/generated/free-time-operations.js +235 -0
  233. package/dist/src/generated/freight-cost-operations.js +325 -0
  234. package/dist/src/generated/logistics-procedure-operations.js +362 -0
  235. package/dist/src/generated/pending-pick-operations.js +1128 -0
  236. package/dist/src/generated/stock-binding-operations.js +175 -0
  237. package/dist/src/generated/stock-observation-operations.js +93 -0
  238. package/dist/src/generated/trip-utilization-operations.js +140 -0
  239. package/dist/src/generated/wspace-operations.js +708 -0
  240. package/dist/utils/consolidationHistoryTarget.js +27 -0
  241. package/dist/utils/consolidationInput.js +21 -0
  242. package/dist/utils/consolidationLot.js +29 -0
  243. package/dist/utils/consolidationPins.js +13 -0
  244. package/dist/utils/consolidationRecovery.js +40 -0
  245. package/dist/utils/consolidationReportHead.js +18 -0
  246. package/dist/utils/freeTimeDate.js +26 -0
  247. package/dist/utils/freightAcknowledgement.js +8 -0
  248. package/dist/utils/freightDraft.js +125 -0
  249. package/dist/utils/freightRecovery.js +36 -0
  250. package/dist/utils/graphqlClient.js +28 -28
  251. package/dist/utils/pendingPickDraft.js +46 -0
  252. package/dist/utils/procedureInput.js +43 -0
  253. package/dist/utils/procedureRecovery.js +42 -0
  254. package/dist/utils/reuseAttempt.js +20 -0
  255. package/dist/utils/reuseForm.js +25 -0
  256. package/dist/utils/reuseRecovery.js +71 -0
  257. package/dist/utils/stockBindingForm.js +142 -0
  258. package/dist/utils/stockBindingLabels.js +23 -0
  259. package/dist/utils/stockObservationForm.js +55 -0
  260. package/dist/utils/tripDraftContext.js +19 -0
  261. package/dist/utils/tripUtilizationForm.js +60 -0
  262. package/package.json +19 -5
  263. package/src/generated/consolidation-operations.ts +1138 -0
  264. package/src/generated/container-condition-operations.ts +771 -0
  265. package/src/generated/container-operations.ts +376 -0
  266. package/src/generated/empty-reuse-operations.ts +1648 -0
  267. package/src/generated/free-time-operations.ts +814 -0
  268. package/src/generated/freight-cost-operations.ts +753 -0
  269. package/src/generated/logistics-procedure-operations.ts +1047 -0
  270. package/src/generated/pending-pick-operations.ts +1508 -0
  271. package/src/generated/stock-binding-operations.ts +631 -0
  272. package/src/generated/stock-observation-operations.ts +373 -0
  273. package/src/generated/trip-utilization-operations.ts +500 -0
  274. package/src/generated/wspace-operations.ts +116 -0
  275. package/src/movethewheels/MoveTheWheelsRoot.tsx +79 -0
  276. package/src/movethewheels/MoveTheWheelsRoutes.tsx +22 -0
  277. package/src/movethewheels/components/ContainerEvidencePicker.tsx +146 -0
  278. package/src/movethewheels/components/FreeTimeAgreementForm.tsx +483 -0
  279. package/src/movethewheels/components/ReturnInstructionForm.tsx +102 -0
  280. package/src/movethewheels/components/ReuseControls.tsx +138 -0
  281. package/src/movethewheels/components/ReusePermissionForm.tsx +123 -0
  282. package/src/movethewheels/components/ReuseProposalForm.tsx +484 -0
  283. package/src/movethewheels/components/ReuseSourceFields.tsx +80 -0
  284. package/src/movethewheels/components/consolidation/ConsolidationHistory.tsx +159 -0
  285. package/src/movethewheels/components/consolidation/ConsolidationLotEditor.tsx +144 -0
  286. package/src/movethewheels/components/consolidation/ConsolidationManifestWorkbench.tsx +168 -0
  287. package/src/movethewheels/components/consolidation/ConsolidationPlanForm.tsx +185 -0
  288. package/src/movethewheels/components/consolidation/ConsolidationPlanWorkbench.tsx +395 -0
  289. package/src/movethewheels/components/consolidation/ConsolidationReportForm.tsx +124 -0
  290. package/src/movethewheels/components/consolidation/ConsolidationReportsWorkbench.tsx +233 -0
  291. package/src/movethewheels/components/consolidation/ConsolidationSummary.tsx +84 -0
  292. package/src/movethewheels/components/consolidation/OriginalConsolidationHistory.tsx +133 -0
  293. package/src/movethewheels/components/freight-cost/FreightDraftForm.tsx +224 -0
  294. package/src/movethewheels/components/freight-cost/FreightFields.tsx +91 -0
  295. package/src/movethewheels/components/freight-cost/FreightFxEditor.tsx +98 -0
  296. package/src/movethewheels/components/freight-cost/FreightHistory.tsx +91 -0
  297. package/src/movethewheels/components/freight-cost/FreightLineEditor.tsx +192 -0
  298. package/src/movethewheels/components/freight-cost/FreightScopeEditor.tsx +64 -0
  299. package/src/movethewheels/components/freight-cost/FreightTotals.tsx +68 -0
  300. package/src/movethewheels/components/logistics-procedure/ProcedureDecisionForm.tsx +204 -0
  301. package/src/movethewheels/components/logistics-procedure/ProcedureFields.tsx +43 -0
  302. package/src/movethewheels/components/logistics-procedure/ProcedureHistory.tsx +102 -0
  303. package/src/movethewheels/components/logistics-procedure/ProcedurePolicyForm.tsx +226 -0
  304. package/src/movethewheels/components/logistics-procedure/ProcedurePolicyWorkbench.tsx +174 -0
  305. package/src/movethewheels/components/logistics-procedure/ProcedureReviewWorkbench.tsx +278 -0
  306. package/src/movethewheels/components/logistics-procedure/ProcedureRunWorkbench.tsx +292 -0
  307. package/src/movethewheels/components/logistics-procedure/ProcedureSubjectPicker.tsx +111 -0
  308. package/src/movethewheels/components/pending-pick/PendingPickDraft.tsx +82 -0
  309. package/src/movethewheels/components/pending-pick/PendingPickHistory.tsx +93 -0
  310. package/src/movethewheels/components/pending-pick/PickCapture.tsx +70 -0
  311. package/src/movethewheels/components/pending-pick/PickLineSelection.tsx +130 -0
  312. package/src/movethewheels/components/stock-binding/StockAssessmentDraft.tsx +52 -0
  313. package/src/movethewheels/components/stock-binding/StockAssessmentHistory.tsx +56 -0
  314. package/src/movethewheels/components/stock-binding/StockAssessmentSummary.tsx +108 -0
  315. package/src/movethewheels/components/stock-binding/StockFactForm.tsx +186 -0
  316. package/src/movethewheels/components/stock-observation/StockIssueForm.tsx +103 -0
  317. package/src/movethewheels/components/stock-observation/StockIssueHistory.tsx +96 -0
  318. package/src/movethewheels/components/stock-observation/StockIssueReadPanel.tsx +72 -0
  319. package/src/movethewheels/components/trip-utilization/TripReportForm.tsx +116 -0
  320. package/src/movethewheels/components/trip-utilization/TripReportHistory.tsx +51 -0
  321. package/src/movethewheels/components/trip-utilization/TripReportSummary.tsx +127 -0
  322. package/src/movethewheels/components/trip-utilization/TripSegmentFields.tsx +118 -0
  323. package/src/movethewheels/hooks/useConsolidationAction.ts +196 -0
  324. package/src/movethewheels/hooks/useContainerCondition.ts +129 -0
  325. package/src/movethewheels/hooks/useContainerLifecycle.ts +291 -0
  326. package/src/movethewheels/hooks/useEmptyReuseAction.ts +72 -0
  327. package/src/movethewheels/hooks/useFreightRecoveryAction.ts +201 -0
  328. package/src/movethewheels/hooks/useInventory.ts +2 -20
  329. package/src/movethewheels/hooks/useProcedureAction.ts +196 -0
  330. package/src/movethewheels/hooks/useProcedureSelection.ts +75 -0
  331. package/src/movethewheels/hooks/useReuseRecoveryAction.ts +192 -0
  332. package/src/movethewheels/pages/ConsolidationPage.tsx +70 -0
  333. package/src/movethewheels/pages/ContainerConditionPage.tsx +959 -0
  334. package/src/movethewheels/pages/ContainersPage.tsx +490 -0
  335. package/src/movethewheels/pages/EmptyReusePage.tsx +823 -0
  336. package/src/movethewheels/pages/FreeTimePage.tsx +720 -0
  337. package/src/movethewheels/pages/FreightEstimatePage.tsx +353 -0
  338. package/src/movethewheels/pages/InventoryPage.tsx +16 -2
  339. package/src/movethewheels/pages/LogisticsProceduresPage.tsx +86 -0
  340. package/src/movethewheels/pages/PendingPickPage.tsx +226 -0
  341. package/src/movethewheels/pages/StockBindingPage.tsx +299 -0
  342. package/src/movethewheels/pages/StockObservationsPage.tsx +181 -0
  343. package/src/movethewheels/pages/TripUtilizationPage.tsx +315 -0
  344. package/src/movethewheels/utils/consolidationHistoryTarget.ts +39 -0
  345. package/src/movethewheels/utils/consolidationInput.ts +70 -0
  346. package/src/movethewheels/utils/consolidationLot.ts +24 -0
  347. package/src/movethewheels/utils/consolidationPins.ts +52 -0
  348. package/src/movethewheels/utils/consolidationRecovery.ts +88 -0
  349. package/src/movethewheels/utils/consolidationReportHead.ts +29 -0
  350. package/src/movethewheels/utils/freeTimeDate.ts +31 -0
  351. package/src/movethewheels/utils/freightAcknowledgement.ts +31 -0
  352. package/src/movethewheels/utils/freightDraft.ts +170 -0
  353. package/src/movethewheels/utils/freightRecovery.ts +79 -0
  354. package/src/movethewheels/utils/graphqlClient.ts +14 -5
  355. package/src/movethewheels/utils/pendingPickDraft.ts +61 -0
  356. package/src/movethewheels/utils/procedureInput.ts +98 -0
  357. package/src/movethewheels/utils/procedureRecovery.ts +92 -0
  358. package/src/movethewheels/utils/reuseAttempt.ts +29 -0
  359. package/src/movethewheels/utils/reuseForm.ts +30 -0
  360. package/src/movethewheels/utils/reuseRecovery.ts +151 -0
  361. package/src/movethewheels/utils/stockBindingForm.ts +209 -0
  362. package/src/movethewheels/utils/stockBindingLabels.ts +41 -0
  363. package/src/movethewheels/utils/stockObservationForm.ts +73 -0
  364. package/src/movethewheels/utils/tripDraftContext.ts +61 -0
  365. package/src/movethewheels/utils/tripUtilizationForm.ts +105 -0
  366. package/src/operations/condition/container-condition.graphql +41 -0
  367. package/src/operations/consolidation/consolidation.graphql +490 -0
  368. package/src/operations/container/container-lifecycle.graphql +80 -0
  369. package/src/operations/empty-reuse/empty-reuse.graphql +737 -0
  370. package/src/operations/free-time/free-time.graphql +47 -0
  371. package/src/operations/freight-cost/freight.graphql +6 -0
  372. package/src/operations/logistics-procedure/procedure.graphql +15 -0
  373. package/src/operations/pending-pick/pending-pick.graphql +1122 -0
  374. package/src/operations/stock-binding/stock-binding.graphql +160 -0
  375. package/src/operations/stock-observation/stock-observation.graphql +20 -0
  376. package/src/operations/trip-utilization/trip-utilization.graphql +126 -0
  377. package/src/operations/wspace/container-evidence.graphql +6 -0
@@ -0,0 +1,720 @@
1
+ import { useState, type ReactNode } from 'react';
2
+ import { Clock } from 'lucide-react';
3
+
4
+ import { PageLayout } from '../components/PageLayout';
5
+ import { Button, Input } from '../components/ui';
6
+ import {
7
+ ContainerEvidencePicker,
8
+ type SelectedEvidence,
9
+ } from '../components/ContainerEvidencePicker';
10
+ import { FreeTimeAgreementForm } from '../components/FreeTimeAgreementForm';
11
+ import { freeTimeIso } from '../utils/freeTimeDate';
12
+ import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
13
+ import { useConditionAction, useConditionQuery } from '../hooks/useContainerCondition';
14
+ import {
15
+ FreeContainersDocument,
16
+ FreeCyclesDocument,
17
+ FreeEventsDocument,
18
+ FreeClocksDocument,
19
+ FreeAgreementsDocument,
20
+ FreeExtensionsDocument,
21
+ FreeExposureDocument,
22
+ OpenFreeClockDocument,
23
+ RecordFreeAgreementDocument,
24
+ RequestFreeExtensionDocument,
25
+ DecideFreeExtensionDocument,
26
+ type FreeContainersQuery,
27
+ type FreeCyclesQuery,
28
+ type FreeEventsQuery,
29
+ type FreeClocksQuery,
30
+ type FreeAgreementsQuery,
31
+ type FreeExtensionsQuery,
32
+ type FreeExposureQuery,
33
+ } from '../../generated/free-time-operations';
34
+
35
+ const card = 'space-y-4 rounded-xl border bg-bg-surface p-5';
36
+ const select = 'mt-1 w-full rounded-md border bg-bg-surface p-2 text-sm';
37
+ const pageSize = 25;
38
+ interface PageInfo {
39
+ total: number;
40
+ offset: number;
41
+ hasMore: boolean;
42
+ nextOffset?: number | null;
43
+ }
44
+ function Pager({
45
+ page,
46
+ offset,
47
+ setOffset,
48
+ busy,
49
+ }: {
50
+ page?: PageInfo;
51
+ offset: number;
52
+ setOffset: (offset: number) => void;
53
+ busy: boolean;
54
+ }) {
55
+ return (
56
+ <div className="flex flex-wrap items-center gap-2">
57
+ <Button
58
+ type="button"
59
+ variant="outline"
60
+ disabled={busy || offset === 0}
61
+ onClick={() => setOffset(Math.max(0, offset - pageSize))}
62
+ >
63
+ Previous
64
+ </Button>
65
+ <span className="text-sm">
66
+ {page
67
+ ? `${page.total} records; page ${Math.floor(offset / pageSize) + 1}`
68
+ : 'Waiting for records'}
69
+ </span>
70
+ <Button
71
+ type="button"
72
+ variant="outline"
73
+ disabled={busy || !page?.hasMore || page.nextOffset == null || page.nextOffset > 10000}
74
+ onClick={() => {
75
+ if (page?.nextOffset != null) setOffset(page.nextOffset);
76
+ }}
77
+ >
78
+ Next
79
+ </Button>
80
+ </div>
81
+ );
82
+ }
83
+ function RecordState({
84
+ error,
85
+ loading,
86
+ children,
87
+ }: {
88
+ error: string | null;
89
+ loading: boolean;
90
+ children: ReactNode;
91
+ }) {
92
+ return (
93
+ <>
94
+ {error && <p role="alert">{error}</p>}
95
+ {loading && <p role="status">Loading records…</p>}
96
+ {children}
97
+ </>
98
+ );
99
+ }
100
+ export default function FreeTimePage() {
101
+ const { workspaceId, tenantId, currentUser, apiGatewayUrl } = useMoveTheWheels();
102
+ return (
103
+ <PageLayout
104
+ title="Free time and extension decisions"
105
+ subtitle="Separate sourced commercial obligations, actual events and recorded counterparty decisions."
106
+ icon={<Clock aria-hidden="true" />}
107
+ >
108
+ <Workbench key={`${workspaceId}:${tenantId}:${currentUser?.id}:${apiGatewayUrl}`} />
109
+ </PageLayout>
110
+ );
111
+ }
112
+ function Workbench() {
113
+ const [containerId, setContainerId] = useState('');
114
+ const [cycleId, setCycleId] = useState('');
115
+ const [clockId, setClockId] = useState('');
116
+ const [containerOffset, setContainerOffset] = useState(0);
117
+ const [cycleOffset, setCycleOffset] = useState(0);
118
+ const [eventOffset, setEventOffset] = useState(0);
119
+ const [clockOffset, setClockOffset] = useState(0);
120
+ const [agreementOffset, setAgreementOffset] = useState(0);
121
+ const [extensionOffset, setExtensionOffset] = useState(0);
122
+ const [action, setAction] = useState<'open' | 'correct' | 'request' | 'decision'>('open');
123
+ const [chargeKind, setChargeKind] = useState<'DEMURRAGE' | 'DETENTION' | 'TERMINAL_STORAGE'>(
124
+ 'DEMURRAGE'
125
+ );
126
+ const [obligation, setObligation] = useState('');
127
+ const [asOf, setAsOf] = useState(new Date().toISOString());
128
+ const [evaluation, setEvaluation] = useState(asOf);
129
+ const [validation, setValidation] = useState<string | null>(null);
130
+ const [evidence, setEvidence] = useState<SelectedEvidence[]>([]);
131
+ const [extensionId, setExtensionId] = useState('');
132
+ const [decisionKind, setDecisionKind] = useState<'ACCEPTED' | 'REJECTED' | 'EXPIRED'>('ACCEPTED');
133
+ const mutations = useConditionAction();
134
+ const containers = useConditionQuery<FreeContainersQuery>(FreeContainersDocument, {
135
+ pagination: { limit: pageSize, offset: containerOffset },
136
+ });
137
+ const cycles = useConditionQuery<FreeCyclesQuery>(
138
+ FreeCyclesDocument,
139
+ containerId ? { containerId, pagination: { limit: pageSize, offset: cycleOffset } } : null
140
+ );
141
+ const events = useConditionQuery<FreeEventsQuery>(
142
+ FreeEventsDocument,
143
+ cycleId ? { cycleId, pagination: { limit: pageSize, offset: eventOffset } } : null,
144
+ mutations.revision
145
+ );
146
+ const clocks = useConditionQuery<FreeClocksQuery>(
147
+ FreeClocksDocument,
148
+ cycleId ? { cycleId, pagination: { limit: pageSize, offset: clockOffset } } : null,
149
+ mutations.revision
150
+ );
151
+ const agreements = useConditionQuery<FreeAgreementsQuery>(
152
+ FreeAgreementsDocument,
153
+ clockId ? { clockId, pagination: { limit: pageSize, offset: agreementOffset } } : null,
154
+ mutations.revision
155
+ );
156
+ const currentAgreement = useConditionQuery<FreeAgreementsQuery>(
157
+ FreeAgreementsDocument,
158
+ clockId ? { clockId, pagination: { limit: 1, offset: 0 } } : null,
159
+ mutations.revision
160
+ );
161
+ const extensions = useConditionQuery<FreeExtensionsQuery>(
162
+ FreeExtensionsDocument,
163
+ clockId ? { clockId, pagination: { limit: pageSize, offset: extensionOffset } } : null,
164
+ mutations.revision
165
+ );
166
+ const exposure = useConditionQuery<FreeExposureQuery>(
167
+ FreeExposureDocument,
168
+ clockId ? { clockId, asOf: evaluation } : null,
169
+ mutations.revision
170
+ );
171
+ const clock = clocks.data?.mtwFreeTimeClockPage.items.find((item) => item.id === clockId);
172
+ const current = currentAgreement.data?.mtwFreeTimeAgreementPage.items[0];
173
+ const pending =
174
+ extensions.data?.mtwFreeTimeExtensionPage.items.filter((item) => !item.decision) ?? [];
175
+ const resetClock = () => {
176
+ setClockId('');
177
+ setAgreementOffset(0);
178
+ setExtensionOffset(0);
179
+ setExtensionId('');
180
+ setEvidence([]);
181
+ setAction('open');
182
+ setObligation('');
183
+ setValidation(null);
184
+ mutations.resetFeedback();
185
+ };
186
+ const estimate = exposure.data?.mtwFreeTimeExposure;
187
+ const evaluatedAgreement =
188
+ agreements.data?.mtwFreeTimeAgreementPage.items.find(
189
+ (item) => item.id === estimate?.agreementId
190
+ ) ?? (current?.id === estimate?.agreementId ? current : undefined);
191
+ const refs = () => {
192
+ if (!evidence.length) throw new Error('Select exact decision/request evidence versions.');
193
+ return evidence.map(({ fileId, versionId }) => ({ fileId, versionId }));
194
+ };
195
+ return (
196
+ <div className="space-y-6">
197
+ <p className="rounded-lg border p-4 text-sm">
198
+ These are estimates under recorded source terms. Separate storage, demurrage and detention
199
+ may overlap commercially; they are not automatically merged or summed across currencies. An
200
+ extension changes the clock only after external acceptance is recorded. This service does
201
+ not negotiate or certify acceptance.
202
+ </p>
203
+ <section className={card} aria-label="Container and commercial obligation">
204
+ <label className="block">
205
+ Container
206
+ <select
207
+ className={select}
208
+ value={containerId}
209
+ disabled={mutations.busy}
210
+ onChange={(event) => {
211
+ setContainerId(event.target.value);
212
+ setCycleId('');
213
+ setCycleOffset(0);
214
+ setEventOffset(0);
215
+ setClockOffset(0);
216
+ resetClock();
217
+ }}
218
+ >
219
+ <option value="">Choose container</option>
220
+ {containers.data?.mtwContainerPage.items.map((item) => (
221
+ <option key={item.id} value={item.id}>
222
+ {item.containerNumber}
223
+ </option>
224
+ ))}
225
+ </select>
226
+ </label>
227
+ <RecordState error={containers.error} loading={containers.loading}>
228
+ <Pager
229
+ page={containers.data?.mtwContainerPage}
230
+ offset={containerOffset}
231
+ busy={containers.loading || mutations.busy}
232
+ setOffset={(offset) => {
233
+ setContainerOffset(offset);
234
+ setContainerId('');
235
+ setCycleId('');
236
+ resetClock();
237
+ }}
238
+ />
239
+ </RecordState>
240
+ <label className="block">
241
+ Usage cycle
242
+ <select
243
+ className={select}
244
+ value={cycleId}
245
+ disabled={!containerId || mutations.busy}
246
+ onChange={(event) => {
247
+ setCycleId(event.target.value);
248
+ setEventOffset(0);
249
+ setClockOffset(0);
250
+ resetClock();
251
+ }}
252
+ >
253
+ <option value="">Choose cycle</option>
254
+ {cycles.data?.mtwContainerCyclePage.items.map((item) => (
255
+ <option key={item.id} value={item.id}>
256
+ {item.bookingReference ?? item.id} — {item.status} — {item.openedAt}
257
+ </option>
258
+ ))}
259
+ </select>
260
+ </label>
261
+ <RecordState error={cycles.error} loading={cycles.loading}>
262
+ <Pager
263
+ page={cycles.data?.mtwContainerCyclePage}
264
+ offset={cycleOffset}
265
+ busy={cycles.loading || mutations.busy}
266
+ setOffset={(offset) => {
267
+ setCycleOffset(offset);
268
+ setCycleId('');
269
+ resetClock();
270
+ }}
271
+ />
272
+ </RecordState>
273
+ <label className="block">
274
+ Commercial obligation
275
+ <select
276
+ className={select}
277
+ value={clockId}
278
+ disabled={!cycleId || mutations.busy}
279
+ onChange={(event) => {
280
+ setClockId(event.target.value);
281
+ setAgreementOffset(0);
282
+ setExtensionOffset(0);
283
+ setExtensionId('');
284
+ setEvidence([]);
285
+ setAction('correct');
286
+ setValidation(null);
287
+ mutations.resetFeedback();
288
+ }}
289
+ >
290
+ <option value="">New obligation / choose existing</option>
291
+ {clocks.data?.mtwFreeTimeClockPage.items.map((item) => (
292
+ <option key={item.id} value={item.id}>
293
+ {item.chargeKind} — {item.obligationReference}
294
+ </option>
295
+ ))}
296
+ </select>
297
+ </label>
298
+ <RecordState error={clocks.error} loading={clocks.loading}>
299
+ <Pager
300
+ page={clocks.data?.mtwFreeTimeClockPage}
301
+ offset={clockOffset}
302
+ busy={clocks.loading || mutations.busy}
303
+ setOffset={(offset) => {
304
+ setClockOffset(offset);
305
+ resetClock();
306
+ }}
307
+ />
308
+ </RecordState>
309
+ </section>
310
+ {clockId && (
311
+ <section className={card} aria-label="Recorded exposure">
312
+ <h2 className="text-lg font-semibold">Recorded exposure</h2>
313
+ <form
314
+ className="flex flex-wrap items-end gap-3"
315
+ onSubmit={(event) => {
316
+ event.preventDefault();
317
+ try {
318
+ setEvaluation(freeTimeIso(asOf));
319
+ setValidation(null);
320
+ } catch (failure) {
321
+ setValidation(
322
+ failure instanceof Error ? failure.message : 'Invalid evaluation time'
323
+ );
324
+ }
325
+ }}
326
+ >
327
+ <label>
328
+ Evaluate at time with timezone
329
+ <Input value={asOf} onChange={(event) => setAsOf(event.target.value)} required />
330
+ </label>
331
+ <Button type="submit">Estimate exposure</Button>
332
+ </form>
333
+ <RecordState error={exposure.error} loading={exposure.loading}>
334
+ {estimate && (
335
+ <>
336
+ <p>
337
+ Evaluation agreement: {estimate.agreementId ?? 'Unknown'}.{' '}
338
+ {evaluatedAgreement
339
+ ? `${evaluatedAgreement.payer} → ${evaluatedAgreement.payee}. Source: ${evaluatedAgreement.sourceReference}. Timezone: ${evaluatedAgreement.terms?.timeZone ?? 'Pricing terms unavailable'}.`
340
+ : 'See the matching history version for source and parties.'}
341
+ </p>
342
+ <p>
343
+ {estimate.status === 'ESTIMATED'
344
+ ? 'Estimated under recorded terms'
345
+ : `Cannot estimate: ${estimate.reason ?? 'Incomplete data'}`}
346
+ </p>
347
+ <p>
348
+ Exact deadline: {estimate.freeUntil ?? 'Unknown'}
349
+ {estimate.localLastFreeDate
350
+ ? `; local last-free date ${estimate.localLastFreeDate}`
351
+ : ''}
352
+ </p>
353
+ {estimate.status === 'ESTIMATED' && (
354
+ <p>
355
+ {estimate.chargedDays} charged dates;{' '}
356
+ {typeof estimate.amountMinorUnits === 'number' &&
357
+ typeof estimate.minorUnitDigits === 'number'
358
+ ? `${(estimate.amountMinorUnits / 10 ** estimate.minorUnitDigits).toFixed(estimate.minorUnitDigits)} ${estimate.currency}`
359
+ : 'Price data unavailable'}
360
+ . Deadline source: {estimate.deadlineSource}.
361
+ </p>
362
+ )}
363
+ <p className="text-sm">
364
+ The exact timestamp takes precedence over a date label. Recalculated using
365
+ versions effective at evaluation time; this does not reconstruct what was known
366
+ then. Prospective segmented tariffs are unsupported.
367
+ </p>
368
+ </>
369
+ )}
370
+ </RecordState>
371
+ </section>
372
+ )}
373
+ {cycleId && (
374
+ <section className={card} aria-label="Record contractual change">
375
+ <h2 className="text-lg font-semibold">Record contractual change</h2>
376
+ <label className="block">
377
+ Free-time action
378
+ <select
379
+ className={select}
380
+ value={action}
381
+ disabled={mutations.busy}
382
+ onChange={(event) => {
383
+ const value = (['open', 'correct', 'request', 'decision'] as const).find(
384
+ (item) => item === event.target.value
385
+ );
386
+ if (value) {
387
+ setAction(value);
388
+ mutations.resetFeedback();
389
+ setExtensionId('');
390
+ setEvidence([]);
391
+ setValidation(null);
392
+ }
393
+ }}
394
+ >
395
+ <option value="open">Open a separate sourced obligation</option>
396
+ <option value="correct" disabled={!clock}>
397
+ Correct agreement / actual event binding
398
+ </option>
399
+ <option value="request" disabled={!clock}>
400
+ Record extension request
401
+ </option>
402
+ <option value="decision" disabled={!clock}>
403
+ Record external decision
404
+ </option>
405
+ </select>
406
+ </label>
407
+ {(action === 'open' || action === 'correct') && (
408
+ <>
409
+ {action === 'open' && (
410
+ <div className="grid gap-3 md:grid-cols-2">
411
+ <label>
412
+ Charge kind
413
+ <select
414
+ className={select}
415
+ value={chargeKind}
416
+ onChange={(event) => {
417
+ const value = (
418
+ ['DEMURRAGE', 'DETENTION', 'TERMINAL_STORAGE'] as const
419
+ ).find((item) => item === event.target.value);
420
+ if (value) setChargeKind(value);
421
+ }}
422
+ >
423
+ <option>DEMURRAGE</option>
424
+ <option>DETENTION</option>
425
+ <option>TERMINAL_STORAGE</option>
426
+ </select>
427
+ </label>
428
+ <label>
429
+ Commercial obligation reference
430
+ <Input
431
+ required
432
+ maxLength={255}
433
+ value={obligation}
434
+ onChange={(event) => setObligation(event.target.value)}
435
+ placeholder="Payee / terminal / booking / segment"
436
+ />
437
+ </label>
438
+ </div>
439
+ )}
440
+ <RecordState error={events.error} loading={events.loading}>
441
+ <Pager
442
+ page={events.data?.mtwContainerEventPage}
443
+ offset={eventOffset}
444
+ setOffset={setEventOffset}
445
+ busy={events.loading || mutations.busy}
446
+ />
447
+ </RecordState>
448
+ {(action === 'open' || current) && (
449
+ <FreeTimeAgreementForm
450
+ key={`${action}:${cycleId}:${clockId}:${current?.id}`}
451
+ events={events.data?.mtwContainerEventPage.items ?? []}
452
+ initial={action === 'correct' ? current : undefined}
453
+ busy={
454
+ mutations.busy ||
455
+ events.loading ||
456
+ (action === 'correct' && currentAgreement.loading)
457
+ }
458
+ onSubmit={async (agreement) => {
459
+ if (action === 'open') {
460
+ if (!obligation.trim())
461
+ throw new Error('Enter a distinct commercial obligation reference.');
462
+ await mutations.run(
463
+ OpenFreeClockDocument,
464
+ { cycleId, chargeKind, obligationReference: obligation, agreement },
465
+ 'Sourced clock opened.'
466
+ );
467
+ } else {
468
+ if (!clock || !current)
469
+ throw new Error('Reload the current obligation before correcting it.');
470
+ await mutations.run(
471
+ RecordFreeAgreementDocument,
472
+ { clockId, expectedVersion: clock.version, agreement },
473
+ 'New immutable agreement version recorded.'
474
+ );
475
+ }
476
+ }}
477
+ />
478
+ )}
479
+ </>
480
+ )}
481
+ {(action === 'request' || action === 'decision') && (
482
+ <form
483
+ className="space-y-4"
484
+ onSubmit={async (event) => {
485
+ event.preventDefault();
486
+ setValidation(null);
487
+ try {
488
+ if (!clock || !current)
489
+ throw new Error('Reload the current obligation and agreement.');
490
+ const values = new FormData(event.currentTarget);
491
+ const text = (name: string) => String(values.get(name) ?? '').trim();
492
+ if (action === 'request')
493
+ await mutations.run(
494
+ RequestFreeExtensionDocument,
495
+ {
496
+ clockId,
497
+ expectedVersion: clock.version,
498
+ baseAgreementId: current.id,
499
+ requestedFreeUntil: freeTimeIso(text('requestedDeadline')),
500
+ requestedAt: freeTimeIso(text('requestedAt')),
501
+ expiresAt: freeTimeIso(text('expiresAt')),
502
+ reason: text('reason'),
503
+ evidence: refs(),
504
+ },
505
+ 'Request recorded; current terms remain unchanged.'
506
+ );
507
+ else {
508
+ if (!pending.some((item) => item.id === extensionId))
509
+ throw new Error('Choose an unanswered request.');
510
+ await mutations.run(
511
+ DecideFreeExtensionDocument,
512
+ {
513
+ extensionId,
514
+ expectedVersion: clock.version,
515
+ decision: decisionKind,
516
+ decidedAt: freeTimeIso(text('decidedAt')),
517
+ effectiveAt:
518
+ decisionKind === 'ACCEPTED' ? freeTimeIso(text('effectiveAt')) : null,
519
+ acceptedFreeUntil:
520
+ decisionKind === 'ACCEPTED'
521
+ ? freeTimeIso(text('acceptedDeadline'))
522
+ : null,
523
+ counterparty: text('counterparty'),
524
+ sourceReference: text('confirmation'),
525
+ note: text('note'),
526
+ evidence: refs(),
527
+ },
528
+ 'External decision recorded with immutable history.'
529
+ );
530
+ }
531
+ } catch (failure) {
532
+ setValidation(
533
+ failure instanceof Error ? failure.message : 'Unable to record change.'
534
+ );
535
+ }
536
+ }}
537
+ >
538
+ {action === 'request' ? (
539
+ <div className="grid gap-3 md:grid-cols-2">
540
+ {[
541
+ ['requestedDeadline', 'Requested deadline with timezone'],
542
+ ['requestedAt', 'Actual request time with timezone'],
543
+ ['expiresAt', 'Request expiry with timezone'],
544
+ ].map(([name, label]) => (
545
+ <label key={name}>
546
+ {label}
547
+ <Input name={name} required placeholder="2026-10-04T09:00:00+05:30" />
548
+ </label>
549
+ ))}
550
+ <label>
551
+ Request reason
552
+ <Input name="reason" required maxLength={2000} />
553
+ </label>
554
+ </div>
555
+ ) : (
556
+ <>
557
+ <label className="block">
558
+ Unanswered extension request
559
+ <select
560
+ className={select}
561
+ required
562
+ value={extensionId}
563
+ onChange={(event) => setExtensionId(event.target.value)}
564
+ >
565
+ <option value="">Choose request from this page</option>
566
+ {pending.map((item) => (
567
+ <option key={item.id} value={item.id}>
568
+ {item.requestedFreeUntil} — expires {item.expiresAt} — base{' '}
569
+ {item.baseAgreementId}
570
+ </option>
571
+ ))}
572
+ </select>
573
+ </label>
574
+ <label className="block">
575
+ Recorded decision
576
+ <select
577
+ className={select}
578
+ value={decisionKind}
579
+ onChange={(event) => {
580
+ const value = (['ACCEPTED', 'REJECTED', 'EXPIRED'] as const).find(
581
+ (item) => item === event.target.value
582
+ );
583
+ if (value) setDecisionKind(value);
584
+ }}
585
+ >
586
+ <option>ACCEPTED</option>
587
+ <option>REJECTED</option>
588
+ <option>EXPIRED</option>
589
+ </select>
590
+ </label>
591
+ <div className="grid gap-3 md:grid-cols-2">
592
+ <label>
593
+ Actual decision time with timezone
594
+ <Input name="decidedAt" required />
595
+ </label>
596
+ <label>
597
+ Counterparty / expiry authority
598
+ <Input name="counterparty" required maxLength={255} />
599
+ </label>
600
+ <label>
601
+ External confirmation source reference
602
+ <Input name="confirmation" required maxLength={255} />
603
+ </label>
604
+ {decisionKind === 'ACCEPTED' && (
605
+ <>
606
+ <label>
607
+ Externally accepted deadline with timezone
608
+ <Input name="acceptedDeadline" required />
609
+ </label>
610
+ <label>
611
+ Explicit effective time with timezone
612
+ <Input name="effectiveAt" required />
613
+ </label>
614
+ </>
615
+ )}
616
+ <label>
617
+ Decision note and applicability
618
+ <Input name="note" required maxLength={2000} />
619
+ </label>
620
+ </div>
621
+ <p className="text-sm">
622
+ Requested and accepted deadlines can differ. Accepted extensions must move a
623
+ known current cutoff later. Late decisions or a superseded base agreement
624
+ require explicit reconciliation. Expiry never reverses an accepted agreement.
625
+ </p>
626
+ </>
627
+ )}
628
+ <ContainerEvidencePicker
629
+ description="Choose exact source versions. Integrity does not independently establish contractual terms or counterparty acceptance."
630
+ value={evidence}
631
+ onChange={setEvidence}
632
+ />
633
+ <Button
634
+ type="submit"
635
+ disabled={mutations.busy || currentAgreement.loading || !clock || !current}
636
+ >
637
+ {action === 'request' ? 'Record extension request' : 'Record counterparty decision'}
638
+ </Button>
639
+ </form>
640
+ )}
641
+ {(validation || mutations.error) && <p role="alert">{validation ?? mutations.error}</p>}
642
+ {mutations.notice && <p role="status">{mutations.notice}</p>}
643
+ {mutations.hasPendingAttempt && (
644
+ <div className="space-y-2">
645
+ <p className="text-sm">
646
+ A failed response may still mean the record was saved. Check history before
647
+ discarding or repeating the action, especially after reopening this page.
648
+ </p>
649
+ <Button
650
+ type="button"
651
+ variant="outline"
652
+ disabled={mutations.busy}
653
+ onClick={mutations.discardAttempt}
654
+ >
655
+ Discard failed attempt
656
+ </Button>
657
+ </div>
658
+ )}
659
+ </section>
660
+ )}
661
+ {clockId && (
662
+ <div className="grid gap-6 xl:grid-cols-2">
663
+ <section className={card}>
664
+ <h2 className="text-lg font-semibold">Agreement history</h2>
665
+ <RecordState error={agreements.error} loading={agreements.loading}>
666
+ <ul className="space-y-3">
667
+ {agreements.data?.mtwFreeTimeAgreementPage.items.map((item) => (
668
+ <li className="break-words rounded-lg border p-3 text-sm" key={item.id}>
669
+ Version {item.version} (agreement {item.id}): {item.payer} → {item.payee};
670
+ effective {item.effectiveAt}; {item.applicability}; deadline{' '}
671
+ {item.confirmedFreeUntil ?? 'Calculated / unknown'}. Source{' '}
672
+ {item.sourceReference}. Reason {item.changeReason}.
673
+ <ul>
674
+ {item.evidence.map((proof) => (
675
+ <li className="break-all" key={proof.versionId}>
676
+ Evidence version {proof.versionId}; SHA256 {proof.sha256Hash}
677
+ </li>
678
+ ))}
679
+ </ul>
680
+ </li>
681
+ ))}
682
+ </ul>
683
+ <Pager
684
+ page={agreements.data?.mtwFreeTimeAgreementPage}
685
+ offset={agreementOffset}
686
+ setOffset={setAgreementOffset}
687
+ busy={agreements.loading || mutations.busy}
688
+ />
689
+ </RecordState>
690
+ </section>
691
+ <section className={card}>
692
+ <h2 className="text-lg font-semibold">Extension decisions</h2>
693
+ <RecordState error={extensions.error} loading={extensions.loading}>
694
+ <ul className="space-y-3">
695
+ {extensions.data?.mtwFreeTimeExtensionPage.items.map((item) => (
696
+ <li className="break-words rounded-lg border p-3 text-sm" key={item.id}>
697
+ Requested {item.requestedFreeUntil}; expires {item.expiresAt}; base{' '}
698
+ {item.baseAgreementId}.{' '}
699
+ {item.decision
700
+ ? `${item.decision.decision}: ${item.decision.acceptedFreeUntil ?? 'Terms unchanged'}; ${item.decision.counterparty}; ${item.decision.sourceReference}; ${item.decision.note}`
701
+ : 'REQUESTED — no terminal decision recorded.'}
702
+ </li>
703
+ ))}
704
+ </ul>
705
+ <Pager
706
+ page={extensions.data?.mtwFreeTimeExtensionPage}
707
+ offset={extensionOffset}
708
+ busy={extensions.loading || mutations.busy}
709
+ setOffset={(offset) => {
710
+ setExtensionOffset(offset);
711
+ setExtensionId('');
712
+ }}
713
+ />
714
+ </RecordState>
715
+ </section>
716
+ </div>
717
+ )}
718
+ </div>
719
+ );
720
+ }