@burdenoff/microfe-movethewheels 2026.722.1 → 2026.725.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/hooks/useOrders.js +119 -100
- package/dist/movethewheels/types/index.d.ts +1 -3
- package/dist/pages/CreateOrderPage.js +53 -79
- package/dist/pages/OrderDetailsPage.js +19 -20
- package/dist/pages/OrdersListPage.js +82 -113
- package/package.json +1 -1
- package/src/movethewheels/hooks/useOrders.ts +83 -208
- package/src/movethewheels/pages/CreateOrderPage.tsx +1 -19
- package/src/movethewheels/pages/OrderDetailsPage.tsx +1 -7
- package/src/movethewheels/pages/OrdersListPage.tsx +3 -31
- package/src/movethewheels/types/index.ts +1 -3
|
@@ -27,16 +27,19 @@ interface UseOrdersResult {
|
|
|
27
27
|
updateOrderStatus: (id: string, status: OrderStatus) => Promise<Order>;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
// Wire shape of MtwDeliveryJob (wspace-movethewheels-svc: src/modules/order/schema/order.gql).
|
|
31
|
+
// The `order` domain was renamed to `delivery_jobs`/MtwDeliveryJob on 2026-07-07 (commit
|
|
32
|
+
// 7e99ec5); `orderType` was dropped entirely in that rename with no replacement field, so it
|
|
33
|
+
// is intentionally absent here — see BOFF-4505.
|
|
30
34
|
interface ApiOrder {
|
|
31
35
|
id: string;
|
|
32
|
-
|
|
36
|
+
deliveryJobNumber: string;
|
|
33
37
|
customerId: string;
|
|
34
|
-
orderType: string;
|
|
35
38
|
status: string;
|
|
36
39
|
priority: string;
|
|
37
40
|
pickupAddress: Record<string, unknown> | null;
|
|
38
41
|
deliveryAddress: Record<string, unknown> | null;
|
|
39
|
-
|
|
42
|
+
cargoItems: unknown;
|
|
40
43
|
pricing: unknown;
|
|
41
44
|
trackingNumber?: string | null;
|
|
42
45
|
specialInstructions?: string | null;
|
|
@@ -60,83 +63,57 @@ interface ApiOrder {
|
|
|
60
63
|
}>;
|
|
61
64
|
}
|
|
62
65
|
|
|
66
|
+
const DELIVERY_JOB_FIELDS = `
|
|
67
|
+
id
|
|
68
|
+
deliveryJobNumber
|
|
69
|
+
customerId
|
|
70
|
+
status
|
|
71
|
+
priority
|
|
72
|
+
pickupAddress
|
|
73
|
+
deliveryAddress
|
|
74
|
+
cargoItems
|
|
75
|
+
pricing
|
|
76
|
+
trackingNumber
|
|
77
|
+
specialInstructions
|
|
78
|
+
scheduledDelivery
|
|
79
|
+
vehicleId
|
|
80
|
+
driverId
|
|
81
|
+
createdAt
|
|
82
|
+
updatedAt
|
|
83
|
+
customer {
|
|
84
|
+
name
|
|
85
|
+
email
|
|
86
|
+
phone
|
|
87
|
+
company
|
|
88
|
+
}
|
|
89
|
+
statusHistory {
|
|
90
|
+
status
|
|
91
|
+
notes
|
|
92
|
+
location
|
|
93
|
+
createdAt
|
|
94
|
+
createdBy
|
|
95
|
+
}
|
|
96
|
+
`;
|
|
97
|
+
|
|
63
98
|
const LIST_ORDERS_QUERY = `
|
|
64
|
-
query
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
orderNumber
|
|
68
|
-
customerId
|
|
69
|
-
orderType
|
|
70
|
-
status
|
|
71
|
-
priority
|
|
72
|
-
pickupAddress
|
|
73
|
-
deliveryAddress
|
|
74
|
-
items
|
|
75
|
-
pricing
|
|
76
|
-
trackingNumber
|
|
77
|
-
specialInstructions
|
|
78
|
-
scheduledDelivery
|
|
79
|
-
vehicleId
|
|
80
|
-
driverId
|
|
81
|
-
createdAt
|
|
82
|
-
updatedAt
|
|
83
|
-
customer {
|
|
84
|
-
name
|
|
85
|
-
email
|
|
86
|
-
phone
|
|
87
|
-
company
|
|
88
|
-
}
|
|
89
|
-
statusHistory {
|
|
90
|
-
status
|
|
91
|
-
notes
|
|
92
|
-
location
|
|
93
|
-
createdAt
|
|
94
|
-
createdBy
|
|
95
|
-
}
|
|
99
|
+
query ListDeliveryJobs($filter: DeliveryJobFilterInput, $pagination: PaginationInput) {
|
|
100
|
+
deliveryJobs(filter: $filter, pagination: $pagination) {
|
|
101
|
+
${DELIVERY_JOB_FIELDS}
|
|
96
102
|
}
|
|
97
103
|
}
|
|
98
104
|
`;
|
|
99
105
|
|
|
100
106
|
const GET_ORDER_QUERY = `
|
|
101
|
-
query
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
orderNumber
|
|
105
|
-
customerId
|
|
106
|
-
orderType
|
|
107
|
-
status
|
|
108
|
-
priority
|
|
109
|
-
pickupAddress
|
|
110
|
-
deliveryAddress
|
|
111
|
-
items
|
|
112
|
-
pricing
|
|
113
|
-
trackingNumber
|
|
114
|
-
specialInstructions
|
|
115
|
-
scheduledDelivery
|
|
116
|
-
vehicleId
|
|
117
|
-
driverId
|
|
118
|
-
createdAt
|
|
119
|
-
updatedAt
|
|
120
|
-
customer {
|
|
121
|
-
name
|
|
122
|
-
email
|
|
123
|
-
phone
|
|
124
|
-
company
|
|
125
|
-
}
|
|
126
|
-
statusHistory {
|
|
127
|
-
status
|
|
128
|
-
notes
|
|
129
|
-
location
|
|
130
|
-
createdAt
|
|
131
|
-
createdBy
|
|
132
|
-
}
|
|
107
|
+
query GetDeliveryJob($id: ID!) {
|
|
108
|
+
deliveryJob(id: $id) {
|
|
109
|
+
${DELIVERY_JOB_FIELDS}
|
|
133
110
|
}
|
|
134
111
|
}
|
|
135
112
|
`;
|
|
136
113
|
|
|
137
114
|
const ORDER_STATS_QUERY = `
|
|
138
|
-
query
|
|
139
|
-
|
|
115
|
+
query GetDeliveryJobStatsBundle {
|
|
116
|
+
deliveryJobStats {
|
|
140
117
|
total
|
|
141
118
|
pending
|
|
142
119
|
inTransit
|
|
@@ -154,119 +131,32 @@ const ORDER_STATS_QUERY = `
|
|
|
154
131
|
`;
|
|
155
132
|
|
|
156
133
|
const CREATE_ORDER_MUTATION = `
|
|
157
|
-
mutation
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
orderNumber
|
|
161
|
-
customerId
|
|
162
|
-
orderType
|
|
163
|
-
status
|
|
164
|
-
priority
|
|
165
|
-
pickupAddress
|
|
166
|
-
deliveryAddress
|
|
167
|
-
items
|
|
168
|
-
pricing
|
|
169
|
-
trackingNumber
|
|
170
|
-
specialInstructions
|
|
171
|
-
scheduledDelivery
|
|
172
|
-
vehicleId
|
|
173
|
-
driverId
|
|
174
|
-
createdAt
|
|
175
|
-
updatedAt
|
|
176
|
-
customer {
|
|
177
|
-
name
|
|
178
|
-
email
|
|
179
|
-
phone
|
|
180
|
-
company
|
|
181
|
-
}
|
|
182
|
-
statusHistory {
|
|
183
|
-
status
|
|
184
|
-
notes
|
|
185
|
-
location
|
|
186
|
-
createdAt
|
|
187
|
-
createdBy
|
|
188
|
-
}
|
|
134
|
+
mutation CreateDeliveryJob($input: CreateDeliveryJobInput!) {
|
|
135
|
+
createDeliveryJob(input: $input) {
|
|
136
|
+
${DELIVERY_JOB_FIELDS}
|
|
189
137
|
}
|
|
190
138
|
}
|
|
191
139
|
`;
|
|
192
140
|
|
|
193
141
|
const UPDATE_ORDER_MUTATION = `
|
|
194
|
-
mutation
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
orderNumber
|
|
198
|
-
customerId
|
|
199
|
-
orderType
|
|
200
|
-
status
|
|
201
|
-
priority
|
|
202
|
-
pickupAddress
|
|
203
|
-
deliveryAddress
|
|
204
|
-
items
|
|
205
|
-
pricing
|
|
206
|
-
trackingNumber
|
|
207
|
-
specialInstructions
|
|
208
|
-
scheduledDelivery
|
|
209
|
-
vehicleId
|
|
210
|
-
driverId
|
|
211
|
-
createdAt
|
|
212
|
-
updatedAt
|
|
213
|
-
customer {
|
|
214
|
-
name
|
|
215
|
-
email
|
|
216
|
-
phone
|
|
217
|
-
company
|
|
218
|
-
}
|
|
219
|
-
statusHistory {
|
|
220
|
-
status
|
|
221
|
-
notes
|
|
222
|
-
location
|
|
223
|
-
createdAt
|
|
224
|
-
createdBy
|
|
225
|
-
}
|
|
142
|
+
mutation UpdateDeliveryJob($id: ID!, $input: UpdateDeliveryJobInput!) {
|
|
143
|
+
updateDeliveryJob(id: $id, input: $input) {
|
|
144
|
+
${DELIVERY_JOB_FIELDS}
|
|
226
145
|
}
|
|
227
146
|
}
|
|
228
147
|
`;
|
|
229
148
|
|
|
230
149
|
const UPDATE_ORDER_STATUS_MUTATION = `
|
|
231
|
-
mutation
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
orderNumber
|
|
235
|
-
customerId
|
|
236
|
-
orderType
|
|
237
|
-
status
|
|
238
|
-
priority
|
|
239
|
-
pickupAddress
|
|
240
|
-
deliveryAddress
|
|
241
|
-
items
|
|
242
|
-
pricing
|
|
243
|
-
trackingNumber
|
|
244
|
-
specialInstructions
|
|
245
|
-
scheduledDelivery
|
|
246
|
-
vehicleId
|
|
247
|
-
driverId
|
|
248
|
-
createdAt
|
|
249
|
-
updatedAt
|
|
250
|
-
customer {
|
|
251
|
-
name
|
|
252
|
-
email
|
|
253
|
-
phone
|
|
254
|
-
company
|
|
255
|
-
}
|
|
256
|
-
statusHistory {
|
|
257
|
-
status
|
|
258
|
-
notes
|
|
259
|
-
location
|
|
260
|
-
createdAt
|
|
261
|
-
createdBy
|
|
262
|
-
}
|
|
150
|
+
mutation UpdateDeliveryJobStatus($id: ID!, $input: UpdateDeliveryJobStatusInput!) {
|
|
151
|
+
updateDeliveryJobStatus(id: $id, input: $input) {
|
|
152
|
+
${DELIVERY_JOB_FIELDS}
|
|
263
153
|
}
|
|
264
154
|
}
|
|
265
155
|
`;
|
|
266
156
|
|
|
267
157
|
const DELETE_ORDER_MUTATION = `
|
|
268
|
-
mutation
|
|
269
|
-
|
|
158
|
+
mutation DeleteDeliveryJob($id: ID!) {
|
|
159
|
+
deleteDeliveryJob(id: $id)
|
|
270
160
|
}
|
|
271
161
|
`;
|
|
272
162
|
|
|
@@ -293,10 +183,6 @@ function mapOrderStatus(status: string): OrderStatus {
|
|
|
293
183
|
}
|
|
294
184
|
}
|
|
295
185
|
|
|
296
|
-
function mapOrderType(type: string): 'b2b' | 'b2c' {
|
|
297
|
-
return type === 'B2B' ? 'b2b' : 'b2c';
|
|
298
|
-
}
|
|
299
|
-
|
|
300
186
|
function mapOrderPriority(priority: string): 'low' | 'normal' | 'high' | 'urgent' {
|
|
301
187
|
switch (priority) {
|
|
302
188
|
case 'LOW':
|
|
@@ -334,10 +220,6 @@ function toApiStatus(status: OrderStatus): string {
|
|
|
334
220
|
}
|
|
335
221
|
}
|
|
336
222
|
|
|
337
|
-
function toApiOrderType(orderType: 'b2b' | 'b2c' | undefined): string {
|
|
338
|
-
return orderType === 'b2b' ? 'B2B' : 'B2C';
|
|
339
|
-
}
|
|
340
|
-
|
|
341
223
|
function toApiPriority(priority: 'low' | 'normal' | 'high' | 'urgent' | undefined): string {
|
|
342
224
|
switch (priority) {
|
|
343
225
|
case 'low':
|
|
@@ -365,7 +247,7 @@ function mapAddress(address: Record<string, unknown> | null | undefined): Order[
|
|
|
365
247
|
function mapOrder(order: ApiOrder): Order {
|
|
366
248
|
return {
|
|
367
249
|
id: order.id,
|
|
368
|
-
orderNumber: order.
|
|
250
|
+
orderNumber: order.deliveryJobNumber,
|
|
369
251
|
customerId: order.customerId,
|
|
370
252
|
customerInfo: {
|
|
371
253
|
name: order.customer?.name ?? 'Unknown Customer',
|
|
@@ -373,9 +255,8 @@ function mapOrder(order: ApiOrder): Order {
|
|
|
373
255
|
phone: order.customer?.phone ?? '',
|
|
374
256
|
company: order.customer?.company ?? undefined,
|
|
375
257
|
},
|
|
376
|
-
items: Array.isArray(order.
|
|
258
|
+
items: Array.isArray(order.cargoItems) ? (order.cargoItems as Order['items']) : [],
|
|
377
259
|
status: mapOrderStatus(order.status),
|
|
378
|
-
orderType: mapOrderType(order.orderType),
|
|
379
260
|
priority: mapOrderPriority(order.priority),
|
|
380
261
|
pickupAddress: mapAddress(order.pickupAddress),
|
|
381
262
|
deliveryAddress: mapAddress(order.deliveryAddress),
|
|
@@ -419,7 +300,6 @@ export function useOrders(options: UseOrdersOptions = {}): UseOrdersResult {
|
|
|
419
300
|
[
|
|
420
301
|
rawFilters?.status,
|
|
421
302
|
rawFilters?.priority,
|
|
422
|
-
rawFilters?.orderType,
|
|
423
303
|
rawFilters?.customerId,
|
|
424
304
|
rawFilters?.driverId,
|
|
425
305
|
rawFilters?.unassigned,
|
|
@@ -450,21 +330,20 @@ export function useOrders(options: UseOrdersOptions = {}): UseOrdersResult {
|
|
|
450
330
|
setError(null);
|
|
451
331
|
try {
|
|
452
332
|
const data = await executeGraphQL<{
|
|
453
|
-
|
|
333
|
+
deliveryJobs: ApiOrder[];
|
|
454
334
|
}>(graphQLOptions, LIST_ORDERS_QUERY, {
|
|
455
335
|
filter: {
|
|
456
336
|
status: filters?.status ? toApiStatus(filters.status) : undefined,
|
|
457
337
|
priority: filters?.priority
|
|
458
338
|
? toApiPriority(filters.priority as 'low' | 'normal' | 'high' | 'urgent')
|
|
459
339
|
: undefined,
|
|
460
|
-
orderType: filters?.orderType ? toApiOrderType(filters.orderType) : undefined,
|
|
461
340
|
customerId: filters?.customerId,
|
|
462
341
|
driverId: filters?.driverId,
|
|
463
342
|
},
|
|
464
343
|
pagination: { limit, offset },
|
|
465
344
|
});
|
|
466
345
|
|
|
467
|
-
const raw = data.
|
|
346
|
+
const raw = data.deliveryJobs;
|
|
468
347
|
setHasMore(raw.length === limit);
|
|
469
348
|
let mapped = raw.map(mapOrder);
|
|
470
349
|
if (filters?.unassigned) {
|
|
@@ -488,22 +367,21 @@ export function useOrders(options: UseOrdersOptions = {}): UseOrdersResult {
|
|
|
488
367
|
|
|
489
368
|
const createOrder = useCallback(
|
|
490
369
|
async (orderData: Partial<Order>): Promise<Order> => {
|
|
491
|
-
const
|
|
370
|
+
const deliveryJobNumber =
|
|
492
371
|
orderData.orderNumber ??
|
|
493
372
|
`ORD-${new Date().getFullYear()}-${Date.now().toString().slice(-6)}`;
|
|
494
373
|
|
|
495
374
|
const data = await executeGraphQL<{
|
|
496
|
-
|
|
375
|
+
createDeliveryJob: ApiOrder;
|
|
497
376
|
}>(graphQLOptions, CREATE_ORDER_MUTATION, {
|
|
498
377
|
input: {
|
|
499
|
-
|
|
500
|
-
orderType: toApiOrderType(orderData.orderType),
|
|
378
|
+
deliveryJobNumber,
|
|
501
379
|
status: toApiStatus(orderData.status ?? 'pending'),
|
|
502
380
|
priority: toApiPriority(orderData.priority),
|
|
503
381
|
customerId: orderData.customerId,
|
|
504
382
|
pickupAddress: orderData.pickupAddress ?? {},
|
|
505
383
|
deliveryAddress: orderData.deliveryAddress ?? {},
|
|
506
|
-
|
|
384
|
+
cargoItems: orderData.items ?? [],
|
|
507
385
|
pricing: orderData.pricing ?? null,
|
|
508
386
|
specialInstructions: orderData.specialInstructions,
|
|
509
387
|
trackingNumber: orderData.trackingNumber,
|
|
@@ -513,7 +391,7 @@ export function useOrders(options: UseOrdersOptions = {}): UseOrdersResult {
|
|
|
513
391
|
},
|
|
514
392
|
});
|
|
515
393
|
|
|
516
|
-
const created = mapOrder(data.
|
|
394
|
+
const created = mapOrder(data.createDeliveryJob);
|
|
517
395
|
setOrders((previous) => [created, ...previous]);
|
|
518
396
|
return created;
|
|
519
397
|
},
|
|
@@ -523,17 +401,16 @@ export function useOrders(options: UseOrdersOptions = {}): UseOrdersResult {
|
|
|
523
401
|
const updateOrder = useCallback(
|
|
524
402
|
async (id: string, updates: Partial<Order>): Promise<Order> => {
|
|
525
403
|
const data = await executeGraphQL<{
|
|
526
|
-
|
|
404
|
+
updateDeliveryJob: ApiOrder;
|
|
527
405
|
}>(graphQLOptions, UPDATE_ORDER_MUTATION, {
|
|
528
406
|
id,
|
|
529
407
|
input: {
|
|
530
|
-
orderType: updates.orderType ? toApiOrderType(updates.orderType) : undefined,
|
|
531
408
|
status: updates.status ? toApiStatus(updates.status) : undefined,
|
|
532
409
|
priority: updates.priority ? toApiPriority(updates.priority) : undefined,
|
|
533
410
|
customerId: updates.customerId,
|
|
534
411
|
pickupAddress: updates.pickupAddress,
|
|
535
412
|
deliveryAddress: updates.deliveryAddress,
|
|
536
|
-
|
|
413
|
+
cargoItems: updates.items,
|
|
537
414
|
pricing: updates.pricing,
|
|
538
415
|
specialInstructions: updates.specialInstructions,
|
|
539
416
|
trackingNumber: updates.trackingNumber,
|
|
@@ -543,7 +420,7 @@ export function useOrders(options: UseOrdersOptions = {}): UseOrdersResult {
|
|
|
543
420
|
},
|
|
544
421
|
});
|
|
545
422
|
|
|
546
|
-
const updated = mapOrder(data.
|
|
423
|
+
const updated = mapOrder(data.updateDeliveryJob);
|
|
547
424
|
setOrders((previous) => previous.map((item) => (item.id === id ? updated : item)));
|
|
548
425
|
return updated;
|
|
549
426
|
},
|
|
@@ -552,11 +429,9 @@ export function useOrders(options: UseOrdersOptions = {}): UseOrdersResult {
|
|
|
552
429
|
|
|
553
430
|
const deleteOrder = useCallback(
|
|
554
431
|
async (id: string): Promise<void> => {
|
|
555
|
-
await executeGraphQL<{
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
{ id }
|
|
559
|
-
);
|
|
432
|
+
await executeGraphQL<{ deleteDeliveryJob: boolean }>(graphQLOptions, DELETE_ORDER_MUTATION, {
|
|
433
|
+
id,
|
|
434
|
+
});
|
|
560
435
|
setOrders((previous) => previous.filter((item) => item.id !== id));
|
|
561
436
|
},
|
|
562
437
|
[graphQLOptions]
|
|
@@ -565,7 +440,7 @@ export function useOrders(options: UseOrdersOptions = {}): UseOrdersResult {
|
|
|
565
440
|
const updateOrderStatus = useCallback(
|
|
566
441
|
async (id: string, status: OrderStatus): Promise<Order> => {
|
|
567
442
|
const data = await executeGraphQL<{
|
|
568
|
-
|
|
443
|
+
updateDeliveryJobStatus: ApiOrder;
|
|
569
444
|
}>(graphQLOptions, UPDATE_ORDER_STATUS_MUTATION, {
|
|
570
445
|
id,
|
|
571
446
|
input: {
|
|
@@ -573,7 +448,7 @@ export function useOrders(options: UseOrdersOptions = {}): UseOrdersResult {
|
|
|
573
448
|
},
|
|
574
449
|
});
|
|
575
450
|
|
|
576
|
-
const updated = mapOrder(data.
|
|
451
|
+
const updated = mapOrder(data.updateDeliveryJobStatus);
|
|
577
452
|
setOrders((previous) => previous.map((item) => (item.id === id ? updated : item)));
|
|
578
453
|
return updated;
|
|
579
454
|
},
|
|
@@ -623,10 +498,10 @@ export function useOrder(orderId: string | undefined) {
|
|
|
623
498
|
setError(null);
|
|
624
499
|
try {
|
|
625
500
|
const data = await executeGraphQL<{
|
|
626
|
-
|
|
501
|
+
deliveryJob: ApiOrder | null;
|
|
627
502
|
}>(graphQLOptions, GET_ORDER_QUERY, { id: orderId });
|
|
628
503
|
|
|
629
|
-
setOrder(data.
|
|
504
|
+
setOrder(data.deliveryJob ? mapOrder(data.deliveryJob) : null);
|
|
630
505
|
} catch (fetchError) {
|
|
631
506
|
setError(fetchError instanceof Error ? fetchError : new Error('Failed to load order'));
|
|
632
507
|
} finally {
|
|
@@ -685,7 +560,7 @@ export function useOrderStats() {
|
|
|
685
560
|
setError(null);
|
|
686
561
|
try {
|
|
687
562
|
const data = await executeGraphQL<{
|
|
688
|
-
|
|
563
|
+
deliveryJobStats: {
|
|
689
564
|
total: number;
|
|
690
565
|
pending: number;
|
|
691
566
|
inTransit: number;
|
|
@@ -702,17 +577,17 @@ export function useOrderStats() {
|
|
|
702
577
|
}>(graphQLOptions, ORDER_STATS_QUERY);
|
|
703
578
|
|
|
704
579
|
setStats({
|
|
705
|
-
total: data.
|
|
580
|
+
total: data.deliveryJobStats.total,
|
|
706
581
|
byStatus: {
|
|
707
|
-
pending: data.
|
|
582
|
+
pending: data.deliveryJobStats.pending,
|
|
708
583
|
confirmed: 0,
|
|
709
584
|
assigned: 0,
|
|
710
585
|
picked_up: 0,
|
|
711
|
-
in_transit: data.
|
|
586
|
+
in_transit: data.deliveryJobStats.inTransit,
|
|
712
587
|
out_for_delivery: 0,
|
|
713
|
-
delivered: data.
|
|
714
|
-
cancelled: data.
|
|
715
|
-
failed: data.
|
|
588
|
+
delivered: data.deliveryJobStats.delivered,
|
|
589
|
+
cancelled: data.deliveryJobStats.cancelled,
|
|
590
|
+
failed: data.deliveryJobStats.failed,
|
|
716
591
|
},
|
|
717
592
|
totalRevenue: data.financeMetrics.revenue.totalRevenue,
|
|
718
593
|
todayOrders: 0,
|
|
@@ -42,7 +42,6 @@ export default function CreateOrderPage() {
|
|
|
42
42
|
|
|
43
43
|
const [formData, setFormData] = useState({
|
|
44
44
|
customerId: order?.customerId || '',
|
|
45
|
-
orderType: order?.orderType || 'b2c',
|
|
46
45
|
priority: order?.priority || 'normal',
|
|
47
46
|
pickupAddress: {
|
|
48
47
|
street: order?.pickupAddress.street || '',
|
|
@@ -74,7 +73,6 @@ export default function CreateOrderPage() {
|
|
|
74
73
|
}
|
|
75
74
|
setFormData({
|
|
76
75
|
customerId: order.customerId || '',
|
|
77
|
-
orderType: order.orderType || 'b2c',
|
|
78
76
|
priority: order.priority || 'normal',
|
|
79
77
|
pickupAddress: {
|
|
80
78
|
street: order.pickupAddress.street || '',
|
|
@@ -144,7 +142,6 @@ export default function CreateOrderPage() {
|
|
|
144
142
|
phone: selectedCustomer.phone,
|
|
145
143
|
company: selectedCustomer.company,
|
|
146
144
|
},
|
|
147
|
-
orderType: formData.orderType as 'b2b' | 'b2c',
|
|
148
145
|
priority: formData.priority as 'low' | 'normal' | 'high' | 'urgent',
|
|
149
146
|
pickupAddress: formData.pickupAddress,
|
|
150
147
|
deliveryAddress: formData.deliveryAddress,
|
|
@@ -283,7 +280,7 @@ export default function CreateOrderPage() {
|
|
|
283
280
|
<EmphasisPanel>
|
|
284
281
|
<h2 className="text-base font-semibold text-text-primary mb-4">Order Details</h2>
|
|
285
282
|
<div className="space-y-4">
|
|
286
|
-
<div className="grid grid-cols-1 md:grid-cols-
|
|
283
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
287
284
|
<div className="space-y-2">
|
|
288
285
|
<Label htmlFor="customer">Customer</Label>
|
|
289
286
|
<Select
|
|
@@ -302,21 +299,6 @@ export default function CreateOrderPage() {
|
|
|
302
299
|
</SelectContent>
|
|
303
300
|
</Select>
|
|
304
301
|
</div>
|
|
305
|
-
<div className="space-y-2">
|
|
306
|
-
<Label htmlFor="orderType">Order Type</Label>
|
|
307
|
-
<Select
|
|
308
|
-
value={formData.orderType}
|
|
309
|
-
onValueChange={(value) => updateField('orderType', value)}
|
|
310
|
-
>
|
|
311
|
-
<SelectTrigger id="orderType">
|
|
312
|
-
<SelectValue />
|
|
313
|
-
</SelectTrigger>
|
|
314
|
-
<SelectContent>
|
|
315
|
-
<SelectItem value="b2c">B2C (Individual)</SelectItem>
|
|
316
|
-
<SelectItem value="b2b">B2B (Business)</SelectItem>
|
|
317
|
-
</SelectContent>
|
|
318
|
-
</Select>
|
|
319
|
-
</div>
|
|
320
302
|
<div className="space-y-2">
|
|
321
303
|
<Label htmlFor="priority">Priority</Label>
|
|
322
304
|
<Select
|
|
@@ -25,12 +25,7 @@ import {
|
|
|
25
25
|
UserCheck,
|
|
26
26
|
} from 'lucide-react';
|
|
27
27
|
import { PageLayout, LoadingState, ErrorState } from '../components/PageLayout';
|
|
28
|
-
import {
|
|
29
|
-
StatusBadge,
|
|
30
|
-
PriorityBadge,
|
|
31
|
-
TypeBadge,
|
|
32
|
-
PaymentStatusBadge,
|
|
33
|
-
} from '../components/StatusBadge';
|
|
28
|
+
import { StatusBadge, PriorityBadge, PaymentStatusBadge } from '../components/StatusBadge';
|
|
34
29
|
import {
|
|
35
30
|
Card,
|
|
36
31
|
CardContent,
|
|
@@ -205,7 +200,6 @@ export default function OrderDetailsPage() {
|
|
|
205
200
|
<div className="flex flex-wrap gap-2">
|
|
206
201
|
<StatusBadge status={order.status} type="order" />
|
|
207
202
|
<PriorityBadge priority={order.priority} />
|
|
208
|
-
<TypeBadge type={order.orderType} />
|
|
209
203
|
<PaymentStatusBadge status={order.pricing.paymentStatus} />
|
|
210
204
|
</div>
|
|
211
205
|
}
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
import { PageLayout } from '../components/PageLayout';
|
|
21
21
|
import { MetricCard, MetricGrid } from '../components/MetricCard';
|
|
22
22
|
import { DataTable, type Column } from '../components/DataTable';
|
|
23
|
-
import { StatusBadge, PriorityBadge
|
|
23
|
+
import { StatusBadge, PriorityBadge } from '../components/StatusBadge';
|
|
24
24
|
import { CTAOverflowMenu, PagePurpose } from '@burdenoff/fe-libs/ui';
|
|
25
25
|
import {
|
|
26
26
|
Button,
|
|
@@ -48,17 +48,15 @@ export default function OrdersListPage() {
|
|
|
48
48
|
};
|
|
49
49
|
const { basePath, navigate } = useMoveTheWheels();
|
|
50
50
|
const [statusFilter, setStatusFilter] = useState<OrderStatus | 'all'>('all');
|
|
51
|
-
const [typeFilter, setTypeFilter] = useState<'b2b' | 'b2c' | 'all'>('all');
|
|
52
51
|
const [unassignedOnly, setUnassignedOnly] = useState(false);
|
|
53
52
|
const [page, setPage] = useState(0);
|
|
54
53
|
const [pageSize, setPageSize] = useState(25);
|
|
55
54
|
|
|
56
|
-
const filtersActive = statusFilter !== 'all' ||
|
|
55
|
+
const filtersActive = statusFilter !== 'all' || unassignedOnly;
|
|
57
56
|
|
|
58
57
|
const { orders, hasMore, isLoading, error, refetch } = useOrders({
|
|
59
58
|
filters: {
|
|
60
59
|
status: statusFilter === 'all' ? undefined : statusFilter,
|
|
61
|
-
orderType: typeFilter === 'all' ? undefined : typeFilter,
|
|
62
60
|
unassigned: unassignedOnly || undefined,
|
|
63
61
|
},
|
|
64
62
|
limit: pageSize,
|
|
@@ -107,13 +105,6 @@ export default function OrdersListPage() {
|
|
|
107
105
|
className: 'min-w-[130px] whitespace-nowrap',
|
|
108
106
|
cell: (row) => <StatusBadge status={row.status} type="order" />,
|
|
109
107
|
},
|
|
110
|
-
{
|
|
111
|
-
id: 'type',
|
|
112
|
-
header: t('movethewheels.orders.table.type', 'Type'),
|
|
113
|
-
accessorKey: 'orderType',
|
|
114
|
-
className: 'min-w-[70px] whitespace-nowrap',
|
|
115
|
-
cell: (row) => <TypeBadge type={row.orderType} />,
|
|
116
|
-
},
|
|
117
108
|
{
|
|
118
109
|
id: 'priority',
|
|
119
110
|
header: t('movethewheels.orders.table.priority', 'Priority'),
|
|
@@ -227,7 +218,7 @@ export default function OrdersListPage() {
|
|
|
227
218
|
<PagePurpose icon={<Package size={18} />}>
|
|
228
219
|
{t(
|
|
229
220
|
'movethewheels.orders.purpose',
|
|
230
|
-
'Every delivery job lives here —
|
|
221
|
+
'Every delivery job lives here — their status, priority and value. Use this list to find an order, filter by status, and open one to assign a driver, track it, or update fulfilment.'
|
|
231
222
|
)}
|
|
232
223
|
</PagePurpose>
|
|
233
224
|
|
|
@@ -294,24 +285,6 @@ export default function OrdersListPage() {
|
|
|
294
285
|
))}
|
|
295
286
|
</SelectContent>
|
|
296
287
|
</Select>
|
|
297
|
-
<Select
|
|
298
|
-
value={typeFilter}
|
|
299
|
-
onValueChange={(value) => {
|
|
300
|
-
setTypeFilter(value as 'b2b' | 'b2c' | 'all');
|
|
301
|
-
resetPage();
|
|
302
|
-
}}
|
|
303
|
-
>
|
|
304
|
-
<SelectTrigger className="w-[150px]">
|
|
305
|
-
<SelectValue placeholder={t('movethewheels.orders.filters.type', 'Type')} />
|
|
306
|
-
</SelectTrigger>
|
|
307
|
-
<SelectContent>
|
|
308
|
-
<SelectItem value="all">
|
|
309
|
-
{t('movethewheels.orders.filters.allTypes', 'All Types')}
|
|
310
|
-
</SelectItem>
|
|
311
|
-
<SelectItem value="b2b">B2B</SelectItem>
|
|
312
|
-
<SelectItem value="b2c">B2C</SelectItem>
|
|
313
|
-
</SelectContent>
|
|
314
|
-
</Select>
|
|
315
288
|
<Button
|
|
316
289
|
variant={unassignedOnly ? 'default' : 'outline'}
|
|
317
290
|
size="sm"
|
|
@@ -329,7 +302,6 @@ export default function OrdersListPage() {
|
|
|
329
302
|
size="sm"
|
|
330
303
|
onClick={() => {
|
|
331
304
|
setStatusFilter('all');
|
|
332
|
-
setTypeFilter('all');
|
|
333
305
|
setUnassignedOnly(false);
|
|
334
306
|
resetPage();
|
|
335
307
|
}}
|
|
@@ -271,7 +271,6 @@ export interface Order {
|
|
|
271
271
|
};
|
|
272
272
|
items: OrderItem[];
|
|
273
273
|
status: OrderStatus;
|
|
274
|
-
orderType: 'b2b' | 'b2c';
|
|
275
274
|
priority: 'low' | 'normal' | 'high' | 'urgent';
|
|
276
275
|
pickupAddress: Address;
|
|
277
276
|
deliveryAddress: Address;
|
|
@@ -722,10 +721,9 @@ export interface OrderFilter {
|
|
|
722
721
|
dateFrom?: Date;
|
|
723
722
|
dateTo?: Date;
|
|
724
723
|
priority?: string;
|
|
725
|
-
orderType?: 'b2b' | 'b2c';
|
|
726
724
|
/**
|
|
727
725
|
* Client-side quick filter for orders that still need a driver assigned
|
|
728
|
-
* (driverId is null). The backend
|
|
726
|
+
* (driverId is null). The backend DeliveryJobFilterInput has no null-driver
|
|
729
727
|
* predicate, so this is applied to the fetched page after mapping.
|
|
730
728
|
*/
|
|
731
729
|
unassigned?: boolean;
|