@burdenoff/microfe-movethewheels 2026.828.1 → 2026.830.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 +86 -83
- package/dist/MoveTheWheelsRoutes.js +107 -104
- package/dist/hooks/index.js +1 -0
- package/dist/index.js +38 -37
- package/dist/movethewheels/hooks/index.d.ts +1 -0
- package/dist/movethewheels/shared/hooks/useTr.d.ts +16 -0
- package/dist/pages/AIAssistantPage.js +45 -43
- package/dist/pages/DashboardPage.js +6 -6
- package/dist/pages/FleetPage.js +7 -7
- package/dist/pages/InventoryPage.js +6 -6
- package/dist/pages/OrdersListPage.js +5 -5
- package/dist/pages/SettingsPage.js +175 -154
- package/dist/pages/TrackingPage.js +5 -5
- package/dist/shared/hooks/useTr.js +12 -0
- package/package.json +1 -1
- package/src/movethewheels/MoveTheWheelsRoot.tsx +28 -24
- package/src/movethewheels/MoveTheWheelsRoutes.tsx +5 -2
- package/src/movethewheels/hooks/index.ts +3 -0
- package/src/movethewheels/pages/AIAssistantPage.tsx +50 -32
- package/src/movethewheels/pages/SettingsPage.tsx +154 -70
- package/src/movethewheels/shared/hooks/useTr.ts +37 -0
|
@@ -30,6 +30,7 @@ import { MoveTheWheelsProvider } from './providers/MoveTheWheelsProvider';
|
|
|
30
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
|
+
import { useTr } from './hooks';
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* Registers the MoveTheWheels sidebar nav tree with the host shell.
|
|
@@ -43,6 +44,8 @@ const NavRegistrar: FC<Pick<MoveTheWheelsRootProps, 'registerNavItems' | 'basePa
|
|
|
43
44
|
registerNavItems,
|
|
44
45
|
basePath = '/',
|
|
45
46
|
}) => {
|
|
47
|
+
const tr = useTr();
|
|
48
|
+
|
|
46
49
|
// The backend has no ServiceProvider/ServiceOffering model (dropped by
|
|
47
50
|
// migration 20260707000001_movethewheels_reuse_cleanup) — hide the
|
|
48
51
|
// Marketplace nav entry until a serviceProviders/serviceOfferings resolver
|
|
@@ -62,7 +65,7 @@ const NavRegistrar: FC<Pick<MoveTheWheelsRootProps, 'registerNavItems' | 'basePa
|
|
|
62
65
|
|
|
63
66
|
const movethewheelsNavItem: NavItem = {
|
|
64
67
|
id: 'movethewheels',
|
|
65
|
-
label: 'MoveTheWheels',
|
|
68
|
+
label: tr('movethewheels.page.title', 'MoveTheWheels'),
|
|
66
69
|
path: basePath,
|
|
67
70
|
icon: <Truck size={20} />,
|
|
68
71
|
order: 25,
|
|
@@ -70,49 +73,49 @@ const NavRegistrar: FC<Pick<MoveTheWheelsRootProps, 'registerNavItems' | 'basePa
|
|
|
70
73
|
children: [
|
|
71
74
|
{
|
|
72
75
|
id: 'mtw-dashboard',
|
|
73
|
-
label: 'Dashboard',
|
|
76
|
+
label: tr('movethewheels.root.nav.dashboard', 'Dashboard'),
|
|
74
77
|
path: basePath,
|
|
75
78
|
icon: <LayoutDashboard size={16} />,
|
|
76
79
|
order: 1,
|
|
77
80
|
},
|
|
78
81
|
{
|
|
79
82
|
id: 'mtw-orders',
|
|
80
|
-
label: 'Orders',
|
|
83
|
+
label: tr('movethewheels.root.nav.orders', 'Orders'),
|
|
81
84
|
path: joinPath(basePath, 'orders'),
|
|
82
85
|
icon: <Package size={16} />,
|
|
83
86
|
order: 2,
|
|
84
87
|
},
|
|
85
88
|
{
|
|
86
89
|
id: 'mtw-tracking',
|
|
87
|
-
label: 'Tracking',
|
|
90
|
+
label: tr('movethewheels.root.nav.tracking', 'Tracking'),
|
|
88
91
|
path: joinPath(basePath, 'tracking'),
|
|
89
92
|
icon: <Map size={16} />,
|
|
90
93
|
order: 3,
|
|
91
94
|
},
|
|
92
95
|
{
|
|
93
96
|
id: 'mtw-fleet',
|
|
94
|
-
label: 'Fleet',
|
|
97
|
+
label: tr('movethewheels.root.nav.fleet', 'Fleet'),
|
|
95
98
|
path: joinPath(basePath, 'fleet'),
|
|
96
99
|
icon: <Truck size={16} />,
|
|
97
100
|
order: 4,
|
|
98
101
|
children: [
|
|
99
102
|
{
|
|
100
103
|
id: 'mtw-fleet-overview',
|
|
101
|
-
label: 'Overview',
|
|
104
|
+
label: tr('movethewheels.root.nav.overview', 'Overview'),
|
|
102
105
|
path: joinPath(basePath, 'fleet'),
|
|
103
106
|
icon: <LayoutDashboard size={14} />,
|
|
104
107
|
order: 1,
|
|
105
108
|
},
|
|
106
109
|
{
|
|
107
110
|
id: 'mtw-vehicles',
|
|
108
|
-
label: 'Vehicles',
|
|
111
|
+
label: tr('movethewheels.root.nav.vehicles', 'Vehicles'),
|
|
109
112
|
path: joinPath(basePath, 'fleet/vehicles'),
|
|
110
113
|
icon: <Car size={14} />,
|
|
111
114
|
order: 2,
|
|
112
115
|
},
|
|
113
116
|
{
|
|
114
117
|
id: 'mtw-drivers',
|
|
115
|
-
label: 'Drivers',
|
|
118
|
+
label: tr('movethewheels.root.nav.drivers', 'Drivers'),
|
|
116
119
|
path: joinPath(basePath, 'fleet/drivers'),
|
|
117
120
|
icon: <UserCheck size={14} />,
|
|
118
121
|
order: 3,
|
|
@@ -121,28 +124,28 @@ const NavRegistrar: FC<Pick<MoveTheWheelsRootProps, 'registerNavItems' | 'basePa
|
|
|
121
124
|
},
|
|
122
125
|
{
|
|
123
126
|
id: 'mtw-inventory',
|
|
124
|
-
label: 'Inventory',
|
|
127
|
+
label: tr('movethewheels.root.nav.inventory', 'Inventory'),
|
|
125
128
|
path: joinPath(basePath, 'inventory'),
|
|
126
129
|
icon: <Warehouse size={16} />,
|
|
127
130
|
order: 5,
|
|
128
131
|
children: [
|
|
129
132
|
{
|
|
130
133
|
id: 'mtw-inventory-overview',
|
|
131
|
-
label: 'Overview',
|
|
134
|
+
label: tr('movethewheels.root.nav.overview', 'Overview'),
|
|
132
135
|
path: joinPath(basePath, 'inventory'),
|
|
133
136
|
icon: <LayoutDashboard size={14} />,
|
|
134
137
|
order: 1,
|
|
135
138
|
},
|
|
136
139
|
{
|
|
137
140
|
id: 'mtw-products',
|
|
138
|
-
label: 'Products',
|
|
141
|
+
label: tr('movethewheels.root.nav.products', 'Products'),
|
|
139
142
|
path: joinPath(basePath, 'inventory/products'),
|
|
140
143
|
icon: <Boxes size={14} />,
|
|
141
144
|
order: 2,
|
|
142
145
|
},
|
|
143
146
|
{
|
|
144
147
|
id: 'mtw-warehouses',
|
|
145
|
-
label: 'Warehouses',
|
|
148
|
+
label: tr('movethewheels.root.nav.warehouses', 'Warehouses'),
|
|
146
149
|
path: joinPath(basePath, 'inventory/warehouses'),
|
|
147
150
|
icon: <Warehouse size={14} />,
|
|
148
151
|
order: 3,
|
|
@@ -151,28 +154,28 @@ const NavRegistrar: FC<Pick<MoveTheWheelsRootProps, 'registerNavItems' | 'basePa
|
|
|
151
154
|
},
|
|
152
155
|
{
|
|
153
156
|
id: 'mtw-customers',
|
|
154
|
-
label: 'Customers',
|
|
157
|
+
label: tr('movethewheels.root.nav.customers', 'Customers'),
|
|
155
158
|
path: joinPath(basePath, 'customers'),
|
|
156
159
|
icon: <Users size={16} />,
|
|
157
160
|
order: 6,
|
|
158
161
|
},
|
|
159
162
|
{
|
|
160
163
|
id: 'mtw-routes',
|
|
161
|
-
label: 'Routes',
|
|
164
|
+
label: tr('movethewheels.root.nav.routes', 'Routes'),
|
|
162
165
|
path: joinPath(basePath, 'routes'),
|
|
163
166
|
icon: <Route size={16} />,
|
|
164
167
|
order: 7,
|
|
165
168
|
},
|
|
166
169
|
{
|
|
167
170
|
id: 'mtw-analytics',
|
|
168
|
-
label: 'Analytics',
|
|
171
|
+
label: tr('movethewheels.root.nav.analytics', 'Analytics'),
|
|
169
172
|
path: joinPath(basePath, 'analytics'),
|
|
170
173
|
icon: <BarChart3 size={16} />,
|
|
171
174
|
order: 8,
|
|
172
175
|
},
|
|
173
176
|
{
|
|
174
177
|
id: 'mtw-finance',
|
|
175
|
-
label: 'Finance',
|
|
178
|
+
label: tr('movethewheels.root.nav.finance', 'Finance'),
|
|
176
179
|
path: joinPath(basePath, 'finance'),
|
|
177
180
|
icon: <DollarSign size={16} />,
|
|
178
181
|
order: 9,
|
|
@@ -183,7 +186,7 @@ const NavRegistrar: FC<Pick<MoveTheWheelsRootProps, 'registerNavItems' | 'basePa
|
|
|
183
186
|
? [
|
|
184
187
|
{
|
|
185
188
|
id: 'mtw-marketplace',
|
|
186
|
-
label: 'Marketplace',
|
|
189
|
+
label: tr('movethewheels.root.nav.marketplace', 'Marketplace'),
|
|
187
190
|
path: joinPath(basePath, 'marketplace'),
|
|
188
191
|
icon: <Store size={16} />,
|
|
189
192
|
order: 10,
|
|
@@ -192,28 +195,28 @@ const NavRegistrar: FC<Pick<MoveTheWheelsRootProps, 'registerNavItems' | 'basePa
|
|
|
192
195
|
: []),
|
|
193
196
|
{
|
|
194
197
|
id: 'mtw-import-export',
|
|
195
|
-
label: 'Import/Export',
|
|
198
|
+
label: tr('movethewheels.root.nav.importExport', 'Import/Export'),
|
|
196
199
|
path: joinPath(basePath, 'import-export'),
|
|
197
200
|
icon: <Globe size={16} />,
|
|
198
201
|
order: 11,
|
|
199
202
|
},
|
|
200
203
|
{
|
|
201
204
|
id: 'mtw-reports',
|
|
202
|
-
label: 'Reports',
|
|
205
|
+
label: tr('movethewheels.root.nav.reports', 'Reports'),
|
|
203
206
|
path: joinPath(basePath, 'reports'),
|
|
204
207
|
icon: <FileText size={16} />,
|
|
205
208
|
order: 12,
|
|
206
209
|
},
|
|
207
210
|
{
|
|
208
211
|
id: 'mtw-ai-assistant',
|
|
209
|
-
label: 'AI Assistant',
|
|
212
|
+
label: tr('movethewheels.root.nav.aiAssistant', 'AI Assistant'),
|
|
210
213
|
path: joinPath(basePath, 'ai-assistant'),
|
|
211
214
|
icon: <Bot size={16} />,
|
|
212
215
|
order: 13,
|
|
213
216
|
},
|
|
214
217
|
{
|
|
215
218
|
id: 'mtw-settings',
|
|
216
|
-
label: 'Settings',
|
|
219
|
+
label: tr('movethewheels.root.nav.settings', 'Settings'),
|
|
217
220
|
path: joinPath(basePath, 'settings'),
|
|
218
221
|
icon: <Settings size={16} />,
|
|
219
222
|
order: 99,
|
|
@@ -226,7 +229,7 @@ const NavRegistrar: FC<Pick<MoveTheWheelsRootProps, 'registerNavItems' | 'basePa
|
|
|
226
229
|
|
|
227
230
|
// Return cleanup function to unregister on unmount
|
|
228
231
|
return cleanup;
|
|
229
|
-
}, [registerNavItems, basePath, marketplaceEnabled]);
|
|
232
|
+
}, [registerNavItems, basePath, marketplaceEnabled, tr]);
|
|
230
233
|
|
|
231
234
|
return null;
|
|
232
235
|
};
|
|
@@ -254,6 +257,7 @@ const NavRegistrar: FC<Pick<MoveTheWheelsRootProps, 'registerNavItems' | 'basePa
|
|
|
254
257
|
*/
|
|
255
258
|
export const MoveTheWheelsRoot: FC<MoveTheWheelsRootProps> = (props) => {
|
|
256
259
|
const { registerNavItems, registerFooterItems, basePath = '/' } = props;
|
|
260
|
+
const tr = useTr();
|
|
257
261
|
|
|
258
262
|
// Register footer items
|
|
259
263
|
useEffect(() => {
|
|
@@ -262,7 +266,7 @@ export const MoveTheWheelsRoot: FC<MoveTheWheelsRootProps> = (props) => {
|
|
|
262
266
|
const footerItems = [
|
|
263
267
|
{
|
|
264
268
|
id: 'mtw-status',
|
|
265
|
-
label: 'Logistics Ready',
|
|
269
|
+
label: tr('movethewheels.root.footer.status', 'Logistics Ready'),
|
|
266
270
|
type: 'status' as const,
|
|
267
271
|
order: 20,
|
|
268
272
|
section: 'left' as const,
|
|
@@ -271,7 +275,7 @@ export const MoveTheWheelsRoot: FC<MoveTheWheelsRootProps> = (props) => {
|
|
|
271
275
|
|
|
272
276
|
const cleanup = registerFooterItems(footerItems);
|
|
273
277
|
return cleanup;
|
|
274
|
-
}, [registerFooterItems]);
|
|
278
|
+
}, [registerFooterItems, tr]);
|
|
275
279
|
|
|
276
280
|
return (
|
|
277
281
|
<FeatureFlagProvider workspaceId={null} gateway="global" defaultEnabled={true}>
|
|
@@ -9,6 +9,7 @@ import { Routes, Route, useNavigate } from 'react-router';
|
|
|
9
9
|
import { lazy, Suspense } from 'react';
|
|
10
10
|
import { NotFoundPage } from '@burdenoff/fe-libs/shared/pages';
|
|
11
11
|
import { useMoveTheWheels } from './providers/MoveTheWheelsProvider';
|
|
12
|
+
import { useTr } from './hooks';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Catch-all 404 rendered inside the content area (previously a redirect to ""
|
|
@@ -18,9 +19,10 @@ import { useMoveTheWheels } from './providers/MoveTheWheelsProvider';
|
|
|
18
19
|
function MoveTheWheelsNotFound() {
|
|
19
20
|
const { navigate, basePath } = useMoveTheWheels();
|
|
20
21
|
const routerNavigate = useNavigate();
|
|
22
|
+
const tr = useTr();
|
|
21
23
|
return (
|
|
22
24
|
<NotFoundPage
|
|
23
|
-
homeLabel=
|
|
25
|
+
homeLabel={tr('movethewheels.root.notFound.homeLabel', 'Back to MoveTheWheels')}
|
|
24
26
|
onGoHome={() => {
|
|
25
27
|
if (navigate) {
|
|
26
28
|
navigate(basePath || '/');
|
|
@@ -34,11 +36,12 @@ function MoveTheWheelsNotFound() {
|
|
|
34
36
|
|
|
35
37
|
// Loading fallback
|
|
36
38
|
function PageLoader() {
|
|
39
|
+
const tr = useTr();
|
|
37
40
|
return (
|
|
38
41
|
<div className="flex items-center justify-center min-h-[400px]">
|
|
39
42
|
<div className="flex flex-col items-center gap-3">
|
|
40
43
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
|
|
41
|
-
<p className="text-sm text-text-secondary">Loading
|
|
44
|
+
<p className="text-sm text-text-secondary">{tr('movethewheels.root.loading', 'Loading...')}</p>
|
|
42
45
|
</div>
|
|
43
46
|
</div>
|
|
44
47
|
);
|
|
@@ -24,38 +24,49 @@ import { Bot, MessageCircle, Activity, ShieldCheck, Wallet } from 'lucide-react'
|
|
|
24
24
|
import { PageLayout, EmptyState } from '../components/PageLayout';
|
|
25
25
|
import { Card, CardContent, CardHeader, CardTitle } from '../components/ui';
|
|
26
26
|
import { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';
|
|
27
|
-
|
|
28
|
-
const roadmapItems = [
|
|
29
|
-
{
|
|
30
|
-
icon: Activity,
|
|
31
|
-
title: 'Agent activity feed',
|
|
32
|
-
description:
|
|
33
|
-
'A live log of what the AI decided, on which shipments, with trigger, model, latency and cost — so an autonomous run is never a black box.',
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
icon: ShieldCheck,
|
|
37
|
-
title: 'Dispatch decision cards',
|
|
38
|
-
description:
|
|
39
|
-
'Proposed driver/vehicle assignments and carrier recommendations with rationale and confidence, requiring an explicit accept or reject before anything is written.',
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
icon: Wallet,
|
|
43
|
-
title: 'AI credit visibility',
|
|
44
|
-
description: 'Per-workspace AI spend for admins, so cost is visible before the invoice.',
|
|
45
|
-
},
|
|
46
|
-
];
|
|
27
|
+
import { useTr } from '../hooks';
|
|
47
28
|
|
|
48
29
|
export default function AIAssistantPage() {
|
|
30
|
+
const tr = useTr();
|
|
31
|
+
|
|
32
|
+
const roadmapItems = [
|
|
33
|
+
{
|
|
34
|
+
icon: Activity,
|
|
35
|
+
title: tr('movethewheels.ai.roadmap.agentActivity.title', 'Agent activity feed'),
|
|
36
|
+
description: tr(
|
|
37
|
+
'movethewheels.ai.roadmap.agentActivity.description',
|
|
38
|
+
'A live log of what the AI decided, on which shipments, with trigger, model, latency and cost — so an autonomous run is never a black box.'
|
|
39
|
+
),
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
icon: ShieldCheck,
|
|
43
|
+
title: tr('movethewheels.ai.roadmap.dispatchDecisionCards.title', 'Dispatch decision cards'),
|
|
44
|
+
description: tr(
|
|
45
|
+
'movethewheels.ai.roadmap.dispatchDecisionCards.description',
|
|
46
|
+
'Proposed driver/vehicle assignments and carrier recommendations with rationale and confidence, requiring an explicit accept or reject before anything is written.'
|
|
47
|
+
),
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
icon: Wallet,
|
|
51
|
+
title: tr('movethewheels.ai.roadmap.aiCreditVisibility.title', 'AI credit visibility'),
|
|
52
|
+
description: tr(
|
|
53
|
+
'movethewheels.ai.roadmap.aiCreditVisibility.description',
|
|
54
|
+
'Per-workspace AI spend for admins, so cost is visible before the invoice.'
|
|
55
|
+
),
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
|
|
49
59
|
return (
|
|
50
60
|
<PageLayout
|
|
51
|
-
title=
|
|
52
|
-
subtitle=
|
|
61
|
+
title={tr('movethewheels.ai.title', 'AI Operations')}
|
|
62
|
+
subtitle={tr('movethewheels.ai.subtitle', 'What the AI is doing on your workspace, and why')}
|
|
53
63
|
icon={<Bot size={24} />}
|
|
54
64
|
>
|
|
55
65
|
<PagePurpose icon={<Bot size={18} />}>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
66
|
+
{tr(
|
|
67
|
+
'movethewheels.ai.purpose',
|
|
68
|
+
'This page will surface AI-driven dispatch decisions and their outcomes once the shared AI runtime lands. It does not host a chat box — chat with your live operational data is always available from the assistant icon anywhere in the app.'
|
|
69
|
+
)}
|
|
59
70
|
</PagePurpose>
|
|
60
71
|
|
|
61
72
|
<GlassCard treatment="glass" className="p-4">
|
|
@@ -63,12 +74,13 @@ export default function AIAssistantPage() {
|
|
|
63
74
|
<MessageCircle size={20} className="text-primary flex-shrink-0 mt-0.5" />
|
|
64
75
|
<div>
|
|
65
76
|
<p className="text-sm font-medium text-text-primary">
|
|
66
|
-
Looking to ask a question about your operations?
|
|
77
|
+
{tr('movethewheels.ai.callout.title', 'Looking to ask a question about your operations?')}
|
|
67
78
|
</p>
|
|
68
79
|
<p className="text-sm text-text-secondary mt-1">
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
80
|
+
{tr(
|
|
81
|
+
'movethewheels.ai.callout.description',
|
|
82
|
+
'Open the assistant from its icon in the corner of the screen — it answers from your live orders, shipments, fleet and inventory data, and it is the only chat surface in this product.'
|
|
83
|
+
)}
|
|
72
84
|
</p>
|
|
73
85
|
</div>
|
|
74
86
|
</div>
|
|
@@ -76,13 +88,19 @@ export default function AIAssistantPage() {
|
|
|
76
88
|
|
|
77
89
|
<Card>
|
|
78
90
|
<CardHeader>
|
|
79
|
-
<CardTitle>On the roadmap</CardTitle>
|
|
91
|
+
<CardTitle>{tr('movethewheels.ai.roadmap.title', 'On the roadmap')}</CardTitle>
|
|
80
92
|
</CardHeader>
|
|
81
93
|
<CardContent>
|
|
82
94
|
<EmptyState
|
|
83
95
|
illustration="empty-agents"
|
|
84
|
-
title=
|
|
85
|
-
|
|
96
|
+
title={tr(
|
|
97
|
+
'movethewheels.ai.emptyState.title',
|
|
98
|
+
"Autonomous dispatch operations aren't live yet"
|
|
99
|
+
)}
|
|
100
|
+
description={tr(
|
|
101
|
+
'movethewheels.ai.emptyState.description',
|
|
102
|
+
"Autonomous dispatch isn't available yet — these capabilities are still in development. Nothing below is available today."
|
|
103
|
+
)}
|
|
86
104
|
/>
|
|
87
105
|
<ul className="mt-4 space-y-4">
|
|
88
106
|
{roadmapItems.map((item) => (
|