PageSourceSearch

https://navpro.truckerpath.com/assets/drivers-new-iEU0Wrvr.js

js truckerpath.com collected 2026-10-01 12:02:38 UTC 37,411 bytes, 1,010 lines download raw bytes

1import { a as __toESM } from "./rolldown-runtime-Cql5ZV07.js";
2import { p as require_react } from "./vendor-charts-D81iZKCV.js";
3import { f as useNavigate, g as require_compiler_runtime, t as require_jsx_runtime, u as useLocation } from "./vendor-react-HZz3WA9p.js";
4import "./vendor-dnd-D_JGdZnv.js";
5import "./vendor-mixpanel-Dh8wsiZW.js";
6import "./device-CBwMusKw.js";
7import "./vendor-redux-CLEI5hTp.js";
8import "./vendor-pdf-DksyQ9Qr.js";
9import "./vendor-utils-DiM3BD4o.js";
10import "./vendor-ui-G6aSO5L-.js";
11import { n as toast } from "./dist-Bh07-69G.js";
12import { G as Plus, Ot as Info, _n as CirclePlus, b as Trash2, n as X, xn as CircleCheckBig } from "./vendor-lucide-EY3Z5fcy.js";
13import { a as cn, i as Spinner, n as buttonVariants, t as Button } from "./button-BWyXpawe.js";
14import "./vendor-twilio-BWAG7uEQ.js";
15import "./app-storage-slice-mFVFfzPf.js";
16import { i as formatPhone, r as formatCurrency } from "./strings-dAFeDkjR.js";
17import { S as useWatch, b as useForm, f as objectType, i as arrayType, m as stringType, t } from "./vendor-form-DCqShb_y.js";
18import "./label-BU8XDazs.js";
19import { a as AlertDialogDescription, c as AlertDialogTitle, i as AlertDialogContent, n as AlertDialogAction, o as AlertDialogFooter, r as AlertDialogCancel, s as AlertDialogHeader, t as AlertDialog } from "./alert-dialog-DqgZ-9QP.js";
20import { Yn as trackMethodCall, Z as SelectField, cn as DialogFooter, d as Alert, in as Dialog, m as InputField, on as DialogContent, pr as Separator, rt as FormWrapper } from "./main-DDHJZG-i.js";
21import "./breadcrumb-DaQ4spt4.js";
22import { t as AppBreadcrumb } from "./app-breadcrumb-C_0-hj4G.js";
23import "./area-DK7oSQ7j.js";
24import { n as FORMATTED_PHONE_REGEX } from "./regex-C8eU81Av.js";
25import { a as useLazyCheckDriverEmailQuery, i as useInviteDriverMutation, n as useCompanyChangeInviteMutation, t as generateMixed } from "./generate-mixed-BuweQD5H.js";
26import { C as useInviteDriverUpgradeMutation, a as useCheckDriverSeatsMutation } from "./driver-service-DR_Z8LWd.js";
27import { t as driver_info_add_default } from "./driver-info-add-BBxWP9yH.js";
28import { n as DRIVER_TYPE_DATA, o as driverTypeLabelMap, t as DriversTypesPopover } from "./drivers-types-popover-Dopha0y8.js";
29import "./terminals-service-C5yhnzod.js";
30import { t as useDriverFormOptions } from "./use-driver-form-options-BVaQhqsQ.js";
31var import_react = /* @__PURE__ */ __toESM(require_react());
32var import_jsx_runtime = /* @__PURE__ */ __toESM(require_jsx_runtime());
33var formatUsdFromCents = (cents) => {
34	return `$${formatCurrency((cents ?? 0) / 100)}`;
35};
36const DriverUpgradeDialog = ({ open, seatInfo, onOpenChange, onCancel, onSuccessConfirm, upgradePayload, cancelButtonProps, confirmButtonProps, successButtonProps }) => {
37	const [success, setSuccess] = (0, import_react.useState)(false);
38	const [inviteDriverUpgrade, { isLoading: isUpgrading }] = useInviteDriverUpgradeMutation();
39	(0, import_react.useEffect)(() => {
40		if (!open) setSuccess(false);
41	}, [open]);
42	const addSeats = seatInfo?.addSeats ?? 0;
43	const hasPaymentMethod = Boolean(seatInfo?.paymentMethod);
44	const originAmount = seatInfo?.originAmount ?? 0;
45	const addSeatsPrice = seatInfo?.addSeatsPrice ?? 0;
46	const taxAmount = seatInfo?.taxAmount ?? 0;
47	const dueToday = addSeatsPrice + taxAmount;
48	const totalAmount = seatInfo?.totalAmount ?? 0;
49	const handleConfirmInDriverUpgradeDialog = async () => {
50		trackMethodCall("handleConfirmInDriverUpgradeDialog", []);
51		if (!upgradePayload) return;
52		try {
53			const res = await inviteDriverUpgrade(upgradePayload).unwrap();
54			if (res.code === 200) setSuccess(true);
55			else toast.error(res.message || "Something went wrong...");
56		} catch {
57			toast.error("Something went wrong...");
58		}
59	};
60	const handleDialogOpenChange = (nextOpen) => {
61		trackMethodCall("handleDialogOpenChange", [nextOpen]);
62		onOpenChange(nextOpen);
63		if (!nextOpen) if (success) onSuccessConfirm?.();
64		else onCancel?.();
65	};
66	const handleConfirmSuccessInDriverUpgradeDialog = () => {
67		trackMethodCall("handleConfirmSuccessInDriverUpgradeDialog", []);
68		onSuccessConfirm?.();
69		setSuccess(false);
70		onOpenChange(false);
71	};
72	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Dialog, {
73		open,
74		onOpenChange: handleDialogOpenChange,
75		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogContent, {
76			className: cn("max-w-140 p-5", success && "pt-5"),
77			showCloseButton: !success,
78			"aria-describedby": void 0,
79			children: !success ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
80				className: "flex flex-col items-center gap-5 p-5",
81				children: [
82					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("figure", {
83						className: "flex items-center justify-center",
84						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {
85							src: driver_info_add_default,
86							alt: "DriverInfoAdd"
87						})
88					}),
89					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h2", {
90						className: "text-center text-xl font-semibold text-foreground",
91						children: [
92							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: `You've reached your plan’s driver seat limit.` }),
93							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
94							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: `Add ` }),
95							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
96								className: "text-primary",
97								children: addSeats
98							}),
99							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: ` more seats to continue?` })
100						]
101					}),
102					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("section", {
103						className: "w-full",
104						children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", {
105							className: "flex w-full flex-col gap-3 rounded-lg bg-muted px-5 py-6",
106							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
107								className: "flex w-full flex-col gap-2",
108								children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
109									className: "flex w-full items-center justify-between",
110									children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
111										className: "text-base font-semibold text-foreground",
112										children: "Due Today"
113									}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
114										className: "text-base font-semibold text-foreground",
115										children: !hasPaymentMethod ? "$0.00" : formatUsdFromCents(dueToday)
116									})]
117								}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("ul", {
118									className: "flex w-full flex-col gap-2 text-sm text-foreground",
119									children: [
120										!hasPaymentMethod && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
121											className: "flex w-full items-start justify-between",
122											children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
123												className: "font-medium",
124												children: "Original Trial Plan"
125											}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
126												className: "text-right",
127												children: formatUsdFromCents(originAmount)
128											})]
129										}),
130										/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
131											className: "flex w-full items-start justify-between",
132											children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
133												className: "font-medium",
134												children: `+${addSeats}\u00A0Driver Seats`
135											}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
136												className: "text-right",
137												children: formatUsdFromCents(addSeatsPrice)
138											})]
139										}),
140										/* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", {
141											className: "flex w-full items-start justify-between",
142											children: hasPaymentMethod ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
143												className: "font-medium",
144												children: "Tax"
145											}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
146												className: "text-right",
147												children: formatUsdFromCents(taxAmount)
148											})] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
149												className: "font-medium",
150												children: "Total"
151											}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
152												className: "text-right",
153												children: formatUsdFromCents(totalAmount)
154											})] })
155										})
156									]
157								})]
158							}
158), hasPaymentMethod ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("footer", {
159								className: "flex w-full items-center border-t border-border pt-3",
160								children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
161									className: "text-sm text-muted-foreground",
162									children: ["Payment method: ", seatInfo?.paymentMethod]
163								})
164							}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("footer", {
165								className: "flex w-full items-center border-t border-border pt-3",
166								children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
167									className: "text-sm text-muted-foreground",
168									children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: `After the trial, NavPro Subscription will cost ` }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
169										className: "font-medium",
170										children: `${formatUsdFromCents(totalAmount)}/month plus tax thereafter.`
171									})]
172								})
173							})]
174						})
175					})
176				]
177			}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogFooter, {
178				className: "w-full py-0 pb-5",
179				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
180					variant: "outline",
181					...cancelButtonProps,
182					className: cn("h-9 flex-1", cancelButtonProps?.className),
183					onClick: () => {
184						return onCancel?.();
185					},
186					children: "No, Thanks"
187				}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
188					...confirmButtonProps,
189					disabled: confirmButtonProps?.disabled ?? !upgradePayload,
190					loading: confirmButtonProps?.loading ?? isUpgrading,
191					className: cn("h-9 flex-1", confirmButtonProps?.className),
192					onClick: handleConfirmInDriverUpgradeDialog,
193					children: "Confirm Upgrade"
194				})]
195			})] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
196				className: "relative flex flex-col items-center gap-3 p-5 py-8 text-center",
197				children: [
198					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
199						type: "button",
200						"aria-label": "Close",
201						className: "absolute top-5 right-5 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:outline-hidden",
202						onClick: handleConfirmSuccessInDriverUpgradeDialog,
203						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(X, { className: "size-5" })
204					}),
205					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
206						className: "flex items-center justify-center",
207						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CircleCheckBig, { className: "size-12 text-emerald-500" })
208					}),
209					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
210						className: "text-lg font-semibold text-foreground",
211						children: "Driver(s) successfully added!"
212					}),
213					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
214						className: "text-sm text-muted-foreground",
215						children: "Your plan has been upgraded. The login credentials have been sent to the driver(s)."
216					}),
217					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
218						type: "button",
219						...successButtonProps,
220						className: cn("mt-2 w-40", successButtonProps?.className),
221						onClick: handleConfirmSuccessInDriverUpgradeDialog,
222						children: "CLOSE"
223					})
224				]
225			})
226		})
227	});
228};
229var import_compiler_runtime$1 = /* @__PURE__ */ __toESM(require_compiler_runtime());
230const driverFormSchema = objectType({
231	firstName: stringType().min(1, "First name is required"),
232	lastName: stringType().min(1, "Last name is required"),
233	phone: stringType().min(1, "Contact number is required").refine((value) => {
234		return FORMATTED_PHONE_REGEX.test(value);
235	}),
236	email: stringType().min(1, "Email is required").email("Please enter a valid email"),
237	password: stringType().min(4, "Password must be at least 4 characters"),
238	permissionGroupId: stringType().optional(),
239	driverType: stringType().optional(),
240	groupId: stringType().optional()
241});
242const driversNewFormSchema = objectType({ drivers: arrayType(driverFormSchema).min(1, "At least one driver is required") });
243const useSelectWithAdd = ({ options, fieldName, addRoute, addLabel, addState, form }) => {
244	const navigate = useNavigate();
245	const fieldKey = (0, import_react.useMemo)(() => {
246		const parts = String(fieldName)?.split(".");
247		return parts[parts.length - 1] || "";
248	}, [fieldName]);
249	const addValue = (0, import_react.useMemo)(() => {
250		return `add_${fieldKey}`;
251	}, [fieldKey]);
252	const handleChange = (0, import_react.useCallback)((value) => {
253		trackMethodCall("handleChange", [value]);
254		if (value === addValue) {
255			navigate(addRoute, { state: {
256				...addState,
257				formSnapshot: form.getValues()
258			} });
259			return;
260		}
261		form.setValue(fieldName, value, {
262			shouldDirty: true,
263			shouldValidate: true
264		});
265	}, [
266		addValue,
267		addRoute,
268		navigate,
269		form,
270		fieldName
271	]);
272	return {
273		options: (0, import_react.useMemo)(() => {
274			return options.length > 0 ? options : [{
275				value: addValue,
276				label: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
277					className: "flex items-center gap-2",
278					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CirclePlus, { className: "size-4" }
278), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
279						className: "text-primary",
280						children: addLabel
281					})]
282				})
283			}];
284		}, [
285			options,
286			addValue,
287			addLabel
288		]),
289		onValueChange: handleChange
290	};
291};
292var getInviteErrorDetail = (error) => {
293	return error?.data?.detail || "Failed to send invitation";
294};
295var setValueOptions = {
296	shouldDirty: true,
297	shouldValidate: true
298};
299const DriversNewDriverSection = (props) => {
300	const { index, form, driverCount, onDeleteDriver, onInOtherFleetChange } = props;
301	const location = useLocation();
302	const groupName = location.state?.group;
303	const terminalName = location.state?.terminal;
304	const { terminalOptions, groupOptions } = useDriverFormOptions();
305	const [checkDriverEmail, { isLoading }] = useLazyCheckDriverEmailQuery();
306	const [companyChangeInvite, { isLoading: isSendingInvitation }] = useCompanyChangeInviteMutation();
307	const [isInOtherFleet, setIsInOtherFleet] = (0, import_react.useState)(false);
308	const isPasswordDisabled = useWatch({
309		control: form.control,
310		name: `drivers.${index}.password`
311	}) === "******";
312	const invitationFirstName = useWatch({
313		control: form.control,
314		name: `drivers.${index}.firstName`
315	});
316	const invitationLastName = useWatch({
317		control: form.control,
318		name: `drivers.${index}.lastName`
319	});
320	const invitationPhone = useWatch({
321		control: form.control,
322		name: `drivers.${index}.phone`
323	});
324	const isInvitationInfoIncomplete = !invitationFirstName?.trim() || !invitationLastName?.trim() || !invitationPhone?.trim();
325	const updateDriverFields = (fields, options = setValueOptions) => {
326		Object.entries(fields).forEach(([key, value]) => {
327			if (value !== void 0) form.setValue(`drivers.${index}.${key}`, value, options);
328		});
329	};
330	const clearDriverFields = () => {
331		updateDriverFields({
332			firstName: "",
333			lastName: "",
334			phone: "",
335			password: ""
336		}, {
337			shouldDirty: true,
338			shouldValidate: false
339		});
340	};
341	const handleEmailBlur = async (email) => {
342		trackMethodCall("handleEmailBlur", [email]);
343		const emailFieldName = `drivers.${index}.email`;
344		await form.trigger(emailFieldName);
345		if (form.getFieldState(emailFieldName).invalid) return;
346		try {
347			const userInfo = (await checkDriverEmail({ email })).data?.data?.[0];
348			if (!userInfo) {
349				const randomPassword = generateMixed();
350				form.setValue(`drivers.${index}.password`, randomPassword, setValueOptions);
351				form.clearErrors(emailFieldName);
352				setIsInOtherFleet(false);
353				onInOtherFleetChange?.(index, false);
354				return;
355			}
356			if (userInfo.invitationCheckStatus === "USER_IN_ANOTHER_TEAM") {
357				const formattedPhone = userInfo.phone ? formatPhone(userInfo.phone, "dash") : "";
358				updateDriverFields({
359					firstName: userInfo.first_name || "",
360					lastName: userInfo.last_name || "",
361					phone: formattedPhone,
362					password: "******"
363				});
364				form.setError(emailFieldName, {
365					type: "manual",
366					message: userInfo.status
367				});
368				setIsInOtherFleet(true);
369				onInOtherFleetChange?.(index, true);
370				return;
371			}
372			setIsInOtherFleet(false);
373			onInOtherFleetChange?.(index, false);
374			if (userInfo.invitationCheckStatus !== "MIGRATION_ALLOWED") {
375				const formattedPhone_0 = userInfo.phone ? formatPhone(userInfo.phone, "dash") : "";
376				updateDriverFields({
377					firstName: userInfo.first_name || "",
378					lastName: userInfo.last_name || "",
379					phone: formattedPhone_0,
380					password: "******"
381				});
382				form.setError(emailFieldName, {
383					type: "manual",
384					message: userInfo.status
385				});
386			} else {
387				const randomPassword_0 = generateMixed();
388				clearDriverFields();
389				form.clearErrors(emailFieldName);
390				form.setValue(`drivers.${index}.password`, randomPassword_0, setValueOptions);
391			}
392		} catch {
393			toast.error("Something went wrong...");
394			form.clearErrors(emailFieldName);
395			setIsInOtherFleet(false);
396			onInOtherFleetChange?.(index, false);
397		}
398	};
399	const handleSendInvitation = async () => {
400		trackMethodCall("handleSendInvitation", []);
401		const driver = form.getValues(`drivers.${index}`);
402		try {
403			await companyChangeInvite({
404				email: driver.email,
405				phoneNumber: driver.phone.replace(/\D/g, ""),
406				firstName: driver.firstName,
407				lastName: driver.lastName,
408				migrationType: "DRIVER"
409			}).unwrap();
410			toast.success("Successfully sent an invitation to this driver.");
411			updateDriverFields({
412				firstName: "",
413				lastName: "",
414				phone: "",
415				password: "",
416				driverType: "",
417				groupId: ""
418			}, {
419				shouldDirty: true,
420				shouldValidate: false
421			});
422			form.setValue(`drivers.${index}.email`, "", {
423				shouldDirty: true,
424				shouldValidate: false
425			});
426			form.clearErrors(`drivers.${index}.email`);
427			setIsInOtherFleet(false);
428			onInOtherFleetChange?.(index, false);
429		} catch (error) {
430			toast.error(getInviteErrorDetail(error));
431		}
432	};
433	const handleContactNumberChange = (e) => {
434		trackMethodCall("handleContactNumberChange", [e]);
435		const formatted = formatPhone(e.target.value, "dash");
436		form.setValue(`drivers.${index}.phone`, formatted, {
437			shouldDirty: true,
438			shouldValidate: true
439		});
440	};
441	const selectedDriverType = useWatch({
442		control: form.control,
443		name: `drivers.${index}.driverType`
444	});
445	const groupSelect = useSelectWithAdd({
446		options: groupOptions,
447		fieldName: `drivers.${index}.permissionGroupId`,
448		addRoute: "/settings/drivers/groups/new",
449		addState: { from: "addDrivers" },
450		addLabel: "Add Group",
451		form
452	});
453	const terminalSelect = useSelectWithAdd({
454		options: terminalOptions,
455		fieldName: `drivers.${index}.groupId`,
456		addRoute: "/settings/terminals",
457		addState: { from: "addDrivers" },
458		addLabel: "Add Terminal",
459		form
460	});
461	(0, import_react.useEffect)(() => {
462		if (groupName || terminalName) {
463			const matchedGroup = groupOptions.find((option) => {
464				return option.label === groupName;
465			});
466			const matchedTerminal = terminalOptions.find((option_0) => {
467				return option_0.label === terminalName;
468			});
469			if (matchedGroup) form.setValue(`drivers.${index}.permissionGroupId`, matchedGroup.value, {
470				shouldDirty: true,
471				shouldValidate: true
472			});
473			if (matchedTerminal) form.setValue(`drivers.${index}.groupId`, matchedTerminal.value, {
474				shouldDirty: true,
475				shouldValidate: true
476			});
477		}
478	}, [
479		form,
480		groupName,
481		groupOptions,
482		index,
483		terminalName,
484		terminalOptions
485	]);
486	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
487		className: "flex flex-col gap-5 rounded-lg border border-border bg-background p-6",
488		children: [
489			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
490				className: "flex items-center justify-between",
491				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h3", {
492					className: "text-lg font-semibold text-accent-foreground",
493					children: ["Driver ", index + 1]
494				}), driverCount > 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
495					type: "button",
496					variant: "ghost",
497					size: "icon",
498					className: "size-8",
499					onClick: () => {
500						return onDeleteDriver(index);
501					},
502					children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trash2, { className: "size-4 text-destructive" })
503				})]
504			}),
505			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
506				className: "grid grid-cols-3 gap-6",
507				children: [
508					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(InputField, {
509						name: `drivers.${index}.email`,
510						title: "Email Address",
511						type: "email",
512						required: true,
513						onBlur: () => {
514							return handleEmailBlur(form.getValues(`drivers.${index}.email`));
515						},
516						suffixIcon: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, { className: "size-4 text-primary" }) : null
517					}),
518					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(InputField, {
519						name: `drivers.${index}.password`,
520						title: "Password",
521						required: true,
522						disabled: isPasswordDisabled
523					}),
524					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectField, {
525						name: `drivers.${index}.permissionGroupId`,
526						title: "Group",
527						placeholder: "Group",
528						options: groupSelect.options,
529						onValueChange: groupSelect.onValueChange
530					})
531				]
532			}),
533			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
534				className: "grid grid-cols-3 gap-6",
535				children: [
536					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(InputField, {
537						name: `drivers.${index}.firstName`,
538						title: "First Name",
539						required: true
540					}),
541					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(InputField, {
542						name: `drivers.${index}.lastName`,
543						title: "Last Name",
544						required: true
545					}),
546					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(InputField, {
547						name: `drivers.${index}.phone`,
548						title: "Contact Number",
549						required: true,
550						inputMode: "numeric",
551						maxLength: 12,
552						onChange: handleContactNumberChange
553					})
554				]
555			}),
556			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
557				className: "grid grid-cols-3 gap-6",
558				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
559					className: "flex flex-col space-y-2",
560					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectField, {
561						name: `drivers.${index}.driverType`,
562						title: "Driver Type",
563						placeholder: "Driver Type",
564						options: DRIVER_TYPE_DATA.map((type) => {
565							return {
566								value: type.value,
567								label: type.message ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
568									className: "flex flex-col gap-0.5",
569									children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: type.label }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
570										className: "text-xs text-muted-foreground",
571										children: type.message
572									})]
573								}) : type.label
574							};
575						}),
576						selectValueProps: { children: selectedDriverType ? driverTypeLabelMap[selectedDriverType] || "" : void 0 }
577					}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DriversTypesPopover, {})]
578				}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectField, {
579					name: `drivers.${index}.groupId`,
580					title: "Terminal",
581					placeholder: "Select terminal",
582					options: terminalSelect.options,
583					onValueChange: terminalSelect.onValueChange
584				})]
585			}),
586			isInOtherFleet && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Alert, {
587				variant: "info",
588				className: "flex items-center justify-between",
589				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
590					className: "flex items-start gap-3",
591					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Info, { className: "mt-0.5 size-4 shrink-0 text-primary" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
592						className: "text-sm font-medium",
593						children: "This driver is currently active in a different fleet. You can send an invitation to the driver to join your fleet."
594					})]
595				}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
596					type: "button",
597					size: "sm",
598					className: "ml-3 shrink-0",
599					onClick: handleSendInvitation,
600					disabled: isSendingInvitation || isInvitationInfoIncomplete,
601					children: isSendingInvitation ? "Sending..." : "Send Invitation"
602				})]
603			})
604		]
605	});
606};
607const DeleteDriverDialog = (props) => {
608	const $ = (0, import_compiler_runtime$1.c)(18);
609	const { open, onOpenChange, onConfirm, onCancel } = props;
610	let t0;
611	if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
612		t0 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(AlertDialogHeader, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDialogTitle, { children: "Are you sure you want to delete this Driver?" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDialogDescription, { children: "The Driver will be deleted from Add Drivers list." })] });
613		$[0] = t0;
614	} else t0 = $[0];
615	let t1;
616	if ($[1] !== onCancel) {
617		t1 = () => onCancel?.();
618		$[1] = onCancel;
619		$[2] = t1;
620	} else t1 = $[2];
621	let t2;
622	if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
623		t2 = cn(buttonVariants({ variant: "outline" }));
624		$[3] = t2;
625	} else t2 = $[3];
626	let t3;
627	if ($[4] !== t1) {
628		t3 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDialogCancel, {
629			onClick: t1,
630			className: t2,
631			children: "Cancel"
632		});
633		$[4] = t1;
634		$[5] = t3;
635	} else t3 = $[5];
636	let t4;
637	if ($[6] !== onConfirm) {
638		t4 = () => onConfirm?.();
639		$[6] = onConfirm;
640		$[7] = t4;
641	} else t4 = $[7];
642	let t5;
643	if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
644		t5 = cn(buttonVariants({ variant: "destructive" }));
645		$[8] = t5;
646	} else t5 = $[8];
647	let t6;
648	if ($[9] !== t4) {
649		t6 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDialogAction, {
650			onClick: t4,
651			className: t5,
652			children: "Delete"
653		});
654		$[9] = t4;
655		$[10] = t6;
656	} else t6 = $[10];
657	let t7;
658	if ($[11] !== t3 || $[12] !== t6) {
659		t7 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(AlertDialogContent, { children: [t0, /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(AlertDialogFooter, { children: [t3, t6] })] });
660		$[11] = t3;
661		$[12] = t6;
662		$[13] = t7;
663	} else t7 = $[13];
664	let t8;
665	if ($[14] !== onOpenChange || $[15] !== open || $[16] !== t7) {
666		t8 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDialog, {
667			open,
668			onOpenChange,
669			children: t7
670		});
671		$[14] = onOpenChange;
672		$[15] = open;
673		$[16] = t7;
674		$[17] = t8;
675	} else t8 = $[17];
676	return t8;
677};
678var import_compiler_runtime = /* @__PURE__ */ __toESM(require_compiler_runtime());
679const DriversNewForm = (t0) => {
680	const $ = (0, import_compiler_runtime.c)(42);
681	const { onSubmit, onUnresolvedInvitationChange } = t0;
682	const [deleteDriverDialogOpen, setDeleteDriverDialogOpen] = (0, import_react.useState)(false);
683	const [deleteDriverIndex, setDeleteDriverIndex] = (0, import_react.useState)(0);
684	const formSnapshot = useLocation().state?.formSnapshot;
685	const [driverCount, setDriverCount] = (0, import_react.useState)(formSnapshot?.drivers.length ?? 1);
686	let t1;
687	if ($[0] !== formSnapshot?.drivers.length) {
688		t1 = () => new Array(formSnapshot?.drivers.length ?? 1).fill(false);
689		$[0] = formSnapshot?.drivers.length;
690		$[1] = t1;
691	} else t1 = $[1];
692	const [inOtherFleetFlags, setInOtherFleetFlags] = (0, import_react.useState)(t1);
693	let t2;
694	let t3;
695	if ($[2] !== inOtherFleetFlags || $[3] !== onUnresolvedInvitationChange) {
696		t2 = () => {
697			onUnresolvedInvitationChange?.(inOtherFleetFlags.some(Boolean));
698		};
699		t3 = [inOtherFleetFlags, onUnresolvedInvitationChange];
700		$[2] = inOtherFleetFlags;
701		$[3] = onUnresolvedInvitationChange;
702		$[4] = t2;
703		$[5] = t3;
704	} else {
705		t2 = $[4];
706		t3 = $[5];
707	}
708	(0, import_react.useEffect)(t2, t3);
709	let t4;
710	if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
711		t4 = t(driversNewFormSchema);
712		$[6] = t4;
713	} else t4 = $[6];
714	let t5;
715	if ($[7] !== formSnapshot) {
716		t5 = formSnapshot ?? { drivers: [{
717			firstName: "",
718			lastName: "",
719			phone: "",
720			email: "",
721			password: "",
722			permissionGroupId: "",
723			driverType: "",
724			groupId: ""
725		}] };
726		$[7] = formSnapshot;
727		$[8] = t5;
728	} else t5 = $[8];
729	let t6;
730	if ($[9] !== t5) {
731		t6 = {
732			resolver: t4,
733			defaultValues: t5,
734			mode: "onChange"
735		};
736		$[9] = t5;
737		$[10] = t6;
738	} else t6 = $[10];
739	const form = useForm(t6);
740	let t7;
741	if ($[11] !== form) {
742		t7 = () => {
743			trackMethodCall("handleAddDriver", []);
744			setDriverCount(_temp);
745			setInOtherFleetFlags(_temp2);
746			const currentDrivers = form.getValues("drivers");
747			form.setValue("drivers", [...currentDrivers, {
748				firstName: "",
749				lastName: "",
750				phone: "",
751				email: "",
752				password: "",
753				permissionGroupId: "",
754				driverType: "",
755				groupId: ""
756			}]);
757		};
758		$[11] = form;
759		$[12] = t7;
760	} else t7 = $[12];
761	const handleAddDriver = t7;
762	let t8;
763	if ($[13] !== driverCount || $[14] !== form) {
764		t8 = (index) => {
765			trackMethodCall("handleDeleteDriver", [index]);
766			if (driverCount <= 1) return;
767			setDriverCount(_temp3);
768			setInOtherFleetFlags((prev_2) => prev_2.filter((_, i) => i !== index));
769			const newDrivers = form.getValues("drivers").filter((__0, i_0) => i_0 !== index);
770			form.setValue("drivers", newDrivers);
771		};
772		$[13] = driverCount;
773		$[14] = form;
774		$[15] = t8;
775	} else t8 = $[15];
776	const handleDeleteDriver = t8;
777	let t9;
778	if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
779		t9 = (index_0, value) => {
780			trackMethodCall("handleInOtherFleetChange", [index_0, value]);
781			setInOtherFleetFlags((prev_3) => {
782				const next = [...prev_3];
783				next[index_0] = value;
784				return next;
785			});
786		};
787		$[16] = t9;
788	} else t9 = $[16];
789	const handleInOtherFleetChange = t9;
790	let t10;
791	if ($[17] !== form || $[18] !== onSubmit) {
792		t10 = form.handleSubmit(onSubmit);
793		$[17] = form;
794		$[18] = onSubmit;
795		$[19] = t10;
796	} else t10 = $[19];
797	let t11;
798	if ($[20] !== driverCount) {
799		t11 = Array.from({ length: driverCount });
800		$[20] = driverCount;
801		$[21] = t11;
802	} else t11 = $[21];
803	let t12;
804	if ($[22] !== driverCount || $[23] !== form || $[24] !== t11) {
805		t12 = t11.map((__1, index_1) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DriversNewDriverSection, {
806			index: index_1,
807			form,
808			driverCount,
809			onDeleteDriver: (index_2) => {
810				setDeleteDriverIndex(index_2);
811				setDeleteDriverDialogOpen(true);
812			},
813			onInOtherFleetChange: handleInOtherFleetChange
814		}, index_1));
815		$[22] = driverCount;
816		$[23] = form;
817		$[24] = t11;
818		$[25] = t12;
819	} else t12 = $[25];
820	let t13;
821	if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
822		t13 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Plus, { className: "size-4" });
823		$[26] = t13;
824	} else t13 = $[26];
825	let t14;
826	if ($[27] !== handleAddDriver) {
827		t14 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
828			type: "button",
829			variant: "default-subtle",
830			onClick: handleAddDriver,
831			className: "self-start",
832			children: [t13, "Add New Driver"]
833		});
834		$[27] = handleAddDriver;
835		$[28] = t14;
836	} else t14 = $[28];
837	let t15;
838	if ($[29] !== deleteDriverIndex || $[30] !== handleDeleteDriver) {
839		t15 = () => handleDeleteDriver(deleteDriverIndex);
840		$[29] = deleteDriverIndex;
841		$[30] = handleDeleteDriver;
842		$[31] = t15;
843	} else t15 = $[31];
844	let t16;
845	if ($[32] === Symbol.for("react.memo_cache_sentinel")) {
846		t16 = () => setDeleteDriverDialogOpen(false);
847		$[32] = t16;
848	} else t16 = $[32];
849	let t17;
850	if ($[33] !== deleteDriverDialogOpen || $[34] !== t15) {
851		t17 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DeleteDriverDialog, {
852			open: deleteDriverDialogOpen,
853			onOpenChange: setDeleteDriverDialogOpen,
854			onConfirm: t15,
855			onCancel: t16
856		});
857		$[33] = deleteDriverDialogOpen;
858		$[34] = t15;
859		$[35] = t17;
860	} else t17 = $[35];
861	let t18;
862	if ($[36] !== form || $[37] !== t10 || $[38] !== t12 || $[39] !== t14 || $[40] !== t17) {
863		t18 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(FormWrapper, {
864			form,
865			id: "drivers-new-form",
866			onSubmit: t10,
867			className: "flex w-full max-w-[1100px] flex-col space-y-5",
868			children: [
869				t12,
870				t14,
871				t17
872			]
873		});
874		$[36] = form;
875		$[37] = t10;
876		$[38] = t12;
877		$[39] = t14;
878		$[40] = t17;
879		$[41] = t18;
880	} else t18 = $[41];
881	return t18;
882};
883function _temp(prev) {
884	return prev + 1;
885}
886function _temp2(prev_0) {
887	return [...prev_0, false];
888}
889function _temp3(prev_1) {
890	return prev_1 - 1;
891}
892var DriversNew = () => {
893	const [checkDriverSeats, { isLoading: isCheckingSeats }] = useCheckDriverSeatsMutation();
894	const [inviteDriver] = useInviteDriverMutation();
895	const navigate = useNavigate();
896	const [upgradeDialogOpen, setUpgradeDialogOpen] = (0, import_react.useState)(false);
897	const [seatInfo, setSeatInfo] = (0, import_react.useState)(null);
898	const [upgradePayload, setUpgradePayload] = (0, import_react.useState)();
899	const [hasUnresolvedInvitation, setHasUnresolvedInvitation] = (0, import_react.useState)(false);
900	const handleAddDrivers = async (data) => {
901		trackMethodCall("handleAddDrivers", [data]);
902		try {
903			const emailList = data.drivers.map((driver) => {
904				return driver.email;
905			});
906			const checkSeatsResult = await checkDriverSeats({
907				rank: "DRIVER",
908				emailList
909			}).unwrap();
910			if (checkSeatsResult.code !== 200) {
911				toast.error(checkSeatsResult.message || "Something went wrong...");
912				return;
913			}
914			const checkData = checkSeatsResult.data ?? null;
915			setSeatInfo(checkData);
916			if ((checkData?.addSeats ?? 0) > 0) {
917				setUpgradePayload({
918					totalAmount: checkData?.addSeatsPrice ?? 0,
919					taxAmount: checkData?.taxAmount ?? 0,
920					inviteMembers: data.drivers.map((driver_0) => {
921						return {
922							firstName: driver_0.firstName,
923							lastName: driver_0.lastName,
924							email: driver_0.email,
925							password: driver_0.password,
926							phone: driver_0.phone,
927							truckIds: [],
928							trailerIds: [],
929							rank: "DRIVER"
930						};
931					})
932				});
933				setUpgradeDialogOpen(true);
934				return;
935			}
936			const invitePayload = { inviteDrivers: data.drivers.map((driver_1) => {
937				return {
938					firstName: driver_1.firstName,
939					lastName: driver_1.lastName,
940					email: driver_1.email,
941					password: driver_1.password,
942					phone: driver_1.phone,
943					driverType: driver_1.driverType || void 0,
944					permissionGroupId: driver_1.permissionGroupId ? Number(driver_1.permissionGroupId) : void 0,
945					groupId: driver_1.groupId ? Number(driver_1.groupId) : void 0
946				};
947			}) };
948			const inviteResult = await inviteDriver(invitePayload).unwrap();
949			if (inviteResult.successDrivers.length > 0) toast.success(`Successfully invited ${inviteResult.successDrivers.length} driver(s)`);
950			if (inviteResult.causes && inviteResult.causes.length > 0) {
951				const errorMessages = inviteResult.causes.map((cause) => {
952					return `${cause.email}: ${cause.cause}`;
953				}).join("; ");
954				toast.error(errorMessages);
955			}
956			navigate("/settings/drivers");
957		} catch {
958			toast.error("Failed to submit drivers. Please try again.");
959		}
960	};
961	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
962		className: "flex h-full flex-col px-5",
963		children: [
964			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
965				className: "pt-8 pb-6",
966				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppBreadcrumb, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
967					className: "mt-4 flex items-center justify-between",
968					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
969						className: "flex flex-col space-y-0.5",
970						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {
971							className: "text-2xl font-semibold text-foreground",
972							children: "Add Drivers"
973						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
974							className: "text-sm text-muted-foreground",
975							children: "Email Address and Password will be used as the primary login info for your driver to log into Trucker Path app."
976						})]
977					}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
978						type: "submit",
979						form: "drivers-new-form",
980						loading: isCheckingSeats,
981						disabled: hasUnresolvedInvitation,
982						children: "Save"
983					})]
984				})]
985			}),
986			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Separator, {}),
987			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
988				className: "flex min-h-0 flex-1 justify-center overflow-y-auto py-6",
989				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DriversNewForm, {
990					onSubmit: handleAddDrivers,
991					onUnresolvedInvitationChange: setHasUnresolvedInvitation
992				})
993			}),
994			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DriverUpgradeDialog, {
995				open: upgradeDialogOpen,
996				seatInfo,
997				upgradePayload,
998				onOpenChange: setUpgradeDialogOpen,
999				onCancel: () => {
1000					return setUpgradeDialogOpen(false);
1001				},
1002				onSuccessConfirm: () => {
1003					setUpgradeDialogOpen(false);
1004					navigate("/settings/drivers");
1005				}
1006			})
1007		]
1008	});
1009};
1010export { DriversNew };

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.