@burdenoff/microfe-movethewheels 2026.827.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.
Files changed (39) hide show
  1. package/dist/MoveTheWheelsRoot.js +86 -83
  2. package/dist/MoveTheWheelsRoutes.js +107 -104
  3. package/dist/hooks/index.js +1 -0
  4. package/dist/hooks/useImportExport.js +22 -51
  5. package/dist/hooks/useReports.js +63 -73
  6. package/dist/hooks/useSettings.js +52 -44
  7. package/dist/index.js +38 -37
  8. package/dist/movethewheels/hooks/index.d.ts +1 -0
  9. package/dist/movethewheels/hooks/useImportExport.d.ts +10 -0
  10. package/dist/movethewheels/pages/MarketplacePage.d.ts +7 -4
  11. package/dist/movethewheels/shared/hooks/useTr.d.ts +16 -0
  12. package/dist/pages/AIAssistantPage.js +45 -43
  13. package/dist/pages/DashboardPage.js +6 -6
  14. package/dist/pages/FleetPage.js +7 -7
  15. package/dist/pages/InventoryPage.js +6 -6
  16. package/dist/pages/MarketplacePage.js +11 -432
  17. package/dist/pages/OrdersListPage.js +5 -5
  18. package/dist/pages/ReportsPage.js +120 -109
  19. package/dist/pages/SettingsPage.js +175 -154
  20. package/dist/pages/TrackingPage.js +5 -5
  21. package/dist/shared/hooks/useTr.js +12 -0
  22. package/package.json +2 -2
  23. package/src/movethewheels/MoveTheWheelsRoot.tsx +28 -24
  24. package/src/movethewheels/MoveTheWheelsRoutes.tsx +5 -2
  25. package/src/movethewheels/hooks/index.ts +3 -0
  26. package/src/movethewheels/hooks/useImportExport.ts +36 -72
  27. package/src/movethewheels/hooks/useReports.ts +73 -87
  28. package/src/movethewheels/hooks/useSettings.ts +50 -53
  29. package/src/movethewheels/pages/AIAssistantPage.tsx +50 -32
  30. package/src/movethewheels/pages/MarketplacePage.tsx +16 -539
  31. package/src/movethewheels/pages/ReportsPage.tsx +23 -0
  32. package/src/movethewheels/pages/SettingsPage.tsx +154 -70
  33. package/src/movethewheels/shared/hooks/useTr.ts +37 -0
  34. package/dist/generated/global-operations.d.ts +0 -1
  35. package/dist/generated/global-types.d.ts +0 -23526
  36. package/dist/node_modules/lucide-react/dist/esm/icons/chevron-down.js +0 -8
  37. package/dist/node_modules/lucide-react/dist/esm/icons/chevron-up.js +0 -8
  38. package/src/generated/global-operations.ts +0 -2
  39. package/src/generated/global-types.ts +0 -27259
@@ -1,6 +1,5 @@
1
1
  import { useCallback, useEffect, useMemo, useState } from 'react';
2
2
  import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
3
- import { executeGraphQL } from '../utils/graphqlClient';
4
3
 
5
4
  export type ModulePreferences = Record<string, unknown>;
6
5
 
@@ -10,26 +9,6 @@ export interface ModuleSettings {
10
9
  workspaceId: string;
11
10
  }
12
11
 
13
- const MODULE_SETTINGS_QUERY = `
14
- query MovethewheelsModuleSettings {
15
- moduleSettings {
16
- preferences
17
- updatedAt
18
- workspaceId
19
- }
20
- }
21
- `;
22
-
23
- const UPDATE_MODULE_SETTINGS_MUTATION = `
24
- mutation UpdateMovethewheelsModuleSettings($input: UpdateMovethewheelsModuleSettingsInput!) {
25
- updateModuleSettings(input: $input) {
26
- preferences
27
- updatedAt
28
- workspaceId
29
- }
30
- }
31
- `;
32
-
33
12
  interface UseModuleSettingsResult {
34
13
  settings: ModuleSettings | null;
35
14
  preferences: ModulePreferences;
@@ -40,41 +19,58 @@ interface UseModuleSettingsResult {
40
19
  savePreferences: (preferences: ModulePreferences) => Promise<ModuleSettings>;
41
20
  }
42
21
 
22
+ function readSettings(workspaceId: string): ModuleSettings | null {
23
+ if (typeof window === 'undefined') return null;
24
+ try {
25
+ const raw = window.localStorage.getItem(`movethewheels:moduleSettings:${workspaceId}`);
26
+ if (!raw) return null;
27
+ const parsed = JSON.parse(raw) as ModuleSettings;
28
+ if (parsed && typeof parsed === 'object' && 'preferences' in parsed) {
29
+ return parsed;
30
+ }
31
+ return null;
32
+ } catch {
33
+ return null;
34
+ }
35
+ }
36
+
37
+ function writeSettings(settings: ModuleSettings): void {
38
+ if (typeof window === 'undefined') return;
39
+ try {
40
+ window.localStorage.setItem(
41
+ `movethewheels:moduleSettings:${settings.workspaceId}`,
42
+ JSON.stringify(settings)
43
+ );
44
+ } catch {
45
+ // Ignore storage errors (e.g. private mode quota).
46
+ }
47
+ }
48
+
43
49
  export function useModuleSettings(): UseModuleSettingsResult {
44
- const { apiGatewayUrl, authToken, workspaceToken, workspaceId, tenantId, currentUser } =
45
- useMoveTheWheels();
50
+ const { workspaceId } = useMoveTheWheels();
46
51
  const [settings, setSettings] = useState<ModuleSettings | null>(null);
47
52
  const [isLoading, setIsLoading] = useState(false);
48
53
  const [isSaving, setIsSaving] = useState(false);
49
54
  const [error, setError] = useState<Error | null>(null);
50
55
 
51
- const graphQLOptions = useMemo(
52
- () => ({
53
- apiGatewayUrl,
54
- authToken,
55
- workspaceToken,
56
- workspaceId,
57
- tenantId,
58
- actorId: currentUser?.id,
59
- }),
60
- [apiGatewayUrl, authToken, workspaceToken, workspaceId, tenantId, currentUser?.id]
61
- );
62
-
63
- const load = useCallback(async () => {
56
+ const load = useCallback(() => {
64
57
  setIsLoading(true);
65
58
  setError(null);
66
59
  try {
67
- const data = await executeGraphQL<{ moduleSettings: ModuleSettings }>(
68
- graphQLOptions,
69
- MODULE_SETTINGS_QUERY
60
+ const stored = workspaceId ? readSettings(workspaceId) : null;
61
+ setSettings(
62
+ stored ?? {
63
+ preferences: {},
64
+ updatedAt: new Date().toISOString(),
65
+ workspaceId: workspaceId ?? '',
66
+ }
70
67
  );
71
- setSettings(data.moduleSettings);
72
- } catch (fetchError) {
73
- setError(fetchError instanceof Error ? fetchError : new Error('Failed to load settings'));
68
+ } catch (loadError) {
69
+ setError(loadError instanceof Error ? loadError : new Error('Failed to load settings'));
74
70
  } finally {
75
71
  setIsLoading(false);
76
72
  }
77
- }, [graphQLOptions]);
73
+ }, [workspaceId]);
78
74
 
79
75
  useEffect(() => {
80
76
  void load();
@@ -89,23 +85,24 @@ export function useModuleSettings(): UseModuleSettingsResult {
89
85
  setIsSaving(true);
90
86
  setError(null);
91
87
  try {
92
- const data = await executeGraphQL<{ updateModuleSettings: ModuleSettings }>(
93
- graphQLOptions,
94
- UPDATE_MODULE_SETTINGS_MUTATION,
95
- { input: { preferences } }
96
- );
97
- setSettings(data.updateModuleSettings);
98
- return data.updateModuleSettings;
99
- } catch (fetchError) {
88
+ const next: ModuleSettings = {
89
+ preferences,
90
+ updatedAt: new Date().toISOString(),
91
+ workspaceId: workspaceId ?? '',
92
+ };
93
+ writeSettings(next);
94
+ setSettings(next);
95
+ return next;
96
+ } catch (saveError) {
100
97
  const normalized =
101
- fetchError instanceof Error ? fetchError : new Error('Failed to save settings');
98
+ saveError instanceof Error ? saveError : new Error('Failed to save settings');
102
99
  setError(normalized);
103
100
  throw normalized;
104
101
  } finally {
105
102
  setIsSaving(false);
106
103
  }
107
104
  },
108
- [graphQLOptions]
105
+ [workspaceId]
109
106
  );
110
107
 
111
108
  // Stabilize the preferences reference. Returning `settings?.preferences ?? {}`
@@ -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="AI Operations"
52
- subtitle="What the AI is doing on your workspace, and why"
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
- This page will surface AI-driven dispatch decisions and their outcomes once the shared AI
57
- runtime lands. It does not host a chat box — chat with your live operational data is always
58
- available from the assistant icon anywhere in the app.
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
- Open the assistant from its icon in the corner of the screen — it answers from your
70
- live orders, shipments, fleet and inventory data, and it is the only chat surface in
71
- this product.
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="Autonomous dispatch operations aren't live yet"
85
- description="Autonomous dispatch isn't available yet — these capabilities are still in development. Nothing below is available today."
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) => (