@burdenoff/microfe-movethewheels 2026.930.2 → 2026.930.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-movethewheels",
3
- "version": "2026.930.2",
3
+ "version": "2026.930.3",
4
4
  "description": "Burdenoff MoveTheWheels Microfrontend - Logistics & Supply Chain Management Platform",
5
5
  "type": "module",
6
6
  "files": [
@@ -75,6 +75,7 @@ interface UseFleetResult {
75
75
  updateVehicle: (id: string, input: CreateVehicleInput) => Promise<Vehicle>;
76
76
  updateDriver: (id: string, input: UpdateDriverInput) => Promise<Driver>;
77
77
  deleteVehicle: (id: string) => Promise<void>;
78
+ deleteDriver: (id: string) => Promise<void>;
78
79
  }
79
80
 
80
81
  export interface ApiVehicle {
@@ -256,6 +257,12 @@ const GET_DRIVER_QUERY = `
256
257
  }
257
258
  `;
258
259
 
260
+ const DELETE_DRIVER_MUTATION = `
261
+ mutation DeleteDriver($id: ID!) {
262
+ deleteDriver(id: $id)
263
+ }
264
+ `;
265
+
259
266
  const DELETE_VEHICLE_MUTATION = `
260
267
  mutation DeleteVehicle($id: ID!) {
261
268
  deleteVehicle(id: $id)
@@ -891,6 +898,16 @@ export function useFleet(options: UseFleetOptions = {}): UseFleetResult {
891
898
  [graphQLOptions]
892
899
  );
893
900
 
901
+ const deleteDriver = useCallback(
902
+ async (id: string): Promise<void> => {
903
+ await executeGraphQL<{ deleteDriver: boolean }>(graphQLOptions, DELETE_DRIVER_MUTATION, {
904
+ id,
905
+ });
906
+ setDrivers((previous) => previous.filter((item) => item.id !== id));
907
+ },
908
+ [graphQLOptions]
909
+ );
910
+
894
911
  return {
895
912
  vehicles,
896
913
  drivers,
@@ -904,6 +921,7 @@ export function useFleet(options: UseFleetOptions = {}): UseFleetResult {
904
921
  updateVehicle,
905
922
  updateDriver,
906
923
  deleteVehicle,
924
+ deleteDriver,
907
925
  };
908
926
  }
909
927
 
@@ -15,6 +15,7 @@ import {
15
15
  MapPin,
16
16
  Save,
17
17
  UserX,
18
+ Trash2,
18
19
  Truck,
19
20
  StickyNote,
20
21
  } from 'lucide-react';
@@ -120,7 +121,7 @@ const emptyForm: DriverFormState = {
120
121
 
121
122
  function NewDriverForm({ editId }: { editId?: string }) {
122
123
  const { basePath, navigate } = useMoveTheWheels();
123
- const { createDriver, updateDriver } = useFleet();
124
+ const { createDriver, updateDriver, deleteDriver } = useFleet();
124
125
  const { driver, refetch: refetchDriver } = useDriver(editId);
125
126
  const isEditing = !!editId;
126
127
  const [form, setForm] = useState<DriverFormState>(emptyForm);
@@ -130,6 +131,9 @@ function NewDriverForm({ editId }: { editId?: string }) {
130
131
  const [dismissReason, setDismissReason] = useState('');
131
132
  const [dismissing, setDismissing] = useState(false);
132
133
  const [dismissError, setDismissError] = useState<string | null>(null);
134
+ const [deleteOpen, setDeleteOpen] = useState(false);
135
+ const [deleting, setDeleting] = useState(false);
136
+ const [deleteError, setDeleteError] = useState<string | null>(null);
133
137
 
134
138
  const [vehicleSearch, setVehicleSearch] = useState('');
135
139
  const debouncedVehicleSearch = useDebouncedValue(vehicleSearch);
@@ -250,6 +254,21 @@ function NewDriverForm({ editId }: { editId?: string }) {
250
254
  }
251
255
  };
252
256
 
257
+ const handleDelete = async () => {
258
+ if (!editId) return;
259
+ setDeleting(true);
260
+ setDeleteError(null);
261
+ try {
262
+ await deleteDriver(editId);
263
+ setDeleteOpen(false);
264
+ navigate?.(joinPath(basePath, 'fleet/drivers'));
265
+ } catch (err) {
266
+ setDeleteError(err instanceof Error ? err.message : 'Failed to delete driver.');
267
+ } finally {
268
+ setDeleting(false);
269
+ }
270
+ };
271
+
253
272
  const alreadyDismissed = isEditing && Boolean(driver?.terminatedAt);
254
273
 
255
274
  return (
@@ -585,8 +604,60 @@ function NewDriverForm({ editId }: { editId?: string }) {
585
604
  </CardContent>
586
605
  </Card>
587
606
  )}
607
+
608
+ {isEditing && (
609
+ <Card className="border-status-error-border">
610
+ <CardHeader>
611
+ <CardTitle className="flex items-center gap-2 text-status-error-text">
612
+ <Trash2 size={18} /> Delete Driver
613
+ </CardTitle>
614
+ </CardHeader>
615
+ <CardContent>
616
+ <p className="mb-3 text-sm text-text-secondary">
617
+ Removes this driver record, for example one entered by mistake, and unlinks them
618
+ from any vehicle. To keep delivery history for someone who has left, dismiss them
619
+ instead. This cannot be undone from here.
620
+ </p>
621
+ <Button
622
+ type="button"
623
+ variant="outline"
624
+ className="border-status-error-border text-status-error-text hover:bg-status-error-bg-subtle"
625
+ onClick={() => setDeleteOpen(true)}
626
+ >
627
+ <Trash2 size={16} /> Delete this driver
628
+ </Button>
629
+ </CardContent>
630
+ </Card>
631
+ )}
588
632
  </form>
589
633
 
634
+ <ResponsiveDialog open={deleteOpen} onOpenChange={setDeleteOpen}>
635
+ <ResponsiveDialogContent>
636
+ <ResponsiveDialogHeader>
637
+ <ResponsiveDialogTitle>Delete this driver?</ResponsiveDialogTitle>
638
+ <ResponsiveDialogDescription>
639
+ This removes {`${form.firstName} ${form.lastName}`.trim() || 'this driver'} and
640
+ unlinks them from any vehicle. It cannot be undone from here.
641
+ </ResponsiveDialogDescription>
642
+ </ResponsiveDialogHeader>
643
+ <div className="px-1">
644
+ <FormError message={deleteError} />
645
+ </div>
646
+ <ResponsiveDialogFooter>
647
+ <Button variant="outline" onClick={() => setDeleteOpen(false)} disabled={deleting}>
648
+ Cancel
649
+ </Button>
650
+ <Button
651
+ className="bg-status-error-text text-text-inverse hover:opacity-90"
652
+ onClick={handleDelete}
653
+ disabled={deleting}
654
+ >
655
+ {deleting ? 'Deleting...' : 'Delete driver'}
656
+ </Button>
657
+ </ResponsiveDialogFooter>
658
+ </ResponsiveDialogContent>
659
+ </ResponsiveDialog>
660
+
590
661
  <ResponsiveDialog open={dismissOpen} onOpenChange={setDismissOpen}>
591
662
  <ResponsiveDialogContent>
592
663
  <ResponsiveDialogHeader>