@burdenoff/microfe-movethewheels 2026.725.1 → 2026.728.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.
- package/dist/MoveTheWheelsRoutes.js +7 -3
- package/dist/components/ProofOfDeliveryCard.js +155 -0
- package/dist/components/SignaturePad.js +82 -0
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useEntityDocuments.js +4 -4
- package/dist/hooks/useEpod.js +208 -0
- package/dist/index.js +22 -21
- package/dist/movethewheels/components/ProofOfDeliveryCard.d.ts +5 -0
- package/dist/movethewheels/components/SignaturePad.d.ts +11 -0
- package/dist/movethewheels/hooks/index.d.ts +1 -0
- package/dist/movethewheels/hooks/useEntityDocuments.d.ts +17 -1
- package/dist/movethewheels/hooks/useEpod.d.ts +59 -0
- package/dist/movethewheels/pages/DeliveryCapturePage.d.ts +1 -0
- package/dist/movethewheels/types/index.d.ts +18 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/loader-circle.js +8 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/pen-line.js +11 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/type.js +24 -0
- package/dist/pages/DeliveryCapturePage.js +245 -0
- package/dist/pages/OrderDetailsPage.js +14 -12
- package/dist/pages/TrackingPage.js +156 -154
- package/dist/utils/formatters.js +13 -2
- package/package.json +4 -3
- package/src/movethewheels/MoveTheWheelsRoutes.tsx +4 -0
- package/src/movethewheels/components/ProofOfDeliveryCard.tsx +149 -0
- package/src/movethewheels/components/SignaturePad.tsx +157 -0
- package/src/movethewheels/hooks/index.ts +12 -0
- package/src/movethewheels/hooks/useEntityDocuments.ts +30 -12
- package/src/movethewheels/hooks/useEpod.ts +410 -0
- package/src/movethewheels/pages/DeliveryCapturePage.tsx +297 -0
- package/src/movethewheels/pages/OrderDetailsPage.tsx +4 -0
- package/src/movethewheels/pages/TrackingPage.tsx +4 -0
- package/src/movethewheels/types/index.ts +21 -0
|
@@ -25,8 +25,8 @@ function u() {
|
|
|
25
25
|
})
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
|
-
var d = n(() => import("./pages/DashboardPage.js")), f = n(() => import("./pages/OrdersListPage.js")), p = n(() => import("./pages/OrderDetailsPage.js")), m = n(() => import("./pages/CreateOrderPage.js")), h = n(() => import("./pages/TrackingPage.js")), g = n(() => import("./pages/LiveTrackingPage.js")), _ = n(() => import("./pages/FleetPage.js")), v = n(() => import("./pages/VehiclesPage.js")), y = n(() => import("./pages/VehicleDetailsPage.js")), b = n(() => import("./pages/DriversPage.js")), x = n(() => import("./pages/DriverDetailsPage.js")), S = n(() => import("./pages/InventoryPage.js")), C = n(() => import("./pages/ProductsPage.js")), w = n(() => import("./pages/ProductDetailsPage.js")), T = n(() => import("./pages/WarehousesPage.js")), E = n(() => import("./pages/WarehouseDetailsPage.js")), D = n(() => import("./pages/CustomersPage.js")), O = n(() => import("./pages/CustomerDetailsPage.js")), k = n(() => import("./pages/RoutesPage.js")), A = n(() => import("./pages/RouteDetailsPage.js")), j = n(() => import("./pages/AnalyticsPage.js")), M = n(() => import("./pages/FinancePage.js")), N = n(() => import("./pages/MarketplacePage.js")), P = n(() => import("./pages/ImportExportPage.js")), F = n(() => import("./pages/ReportsPage.js")), I = n(() => import("./pages/SettingsPage.js")), L = n(() => import("./pages/AIAssistantPage.js"));
|
|
29
|
-
function
|
|
28
|
+
var d = n(() => import("./pages/DashboardPage.js")), f = n(() => import("./pages/OrdersListPage.js")), p = n(() => import("./pages/OrderDetailsPage.js")), m = n(() => import("./pages/CreateOrderPage.js")), h = n(() => import("./pages/TrackingPage.js")), g = n(() => import("./pages/LiveTrackingPage.js")), _ = n(() => import("./pages/FleetPage.js")), v = n(() => import("./pages/VehiclesPage.js")), y = n(() => import("./pages/VehicleDetailsPage.js")), b = n(() => import("./pages/DriversPage.js")), x = n(() => import("./pages/DriverDetailsPage.js")), S = n(() => import("./pages/InventoryPage.js")), C = n(() => import("./pages/ProductsPage.js")), w = n(() => import("./pages/ProductDetailsPage.js")), T = n(() => import("./pages/WarehousesPage.js")), E = n(() => import("./pages/WarehouseDetailsPage.js")), D = n(() => import("./pages/CustomersPage.js")), O = n(() => import("./pages/CustomerDetailsPage.js")), k = n(() => import("./pages/RoutesPage.js")), A = n(() => import("./pages/RouteDetailsPage.js")), j = n(() => import("./pages/AnalyticsPage.js")), M = n(() => import("./pages/FinancePage.js")), N = n(() => import("./pages/MarketplacePage.js")), P = n(() => import("./pages/ImportExportPage.js")), F = n(() => import("./pages/ReportsPage.js")), I = n(() => import("./pages/SettingsPage.js")), L = n(() => import("./pages/AIAssistantPage.js")), R = n(() => import("./pages/DeliveryCapturePage.js"));
|
|
29
|
+
function z() {
|
|
30
30
|
return /* @__PURE__ */ o(t, {
|
|
31
31
|
fallback: /* @__PURE__ */ o(u, {}),
|
|
32
32
|
children: /* @__PURE__ */ s(i, { children: [
|
|
@@ -58,6 +58,10 @@ function R() {
|
|
|
58
58
|
path: "tracking/live",
|
|
59
59
|
element: /* @__PURE__ */ o(g, {})
|
|
60
60
|
}),
|
|
61
|
+
/* @__PURE__ */ o(r, {
|
|
62
|
+
path: "deliveries/mine",
|
|
63
|
+
element: /* @__PURE__ */ o(R, {})
|
|
64
|
+
}),
|
|
61
65
|
/* @__PURE__ */ o(r, {
|
|
62
66
|
path: "fleet",
|
|
63
67
|
element: /* @__PURE__ */ o(_, {})
|
|
@@ -194,4 +198,4 @@ function R() {
|
|
|
194
198
|
});
|
|
195
199
|
}
|
|
196
200
|
//#endregion
|
|
197
|
-
export {
|
|
201
|
+
export { z as MoveTheWheelsRoutes };
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { CircleCheck as e } from "../node_modules/lucide-react/dist/esm/icons/circle-check.js";
|
|
2
|
+
import { Clock as t } from "../node_modules/lucide-react/dist/esm/icons/clock.js";
|
|
3
|
+
import { Download as n } from "../node_modules/lucide-react/dist/esm/icons/download.js";
|
|
4
|
+
import { MapPin as r } from "../node_modules/lucide-react/dist/esm/icons/map-pin.js";
|
|
5
|
+
import { User as i } from "../node_modules/lucide-react/dist/esm/icons/user.js";
|
|
6
|
+
import { useEpod as a, useEpodPhotoUrl as o } from "../hooks/useEpod.js";
|
|
7
|
+
import { Badge as s, Card as c, CardContent as l, CardHeader as u, CardTitle as d } from "./ui.js";
|
|
8
|
+
import { formatDateTime as f } from "../utils/formatters.js";
|
|
9
|
+
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
10
|
+
//#region src/movethewheels/components/ProofOfDeliveryCard.tsx
|
|
11
|
+
function h({ fileId: e }) {
|
|
12
|
+
let { url: t, isLoading: n } = o(e);
|
|
13
|
+
return n ? /* @__PURE__ */ p("div", { className: "h-20 w-20 rounded-lg bg-bg-sunken animate-pulse" }) : t ? /* @__PURE__ */ p("a", {
|
|
14
|
+
href: t,
|
|
15
|
+
target: "_blank",
|
|
16
|
+
rel: "noopener noreferrer",
|
|
17
|
+
className: "shrink-0",
|
|
18
|
+
children: /* @__PURE__ */ p("img", {
|
|
19
|
+
src: t,
|
|
20
|
+
alt: "Delivery photo",
|
|
21
|
+
className: "h-20 w-20 rounded-lg object-cover border border-border"
|
|
22
|
+
})
|
|
23
|
+
}) : null;
|
|
24
|
+
}
|
|
25
|
+
function g({ deliveryJobId: o }) {
|
|
26
|
+
let { epod: g, isLoading: _, error: v } = a(o);
|
|
27
|
+
return /* @__PURE__ */ m(c, { children: [/* @__PURE__ */ m(u, {
|
|
28
|
+
className: "flex flex-row items-center justify-between",
|
|
29
|
+
children: [/* @__PURE__ */ m(d, {
|
|
30
|
+
className: "flex items-center gap-2",
|
|
31
|
+
children: [/* @__PURE__ */ p(e, { size: 18 }), " Proof of Delivery"]
|
|
32
|
+
}), g && /* @__PURE__ */ p(s, {
|
|
33
|
+
variant: "success",
|
|
34
|
+
children: "Captured"
|
|
35
|
+
})]
|
|
36
|
+
}), /* @__PURE__ */ p(l, { children: _ ? /* @__PURE__ */ p("p", {
|
|
37
|
+
className: "text-text-secondary text-center py-4",
|
|
38
|
+
children: "Loading proof of delivery…"
|
|
39
|
+
}) : v ? /* @__PURE__ */ p("p", {
|
|
40
|
+
className: "text-sm text-status-error-text text-center py-4",
|
|
41
|
+
children: "Failed to load proof of delivery."
|
|
42
|
+
}) : g ? /* @__PURE__ */ m("div", {
|
|
43
|
+
className: "space-y-4",
|
|
44
|
+
children: [
|
|
45
|
+
/* @__PURE__ */ m("div", {
|
|
46
|
+
className: "grid grid-cols-1 sm:grid-cols-2 gap-4",
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ m("div", {
|
|
49
|
+
className: "flex items-start gap-2",
|
|
50
|
+
children: [/* @__PURE__ */ p(i, {
|
|
51
|
+
size: 16,
|
|
52
|
+
className: "mt-0.5 text-text-secondary shrink-0"
|
|
53
|
+
}), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("p", {
|
|
54
|
+
className: "text-xs text-text-secondary",
|
|
55
|
+
children: "Received by"
|
|
56
|
+
}), /* @__PURE__ */ p("p", {
|
|
57
|
+
className: "font-medium",
|
|
58
|
+
children: g.recipientName
|
|
59
|
+
})] })]
|
|
60
|
+
}),
|
|
61
|
+
/* @__PURE__ */ m("div", {
|
|
62
|
+
className: "flex items-start gap-2",
|
|
63
|
+
children: [/* @__PURE__ */ p(t, {
|
|
64
|
+
size: 16,
|
|
65
|
+
className: "mt-0.5 text-text-secondary shrink-0"
|
|
66
|
+
}), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("p", {
|
|
67
|
+
className: "text-xs text-text-secondary",
|
|
68
|
+
children: "Delivered at"
|
|
69
|
+
}), /* @__PURE__ */ p("p", {
|
|
70
|
+
className: "font-medium",
|
|
71
|
+
children: f(g.deliveredAt)
|
|
72
|
+
})] })]
|
|
73
|
+
}),
|
|
74
|
+
g.latitude != null && g.longitude != null && /* @__PURE__ */ m("div", {
|
|
75
|
+
className: "flex items-start gap-2 sm:col-span-2",
|
|
76
|
+
children: [/* @__PURE__ */ p(r, {
|
|
77
|
+
size: 16,
|
|
78
|
+
className: "mt-0.5 text-text-secondary shrink-0"
|
|
79
|
+
}), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("p", {
|
|
80
|
+
className: "text-xs text-text-secondary",
|
|
81
|
+
children: "Delivery location"
|
|
82
|
+
}), /* @__PURE__ */ m("p", {
|
|
83
|
+
className: "font-medium",
|
|
84
|
+
children: [
|
|
85
|
+
g.latitude.toFixed(5),
|
|
86
|
+
", ",
|
|
87
|
+
g.longitude.toFixed(5),
|
|
88
|
+
g.locationAccuracy != null && /* @__PURE__ */ m("span", {
|
|
89
|
+
className: "text-text-secondary",
|
|
90
|
+
children: [
|
|
91
|
+
" (±",
|
|
92
|
+
Math.round(g.locationAccuracy),
|
|
93
|
+
"m)"
|
|
94
|
+
]
|
|
95
|
+
})
|
|
96
|
+
]
|
|
97
|
+
})] })]
|
|
98
|
+
})
|
|
99
|
+
]
|
|
100
|
+
}),
|
|
101
|
+
g.notes && /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("p", {
|
|
102
|
+
className: "text-xs text-text-secondary mb-1",
|
|
103
|
+
children: "Notes"
|
|
104
|
+
}), /* @__PURE__ */ p("p", {
|
|
105
|
+
className: "text-sm",
|
|
106
|
+
children: g.notes
|
|
107
|
+
})] }),
|
|
108
|
+
/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ m("p", {
|
|
109
|
+
className: "text-xs text-text-secondary mb-1",
|
|
110
|
+
children: ["Signature ", g.signatureType === "typed" ? "(typed)" : "(drawn)"]
|
|
111
|
+
}), g.signatureType === "drawn" ? /* @__PURE__ */ p("div", {
|
|
112
|
+
className: "border rounded-lg p-2 inline-block bg-white",
|
|
113
|
+
children: /* @__PURE__ */ p("img", {
|
|
114
|
+
src: g.signatureData,
|
|
115
|
+
alt: "Recipient signature",
|
|
116
|
+
className: "h-16"
|
|
117
|
+
})
|
|
118
|
+
}) : /* @__PURE__ */ p("p", {
|
|
119
|
+
className: "text-lg italic font-medium border-b border-border inline-block pb-1",
|
|
120
|
+
children: g.signatureData
|
|
121
|
+
})] }),
|
|
122
|
+
g.photoFileIds.length > 0 && /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("p", {
|
|
123
|
+
className: "text-xs text-text-secondary mb-2",
|
|
124
|
+
children: "Delivery photos"
|
|
125
|
+
}), /* @__PURE__ */ p("div", {
|
|
126
|
+
className: "flex flex-wrap gap-2",
|
|
127
|
+
children: g.photoFileIds.map((e) => /* @__PURE__ */ p(h, { fileId: e }, e))
|
|
128
|
+
})] }),
|
|
129
|
+
/* @__PURE__ */ m("a", {
|
|
130
|
+
href: `data:text/plain;charset=utf-8,${encodeURIComponent(`Proof of Delivery\nRecipient: ${g.recipientName}\nDelivered at: ${f(g.deliveredAt)}${g.latitude != null && g.longitude != null ? `\nLocation: ${g.latitude}, ${g.longitude}` : ""}${g.notes ? `\nNotes: ${g.notes}` : ""}`)}`,
|
|
131
|
+
download: `pod-${o}.txt`,
|
|
132
|
+
className: "inline-flex items-center gap-1 text-sm text-primary hover:underline",
|
|
133
|
+
children: [/* @__PURE__ */ p(n, { size: 14 }), " Download record"]
|
|
134
|
+
})
|
|
135
|
+
]
|
|
136
|
+
}) : /* @__PURE__ */ m("div", {
|
|
137
|
+
className: "text-center py-6",
|
|
138
|
+
children: [
|
|
139
|
+
/* @__PURE__ */ p(e, {
|
|
140
|
+
size: 32,
|
|
141
|
+
className: "mx-auto mb-2 text-text-secondary opacity-50"
|
|
142
|
+
}),
|
|
143
|
+
/* @__PURE__ */ p("p", {
|
|
144
|
+
className: "text-text-secondary",
|
|
145
|
+
children: "Not yet delivered"
|
|
146
|
+
}),
|
|
147
|
+
/* @__PURE__ */ p("p", {
|
|
148
|
+
className: "text-xs text-text-secondary mt-1",
|
|
149
|
+
children: "Proof of delivery will appear here once the driver completes capture."
|
|
150
|
+
})
|
|
151
|
+
]
|
|
152
|
+
}) })] });
|
|
153
|
+
}
|
|
154
|
+
//#endregion
|
|
155
|
+
export { g as ProofOfDeliveryCard };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { cn as e } from "../utils/cn.js";
|
|
2
|
+
import { Button as t } from "./ui.js";
|
|
3
|
+
import { forwardRef as n, useCallback as r, useEffect as i, useImperativeHandle as a, useRef as o, useState as s } from "react";
|
|
4
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
5
|
+
//#region src/movethewheels/components/SignaturePad.tsx
|
|
6
|
+
var u = n(({ className: n, onChange: u }, d) => {
|
|
7
|
+
let f = o(null), p = o(!1), m = o(!1), h = o(null), [g, _] = s(!1), v = r(() => {
|
|
8
|
+
let e = f.current;
|
|
9
|
+
return e ? e.getContext("2d") : null;
|
|
10
|
+
}, []);
|
|
11
|
+
i(() => {
|
|
12
|
+
let e = f.current, t = v();
|
|
13
|
+
if (!e || !t) return;
|
|
14
|
+
let n = window.devicePixelRatio || 1, r = e.getBoundingClientRect();
|
|
15
|
+
e.width = r.width * n, e.height = r.height * n, t.scale(n, n), t.lineWidth = 2, t.lineCap = "round", t.lineJoin = "round", t.strokeStyle = getComputedStyle(e).color || "currentColor";
|
|
16
|
+
}, [v]);
|
|
17
|
+
let y = r((e) => {
|
|
18
|
+
let t = f.current;
|
|
19
|
+
if (!t) return {
|
|
20
|
+
x: 0,
|
|
21
|
+
y: 0
|
|
22
|
+
};
|
|
23
|
+
let n = t.getBoundingClientRect();
|
|
24
|
+
return {
|
|
25
|
+
x: e.clientX - n.left,
|
|
26
|
+
y: e.clientY - n.top
|
|
27
|
+
};
|
|
28
|
+
}, []), b = r((e) => {
|
|
29
|
+
let t = f.current, n = v();
|
|
30
|
+
!t || !n || (t.setPointerCapture(e.pointerId), p.current = !0, h.current = y(e));
|
|
31
|
+
}, [v, y]), x = r((e) => {
|
|
32
|
+
if (!p.current) return;
|
|
33
|
+
let t = v(), n = h.current;
|
|
34
|
+
if (!t || !n) return;
|
|
35
|
+
let r = y(e);
|
|
36
|
+
t.beginPath(), t.moveTo(n.x, n.y), t.lineTo(r.x, r.y), t.stroke(), h.current = r, m.current || (m.current = !0, _(!0), u?.(!0));
|
|
37
|
+
}, [
|
|
38
|
+
v,
|
|
39
|
+
u,
|
|
40
|
+
y
|
|
41
|
+
]), S = r((e) => {
|
|
42
|
+
p.current = !1, h.current = null;
|
|
43
|
+
let t = f.current;
|
|
44
|
+
t?.hasPointerCapture(e.pointerId) && t.releasePointerCapture(e.pointerId);
|
|
45
|
+
}, []), C = r(() => {
|
|
46
|
+
let e = f.current, t = v();
|
|
47
|
+
!e || !t || (t.clearRect(0, 0, e.width, e.height), m.current = !1, _(!1), u?.(!1));
|
|
48
|
+
}, [v, u]), w = r(() => m.current ? f.current?.toDataURL("image/png") ?? null : null, []);
|
|
49
|
+
return a(d, () => ({
|
|
50
|
+
clear: C,
|
|
51
|
+
isEmpty: () => !m.current,
|
|
52
|
+
toDataUrl: w
|
|
53
|
+
}), [C, w]), /* @__PURE__ */ l("div", {
|
|
54
|
+
className: e("space-y-2", n),
|
|
55
|
+
children: [/* @__PURE__ */ c("canvas", {
|
|
56
|
+
ref: f,
|
|
57
|
+
className: "w-full h-40 rounded-lg border-2 border-dashed border-border bg-bg-surface text-text-primary touch-none cursor-crosshair",
|
|
58
|
+
onPointerDown: b,
|
|
59
|
+
onPointerMove: x,
|
|
60
|
+
onPointerUp: S,
|
|
61
|
+
onPointerLeave: S,
|
|
62
|
+
role: "img",
|
|
63
|
+
"aria-label": "Signature capture pad"
|
|
64
|
+
}), /* @__PURE__ */ l("div", {
|
|
65
|
+
className: "flex items-center justify-between",
|
|
66
|
+
children: [/* @__PURE__ */ c("p", {
|
|
67
|
+
className: "text-xs text-text-secondary",
|
|
68
|
+
children: g ? "Signature captured" : "Sign above with your finger or mouse"
|
|
69
|
+
}), /* @__PURE__ */ c(t, {
|
|
70
|
+
type: "button",
|
|
71
|
+
variant: "ghost",
|
|
72
|
+
size: "sm",
|
|
73
|
+
onClick: C,
|
|
74
|
+
disabled: !g,
|
|
75
|
+
children: "Clear"
|
|
76
|
+
})]
|
|
77
|
+
})]
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
u.displayName = "SignaturePad";
|
|
81
|
+
//#endregion
|
|
82
|
+
export { u as SignaturePad };
|
package/dist/hooks/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { useMoveTheWheels as e } from "../providers/MoveTheWheelsProvider.js";
|
|
|
2
2
|
import { executeGraphQL as t } from "../utils/graphqlClient.js";
|
|
3
3
|
import { useCallback as n, useEffect as r, useMemo as i, useState as a } from "react";
|
|
4
4
|
//#region src/movethewheels/hooks/useEntityDocuments.ts
|
|
5
|
-
var o = "\n query ListEntityDocuments($filter: FileFilterInput, $pagination: PaginationInput) {\n
|
|
5
|
+
var o = "\n query ListEntityDocuments($filter: FileFilterInput, $pagination: PaginationInput) {\n getFiles(filter: $filter, pagination: $pagination) {\n files {\n id\n name\n size\n mimeType\n createdAt\n downloadUrl\n }\n }\n }\n";
|
|
6
6
|
function s(e) {
|
|
7
7
|
return {
|
|
8
8
|
id: e.id,
|
|
@@ -38,16 +38,16 @@ function c(c, l) {
|
|
|
38
38
|
_(((await t(S, o, {
|
|
39
39
|
filter: { tags: [{
|
|
40
40
|
key: "mtwEntityType",
|
|
41
|
-
|
|
41
|
+
label: c
|
|
42
42
|
}, {
|
|
43
43
|
key: "mtwEntityId",
|
|
44
|
-
|
|
44
|
+
label: l
|
|
45
45
|
}] },
|
|
46
46
|
pagination: {
|
|
47
47
|
limit: 50,
|
|
48
48
|
offset: 0
|
|
49
49
|
}
|
|
50
|
-
})).files ?? []).map(s));
|
|
50
|
+
})).getFiles?.files ?? []).map(s));
|
|
51
51
|
} catch (e) {
|
|
52
52
|
x(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load documents")), _([]);
|
|
53
53
|
} finally {
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { useMoveTheWheels as e } from "../providers/MoveTheWheelsProvider.js";
|
|
2
|
+
import { executeGraphQL as t } from "../utils/graphqlClient.js";
|
|
3
|
+
import { useCallback as n, useEffect as r, useMemo as i, useState as a } from "react";
|
|
4
|
+
//#region src/movethewheels/hooks/useEpod.ts
|
|
5
|
+
var o = "\n id\n deliveryJobId\n shipmentId\n recipientName\n signatureType\n signatureData\n photoFileIds\n latitude\n longitude\n locationAccuracy\n deliveredAt\n capturedByDriverId\n notes\n", s = `
|
|
6
|
+
query GetEpod($deliveryJobId: ID!) {
|
|
7
|
+
epod(deliveryJobId: $deliveryJobId) {
|
|
8
|
+
${o}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
`, c = "\n query MyPendingEpodDeliveryJobs($pagination: PaginationInput) {\n myPendingEpodDeliveryJobs(pagination: $pagination) {\n id\n deliveryJobNumber\n status\n priority\n deliveryAddress\n scheduledDelivery\n customer {\n name\n phone\n }\n }\n }\n", l = `
|
|
12
|
+
mutation CaptureEpod($input: CaptureEpodInput!) {
|
|
13
|
+
captureEpod(input: $input) {
|
|
14
|
+
${o}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
`, u = "\n mutation EpodInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) {\n uploadUrl\n session { id }\n }\n }\n", d = "\n mutation EpodCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) {\n fileId\n }\n }\n", f = "\n query EpodFileUrl($id: ID!, $expiresIn: Int) {\n getFileDownloadUrl(id: $id, expiresIn: $expiresIn)\n }\n", p = 21600;
|
|
18
|
+
function m(e) {
|
|
19
|
+
return e === "typed" ? "TYPED" : "DRAWN";
|
|
20
|
+
}
|
|
21
|
+
function h(e) {
|
|
22
|
+
return {
|
|
23
|
+
id: e.id,
|
|
24
|
+
deliveryJobId: e.deliveryJobId,
|
|
25
|
+
shipmentId: e.shipmentId ?? void 0,
|
|
26
|
+
recipientName: e.recipientName,
|
|
27
|
+
signatureType: e.signatureType === "TYPED" ? "typed" : "drawn",
|
|
28
|
+
signatureData: e.signatureData,
|
|
29
|
+
photoFileIds: e.photoFileIds ?? [],
|
|
30
|
+
latitude: e.latitude ?? void 0,
|
|
31
|
+
longitude: e.longitude ?? void 0,
|
|
32
|
+
locationAccuracy: e.locationAccuracy ?? void 0,
|
|
33
|
+
deliveredAt: new Date(e.deliveredAt),
|
|
34
|
+
capturedByDriverId: e.capturedByDriverId,
|
|
35
|
+
notes: e.notes ?? void 0
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function g() {
|
|
39
|
+
let { apiGatewayUrl: t, authToken: n, workspaceToken: r, workspaceId: a, tenantId: o, currentUser: s } = e();
|
|
40
|
+
return i(() => ({
|
|
41
|
+
apiGatewayUrl: t,
|
|
42
|
+
authToken: n,
|
|
43
|
+
workspaceToken: r,
|
|
44
|
+
workspaceId: a,
|
|
45
|
+
tenantId: o,
|
|
46
|
+
actorId: s?.id
|
|
47
|
+
}), [
|
|
48
|
+
t,
|
|
49
|
+
n,
|
|
50
|
+
r,
|
|
51
|
+
a,
|
|
52
|
+
o,
|
|
53
|
+
s?.id
|
|
54
|
+
]);
|
|
55
|
+
}
|
|
56
|
+
function _(e) {
|
|
57
|
+
let i = g(), [o, c] = a(null), [l, u] = a(!1), [d, f] = a(null), p = n(async () => {
|
|
58
|
+
if (!e) {
|
|
59
|
+
c(null);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
u(!0), f(null);
|
|
63
|
+
try {
|
|
64
|
+
let n = await t(i, s, { deliveryJobId: e });
|
|
65
|
+
c(n.epod ? h(n.epod) : null);
|
|
66
|
+
} catch (e) {
|
|
67
|
+
f(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load proof of delivery")), c(null);
|
|
68
|
+
} finally {
|
|
69
|
+
u(!1);
|
|
70
|
+
}
|
|
71
|
+
}, [e, i]);
|
|
72
|
+
return r(() => {
|
|
73
|
+
p();
|
|
74
|
+
}, [p]), {
|
|
75
|
+
epod: o,
|
|
76
|
+
isLoading: l,
|
|
77
|
+
error: d,
|
|
78
|
+
refetch: p
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function v() {
|
|
82
|
+
let e = g(), [i, o] = a([]), [s, l] = a(!1), [u, d] = a(null), f = n(async () => {
|
|
83
|
+
l(!0), d(null);
|
|
84
|
+
try {
|
|
85
|
+
o((await t(e, c, { pagination: {
|
|
86
|
+
limit: 50,
|
|
87
|
+
offset: 0
|
|
88
|
+
} })).myPendingEpodDeliveryJobs.map((e) => ({
|
|
89
|
+
id: e.id,
|
|
90
|
+
deliveryJobNumber: e.deliveryJobNumber,
|
|
91
|
+
status: e.status,
|
|
92
|
+
priority: e.priority,
|
|
93
|
+
deliveryAddress: e.deliveryAddress,
|
|
94
|
+
scheduledDelivery: e.scheduledDelivery ? new Date(e.scheduledDelivery) : void 0,
|
|
95
|
+
customerName: e.customer?.name ?? void 0,
|
|
96
|
+
customerPhone: e.customer?.phone ?? void 0
|
|
97
|
+
})));
|
|
98
|
+
} catch (e) {
|
|
99
|
+
d(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load pending deliveries")), o([]);
|
|
100
|
+
} finally {
|
|
101
|
+
l(!1);
|
|
102
|
+
}
|
|
103
|
+
}, [e]);
|
|
104
|
+
return r(() => {
|
|
105
|
+
f();
|
|
106
|
+
}, [f]), {
|
|
107
|
+
jobs: i,
|
|
108
|
+
isLoading: s,
|
|
109
|
+
error: u,
|
|
110
|
+
refetch: f
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function y() {
|
|
114
|
+
let e = g(), [r, i] = a(!1), [o, s] = a(null);
|
|
115
|
+
return {
|
|
116
|
+
captureEpod: n(async (n) => {
|
|
117
|
+
i(!0), s(null);
|
|
118
|
+
try {
|
|
119
|
+
return h((await t(e, l, { input: {
|
|
120
|
+
deliveryJobId: n.deliveryJobId,
|
|
121
|
+
recipientName: n.recipientName,
|
|
122
|
+
signatureType: m(n.signatureType),
|
|
123
|
+
signatureData: n.signatureData,
|
|
124
|
+
photoFileIds: n.photoFileIds,
|
|
125
|
+
latitude: n.latitude,
|
|
126
|
+
longitude: n.longitude,
|
|
127
|
+
locationAccuracy: n.locationAccuracy,
|
|
128
|
+
notes: n.notes
|
|
129
|
+
} })).captureEpod);
|
|
130
|
+
} catch (e) {
|
|
131
|
+
let t = e instanceof Error ? e : /* @__PURE__ */ Error("Failed to capture proof of delivery");
|
|
132
|
+
throw s(t), t;
|
|
133
|
+
} finally {
|
|
134
|
+
i(!1);
|
|
135
|
+
}
|
|
136
|
+
}, [e]),
|
|
137
|
+
isSubmitting: r,
|
|
138
|
+
error: o
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function b() {
|
|
142
|
+
let e = g(), [r, i] = a(!1), [o, s] = a(0), [c, l] = a(null);
|
|
143
|
+
return {
|
|
144
|
+
upload: n(async (n) => {
|
|
145
|
+
i(!0), s(0), l(null);
|
|
146
|
+
try {
|
|
147
|
+
let r = n.name.lastIndexOf("."), i = r > -1 ? n.name.slice(r + 1) : "", a = n.type || "application/octet-stream", o = await t(e, u, { input: {
|
|
148
|
+
fileName: n.name,
|
|
149
|
+
extension: i,
|
|
150
|
+
mimeType: a,
|
|
151
|
+
fileSize: String(n.size),
|
|
152
|
+
visibility: "WORKSPACE"
|
|
153
|
+
} }), { uploadUrl: c } = o.initiateUpload, l = o.initiateUpload.session.id;
|
|
154
|
+
if (!c) throw Error("The file service did not return an upload URL.");
|
|
155
|
+
s(50);
|
|
156
|
+
let f = await fetch(c, {
|
|
157
|
+
method: "PUT",
|
|
158
|
+
headers: { "Content-Type": a },
|
|
159
|
+
body: n
|
|
160
|
+
});
|
|
161
|
+
if (!f.ok) throw Error(`File storage rejected the upload (HTTP ${f.status}).`);
|
|
162
|
+
let p = await t(e, d, { input: {
|
|
163
|
+
sessionId: l,
|
|
164
|
+
fileSize: String(n.size)
|
|
165
|
+
} });
|
|
166
|
+
return s(100), {
|
|
167
|
+
fileId: p.completeUpload.fileId,
|
|
168
|
+
fileName: n.name
|
|
169
|
+
};
|
|
170
|
+
} catch (e) {
|
|
171
|
+
let t = e instanceof Error ? e : /* @__PURE__ */ Error("The photo could not be uploaded.");
|
|
172
|
+
throw l(t), t;
|
|
173
|
+
} finally {
|
|
174
|
+
i(!1);
|
|
175
|
+
}
|
|
176
|
+
}, [e]),
|
|
177
|
+
isUploading: r,
|
|
178
|
+
progress: o,
|
|
179
|
+
error: c
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function x(e) {
|
|
183
|
+
let n = g(), [i, o] = a(null), [s, c] = a(!1);
|
|
184
|
+
return r(() => {
|
|
185
|
+
if (!e) {
|
|
186
|
+
o(null);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
let r = !1;
|
|
190
|
+
return c(!0), t(n, f, {
|
|
191
|
+
id: e,
|
|
192
|
+
expiresIn: p
|
|
193
|
+
}).then((e) => {
|
|
194
|
+
r || o(e.getFileDownloadUrl ?? null);
|
|
195
|
+
}).catch(() => {
|
|
196
|
+
r || o(null);
|
|
197
|
+
}).finally(() => {
|
|
198
|
+
r || c(!1);
|
|
199
|
+
}), () => {
|
|
200
|
+
r = !0;
|
|
201
|
+
};
|
|
202
|
+
}, [e, n]), {
|
|
203
|
+
url: i,
|
|
204
|
+
isLoading: s
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
//#endregion
|
|
208
|
+
export { y as useCaptureEpod, _ as useEpod, b as useEpodPhotoUpload, x as useEpodPhotoUrl, v as useMyPendingEpodDeliveryJobs };
|
package/dist/index.js
CHANGED
|
@@ -13,26 +13,27 @@ import { useReports as B } from "./hooks/useReports.js";
|
|
|
13
13
|
import { useImportExport as V } from "./hooks/useImportExport.js";
|
|
14
14
|
import { useModuleSettings as H } from "./hooks/useSettings.js";
|
|
15
15
|
import { useEntityDocuments as U } from "./hooks/useEntityDocuments.js";
|
|
16
|
+
import { useCaptureEpod as W, useEpod as G, useEpodPhotoUpload as K, useEpodPhotoUrl as q, useMyPendingEpodDeliveryJobs as J } from "./hooks/useEpod.js";
|
|
16
17
|
import "./hooks/index.js";
|
|
17
|
-
import { Avatar as
|
|
18
|
-
import { EmptyState as
|
|
19
|
-
import { chartTokens as
|
|
20
|
-
import { Sparkline as
|
|
21
|
-
import { MetricCard as
|
|
22
|
-
import { GlassPanel as
|
|
23
|
-
import { ChartEmpty as
|
|
24
|
-
import { TrendChart as
|
|
25
|
-
import { VolumeBar as
|
|
26
|
-
import { StatusDonut as
|
|
27
|
-
import { createCurrentIcon as
|
|
28
|
-
import { MapCanvas as
|
|
29
|
-
import { LogisticsMap as
|
|
30
|
-
import { RouteMap as
|
|
31
|
-
import { TrackingMap as
|
|
32
|
-
import { PaymentStatusBadge as
|
|
33
|
-
import { DataTable as
|
|
34
|
-
import { FormError as
|
|
35
|
-
import { Notice as
|
|
36
|
-
import { DocumentsCard as
|
|
18
|
+
import { Avatar as Y, AvatarFallback as X, AvatarImage as Z, Badge as Q, Button as $, Card as ee, CardContent as te, CardDescription as ne, CardFooter as re, CardHeader as ie, CardTitle as ae, Checkbox as oe, Dialog as se, DialogContent as ce, DialogDescription as le, DialogFooter as ue, DialogHeader as de, DialogTitle as fe, DialogTrigger as pe, DropdownMenu as me, DropdownMenuContent as he, DropdownMenuItem as ge, DropdownMenuSeparator as _e, DropdownMenuTrigger as ve, Input as ye, Label as be, Progress as xe, ScrollArea as Se, Select as Ce, SelectContent as we, SelectItem as Te, SelectTrigger as Ee, SelectValue as De, Separator as Oe, Skeleton as ke, Switch as Ae, Table as je, TableBody as Me, TableCell as Ne, TableHead as Pe, TableHeader as Fe, TableRow as Ie, Tabs as Le, TabsContent as Re, TabsList as ze, TabsTrigger as Be, Textarea as Ve, Tooltip as He, TooltipContent as Ue, TooltipProvider as We, TooltipTrigger as Ge } from "./components/ui.js";
|
|
19
|
+
import { EmptyState as Ke, ErrorState as qe, LoadingState as Je, PageLayout as Ye, PageSection as Xe } from "./components/PageLayout.js";
|
|
20
|
+
import { chartTokens as Ze, seriesColor as Qe } from "./components/charts/chartTokens.js";
|
|
21
|
+
import { Sparkline as $e } from "./components/charts/Sparkline.js";
|
|
22
|
+
import { MetricCard as et, MetricCardSkeleton as tt, MetricGrid as nt } from "./components/MetricCard.js";
|
|
23
|
+
import { GlassPanel as rt } from "./components/GlassPanel.js";
|
|
24
|
+
import { ChartEmpty as it, ChartTooltip as at } from "./components/charts/ChartShell.js";
|
|
25
|
+
import { TrendChart as ot } from "./components/charts/TrendChart.js";
|
|
26
|
+
import { VolumeBar as st } from "./components/charts/VolumeBar.js";
|
|
27
|
+
import { StatusDonut as ct } from "./components/charts/StatusDonut.js";
|
|
28
|
+
import { createCurrentIcon as lt, createPinIcon as ut, createStopIcon as dt, isRealCoord as ft } from "./components/maps/leaflet-setup.js";
|
|
29
|
+
import { MapCanvas as pt } from "./components/maps/MapCanvas.js";
|
|
30
|
+
import { LogisticsMap as mt } from "./components/maps/LogisticsMap.js";
|
|
31
|
+
import { RouteMap as ht } from "./components/maps/RouteMap.js";
|
|
32
|
+
import { TrackingMap as gt } from "./components/maps/TrackingMap.js";
|
|
33
|
+
import { PaymentStatusBadge as _t, PriorityBadge as vt, StatusBadge as yt, TypeBadge as bt, VehicleTypeBadge as xt } from "./components/StatusBadge.js";
|
|
34
|
+
import { DataTable as St } from "./components/DataTable.js";
|
|
35
|
+
import { FormError as Ct } from "./components/FormError.js";
|
|
36
|
+
import { Notice as wt, useNotice as Tt } from "./components/Notice.js";
|
|
37
|
+
import { DocumentsCard as Et } from "./components/DocumentsCard.js";
|
|
37
38
|
import "./components/index.js";
|
|
38
|
-
export {
|
|
39
|
+
export { Y as Avatar, X as AvatarFallback, Z as AvatarImage, Q as Badge, $ as Button, ee as Card, te as CardContent, ne as CardDescription, re as CardFooter, ie as CardHeader, ae as CardTitle, it as ChartEmpty, at as ChartTooltip, oe as Checkbox, St as DataTable, se as Dialog, ce as DialogContent, le as DialogDescription, ue as DialogFooter, de as DialogHeader, fe as DialogTitle, pe as DialogTrigger, Et as DocumentsCard, me as DropdownMenu, he as DropdownMenuContent, ge as DropdownMenuItem, _e as DropdownMenuSeparator, ve as DropdownMenuTrigger, Ke as EmptyState, qe as ErrorState, Ct as FormError, rt as GlassPanel, ye as Input, be as Label, Je as LoadingState, mt as LogisticsMap, pt as MapCanvas, et as MetricCard, tt as MetricCardSkeleton, nt as MetricGrid, n as MoveTheWheelsRoot, wt as Notice, Ye as PageLayout, Xe as PageSection, _t as PaymentStatusBadge, vt as PriorityBadge, xe as Progress, ht as RouteMap, Se as ScrollArea, Ce as Select, we as SelectContent, Te as SelectItem, Ee as SelectTrigger, De as SelectValue, Oe as Separator, ke as Skeleton, $e as Sparkline, yt as StatusBadge, ct as StatusDonut, Ae as Switch, je as Table, Me as TableBody, Ne as TableCell, Pe as TableHead, Fe as TableHeader, Ie as TableRow, Le as Tabs, Re as TabsContent, ze as TabsList, Be as TabsTrigger, Ve as Textarea, He as Tooltip, Ue as TooltipContent, We as TooltipProvider, Ge as TooltipTrigger, gt as TrackingMap, ot as TrendChart, bt as TypeBadge, xt as VehicleTypeBadge, st as VolumeBar, Ze as chartTokens, lt as createCurrentIcon, ut as createPinIcon, dt as createStopIcon, ft as isRealCoord, Qe as seriesColor, E as useAnalytics, W as useCaptureEpod, b as useCustomer, x as useCustomerStats, S as useCustomers, D as useDashboardMetrics, c as useDriver, N as useDriverTracking, l as useDrivers, U as useEntityDocuments, G as useEpod, K as useEpodPhotoUpload, q as useEpodPhotoUrl, O as useFinanceMetrics, u as useFleet, k as useFleetAnalytics, d as useFleetStats, P as useGeofence, V as useImportExport, m as useInventory, h as useInventoryStats, F as useLiveTracking, H as useModuleSettings, e as useMoveTheWheels, t as useMoveTheWheelsNavigate, r as useMoveTheWheelsStore, J as useMyPendingEpodDeliveryJobs, Tt as useNotice, a as useOrder, A as useOrderAnalytics, o as useOrderStats, I as useOrderTracking, s as useOrders, j as usePerformanceAnalytics, g as useProduct, _ as useProducts, B as useReports, M as useRevenueAnalytics, C as useRoute, w as useRouteStats, T as useRoutes, i as useSandboxAssistantTransport, L as useTracking, R as useTrackingAlerts, f as useVehicle, z as useVehicleTracking, p as useVehicles, v as useWarehouse, y as useWarehouses };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface SignaturePadHandle {
|
|
2
|
+
clear: () => void;
|
|
3
|
+
isEmpty: () => boolean;
|
|
4
|
+
toDataUrl: () => string | null;
|
|
5
|
+
}
|
|
6
|
+
interface SignaturePadProps {
|
|
7
|
+
className?: string;
|
|
8
|
+
onChange?: (hasSignature: boolean) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const SignaturePad: import('react').ForwardRefExoticComponent<SignaturePadProps & import('react').RefAttributes<SignaturePadHandle>>;
|
|
11
|
+
export {};
|
|
@@ -14,3 +14,4 @@ export { useReports } from './useReports';
|
|
|
14
14
|
export { useImportExport } from './useImportExport';
|
|
15
15
|
export { useModuleSettings } from './useSettings';
|
|
16
16
|
export { useEntityDocuments, type EntityDocument, type EntityDocumentType, } from './useEntityDocuments';
|
|
17
|
+
export { useEpod, useMyPendingEpodDeliveryJobs, useCaptureEpod, useEpodPhotoUpload, useEpodPhotoUrl, type PendingEpodDeliveryJob, type CaptureEpodArgs, type UploadedEpodPhoto, } from './useEpod';
|
|
@@ -5,10 +5,26 @@
|
|
|
5
5
|
* driver or order live in the platform Files module (wspace-files-svc), which
|
|
6
6
|
* federates into the same workspace gateway. We tag each uploaded file with two
|
|
7
7
|
* marqueue entity tags — `mtwEntityType` and `mtwEntityId` — and list them back
|
|
8
|
-
* here through
|
|
8
|
+
* here through `getFiles(filter:{ tags:[...] })`.
|
|
9
9
|
*
|
|
10
10
|
* There is no upload UI here (out of scope): uploading/managing happens in the
|
|
11
11
|
* Files module, deep-linked from DocumentsCard. This hook is read-only.
|
|
12
|
+
*
|
|
13
|
+
* BOFF-3922 fix (2026-07-26): this previously called a non-existent root field
|
|
14
|
+
* `files(...)` — the wspace gateway only exposes `Workspace.files` (nested) and
|
|
15
|
+
* root fields `getFiles`/`searchFiles`/`ownedFiles`/`uploadedFiles`, none named
|
|
16
|
+
* bare `files`. Fixed to `getFiles(...): FileList!` (unwrapping `.files`), the
|
|
17
|
+
* root field whose `folderId` arg is optional so it supports a workspace-wide
|
|
18
|
+
* filter-only lookup. Caught by the new graphql-schema-drift CI guard, which
|
|
19
|
+
* had zero prior coverage on this repo — this bug would otherwise have shipped
|
|
20
|
+
* to prod undetected, same as BOFF-3915/BOFF-4703/BOFF-3529.
|
|
21
|
+
*
|
|
22
|
+
* NOT verified by this fix: whether `TagFilterInput.label` (renamed here from
|
|
23
|
+
* the nonexistent `.value`) actually produces the intended
|
|
24
|
+
* mtwEntityType+mtwEntityId AND-filter semantics against wspace-files-svc's
|
|
25
|
+
* tag-matching resolver — that's a wspace-files-svc/wspace-tags-svc business-
|
|
26
|
+
* logic question outside a schema-shape validator's reach (it operates on
|
|
27
|
+
* runtime variable values, not the query document). Flagged as follow-up.
|
|
12
28
|
*/
|
|
13
29
|
export type EntityDocumentType = 'vehicle' | 'driver' | 'order';
|
|
14
30
|
export interface EntityDocument {
|