@burdenoff/microfe-movethewheels 2026.625.1 → 2026.626.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 (80) hide show
  1. package/dist/{AIAssistantPage-CNyoKtID.js → AIAssistantPage-AvsMbunM.js} +35 -29
  2. package/dist/{AnalyticsPage-Ck615ox7.js → AnalyticsPage-CCLfHgQZ.js} +36 -25
  3. package/dist/CreateOrderPage-CjlnEtk3.js +510 -0
  4. package/dist/CustomerDetailsPage-I6cdDHUi.js +265 -0
  5. package/dist/CustomersPage-CGGfD4ki.js +163 -0
  6. package/dist/{DashboardPage-DTmyuC11.js → DashboardPage-D2HRqwg9.js} +93 -89
  7. package/dist/DataTable-CD9ZhpLB.js +249 -0
  8. package/dist/DriverDetailsPage-rg_pGNuP.js +330 -0
  9. package/dist/DriversPage-DKiynISH.js +167 -0
  10. package/dist/FinancePage-Vg8WPs38.js +158 -0
  11. package/dist/{FleetPage-DCfOmBa2.js → FleetPage-DddXt8r8.js} +109 -71
  12. package/dist/ImportExportPage-BW6qO3kc.js +248 -0
  13. package/dist/{InventoryPage-BW0QXWuf.js → InventoryPage-rMGuaJN-.js} +74 -70
  14. package/dist/LiveTrackingPage-DQ1q4Id3.js +375 -0
  15. package/dist/MarketplacePage-DKrXAv62.js +219 -0
  16. package/dist/OrderDetailsPage-CFASgsYX.js +431 -0
  17. package/dist/OrdersListPage-BHeT8S5o.js +309 -0
  18. package/dist/ProductDetailsPage-CFGcbaHo.js +195 -0
  19. package/dist/ProductsPage--xEpbQ8A.js +171 -0
  20. package/dist/{ReportsPage-Df3hciPy.js → ReportsPage-Bb7_90rK.js} +53 -45
  21. package/dist/RouteDetailsPage-CVtDVb1N.js +282 -0
  22. package/dist/RoutesPage-s57PtgcQ.js +163 -0
  23. package/dist/SettingsPage-BYNCBOpN.js +298 -0
  24. package/dist/{TrackingPage-CU0Vk4mx.js → TrackingPage-CcRc_dva.js} +77 -72
  25. package/dist/VehicleDetailsPage-3YDMPsPs.js +220 -0
  26. package/dist/VehiclesPage-UlxPWP9K.js +167 -0
  27. package/dist/WarehouseDetailsPage-Db7KeN-d.js +238 -0
  28. package/dist/WarehousesPage-CuTO-OPp.js +164 -0
  29. package/dist/index.js +2 -2
  30. package/package.json +2 -2
  31. package/src/movethewheels/components/DataTable.tsx +37 -2
  32. package/src/movethewheels/components/MetricCard.tsx +3 -1
  33. package/src/movethewheels/pages/AIAssistantPage.tsx +11 -3
  34. package/src/movethewheels/pages/AnalyticsPage.tsx +31 -25
  35. package/src/movethewheels/pages/CreateOrderPage.tsx +56 -17
  36. package/src/movethewheels/pages/CustomerDetailsPage.tsx +63 -38
  37. package/src/movethewheels/pages/CustomersPage.tsx +40 -2
  38. package/src/movethewheels/pages/DashboardPage.tsx +8 -1
  39. package/src/movethewheels/pages/DriverDetailsPage.tsx +57 -26
  40. package/src/movethewheels/pages/DriversPage.tsx +37 -1
  41. package/src/movethewheels/pages/FinancePage.tsx +45 -41
  42. package/src/movethewheels/pages/FleetPage.tsx +68 -25
  43. package/src/movethewheels/pages/ImportExportPage.tsx +46 -29
  44. package/src/movethewheels/pages/InventoryPage.tsx +20 -23
  45. package/src/movethewheels/pages/LiveTrackingPage.tsx +58 -20
  46. package/src/movethewheels/pages/MarketplacePage.tsx +37 -3
  47. package/src/movethewheels/pages/OrderDetailsPage.tsx +74 -46
  48. package/src/movethewheels/pages/OrdersListPage.tsx +62 -1
  49. package/src/movethewheels/pages/ProductDetailsPage.tsx +36 -11
  50. package/src/movethewheels/pages/ProductsPage.tsx +33 -1
  51. package/src/movethewheels/pages/ReportsPage.tsx +23 -19
  52. package/src/movethewheels/pages/RouteDetailsPage.tsx +71 -31
  53. package/src/movethewheels/pages/RoutesPage.tsx +41 -5
  54. package/src/movethewheels/pages/SettingsPage.tsx +68 -26
  55. package/src/movethewheels/pages/TrackingPage.tsx +50 -47
  56. package/src/movethewheels/pages/VehicleDetailsPage.tsx +49 -24
  57. package/src/movethewheels/pages/VehiclesPage.tsx +33 -1
  58. package/src/movethewheels/pages/WarehouseDetailsPage.tsx +55 -30
  59. package/src/movethewheels/pages/WarehousesPage.tsx +42 -4
  60. package/dist/CreateOrderPage-C9Vb57Yn.js +0 -471
  61. package/dist/CustomerDetailsPage-BVkHRZvi.js +0 -239
  62. package/dist/CustomersPage-DhQg-6h_.js +0 -118
  63. package/dist/DataTable-CfWvFw5B.js +0 -239
  64. package/dist/DriverDetailsPage-DaaCQ-2O.js +0 -297
  65. package/dist/DriversPage-D0RMBB_t.js +0 -129
  66. package/dist/FinancePage-BUXqW1IM.js +0 -154
  67. package/dist/ImportExportPage-BM1BoRcE.js +0 -232
  68. package/dist/LiveTrackingPage-DqcGXdkw.js +0 -332
  69. package/dist/MarketplacePage-DFqsxNYU.js +0 -192
  70. package/dist/OrderDetailsPage-Dx1m3cVA.js +0 -398
  71. package/dist/OrdersListPage-DHYBGrWf.js +0 -256
  72. package/dist/ProductDetailsPage-DOXO90kb.js +0 -168
  73. package/dist/ProductsPage-RLMTwWN0.js +0 -133
  74. package/dist/RouteDetailsPage-xzFDeR-X.js +0 -240
  75. package/dist/RoutesPage-DDFy1QVi.js +0 -118
  76. package/dist/SettingsPage-JH_-UPbf.js +0 -247
  77. package/dist/VehicleDetailsPage-P4xDttKw.js +0 -194
  78. package/dist/VehiclesPage-tJZ64QKV.js +0 -129
  79. package/dist/WarehouseDetailsPage-Bt_w2Yf7.js +0 -215
  80. package/dist/WarehousesPage-HsPpEFeG.js +0 -126
@@ -17,6 +17,7 @@ import {
17
17
  SelectTrigger,
18
18
  SelectValue,
19
19
  } from '../components/ui';
20
+ import { EmphasisPanel, PagePurpose } from '@burdenoff/fe-libs/ui';
20
21
 
21
22
  export default function ReportsPage() {
22
23
  const reports = [
@@ -87,6 +88,12 @@ export default function ReportsPage() {
87
88
  </div>
88
89
  }
89
90
  >
91
+ <PagePurpose icon={<FileBarChart size={18} />}>
92
+ Turn your operational data into shareable summaries. Generate one-off reports on orders,
93
+ finance, fleet, customers or inventory, or schedule them to land in inboxes automatically —
94
+ so stakeholders always have the latest numbers without logging in.
95
+ </PagePurpose>
96
+
90
97
  <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
91
98
  <div className="lg:col-span-2 space-y-4">
92
99
  <h3 className="font-semibold">Available Reports</h3>
@@ -121,25 +128,22 @@ export default function ReportsPage() {
121
128
  </div>
122
129
 
123
130
  <div className="space-y-6">
124
- <Card>
125
- <CardHeader>
126
- <CardTitle className="flex items-center gap-2">
127
- <Clock size={18} /> Scheduled Reports
128
- </CardTitle>
129
- </CardHeader>
130
- <CardContent className="space-y-3">
131
- {scheduledReports.map((report) => (
132
- <div key={report.name} className="p-3 border rounded-lg">
133
- <p className="font-medium">{report.name}</p>
134
- <p className="text-sm text-text-secondary">Next: {report.nextRun}</p>
135
- <p className="text-xs text-text-secondary">{report.recipients} recipients</p>
136
- </div>
137
- ))}
138
- <Button variant="outline" className="w-full">
139
- Schedule New Report
140
- </Button>
141
- </CardContent>
142
- </Card>
131
+ {/* Scheduled Reports — the page's single emphasis zone */}
132
+ <EmphasisPanel className="space-y-3">
133
+ <h2 className="flex items-center gap-2 text-base font-semibold text-text-primary">
134
+ <Clock size={18} /> Scheduled Reports
135
+ </h2>
136
+ {scheduledReports.map((report) => (
137
+ <div key={report.name} className="p-3 border border-border-seam rounded-lg">
138
+ <p className="font-medium">{report.name}</p>
139
+ <p className="text-sm text-text-secondary">Next: {report.nextRun}</p>
140
+ <p className="text-xs text-text-secondary">{report.recipients} recipients</p>
141
+ </div>
142
+ ))}
143
+ <Button variant="outline" className="w-full">
144
+ Schedule New Report
145
+ </Button>
146
+ </EmphasisPanel>
143
147
 
144
148
  <Card>
145
149
  <CardHeader>
@@ -4,9 +4,10 @@
4
4
 
5
5
  import { useParams } from 'react-router-dom';
6
6
  import { Navigation, ArrowLeft, Edit, MapPin, Clock, Zap, CheckCircle } from 'lucide-react';
7
- import { PageLayout, LoadingState, ErrorState } from '../components/PageLayout';
7
+ import { PageLayout, LoadingState, ErrorState, EmptyState } from '../components/PageLayout';
8
8
  import { StatusBadge } from '../components/StatusBadge';
9
9
  import { Card, CardContent, CardHeader, CardTitle, Button, Badge } from '../components/ui';
10
+ import { EmphasisPanel, NextSteps, PagePurpose } from '@burdenoff/fe-libs/ui';
10
11
  import { useRoute, useRoutes } from '../hooks/useRoutes';
11
12
  import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
12
13
  import { formatDate, formatAddress } from '../utils/formatters';
@@ -19,6 +20,7 @@ export default function RouteDetailsPage() {
19
20
  const { optimizeRoute } = useRoutes();
20
21
 
21
22
  const goBack = () => navigate?.(joinPath(basePath, 'routes'));
23
+ const goTo = (path: string) => navigate?.(joinPath(basePath, path));
22
24
 
23
25
  // Handle new route form
24
26
  if (!routeId) {
@@ -33,11 +35,15 @@ export default function RouteDetailsPage() {
33
35
  </Button>
34
36
  }
35
37
  >
36
- <Card>
37
- <CardContent className="p-8 text-center">
38
- <p className="text-text-secondary">Route creation form would go here</p>
39
- </CardContent>
40
- </Card>
38
+ <PagePurpose icon={<Navigation size={18} />}>
39
+ Plan a new delivery route — pick the stops to visit, and the optimizer will sequence them
40
+ into the shortest driving plan so one driver can cover them in a single run.
41
+ </PagePurpose>
42
+ <EmptyState
43
+ illustration="onboarding"
44
+ title="Build your route"
45
+ description="The route planner lets you add stops, set the running order, and optimize for distance and time."
46
+ />
41
47
  </PageLayout>
42
48
  );
43
49
  }
@@ -90,6 +96,43 @@ export default function RouteDetailsPage() {
90
96
  </div>
91
97
  }
92
98
  >
99
+ <PagePurpose icon={<Navigation size={18} />}>
100
+ A single optimized driving plan that chains together this route&apos;s stops. Review the
101
+ sequence, distance and timing here, re-optimize if traffic or stops change, then hand the
102
+ itinerary to a driver.
103
+ </PagePurpose>
104
+
105
+ <NextSteps
106
+ storageKey="movethewheels-route-details"
107
+ steps={[
108
+ ...(!route.optimized
109
+ ? [
110
+ {
111
+ id: 'optimize',
112
+ label: 'Optimize this route',
113
+ description: 'Reorder stops to cut distance and driving time.',
114
+ icon: <Zap size={16} />,
115
+ onClick: handleOptimize,
116
+ },
117
+ ]
118
+ : []),
119
+ {
120
+ id: 'edit',
121
+ label: 'Adjust stops',
122
+ description: 'Add, remove or reorder the delivery stops.',
123
+ icon: <Edit size={16} />,
124
+ onClick: () => {},
125
+ },
126
+ {
127
+ id: 'orders',
128
+ label: 'Review the orders on this route',
129
+ description: 'Check the deliveries bundled into this run.',
130
+ icon: <MapPin size={16} />,
131
+ onClick: () => goTo('orders'),
132
+ },
133
+ ]}
134
+ />
135
+
93
136
  <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
94
137
  <div className="lg:col-span-2 space-y-6">
95
138
  <Card>
@@ -161,36 +204,33 @@ export default function RouteDetailsPage() {
161
204
  </div>
162
205
 
163
206
  <div className="space-y-6">
164
- <Card>
165
- <CardHeader>
166
- <CardTitle>Route Info</CardTitle>
167
- </CardHeader>
168
- <CardContent className="space-y-4">
169
- <div>
170
- <p className="text-sm text-text-secondary">Total Distance</p>
171
- <p className="text-2xl font-bold">
172
- {route.distance.toFixed(1)}
173
- <span className="text-sm font-normal"> km</span>
174
- </p>
175
- </div>
207
+ {/* Route Info — the page's single emphasis zone */}
208
+ <EmphasisPanel className="space-y-4">
209
+ <h2 className="text-base font-semibold text-text-primary">Route Info</h2>
210
+ <div>
211
+ <p className="text-sm text-text-secondary">Total Distance</p>
212
+ <p className="text-2xl font-bold">
213
+ {route.distance.toFixed(1)}
214
+ <span className="text-sm font-normal"> km</span>
215
+ </p>
216
+ </div>
217
+ <div>
218
+ <p className="text-sm text-text-secondary">Est. Duration</p>
219
+ <p className="text-2xl font-bold">
220
+ {route.estimatedDuration}
221
+ <span className="text-sm font-normal"> min</span>
222
+ </p>
223
+ </div>
224
+ {route.actualDuration && (
176
225
  <div>
177
- <p className="text-sm text-text-secondary">Est. Duration</p>
226
+ <p className="text-sm text-text-secondary">Actual Duration</p>
178
227
  <p className="text-2xl font-bold">
179
- {route.estimatedDuration}
228
+ {route.actualDuration}
180
229
  <span className="text-sm font-normal"> min</span>
181
230
  </p>
182
231
  </div>
183
- {route.actualDuration && (
184
- <div>
185
- <p className="text-sm text-text-secondary">Actual Duration</p>
186
- <p className="text-2xl font-bold">
187
- {route.actualDuration}
188
- <span className="text-sm font-normal"> min</span>
189
- </p>
190
- </div>
191
- )}
192
- </CardContent>
193
- </Card>
232
+ )}
233
+ </EmphasisPanel>
194
234
 
195
235
  <Card>
196
236
  <CardHeader>
@@ -6,8 +6,8 @@ import { Plus, RefreshCw, Navigation } from 'lucide-react';
6
6
  import { PageLayout } from '../components/PageLayout';
7
7
  import { DataTable, type Column } from '../components/DataTable';
8
8
  import { StatusBadge } from '../components/StatusBadge';
9
- import { Badge } from '../components/ui';
10
- import { CTAOverflowMenu } from '@burdenoff/fe-libs/ui';
9
+ import { Badge, Button } from '../components/ui';
10
+ import { CTAOverflowMenu, EmphasisPanel, PagePurpose } from '@burdenoff/fe-libs/ui';
11
11
  import { useRoutes } from '../hooks/useRoutes';
12
12
  import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
13
13
  import { formatDate } from '../utils/formatters';
@@ -86,12 +86,39 @@ export default function RoutesPage() {
86
86
  icon: <Plus size={16} />,
87
87
  onSelect: () => goTo('routes/new'),
88
88
  }}
89
- actions={[
90
- { label: 'Refresh', icon: <RefreshCw size={16} />, onSelect: () => refetch() },
91
- ]}
89
+ actions={[{ label: 'Refresh', icon: <RefreshCw size={16} />, onSelect: () => refetch() }]}
92
90
  />
93
91
  }
94
92
  >
93
+ <PagePurpose icon={<Navigation size={18} />}>
94
+ Routes group multiple delivery stops into an optimized driving plan. Build a route to batch
95
+ nearby drop-offs, cut distance and fuel, and give drivers a single ordered itinerary — then
96
+ open one to review stops, distance and optimization status.
97
+ </PagePurpose>
98
+
99
+ {/* Routes at a glance — the page's single emphasis zone */}
100
+ <EmphasisPanel>
101
+ <p className="text-sm font-medium text-text-secondary">Routes at a glance</p>
102
+ <div className="mt-3 grid grid-cols-3 gap-4">
103
+ <div>
104
+ <p className="text-2xl font-bold text-text-primary tabular-nums">{totalRoutes}</p>
105
+ <p className="text-xs text-text-secondary">Total routes</p>
106
+ </div>
107
+ <div>
108
+ <p className="text-2xl font-bold text-text-primary tabular-nums">
109
+ {routes.filter((r) => r.status === 'in_progress').length}
110
+ </p>
111
+ <p className="text-xs text-text-secondary">In progress</p>
112
+ </div>
113
+ <div>
114
+ <p className="text-2xl font-bold text-text-primary tabular-nums">
115
+ {routes.filter((r) => r.optimized).length}
116
+ </p>
117
+ <p className="text-xs text-text-secondary">Optimized</p>
118
+ </div>
119
+ </div>
120
+ </EmphasisPanel>
121
+
95
122
  <DataTable
96
123
  columns={columns}
97
124
  data={routes}
@@ -101,6 +128,15 @@ export default function RoutesPage() {
101
128
  searchFields={['name'] as (keyof Route)[]}
102
129
  onRowClick={(row) => goTo(`routes/${row.id}`)}
103
130
  getRowId={(row) => row.id}
131
+ emptyIllustration="empty-data"
132
+ emptyTitle="No routes yet"
133
+ emptyDescription="Create a route to batch deliveries into an optimized driving plan."
134
+ emptyAction={
135
+ <Button onClick={() => goTo('routes/new')}>
136
+ <Plus size={16} className="mr-1.5" />
137
+ Create Route
138
+ </Button>
139
+ }
104
140
  />
105
141
  </PageLayout>
106
142
  );
@@ -2,6 +2,7 @@
2
2
  * Settings Page
3
3
  */
4
4
 
5
+ import { useState } from 'react';
5
6
  import { Settings, User, Bell, Shield, Globe, Webhook, Save } from 'lucide-react';
6
7
  import { PageLayout } from '../components/PageLayout';
7
8
  import {
@@ -24,15 +25,59 @@ import {
24
25
  TabsTrigger,
25
26
  TabsContent,
26
27
  } from '../components/ui';
28
+ import { EmphasisPanel, PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';
27
29
 
28
30
  export default function SettingsPage() {
31
+ const [tab, setTab] = useState('general');
32
+
29
33
  return (
30
34
  <PageLayout
31
35
  title="Settings"
32
36
  subtitle="Manage your account and preferences"
33
37
  icon={<Settings size={24} />}
34
38
  >
35
- <Tabs defaultValue="general">
39
+ <PagePurpose icon={<Settings size={18} />}>
40
+ Configure how MoveTheWheels works for your business — company details and localization,
41
+ which notifications you receive, account security, and the integrations (maps, payments,
42
+ messaging) that power deliveries. Set these once so the rest of the app behaves the way you
43
+ expect.
44
+ </PagePurpose>
45
+
46
+ <NextSteps
47
+ storageKey="movethewheels-settings"
48
+ steps={[
49
+ {
50
+ id: 'company',
51
+ label: 'Confirm company details & localization',
52
+ description: 'Set your name, contact info, timezone, currency and language.',
53
+ icon: <User size={16} />,
54
+ onClick: () => setTab('general'),
55
+ },
56
+ {
57
+ id: 'notifications',
58
+ label: 'Choose your notifications',
59
+ description: 'Decide which order, delivery and report emails you receive.',
60
+ icon: <Bell size={16} />,
61
+ onClick: () => setTab('notifications'),
62
+ },
63
+ {
64
+ id: 'security',
65
+ label: 'Secure your account',
66
+ description: 'Update your password and enable two-factor authentication.',
67
+ icon: <Shield size={16} />,
68
+ onClick: () => setTab('security'),
69
+ },
70
+ {
71
+ id: 'integrations',
72
+ label: 'Connect your tools',
73
+ description: 'Link maps, payments and messaging providers.',
74
+ icon: <Webhook size={16} />,
75
+ onClick: () => setTab('integrations'),
76
+ },
77
+ ]}
78
+ />
79
+
80
+ <Tabs value={tab} onValueChange={setTab}>
36
81
  <TabsList className="mb-6">
37
82
  <TabsTrigger value="general">
38
83
  <User size={16} /> General
@@ -49,32 +94,29 @@ export default function SettingsPage() {
49
94
  </TabsList>
50
95
 
51
96
  <TabsContent value="general" className="space-y-6">
52
- <Card>
53
- <CardHeader>
54
- <CardTitle>Company Information</CardTitle>
55
- <CardDescription>Basic company details</CardDescription>
56
- </CardHeader>
57
- <CardContent className="space-y-4">
58
- <div className="grid grid-cols-2 gap-4">
59
- <div>
60
- <Label>Company Name</Label>
61
- <Input defaultValue="QuickLogistics Pro" />
62
- </div>
63
- <div>
64
- <Label>Contact Email</Label>
65
- <Input defaultValue="contact@quicklogistics.com" />
66
- </div>
67
- <div>
68
- <Label>Phone</Label>
69
- <Input defaultValue="+1-555-QUICK" />
70
- </div>
71
- <div>
72
- <Label>Website</Label>
73
- <Input defaultValue="https://quicklogistics.com" />
74
- </div>
97
+ {/* Company Information — the page's single emphasis zone */}
98
+ <EmphasisPanel>
99
+ <h2 className="text-base font-semibold text-text-primary">Company Information</h2>
100
+ <p className="text-sm text-text-secondary mb-4">Basic company details</p>
101
+ <div className="grid grid-cols-2 gap-4">
102
+ <div>
103
+ <Label>Company Name</Label>
104
+ <Input defaultValue="QuickLogistics Pro" />
75
105
  </div>
76
- </CardContent>
77
- </Card>
106
+ <div>
107
+ <Label>Contact Email</Label>
108
+ <Input defaultValue="contact@quicklogistics.com" />
109
+ </div>
110
+ <div>
111
+ <Label>Phone</Label>
112
+ <Input defaultValue="+1-555-QUICK" />
113
+ </div>
114
+ <div>
115
+ <Label>Website</Label>
116
+ <Input defaultValue="https://quicklogistics.com" />
117
+ </div>
118
+ </div>
119
+ </EmphasisPanel>
78
120
 
79
121
  <Card>
80
122
  <CardHeader>
@@ -10,6 +10,7 @@ import { MapPin, Search, Package, Truck, Clock, CheckCircle, AlertCircle } from
10
10
  import { PageLayout, EmptyState } from '../components/PageLayout';
11
11
  import { StatusBadge } from '../components/StatusBadge';
12
12
  import { Card, CardContent, CardHeader, CardTitle, Button, Input } from '../components/ui';
13
+ import { EmphasisPanel, PagePurpose } from '@burdenoff/fe-libs/ui';
13
14
  import { useOrderTracking } from '../hooks/useTracking';
14
15
  import { formatDate, formatAddress } from '../utils/formatters';
15
16
  import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
@@ -56,6 +57,13 @@ export default function TrackingPage() {
56
57
  </Button>
57
58
  }
58
59
  >
60
+ <PagePurpose icon={<MapPin size={18} />}>
61
+ {t(
62
+ 'movethewheels.tracking.purpose',
63
+ 'Look up any single shipment by its tracking number or order ID to see exactly where it is, its progress through pickup and delivery, the current location and any alerts — the same view you can share with a customer.'
64
+ )}
65
+ </PagePurpose>
66
+
59
67
  {/* Search Form */}
60
68
  <Card>
61
69
  <CardContent className="p-6">
@@ -120,55 +128,50 @@ export default function TrackingPage() {
120
128
  <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
121
129
  {/* Main Tracking Info */}
122
130
  <div className="lg:col-span-2 space-y-6">
123
- {/* Status Card */}
124
- <Card>
125
- <CardHeader>
126
- <div className="flex items-center justify-between">
127
- <CardTitle className="flex items-center gap-2">
128
- <Package size={20} />
129
- {t('movethewheels.tracking.orderLabel', 'Order')} {order.orderNumber}
130
- </CardTitle>
131
- <StatusBadge status={order.status} type="order" />
131
+ {/* Status Card — the page's single emphasis zone */}
132
+ <EmphasisPanel>
133
+ <div className="flex items-center justify-between mb-4">
134
+ <h2 className="flex items-center gap-2 text-base font-semibold text-text-primary">
135
+ <Package size={20} />
136
+ {t('movethewheels.tracking.orderLabel', 'Order')} {order.orderNumber}
137
+ </h2>
138
+ <StatusBadge status={order.status} type="order" />
139
+ </div>
140
+ <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
141
+ <div>
142
+ <p className="text-sm text-text-secondary">
143
+ {t('movethewheels.tracking.details.trackingNumber', 'Tracking Number')}
144
+ </p>
145
+ <p className="font-mono font-medium">{order.trackingNumber}</p>
132
146
  </div>
133
- </CardHeader>
134
- <CardContent>
135
- <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
136
- <div>
137
- <p className="text-sm text-text-secondary">
138
- {t('movethewheels.tracking.details.trackingNumber', 'Tracking Number')}
139
- </p>
140
- <p className="font-mono font-medium">{order.trackingNumber}</p>
141
- </div>
142
- <div>
143
- <p className="text-sm text-text-secondary">
144
- {t('movethewheels.tracking.details.estimatedDelivery', 'Estimated Delivery')}
145
- </p>
146
- <p className="font-medium">
147
- {tracking.estimatedArrival
148
- ? formatDate(tracking.estimatedArrival, 'full')
149
- : order.scheduledDelivery
150
- ? formatDate(order.scheduledDelivery, 'full')
151
- : t('movethewheels.tracking.details.tbd', 'TBD')}
152
- </p>
153
- </div>
154
- <div>
155
- <p className="text-sm text-text-secondary">
156
- {t('movethewheels.tracking.details.items', 'Items')}
157
- </p>
158
- <p className="font-medium">
159
- {order.items.length}{' '}
160
- {t('movethewheels.tracking.details.itemsSuffix', 'items')}
161
- </p>
162
- </div>
163
- <div>
164
- <p className="text-sm text-text-secondary">
165
- {t('movethewheels.tracking.details.lastUpdated', 'Last Updated')}
166
- </p>
167
- <p className="font-medium">{formatDate(tracking.lastUpdated, 'relative')}</p>
168
- </div>
147
+ <div>
148
+ <p className="text-sm text-text-secondary">
149
+ {t('movethewheels.tracking.details.estimatedDelivery', 'Estimated Delivery')}
150
+ </p>
151
+ <p className="font-medium">
152
+ {tracking.estimatedArrival
153
+ ? formatDate(tracking.estimatedArrival, 'full')
154
+ : order.scheduledDelivery
155
+ ? formatDate(order.scheduledDelivery, 'full')
156
+ : t('movethewheels.tracking.details.tbd', 'TBD')}
157
+ </p>
169
158
  </div>
170
- </CardContent>
171
- </Card>
159
+ <div>
160
+ <p className="text-sm text-text-secondary">
161
+ {t('movethewheels.tracking.details.items', 'Items')}
162
+ </p>
163
+ <p className="font-medium">
164
+ {order.items.length} {t('movethewheels.tracking.details.itemsSuffix', 'items')}
165
+ </p>
166
+ </div>
167
+ <div>
168
+ <p className="text-sm text-text-secondary">
169
+ {t('movethewheels.tracking.details.lastUpdated', 'Last Updated')}
170
+ </p>
171
+ <p className="font-medium">{formatDate(tracking.lastUpdated, 'relative')}</p>
172
+ </div>
173
+ </div>
174
+ </EmphasisPanel>
172
175
 
173
176
  {/* Progress Timeline */}
174
177
  <Card>
@@ -15,6 +15,7 @@ import {
15
15
  Badge,
16
16
  Progress,
17
17
  } from '../components/ui';
18
+ import { EmphasisPanel, NextSteps, PagePurpose } from '@burdenoff/fe-libs/ui';
18
19
  import { useVehicle } from '../hooks/useFleet';
19
20
  import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
20
21
  import { formatDate } from '../utils/formatters';
@@ -26,6 +27,7 @@ export default function VehicleDetailsPage() {
26
27
  const { vehicle, isLoading, error, refetch } = useVehicle(vehicleId);
27
28
 
28
29
  const goBack = () => navigate?.(joinPath(basePath, 'fleet/vehicles'));
30
+ const goTo = (path: string) => navigate?.(joinPath(basePath, path));
29
31
 
30
32
  if (isLoading) return <LoadingState message="Loading vehicle details..." />;
31
33
  if (error || !vehicle) return <ErrorState title="Vehicle not found" onRetry={refetch} />;
@@ -52,33 +54,56 @@ export default function VehicleDetailsPage() {
52
54
  </div>
53
55
  }
54
56
  >
57
+ <PagePurpose icon={<Truck size={18} />}>
58
+ The full record for this vehicle — specs, capacity, fuel and mileage, maintenance schedule
59
+ and current location. Use it to confirm a vehicle is fuelled, serviced and the right size
60
+ before dispatching it on a delivery.
61
+ </PagePurpose>
62
+
63
+ <NextSteps
64
+ storageKey="movethewheels-vehicle-details"
65
+ steps={[
66
+ {
67
+ id: 'assign',
68
+ label: 'Assign to a delivery',
69
+ description: 'Put this vehicle on an order that fits its capacity.',
70
+ icon: <MapPin size={16} />,
71
+ onClick: () => goTo('orders'),
72
+ },
73
+ {
74
+ id: 'maintenance',
75
+ label: 'Schedule maintenance',
76
+ description: 'Keep it road-ready and compliant.',
77
+ icon: <Wrench size={16} />,
78
+ onClick: () => {},
79
+ },
80
+ ]}
81
+ />
82
+
55
83
  <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
56
84
  <div className="lg:col-span-2 space-y-6">
57
- <Card>
58
- <CardHeader>
59
- <CardTitle>Vehicle Information</CardTitle>
60
- </CardHeader>
61
- <CardContent>
62
- <div className="grid grid-cols-2 md:grid-cols-4 gap-6">
63
- <div>
64
- <p className="text-sm text-text-secondary">Type</p>
65
- <p className="font-medium capitalize">{vehicle.type}</p>
66
- </div>
67
- <div>
68
- <p className="text-sm text-text-secondary">Make</p>
69
- <p className="font-medium">{vehicle.make}</p>
70
- </div>
71
- <div>
72
- <p className="text-sm text-text-secondary">Model</p>
73
- <p className="font-medium">{vehicle.model}</p>
74
- </div>
75
- <div>
76
- <p className="text-sm text-text-secondary">Year</p>
77
- <p className="font-medium">{vehicle.year}</p>
78
- </div>
85
+ {/* Vehicle Information — the page's single emphasis zone */}
86
+ <EmphasisPanel>
87
+ <h2 className="text-base font-semibold text-text-primary mb-4">Vehicle Information</h2>
88
+ <div className="grid grid-cols-2 md:grid-cols-4 gap-6">
89
+ <div>
90
+ <p className="text-sm text-text-secondary">Type</p>
91
+ <p className="font-medium capitalize">{vehicle.type}</p>
79
92
  </div>
80
- </CardContent>
81
- </Card>
93
+ <div>
94
+ <p className="text-sm text-text-secondary">Make</p>
95
+ <p className="font-medium">{vehicle.make}</p>
96
+ </div>
97
+ <div>
98
+ <p className="text-sm text-text-secondary">Model</p>
99
+ <p className="font-medium">{vehicle.model}</p>
100
+ </div>
101
+ <div>
102
+ <p className="text-sm text-text-secondary">Year</p>
103
+ <p className="font-medium">{vehicle.year}</p>
104
+ </div>
105
+ </div>
106
+ </EmphasisPanel>
82
107
 
83
108
  <Card>
84
109
  <CardHeader>