@burdenoff/microfe-movethewheels 2026.719.2 → 2026.722.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/MoveTheWheelsRoot.js +45 -35
- package/dist/pages/AIAssistantPage.js +1 -1
- package/dist/pages/MarketplacePage.js +143 -124
- package/package.json +2 -1
- package/src/movethewheels/MoveTheWheelsRoot.tsx +57 -29
- package/src/movethewheels/pages/AIAssistantPage.tsx +1 -1
- package/src/movethewheels/pages/MarketplacePage.tsx +34 -1
|
@@ -18,16 +18,16 @@ import { Warehouse as g } from "./node_modules/lucide-react/dist/esm/icons/wareh
|
|
|
18
18
|
import { MoveTheWheelsProvider as _ } from "./providers/MoveTheWheelsProvider.js";
|
|
19
19
|
import { MoveTheWheelsRoutes as v } from "./MoveTheWheelsRoutes.js";
|
|
20
20
|
import { useEffect as y } from "react";
|
|
21
|
-
import { jsx as b } from "react/jsx-runtime";
|
|
22
|
-
import { FeatureFlagProvider as
|
|
21
|
+
import { jsx as b, jsxs as x } from "react/jsx-runtime";
|
|
22
|
+
import { FeatureFlagProvider as S, useFeatureFlag as C } from "@burdenoff/fe-libs/shared/feature-flags";
|
|
23
23
|
//#region src/movethewheels/MoveTheWheelsRoot.tsx
|
|
24
|
-
var
|
|
25
|
-
let
|
|
24
|
+
var w = ({ registerNavItems: _, basePath: v = "/" }) => {
|
|
25
|
+
let x = C("movethewheels.marketplace", !1), S = (e, t) => (e.endsWith("/") ? e.slice(0, -1) : e) + (t.startsWith("/") ? t : `/${t}`);
|
|
26
26
|
return y(() => {
|
|
27
|
-
if (
|
|
27
|
+
if (_) return _({
|
|
28
28
|
id: "movethewheels",
|
|
29
29
|
label: "MoveTheWheels",
|
|
30
|
-
path:
|
|
30
|
+
path: v,
|
|
31
31
|
icon: /* @__PURE__ */ b(p, { size: 20 }),
|
|
32
32
|
order: 25,
|
|
33
33
|
group: "workspace",
|
|
@@ -35,49 +35,49 @@ var S = (S) => {
|
|
|
35
35
|
{
|
|
36
36
|
id: "mtw-dashboard",
|
|
37
37
|
label: "Dashboard",
|
|
38
|
-
path:
|
|
38
|
+
path: v,
|
|
39
39
|
icon: /* @__PURE__ */ b(s, { size: 16 }),
|
|
40
40
|
order: 1
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
id: "mtw-orders",
|
|
44
44
|
label: "Orders",
|
|
45
|
-
path:
|
|
45
|
+
path: S(v, "orders"),
|
|
46
46
|
icon: /* @__PURE__ */ b(l, { size: 16 }),
|
|
47
47
|
order: 2
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
id: "mtw-tracking",
|
|
51
51
|
label: "Tracking",
|
|
52
|
-
path:
|
|
52
|
+
path: S(v, "tracking"),
|
|
53
53
|
icon: /* @__PURE__ */ b(c, { size: 16 }),
|
|
54
54
|
order: 3
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
id: "mtw-fleet",
|
|
58
58
|
label: "Fleet",
|
|
59
|
-
path:
|
|
59
|
+
path: S(v, "fleet"),
|
|
60
60
|
icon: /* @__PURE__ */ b(p, { size: 16 }),
|
|
61
61
|
order: 4,
|
|
62
62
|
children: [
|
|
63
63
|
{
|
|
64
64
|
id: "mtw-fleet-overview",
|
|
65
65
|
label: "Overview",
|
|
66
|
-
path:
|
|
66
|
+
path: S(v, "fleet"),
|
|
67
67
|
icon: /* @__PURE__ */ b(s, { size: 14 }),
|
|
68
68
|
order: 1
|
|
69
69
|
},
|
|
70
70
|
{
|
|
71
71
|
id: "mtw-vehicles",
|
|
72
72
|
label: "Vehicles",
|
|
73
|
-
path:
|
|
73
|
+
path: S(v, "fleet/vehicles"),
|
|
74
74
|
icon: /* @__PURE__ */ b(n, { size: 14 }),
|
|
75
75
|
order: 2
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
78
|
id: "mtw-drivers",
|
|
79
79
|
label: "Drivers",
|
|
80
|
-
path:
|
|
80
|
+
path: S(v, "fleet/drivers"),
|
|
81
81
|
icon: /* @__PURE__ */ b(m, { size: 14 }),
|
|
82
82
|
order: 3
|
|
83
83
|
}
|
|
@@ -86,28 +86,28 @@ var S = (S) => {
|
|
|
86
86
|
{
|
|
87
87
|
id: "mtw-inventory",
|
|
88
88
|
label: "Inventory",
|
|
89
|
-
path:
|
|
89
|
+
path: S(v, "inventory"),
|
|
90
90
|
icon: /* @__PURE__ */ b(g, { size: 16 }),
|
|
91
91
|
order: 5,
|
|
92
92
|
children: [
|
|
93
93
|
{
|
|
94
94
|
id: "mtw-inventory-overview",
|
|
95
95
|
label: "Overview",
|
|
96
|
-
path:
|
|
96
|
+
path: S(v, "inventory"),
|
|
97
97
|
icon: /* @__PURE__ */ b(s, { size: 14 }),
|
|
98
98
|
order: 1
|
|
99
99
|
},
|
|
100
100
|
{
|
|
101
101
|
id: "mtw-products",
|
|
102
102
|
label: "Products",
|
|
103
|
-
path:
|
|
103
|
+
path: S(v, "inventory/products"),
|
|
104
104
|
icon: /* @__PURE__ */ b(t, { size: 14 }),
|
|
105
105
|
order: 2
|
|
106
106
|
},
|
|
107
107
|
{
|
|
108
108
|
id: "mtw-warehouses",
|
|
109
109
|
label: "Warehouses",
|
|
110
|
-
path:
|
|
110
|
+
path: S(v, "inventory/warehouses"),
|
|
111
111
|
icon: /* @__PURE__ */ b(g, { size: 14 }),
|
|
112
112
|
order: 3
|
|
113
113
|
}
|
|
@@ -116,88 +116,98 @@ var S = (S) => {
|
|
|
116
116
|
{
|
|
117
117
|
id: "mtw-customers",
|
|
118
118
|
label: "Customers",
|
|
119
|
-
path:
|
|
119
|
+
path: S(v, "customers"),
|
|
120
120
|
icon: /* @__PURE__ */ b(h, { size: 16 }),
|
|
121
121
|
order: 6
|
|
122
122
|
},
|
|
123
123
|
{
|
|
124
124
|
id: "mtw-routes",
|
|
125
125
|
label: "Routes",
|
|
126
|
-
path:
|
|
126
|
+
path: S(v, "routes"),
|
|
127
127
|
icon: /* @__PURE__ */ b(u, { size: 16 }),
|
|
128
128
|
order: 7
|
|
129
129
|
},
|
|
130
130
|
{
|
|
131
131
|
id: "mtw-analytics",
|
|
132
132
|
label: "Analytics",
|
|
133
|
-
path:
|
|
133
|
+
path: S(v, "analytics"),
|
|
134
134
|
icon: /* @__PURE__ */ b(r, { size: 16 }),
|
|
135
135
|
order: 8
|
|
136
136
|
},
|
|
137
137
|
{
|
|
138
138
|
id: "mtw-finance",
|
|
139
139
|
label: "Finance",
|
|
140
|
-
path:
|
|
140
|
+
path: S(v, "finance"),
|
|
141
141
|
icon: /* @__PURE__ */ b(i, { size: 16 }),
|
|
142
142
|
order: 9
|
|
143
143
|
},
|
|
144
|
-
{
|
|
144
|
+
...x ? [{
|
|
145
145
|
id: "mtw-marketplace",
|
|
146
146
|
label: "Marketplace",
|
|
147
|
-
path:
|
|
147
|
+
path: S(v, "marketplace"),
|
|
148
148
|
icon: /* @__PURE__ */ b(f, { size: 16 }),
|
|
149
149
|
order: 10
|
|
150
|
-
},
|
|
150
|
+
}] : [],
|
|
151
151
|
{
|
|
152
152
|
id: "mtw-import-export",
|
|
153
153
|
label: "Import/Export",
|
|
154
|
-
path:
|
|
154
|
+
path: S(v, "import-export"),
|
|
155
155
|
icon: /* @__PURE__ */ b(o, { size: 16 }),
|
|
156
156
|
order: 11
|
|
157
157
|
},
|
|
158
158
|
{
|
|
159
159
|
id: "mtw-reports",
|
|
160
160
|
label: "Reports",
|
|
161
|
-
path:
|
|
161
|
+
path: S(v, "reports"),
|
|
162
162
|
icon: /* @__PURE__ */ b(a, { size: 16 }),
|
|
163
163
|
order: 12
|
|
164
164
|
},
|
|
165
165
|
{
|
|
166
166
|
id: "mtw-ai-assistant",
|
|
167
167
|
label: "AI Assistant",
|
|
168
|
-
path:
|
|
168
|
+
path: S(v, "ai-assistant"),
|
|
169
169
|
icon: /* @__PURE__ */ b(e, { size: 16 }),
|
|
170
170
|
order: 13
|
|
171
171
|
},
|
|
172
172
|
{
|
|
173
173
|
id: "mtw-settings",
|
|
174
174
|
label: "Settings",
|
|
175
|
-
path:
|
|
175
|
+
path: S(v, "settings"),
|
|
176
176
|
icon: /* @__PURE__ */ b(d, { size: 16 }),
|
|
177
177
|
order: 99
|
|
178
178
|
}
|
|
179
179
|
]
|
|
180
180
|
});
|
|
181
|
-
}, [
|
|
182
|
-
|
|
181
|
+
}, [
|
|
182
|
+
_,
|
|
183
|
+
v,
|
|
184
|
+
x
|
|
185
|
+
]), null;
|
|
186
|
+
}, T = (e) => {
|
|
187
|
+
let { registerNavItems: t, registerFooterItems: n, basePath: r = "/" } = e;
|
|
188
|
+
return y(() => {
|
|
189
|
+
if (n) return n([{
|
|
183
190
|
id: "mtw-status",
|
|
184
191
|
label: "Logistics Ready",
|
|
185
192
|
type: "status",
|
|
186
193
|
order: 20,
|
|
187
194
|
section: "left"
|
|
188
195
|
}]);
|
|
189
|
-
}, [
|
|
196
|
+
}, [n]), /* @__PURE__ */ x(S, {
|
|
190
197
|
workspaceId: null,
|
|
191
198
|
gateway: "global",
|
|
192
199
|
defaultEnabled: !0,
|
|
193
|
-
children: /* @__PURE__ */ b(
|
|
194
|
-
|
|
200
|
+
children: [/* @__PURE__ */ b(w, {
|
|
201
|
+
registerNavItems: t,
|
|
202
|
+
basePath: r
|
|
203
|
+
}), /* @__PURE__ */ b(_, {
|
|
204
|
+
...e,
|
|
195
205
|
children: /* @__PURE__ */ b("div", {
|
|
196
206
|
className: "movethewheels-root h-full",
|
|
197
207
|
children: /* @__PURE__ */ b(v, {})
|
|
198
208
|
})
|
|
199
|
-
})
|
|
209
|
+
})]
|
|
200
210
|
});
|
|
201
211
|
};
|
|
202
212
|
//#endregion
|
|
203
|
-
export {
|
|
213
|
+
export { T as MoveTheWheelsRoot };
|
|
@@ -55,7 +55,7 @@ function g() {
|
|
|
55
55
|
/* @__PURE__ */ f(a, { children: [/* @__PURE__ */ d(s, { children: /* @__PURE__ */ d(c, { children: "On the roadmap" }) }), /* @__PURE__ */ f(o, { children: [/* @__PURE__ */ d(l, {
|
|
56
56
|
illustration: "empty-agents",
|
|
57
57
|
title: "Autonomous dispatch operations aren't live yet",
|
|
58
|
-
description: "
|
|
58
|
+
description: "Autonomous dispatch isn't available yet — these capabilities are still in development. Nothing below is available today."
|
|
59
59
|
}), /* @__PURE__ */ d("ul", {
|
|
60
60
|
className: "mt-4 space-y-4",
|
|
61
61
|
children: h.map((e) => /* @__PURE__ */ f("li", {
|
|
@@ -11,13 +11,14 @@ import { Store as i } from "../node_modules/lucide-react/dist/esm/icons/store.js
|
|
|
11
11
|
import { useMoveTheWheels as ae } from "../providers/MoveTheWheelsProvider.js";
|
|
12
12
|
import { executeGraphQL as a } from "../utils/graphqlClient.js";
|
|
13
13
|
import { Badge as o, Button as s, Card as c, CardContent as l, CardHeader as oe, CardTitle as se, Input as ce, Select as u, SelectContent as d, SelectItem as f, SelectTrigger as p, SelectValue as m, Skeleton as le } from "../components/ui.js";
|
|
14
|
-
import { PageLayout as
|
|
15
|
-
import { formatCurrency as
|
|
16
|
-
import { useCallback as
|
|
17
|
-
import { Fragment as
|
|
18
|
-
import {
|
|
14
|
+
import { PageLayout as h } from "../components/PageLayout.js";
|
|
15
|
+
import { formatCurrency as g } from "../utils/formatters.js";
|
|
16
|
+
import { useCallback as _, useEffect as ue, useMemo as v, useState as y } from "react";
|
|
17
|
+
import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
|
|
18
|
+
import { useFeatureFlag as de } from "@burdenoff/fe-libs/shared/feature-flags";
|
|
19
|
+
import { EmphasisPanel as fe, IllustratedEmptyState as C, PagePurpose as pe } from "@burdenoff/fe-libs/ui";
|
|
19
20
|
//#region src/movethewheels/pages/MarketplacePage.tsx
|
|
20
|
-
var
|
|
21
|
+
var me = "movethewheels.marketplace", he = "\n query ListServiceProviders($filter: ServiceProviderFilterInput, $pagination: PaginationInput) {\n serviceProviders(filter: $filter, pagination: $pagination) {\n id\n name\n type\n description\n rating\n isVerified\n isActive\n services\n contactInfo\n }\n }\n", ge = "\n query ListServiceOfferings($filter: ServiceOfferingFilterInput, $pagination: PaginationInput) {\n serviceOfferings(filter: $filter, pagination: $pagination) {\n id\n providerId\n name\n description\n category\n price\n currency\n availability\n provider {\n id\n name\n type\n rating\n }\n }\n }\n", w = 12, _e = [
|
|
21
22
|
{
|
|
22
23
|
value: "0",
|
|
23
24
|
label: "Any rating"
|
|
@@ -35,8 +36,8 @@ var pe = "\n query ListServiceProviders($filter: ServiceProviderFilterInput, $p
|
|
|
35
36
|
label: "4.5+"
|
|
36
37
|
}
|
|
37
38
|
];
|
|
38
|
-
function
|
|
39
|
-
let { apiGatewayUrl: E, authToken: D, workspaceToken: O, workspaceId: k, tenantId: A, currentUser: j } = ae(), [M,
|
|
39
|
+
function T() {
|
|
40
|
+
let T = de(me, !1), { apiGatewayUrl: E, authToken: D, workspaceToken: O, workspaceId: k, tenantId: A, currentUser: j } = ae(), [M, ve] = y([]), [N, ye] = y([]), [P, be] = y(""), [F, I] = y(!1), [L, R] = y(null), [z, B] = y(0), [xe, Se] = y(!1), [V, Ce] = y(!1), [H, U] = y("all"), [W, G] = y(!1), [K, q] = y("0"), [we, J] = y(null), Y = v(() => ({
|
|
40
41
|
apiGatewayUrl: E,
|
|
41
42
|
authToken: D,
|
|
42
43
|
workspaceToken: O,
|
|
@@ -50,30 +51,36 @@ function E() {
|
|
|
50
51
|
k,
|
|
51
52
|
A,
|
|
52
53
|
j?.id
|
|
53
|
-
]), X =
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
54
|
+
]), X = _(async () => {
|
|
55
|
+
if (T) {
|
|
56
|
+
I(!0), R(null);
|
|
57
|
+
try {
|
|
58
|
+
let [e, t] = await Promise.all([a(Y, he, { pagination: {
|
|
59
|
+
limit: w,
|
|
60
|
+
offset: z * w
|
|
61
|
+
} }), a(Y, ge, { pagination: {
|
|
62
|
+
limit: 200,
|
|
63
|
+
offset: 0
|
|
64
|
+
} })]);
|
|
65
|
+
ve(e.serviceProviders), Se(e.serviceProviders.length === w), ye(t.serviceOfferings);
|
|
66
|
+
} catch (e) {
|
|
67
|
+
R(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load marketplace"));
|
|
68
|
+
} finally {
|
|
69
|
+
I(!1);
|
|
70
|
+
}
|
|
68
71
|
}
|
|
69
|
-
}, [
|
|
70
|
-
|
|
72
|
+
}, [
|
|
73
|
+
Y,
|
|
74
|
+
z,
|
|
75
|
+
T
|
|
76
|
+
]);
|
|
77
|
+
ue(() => {
|
|
71
78
|
X();
|
|
72
79
|
}, [X]);
|
|
73
|
-
let
|
|
80
|
+
let Te = v(() => {
|
|
74
81
|
let e = /* @__PURE__ */ new Set();
|
|
75
82
|
return M.forEach((t) => e.add(t.type)), Array.from(e).sort();
|
|
76
|
-
}, [M]), Z =
|
|
83
|
+
}, [M]), Z = v(() => {
|
|
77
84
|
let e = P.trim().toLowerCase(), t = Number(K);
|
|
78
85
|
return M.filter((n) => !(e && !(n.name.toLowerCase().includes(e) || (n.description ?? "").toLowerCase().includes(e) || n.type.toLowerCase().includes(e)) || H !== "all" && n.type !== H || W && !n.isVerified || t > 0 && (n.rating ?? 0) < t));
|
|
79
86
|
}, [
|
|
@@ -82,84 +89,84 @@ function E() {
|
|
|
82
89
|
H,
|
|
83
90
|
W,
|
|
84
91
|
K
|
|
85
|
-
]), Q =
|
|
92
|
+
]), Q = v(() => {
|
|
86
93
|
let e = P.trim().toLowerCase();
|
|
87
94
|
return e ? N.filter((t) => t.name.toLowerCase().includes(e) || (t.description ?? "").toLowerCase().includes(e) || (t.category ?? "").toLowerCase().includes(e)) : N;
|
|
88
|
-
}, [N, P]),
|
|
89
|
-
return /* @__PURE__ */
|
|
95
|
+
}, [N, P]), Ee = _((e) => N.filter((t) => t.providerId === e), [N]), $ = H !== "all" || W || K !== "0";
|
|
96
|
+
return T ? /* @__PURE__ */ S(h, {
|
|
90
97
|
title: "Marketplace",
|
|
91
98
|
subtitle: "Find logistics service providers",
|
|
92
|
-
icon: /* @__PURE__ */
|
|
93
|
-
headerActions: /* @__PURE__ */
|
|
99
|
+
icon: /* @__PURE__ */ x(i, { size: 24 }),
|
|
100
|
+
headerActions: /* @__PURE__ */ S(s, {
|
|
94
101
|
variant: V || $ ? "default" : "outline",
|
|
95
|
-
onClick: () =>
|
|
96
|
-
children: [/* @__PURE__ */
|
|
102
|
+
onClick: () => Ce((e) => !e),
|
|
103
|
+
children: [/* @__PURE__ */ x(r, { size: 16 }), " Filters"]
|
|
97
104
|
}),
|
|
98
105
|
children: [
|
|
99
|
-
/* @__PURE__ */
|
|
100
|
-
icon: /* @__PURE__ */
|
|
106
|
+
/* @__PURE__ */ x(pe, {
|
|
107
|
+
icon: /* @__PURE__ */ x(i, { size: 18 }),
|
|
101
108
|
children: "Don't own every leg of the journey? Find vetted third-party logistics providers and service offerings here — compare ratings, verification status and pricing, then engage a partner to cover routes, warehousing or specialised handling you can't do in-house."
|
|
102
109
|
}),
|
|
103
|
-
/* @__PURE__ */
|
|
110
|
+
/* @__PURE__ */ x(c, { children: /* @__PURE__ */ S(l, {
|
|
104
111
|
className: "p-4 space-y-4",
|
|
105
|
-
children: [/* @__PURE__ */
|
|
112
|
+
children: [/* @__PURE__ */ S("div", {
|
|
106
113
|
className: "relative",
|
|
107
|
-
children: [/* @__PURE__ */
|
|
114
|
+
children: [/* @__PURE__ */ x(re, {
|
|
108
115
|
className: "absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary",
|
|
109
116
|
size: 20
|
|
110
|
-
}), /* @__PURE__ */
|
|
117
|
+
}), /* @__PURE__ */ x(ce, {
|
|
111
118
|
placeholder: "Search services, providers, locations...",
|
|
112
119
|
className: "pl-10",
|
|
113
120
|
value: P,
|
|
114
|
-
onChange: (e) =>
|
|
121
|
+
onChange: (e) => be(e.target.value)
|
|
115
122
|
})]
|
|
116
|
-
}), V && /* @__PURE__ */
|
|
123
|
+
}), V && /* @__PURE__ */ S("div", {
|
|
117
124
|
className: "flex flex-wrap items-center gap-3 border-t border-border-seam pt-4",
|
|
118
125
|
children: [
|
|
119
|
-
/* @__PURE__ */
|
|
126
|
+
/* @__PURE__ */ S("div", {
|
|
120
127
|
className: "flex items-center gap-2",
|
|
121
|
-
children: [/* @__PURE__ */
|
|
128
|
+
children: [/* @__PURE__ */ x("span", {
|
|
122
129
|
className: "text-sm font-medium text-text-secondary",
|
|
123
130
|
children: "Type"
|
|
124
|
-
}), /* @__PURE__ */
|
|
131
|
+
}), /* @__PURE__ */ S(u, {
|
|
125
132
|
value: H,
|
|
126
133
|
onValueChange: U,
|
|
127
|
-
children: [/* @__PURE__ */
|
|
134
|
+
children: [/* @__PURE__ */ x(p, {
|
|
128
135
|
className: "w-[160px]",
|
|
129
|
-
children: /* @__PURE__ */
|
|
130
|
-
}), /* @__PURE__ */
|
|
136
|
+
children: /* @__PURE__ */ x(m, { placeholder: "All types" })
|
|
137
|
+
}), /* @__PURE__ */ S(d, { children: [/* @__PURE__ */ x(f, {
|
|
131
138
|
value: "all",
|
|
132
139
|
children: "All types"
|
|
133
|
-
}),
|
|
140
|
+
}), Te.map((e) => /* @__PURE__ */ x(f, {
|
|
134
141
|
value: e,
|
|
135
142
|
children: e
|
|
136
143
|
}, e))] })]
|
|
137
144
|
})]
|
|
138
145
|
}),
|
|
139
|
-
/* @__PURE__ */
|
|
146
|
+
/* @__PURE__ */ S("div", {
|
|
140
147
|
className: "flex items-center gap-2",
|
|
141
|
-
children: [/* @__PURE__ */
|
|
148
|
+
children: [/* @__PURE__ */ x("span", {
|
|
142
149
|
className: "text-sm font-medium text-text-secondary",
|
|
143
150
|
children: "Min rating"
|
|
144
|
-
}), /* @__PURE__ */
|
|
151
|
+
}), /* @__PURE__ */ S(u, {
|
|
145
152
|
value: K,
|
|
146
153
|
onValueChange: q,
|
|
147
|
-
children: [/* @__PURE__ */
|
|
154
|
+
children: [/* @__PURE__ */ x(p, {
|
|
148
155
|
className: "w-[130px]",
|
|
149
|
-
children: /* @__PURE__ */
|
|
150
|
-
}), /* @__PURE__ */
|
|
156
|
+
children: /* @__PURE__ */ x(m, {})
|
|
157
|
+
}), /* @__PURE__ */ x(d, { children: _e.map((e) => /* @__PURE__ */ x(f, {
|
|
151
158
|
value: e.value,
|
|
152
159
|
children: e.label
|
|
153
160
|
}, e.value)) })]
|
|
154
161
|
})]
|
|
155
162
|
}),
|
|
156
|
-
/* @__PURE__ */
|
|
163
|
+
/* @__PURE__ */ x(s, {
|
|
157
164
|
variant: W ? "default" : "outline",
|
|
158
165
|
size: "sm",
|
|
159
166
|
onClick: () => G((e) => !e),
|
|
160
167
|
children: "Verified only"
|
|
161
168
|
}),
|
|
162
|
-
$ && /* @__PURE__ */
|
|
169
|
+
$ && /* @__PURE__ */ x(s, {
|
|
163
170
|
variant: "ghost",
|
|
164
171
|
size: "sm",
|
|
165
172
|
onClick: () => {
|
|
@@ -170,12 +177,12 @@ function E() {
|
|
|
170
177
|
]
|
|
171
178
|
})]
|
|
172
179
|
}) }),
|
|
173
|
-
/* @__PURE__ */
|
|
180
|
+
/* @__PURE__ */ S("div", {
|
|
174
181
|
className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
|
|
175
|
-
children: [/* @__PURE__ */
|
|
182
|
+
children: [/* @__PURE__ */ S("div", {
|
|
176
183
|
className: "lg:col-span-2 space-y-4",
|
|
177
184
|
children: [
|
|
178
|
-
/* @__PURE__ */
|
|
185
|
+
/* @__PURE__ */ S("h3", {
|
|
179
186
|
className: "font-semibold",
|
|
180
187
|
children: [
|
|
181
188
|
"Service Providers (",
|
|
@@ -183,20 +190,20 @@ function E() {
|
|
|
183
190
|
")"
|
|
184
191
|
]
|
|
185
192
|
}),
|
|
186
|
-
L && !F && /* @__PURE__ */
|
|
193
|
+
L && !F && /* @__PURE__ */ x(c, {
|
|
187
194
|
className: "border-status-error-border",
|
|
188
|
-
children: /* @__PURE__ */
|
|
195
|
+
children: /* @__PURE__ */ S(l, {
|
|
189
196
|
className: "p-6 text-center space-y-3",
|
|
190
197
|
children: [
|
|
191
|
-
/* @__PURE__ */
|
|
198
|
+
/* @__PURE__ */ x("p", {
|
|
192
199
|
className: "text-status-error-text font-medium",
|
|
193
200
|
children: "Couldn't load providers"
|
|
194
201
|
}),
|
|
195
|
-
/* @__PURE__ */
|
|
202
|
+
/* @__PURE__ */ x("p", {
|
|
196
203
|
className: "text-sm text-text-secondary",
|
|
197
204
|
children: L.message
|
|
198
205
|
}),
|
|
199
|
-
/* @__PURE__ */
|
|
206
|
+
/* @__PURE__ */ x(s, {
|
|
200
207
|
variant: "outline",
|
|
201
208
|
onClick: () => void X(),
|
|
202
209
|
children: "Retry"
|
|
@@ -204,57 +211,57 @@ function E() {
|
|
|
204
211
|
]
|
|
205
212
|
})
|
|
206
213
|
}),
|
|
207
|
-
F && Array.from({ length: 3 }).map((e, t) => /* @__PURE__ */
|
|
208
|
-
!F && !L && Z.length === 0 && /* @__PURE__ */
|
|
214
|
+
F && Array.from({ length: 3 }).map((e, t) => /* @__PURE__ */ x(le, { className: "h-32 w-full rounded-lg" }, t)),
|
|
215
|
+
!F && !L && Z.length === 0 && /* @__PURE__ */ x(c, { children: /* @__PURE__ */ x(l, {
|
|
209
216
|
className: "p-0",
|
|
210
|
-
children: /* @__PURE__ */
|
|
217
|
+
children: /* @__PURE__ */ x(C, {
|
|
211
218
|
illustration: P.trim() || $ ? "empty-search" : "empty-people",
|
|
212
219
|
title: P.trim() || $ ? "No providers match your filters" : "No providers yet",
|
|
213
220
|
description: P.trim() || $ ? "Adjust your search or filters to find logistics partners." : "Verified logistics service providers will appear here as they join the marketplace."
|
|
214
221
|
})
|
|
215
222
|
}) }),
|
|
216
223
|
!F && !L && Z.map((t) => {
|
|
217
|
-
let n =
|
|
218
|
-
return /* @__PURE__ */
|
|
224
|
+
let n = we === t.id, r = Ee(t.id);
|
|
225
|
+
return /* @__PURE__ */ S(c, { children: [/* @__PURE__ */ x("button", {
|
|
219
226
|
type: "button",
|
|
220
227
|
"aria-expanded": n,
|
|
221
228
|
className: "w-full text-left",
|
|
222
229
|
onClick: () => J(n ? null : t.id),
|
|
223
|
-
children: /* @__PURE__ */
|
|
230
|
+
children: /* @__PURE__ */ x(l, {
|
|
224
231
|
className: "p-6",
|
|
225
|
-
children: /* @__PURE__ */
|
|
232
|
+
children: /* @__PURE__ */ S("div", {
|
|
226
233
|
className: "flex items-start justify-between gap-3",
|
|
227
|
-
children: [/* @__PURE__ */
|
|
234
|
+
children: [/* @__PURE__ */ S("div", {
|
|
228
235
|
className: "min-w-0",
|
|
229
236
|
children: [
|
|
230
|
-
/* @__PURE__ */
|
|
237
|
+
/* @__PURE__ */ S("div", {
|
|
231
238
|
className: "flex items-center gap-2 flex-wrap",
|
|
232
239
|
children: [
|
|
233
|
-
/* @__PURE__ */
|
|
240
|
+
/* @__PURE__ */ x("h4", {
|
|
234
241
|
className: "font-semibold text-lg",
|
|
235
242
|
children: t.name
|
|
236
243
|
}),
|
|
237
|
-
t.isVerified && /* @__PURE__ */
|
|
244
|
+
t.isVerified && /* @__PURE__ */ x(o, {
|
|
238
245
|
variant: "default",
|
|
239
246
|
children: "Verified"
|
|
240
247
|
}),
|
|
241
|
-
/* @__PURE__ */
|
|
248
|
+
/* @__PURE__ */ x(o, {
|
|
242
249
|
variant: t.isActive ? "default" : "secondary",
|
|
243
250
|
children: t.isActive ? "active" : "inactive"
|
|
244
251
|
})
|
|
245
252
|
]
|
|
246
253
|
}),
|
|
247
|
-
/* @__PURE__ */
|
|
254
|
+
/* @__PURE__ */ x("p", {
|
|
248
255
|
className: "text-text-secondary mt-1",
|
|
249
256
|
children: t.description
|
|
250
257
|
}),
|
|
251
|
-
/* @__PURE__ */
|
|
258
|
+
/* @__PURE__ */ S("div", {
|
|
252
259
|
className: "flex items-center gap-4 mt-3 text-sm text-text-secondary",
|
|
253
260
|
children: [
|
|
254
|
-
/* @__PURE__ */
|
|
261
|
+
/* @__PURE__ */ S("span", {
|
|
255
262
|
className: "flex items-center gap-1",
|
|
256
263
|
children: [
|
|
257
|
-
/* @__PURE__ */
|
|
264
|
+
/* @__PURE__ */ x(ie, {
|
|
258
265
|
size: 14,
|
|
259
266
|
className: "text-status-warning-text fill-current"
|
|
260
267
|
}),
|
|
@@ -262,65 +269,65 @@ function E() {
|
|
|
262
269
|
t.rating ?? 0
|
|
263
270
|
]
|
|
264
271
|
}),
|
|
265
|
-
/* @__PURE__ */
|
|
272
|
+
/* @__PURE__ */ S("span", {
|
|
266
273
|
className: "flex items-center gap-1",
|
|
267
274
|
children: [
|
|
268
|
-
/* @__PURE__ */
|
|
275
|
+
/* @__PURE__ */ x(ne, { size: 14 }),
|
|
269
276
|
" ",
|
|
270
277
|
t.type
|
|
271
278
|
]
|
|
272
279
|
}),
|
|
273
|
-
/* @__PURE__ */
|
|
280
|
+
/* @__PURE__ */ S("span", {
|
|
274
281
|
className: "flex items-center gap-1",
|
|
275
|
-
children: [/* @__PURE__ */
|
|
282
|
+
children: [/* @__PURE__ */ x(te, { size: 14 }), " Listed"]
|
|
276
283
|
})
|
|
277
284
|
]
|
|
278
285
|
})
|
|
279
286
|
]
|
|
280
|
-
}), /* @__PURE__ */
|
|
287
|
+
}), /* @__PURE__ */ S("div", {
|
|
281
288
|
className: "text-right shrink-0",
|
|
282
289
|
children: [
|
|
283
|
-
/* @__PURE__ */
|
|
290
|
+
/* @__PURE__ */ x("p", {
|
|
284
291
|
className: "text-sm text-text-secondary",
|
|
285
292
|
children: "Services"
|
|
286
293
|
}),
|
|
287
|
-
/* @__PURE__ */
|
|
294
|
+
/* @__PURE__ */ x("p", {
|
|
288
295
|
className: "text-lg font-bold",
|
|
289
296
|
children: r.length
|
|
290
297
|
}),
|
|
291
|
-
/* @__PURE__ */
|
|
298
|
+
/* @__PURE__ */ x("span", {
|
|
292
299
|
className: "mt-1 inline-flex items-center gap-1 text-xs text-primary",
|
|
293
|
-
children: n ? /* @__PURE__ */
|
|
300
|
+
children: n ? /* @__PURE__ */ S(b, { children: ["Hide ", /* @__PURE__ */ x(ee, { size: 14 })] }) : /* @__PURE__ */ S(b, { children: ["View ", /* @__PURE__ */ x(e, { size: 14 })] })
|
|
294
301
|
})
|
|
295
302
|
]
|
|
296
303
|
})]
|
|
297
304
|
})
|
|
298
305
|
})
|
|
299
|
-
}), n && /* @__PURE__ */
|
|
306
|
+
}), n && /* @__PURE__ */ S("div", {
|
|
300
307
|
className: "border-t border-border-seam px-6 py-4 space-y-3",
|
|
301
|
-
children: [/* @__PURE__ */
|
|
308
|
+
children: [/* @__PURE__ */ S("p", {
|
|
302
309
|
className: "text-sm font-medium text-text-secondary",
|
|
303
310
|
children: ["Offerings from ", t.name]
|
|
304
|
-
}), r.length === 0 ? /* @__PURE__ */
|
|
311
|
+
}), r.length === 0 ? /* @__PURE__ */ x("p", {
|
|
305
312
|
className: "text-sm text-text-secondary",
|
|
306
313
|
children: "This provider hasn't listed any offerings yet."
|
|
307
|
-
}) : r.map((e) => /* @__PURE__ */
|
|
314
|
+
}) : r.map((e) => /* @__PURE__ */ S("div", {
|
|
308
315
|
className: "flex items-center justify-between gap-3 rounded-lg border border-border-seam p-3",
|
|
309
|
-
children: [/* @__PURE__ */
|
|
316
|
+
children: [/* @__PURE__ */ S("div", {
|
|
310
317
|
className: "min-w-0",
|
|
311
|
-
children: [/* @__PURE__ */
|
|
318
|
+
children: [/* @__PURE__ */ x("p", {
|
|
312
319
|
className: "font-medium truncate",
|
|
313
320
|
children: e.name
|
|
314
|
-
}), /* @__PURE__ */
|
|
321
|
+
}), /* @__PURE__ */ x("p", {
|
|
315
322
|
className: "text-sm text-text-secondary truncate",
|
|
316
323
|
children: e.category ?? "general"
|
|
317
324
|
})]
|
|
318
|
-
}), /* @__PURE__ */
|
|
325
|
+
}), /* @__PURE__ */ S("div", {
|
|
319
326
|
className: "text-right shrink-0",
|
|
320
|
-
children: [/* @__PURE__ */
|
|
327
|
+
children: [/* @__PURE__ */ x("p", {
|
|
321
328
|
className: "font-bold",
|
|
322
|
-
children:
|
|
323
|
-
}), /* @__PURE__ */
|
|
329
|
+
children: g(e.price)
|
|
330
|
+
}), /* @__PURE__ */ x("p", {
|
|
324
331
|
className: "text-xs text-text-secondary",
|
|
325
332
|
children: e.currency
|
|
326
333
|
})]
|
|
@@ -328,9 +335,9 @@ function E() {
|
|
|
328
335
|
}, e.id))]
|
|
329
336
|
})] }, t.id);
|
|
330
337
|
}),
|
|
331
|
-
!F && !L && (M.length > 0 || z > 0) && /* @__PURE__ */
|
|
338
|
+
!F && !L && (M.length > 0 || z > 0) && /* @__PURE__ */ S("div", {
|
|
332
339
|
className: "flex flex-wrap items-center justify-between gap-3 pt-1",
|
|
333
|
-
children: [/* @__PURE__ */
|
|
340
|
+
children: [/* @__PURE__ */ S("span", {
|
|
334
341
|
className: "text-sm text-text-secondary",
|
|
335
342
|
children: [
|
|
336
343
|
"Showing ",
|
|
@@ -339,10 +346,10 @@ function E() {
|
|
|
339
346
|
" ",
|
|
340
347
|
z * w + M.length
|
|
341
348
|
]
|
|
342
|
-
}), /* @__PURE__ */
|
|
349
|
+
}), /* @__PURE__ */ S("div", {
|
|
343
350
|
className: "flex items-center gap-1",
|
|
344
351
|
children: [
|
|
345
|
-
/* @__PURE__ */
|
|
352
|
+
/* @__PURE__ */ x(s, {
|
|
346
353
|
variant: "outline",
|
|
347
354
|
size: "icon",
|
|
348
355
|
className: "h-8 w-8",
|
|
@@ -351,13 +358,13 @@ function E() {
|
|
|
351
358
|
J(null), B((e) => Math.max(0, e - 1));
|
|
352
359
|
},
|
|
353
360
|
disabled: z === 0,
|
|
354
|
-
children: /* @__PURE__ */
|
|
361
|
+
children: /* @__PURE__ */ x(t, { className: "h-4 w-4" })
|
|
355
362
|
}),
|
|
356
|
-
/* @__PURE__ */
|
|
363
|
+
/* @__PURE__ */ S("span", {
|
|
357
364
|
className: "px-3 text-sm",
|
|
358
365
|
children: ["Page ", z + 1]
|
|
359
366
|
}),
|
|
360
|
-
/* @__PURE__ */
|
|
367
|
+
/* @__PURE__ */ x(s, {
|
|
361
368
|
variant: "outline",
|
|
362
369
|
size: "icon",
|
|
363
370
|
className: "h-8 w-8",
|
|
@@ -365,51 +372,51 @@ function E() {
|
|
|
365
372
|
onClick: () => {
|
|
366
373
|
J(null), B((e) => e + 1);
|
|
367
374
|
},
|
|
368
|
-
disabled: !
|
|
369
|
-
children: /* @__PURE__ */
|
|
375
|
+
disabled: !xe,
|
|
376
|
+
children: /* @__PURE__ */ x(n, { className: "h-4 w-4" })
|
|
370
377
|
})
|
|
371
378
|
]
|
|
372
379
|
})]
|
|
373
380
|
})
|
|
374
381
|
]
|
|
375
|
-
}), /* @__PURE__ */
|
|
382
|
+
}), /* @__PURE__ */ S(fe, {
|
|
376
383
|
className: "space-y-4",
|
|
377
384
|
children: [
|
|
378
|
-
/* @__PURE__ */
|
|
385
|
+
/* @__PURE__ */ x("h3", {
|
|
379
386
|
className: "text-base font-semibold text-text-primary",
|
|
380
387
|
children: "Popular Services"
|
|
381
388
|
}),
|
|
382
|
-
Q.length === 0 && /* @__PURE__ */
|
|
389
|
+
Q.length === 0 && /* @__PURE__ */ x(C, {
|
|
383
390
|
illustration: P.trim() ? "empty-search" : "empty-generic",
|
|
384
391
|
title: P.trim() ? "No matching services" : "No services listed yet",
|
|
385
392
|
description: P.trim() ? "Adjust your search to discover service offerings." : "Service offerings from providers will be listed here."
|
|
386
393
|
}),
|
|
387
|
-
Q.map((e) => /* @__PURE__ */
|
|
394
|
+
Q.map((e) => /* @__PURE__ */ S(c, { children: [/* @__PURE__ */ x(oe, { children: /* @__PURE__ */ x(se, {
|
|
388
395
|
className: "text-base",
|
|
389
396
|
children: e.name
|
|
390
|
-
}) }), /* @__PURE__ */
|
|
391
|
-
/* @__PURE__ */
|
|
397
|
+
}) }), /* @__PURE__ */ S(l, { children: [
|
|
398
|
+
/* @__PURE__ */ x("p", {
|
|
392
399
|
className: "text-sm text-text-secondary mb-3",
|
|
393
400
|
children: e.description
|
|
394
401
|
}),
|
|
395
|
-
/* @__PURE__ */
|
|
402
|
+
/* @__PURE__ */ S("div", {
|
|
396
403
|
className: "flex flex-wrap gap-1 mb-3",
|
|
397
|
-
children: [/* @__PURE__ */
|
|
404
|
+
children: [/* @__PURE__ */ x(o, {
|
|
398
405
|
variant: "outline",
|
|
399
406
|
className: "text-xs",
|
|
400
407
|
children: e.category ?? "general"
|
|
401
|
-
}), /* @__PURE__ */
|
|
408
|
+
}), /* @__PURE__ */ x(o, {
|
|
402
409
|
variant: "outline",
|
|
403
410
|
className: "text-xs",
|
|
404
411
|
children: e.provider?.name ?? "provider"
|
|
405
412
|
})]
|
|
406
413
|
}),
|
|
407
|
-
/* @__PURE__ */
|
|
414
|
+
/* @__PURE__ */ S("div", {
|
|
408
415
|
className: "flex items-center justify-between",
|
|
409
|
-
children: [/* @__PURE__ */
|
|
416
|
+
children: [/* @__PURE__ */ x("span", {
|
|
410
417
|
className: "font-bold",
|
|
411
|
-
children:
|
|
412
|
-
}), /* @__PURE__ */
|
|
418
|
+
children: g(e.price)
|
|
419
|
+
}), /* @__PURE__ */ x("span", {
|
|
413
420
|
className: "text-sm text-text-secondary",
|
|
414
421
|
children: e.currency
|
|
415
422
|
})]
|
|
@@ -419,7 +426,19 @@ function E() {
|
|
|
419
426
|
})]
|
|
420
427
|
})
|
|
421
428
|
]
|
|
429
|
+
}) : /* @__PURE__ */ x(h, {
|
|
430
|
+
title: "Marketplace",
|
|
431
|
+
subtitle: "Find logistics service providers",
|
|
432
|
+
icon: /* @__PURE__ */ x(i, { size: 24 }),
|
|
433
|
+
children: /* @__PURE__ */ x(c, { children: /* @__PURE__ */ x(l, {
|
|
434
|
+
className: "p-0",
|
|
435
|
+
children: /* @__PURE__ */ x(C, {
|
|
436
|
+
illustration: "empty-people",
|
|
437
|
+
title: "Marketplace is coming soon",
|
|
438
|
+
description: "The collaborative logistics marketplace is not open yet. Check back after it launches to browse verified third-party service providers."
|
|
439
|
+
})
|
|
440
|
+
}) })
|
|
422
441
|
});
|
|
423
442
|
}
|
|
424
443
|
//#endregion
|
|
425
|
-
export {
|
|
444
|
+
export { T as default };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-movethewheels",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.722.1",
|
|
4
4
|
"description": "Burdenoff MoveTheWheels Microfrontend - Logistics & Supply Chain Management Platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -91,6 +91,7 @@
|
|
|
91
91
|
"lefthook": "^2.1.1",
|
|
92
92
|
"postcss": "^8.4.49",
|
|
93
93
|
"prettier": "^3.4.2",
|
|
94
|
+
"storybook": "^8.6.0",
|
|
94
95
|
"tailwindcss": "^4.0.0",
|
|
95
96
|
"typescript": "^5.9.0",
|
|
96
97
|
"typescript-eslint": "^8.54.0",
|
|
@@ -27,33 +27,27 @@ import {
|
|
|
27
27
|
Bot,
|
|
28
28
|
} from 'lucide-react';
|
|
29
29
|
import { MoveTheWheelsProvider } from './providers/MoveTheWheelsProvider';
|
|
30
|
-
import { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';
|
|
30
|
+
import { FeatureFlagProvider, useFeatureFlag } from '@burdenoff/fe-libs/shared/feature-flags';
|
|
31
31
|
import type { NavItem, MoveTheWheelsRootProps } from './types';
|
|
32
32
|
import { MoveTheWheelsRoutes } from './MoveTheWheelsRoutes';
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* ```tsx
|
|
39
|
-
* import { MoveTheWheelsRoot } from '@burdenoff/microfe-movethewheels';
|
|
35
|
+
* Registers the MoveTheWheels sidebar nav tree with the host shell.
|
|
40
36
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* navigate={(path) => router.push(path)}
|
|
46
|
-
* currentUser={currentUser}
|
|
47
|
-
* workspaceId="ws-123"
|
|
48
|
-
* apiGatewayUrl="https://api.example.com"
|
|
49
|
-
* authToken="token"
|
|
50
|
-
* />
|
|
51
|
-
* );
|
|
52
|
-
* }
|
|
53
|
-
* ```
|
|
37
|
+
* Split out from `MoveTheWheelsRoot` so it renders as a descendant of the
|
|
38
|
+
* `<FeatureFlagProvider>` below — `useFeatureFlag` requires a Provider
|
|
39
|
+
* ancestor, and the Provider is only established once `MoveTheWheelsRoot`'s
|
|
40
|
+
* own JSX (which includes this component) has mounted.
|
|
54
41
|
*/
|
|
55
|
-
|
|
56
|
-
|
|
42
|
+
const NavRegistrar: FC<Pick<MoveTheWheelsRootProps, 'registerNavItems' | 'basePath'>> = ({
|
|
43
|
+
registerNavItems,
|
|
44
|
+
basePath = '/',
|
|
45
|
+
}) => {
|
|
46
|
+
// The backend has no ServiceProvider/ServiceOffering model (dropped by
|
|
47
|
+
// migration 20260707000001_movethewheels_reuse_cleanup) — hide the
|
|
48
|
+
// Marketplace nav entry until a serviceProviders/serviceOfferings resolver
|
|
49
|
+
// ships. Defaults to disabled (fails closed).
|
|
50
|
+
const marketplaceEnabled = useFeatureFlag('movethewheels.marketplace', false);
|
|
57
51
|
|
|
58
52
|
// Helper to join paths correctly, avoiding double slashes
|
|
59
53
|
const joinPath = (base: string, path: string): string => {
|
|
@@ -183,13 +177,19 @@ export const MoveTheWheelsRoot: FC<MoveTheWheelsRootProps> = (props) => {
|
|
|
183
177
|
icon: <DollarSign size={16} />,
|
|
184
178
|
order: 9,
|
|
185
179
|
},
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
180
|
+
// Hidden until a serviceProviders/serviceOfferings backend resolver
|
|
181
|
+
// ships — see the marketplaceEnabled flag check above.
|
|
182
|
+
...(marketplaceEnabled
|
|
183
|
+
? [
|
|
184
|
+
{
|
|
185
|
+
id: 'mtw-marketplace',
|
|
186
|
+
label: 'Marketplace',
|
|
187
|
+
path: joinPath(basePath, 'marketplace'),
|
|
188
|
+
icon: <Store size={16} />,
|
|
189
|
+
order: 10,
|
|
190
|
+
},
|
|
191
|
+
]
|
|
192
|
+
: []),
|
|
193
193
|
{
|
|
194
194
|
id: 'mtw-import-export',
|
|
195
195
|
label: 'Import/Export',
|
|
@@ -226,7 +226,34 @@ export const MoveTheWheelsRoot: FC<MoveTheWheelsRootProps> = (props) => {
|
|
|
226
226
|
|
|
227
227
|
// Return cleanup function to unregister on unmount
|
|
228
228
|
return cleanup;
|
|
229
|
-
}, [registerNavItems, basePath]);
|
|
229
|
+
}, [registerNavItems, basePath, marketplaceEnabled]);
|
|
230
|
+
|
|
231
|
+
return null;
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Root component for the MoveTheWheels microfrontend.
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```tsx
|
|
239
|
+
* import { MoveTheWheelsRoot } from '@burdenoff/microfe-movethewheels';
|
|
240
|
+
*
|
|
241
|
+
* function App() {
|
|
242
|
+
* return (
|
|
243
|
+
* <MoveTheWheelsRoot
|
|
244
|
+
* basePath="/movethewheels"
|
|
245
|
+
* navigate={(path) => router.push(path)}
|
|
246
|
+
* currentUser={currentUser}
|
|
247
|
+
* workspaceId="ws-123"
|
|
248
|
+
* apiGatewayUrl="https://api.example.com"
|
|
249
|
+
* authToken="token"
|
|
250
|
+
* />
|
|
251
|
+
* );
|
|
252
|
+
* }
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
export const MoveTheWheelsRoot: FC<MoveTheWheelsRootProps> = (props) => {
|
|
256
|
+
const { registerNavItems, registerFooterItems, basePath = '/' } = props;
|
|
230
257
|
|
|
231
258
|
// Register footer items
|
|
232
259
|
useEffect(() => {
|
|
@@ -248,6 +275,7 @@ export const MoveTheWheelsRoot: FC<MoveTheWheelsRootProps> = (props) => {
|
|
|
248
275
|
|
|
249
276
|
return (
|
|
250
277
|
<FeatureFlagProvider workspaceId={null} gateway="global" defaultEnabled={true}>
|
|
278
|
+
<NavRegistrar registerNavItems={registerNavItems} basePath={basePath} />
|
|
251
279
|
<MoveTheWheelsProvider {...props}>
|
|
252
280
|
<div className="movethewheels-root h-full">
|
|
253
281
|
<MoveTheWheelsRoutes />
|
|
@@ -82,7 +82,7 @@ export default function AIAssistantPage() {
|
|
|
82
82
|
<EmptyState
|
|
83
83
|
illustration="empty-agents"
|
|
84
84
|
title="Autonomous dispatch operations aren't live yet"
|
|
85
|
-
description="
|
|
85
|
+
description="Autonomous dispatch isn't available yet — these capabilities are still in development. Nothing below is available today."
|
|
86
86
|
/>
|
|
87
87
|
<ul className="mt-4 space-y-4">
|
|
88
88
|
{roadmapItems.map((item) => (
|
|
@@ -37,10 +37,21 @@ import {
|
|
|
37
37
|
SelectValue,
|
|
38
38
|
} from '../components/ui';
|
|
39
39
|
import { EmphasisPanel, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';
|
|
40
|
+
import { useFeatureFlag } from '@burdenoff/fe-libs/shared/feature-flags';
|
|
40
41
|
import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
|
|
41
42
|
import { formatCurrency } from '../utils/formatters';
|
|
42
43
|
import { executeGraphQL } from '../utils/graphqlClient';
|
|
43
44
|
|
|
45
|
+
/**
|
|
46
|
+
* The backend has no ServiceProvider/ServiceOffering model (dropped by
|
|
47
|
+
* migration 20260707000001_movethewheels_reuse_cleanup) — `serviceProviders`
|
|
48
|
+
* and `serviceOfferings` are not resolvable fields today. Gate the whole page
|
|
49
|
+
* behind a flag that defaults to **disabled** so it fails closed (an empty
|
|
50
|
+
* "coming soon" state) instead of erroring on every load. Flip this on only
|
|
51
|
+
* once a serviceProviders/serviceOfferings resolver ships.
|
|
52
|
+
*/
|
|
53
|
+
const MARKETPLACE_FEATURE_FLAG = 'movethewheels.marketplace';
|
|
54
|
+
|
|
44
55
|
interface ApiServiceProvider {
|
|
45
56
|
id: string;
|
|
46
57
|
name: string;
|
|
@@ -117,6 +128,7 @@ const RATING_OPTIONS: { value: string; label: string }[] = [
|
|
|
117
128
|
];
|
|
118
129
|
|
|
119
130
|
export default function MarketplacePage() {
|
|
131
|
+
const marketplaceEnabled = useFeatureFlag(MARKETPLACE_FEATURE_FLAG, false);
|
|
120
132
|
const { apiGatewayUrl, authToken, workspaceToken, workspaceId, tenantId, currentUser } =
|
|
121
133
|
useMoveTheWheels();
|
|
122
134
|
const [providers, setProviders] = useState<ApiServiceProvider[]>([]);
|
|
@@ -149,6 +161,7 @@ export default function MarketplacePage() {
|
|
|
149
161
|
);
|
|
150
162
|
|
|
151
163
|
const load = useCallback(async () => {
|
|
164
|
+
if (!marketplaceEnabled) return;
|
|
152
165
|
setIsLoading(true);
|
|
153
166
|
setError(null);
|
|
154
167
|
try {
|
|
@@ -177,7 +190,7 @@ export default function MarketplacePage() {
|
|
|
177
190
|
} finally {
|
|
178
191
|
setIsLoading(false);
|
|
179
192
|
}
|
|
180
|
-
}, [graphQLOptions, page]);
|
|
193
|
+
}, [graphQLOptions, page, marketplaceEnabled]);
|
|
181
194
|
|
|
182
195
|
useEffect(() => {
|
|
183
196
|
void load();
|
|
@@ -225,6 +238,26 @@ export default function MarketplacePage() {
|
|
|
225
238
|
|
|
226
239
|
const filtersActive = typeFilter !== 'all' || verifiedOnly || minRating !== '0';
|
|
227
240
|
|
|
241
|
+
if (!marketplaceEnabled) {
|
|
242
|
+
return (
|
|
243
|
+
<PageLayout
|
|
244
|
+
title="Marketplace"
|
|
245
|
+
subtitle="Find logistics service providers"
|
|
246
|
+
icon={<Store size={24} />}
|
|
247
|
+
>
|
|
248
|
+
<Card>
|
|
249
|
+
<CardContent className="p-0">
|
|
250
|
+
<IllustratedEmptyState
|
|
251
|
+
illustration="empty-people"
|
|
252
|
+
title="Marketplace is coming soon"
|
|
253
|
+
description="The collaborative logistics marketplace is not open yet. Check back after it launches to browse verified third-party service providers."
|
|
254
|
+
/>
|
|
255
|
+
</CardContent>
|
|
256
|
+
</Card>
|
|
257
|
+
</PageLayout>
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
|
|
228
261
|
return (
|
|
229
262
|
<PageLayout
|
|
230
263
|
title="Marketplace"
|