@mychoice/mychoice-sdk-modules 2.2.27 → 2.2.28

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/cjs/index.js CHANGED
@@ -118,10 +118,14 @@ DateSelectFormBox.defaultProps = {
118
118
 
119
119
  const SwitchButtonBox = (props) => {
120
120
  const { name, title, description, hintMessage, isRemovable, errorMessage, className, defaultValue, items, onChange } = props;
121
+ // Allow boolean true/false answers; empty string means unanswered (neither Yes nor No).
121
122
  const [activeId, setActiveId] = React.useState(defaultValue);
122
123
  const { appConfigState: { appType }, } = mychoiceSdkStore.useStoreAppConfig();
123
124
  const isTheBig = appType === mychoiceSdkComponents.AppTypes.TheBig;
124
125
  const isMychoice = mychoiceSdkComponents.isMyChoiceLike(appType);
126
+ React.useEffect(() => {
127
+ setActiveId(defaultValue);
128
+ }, [defaultValue]);
125
129
  const setClassNames = (isActive) => {
126
130
  if (isTheBig) {
127
131
  return isActive ? 'thebig-bold' : 'thebig-regular';
@@ -131,6 +135,7 @@ const SwitchButtonBox = (props) => {
131
135
  }
132
136
  return '';
133
137
  };
138
+ const isAnswered = activeId === true || activeId === false;
134
139
  const handleClick = React.useCallback((selectedItem) => () => {
135
140
  setActiveId(selectedItem.value);
136
141
  if (onChange) {
@@ -139,8 +144,11 @@ const SwitchButtonBox = (props) => {
139
144
  value: selectedItem.value,
140
145
  });
141
146
  }
142
- }, []);
143
- return (jsxRuntime.jsx(Container, { name: name, className: className, title: title, description: description, errorMessage: errorMessage, isRemovable: isRemovable, hintMessage: hintMessage, children: jsxRuntime.jsx("div", { className: "flex-items-container", children: items.map((item, index) => (jsxRuntime.jsx(mychoiceSdkComponents.ButtonForm, { className: setClassNames(item.value === activeId), onClick: handleClick(item), selected: item.value === activeId, label: item.name }, `${item.name}_${index}`))) }) }));
147
+ }, [name, onChange]);
148
+ return (jsxRuntime.jsx(Container, { name: name, className: className, title: title, description: description, errorMessage: errorMessage, isRemovable: isRemovable, hintMessage: hintMessage, children: jsxRuntime.jsx("div", { className: "flex-items-container", children: items.map((item, index) => {
149
+ const isSelected = isAnswered && item.value === activeId;
150
+ return (jsxRuntime.jsx(mychoiceSdkComponents.ButtonForm, { className: setClassNames(isSelected), onClick: handleClick(item), selected: isSelected, label: item.name }, `${item.name}_${index}`));
151
+ }) }) }));
144
152
  };
145
153
  SwitchButtonBox.defaultProps = {
146
154
  defaultValue: '',
@@ -209,18 +217,41 @@ const capitalize = (text) => text.charAt(0).toUpperCase() + text.slice(1);
209
217
  const BlockVehLinks = () => {
210
218
  const { vehicleState: { items: vehicles } } = mychoiceSdkStore.useStoreFormCarVehicle();
211
219
  const { driverState: { items: drivers } } = mychoiceSdkStore.useStoreFormCarDriverBase();
212
- const { discountState: { vehlinks, occVehlinks }, dispatchDiscountState } = mychoiceSdkStore.useStoreFormCarDiscount();
220
+ const { discountState: { vehlinks, occVehlinks, inValidation }, dispatchDiscountState } = mychoiceSdkStore.useStoreFormCarDiscount();
221
+ // Spec: 2 drivers / 2 vehicles — ask only for Vehicle1; system assigns the other driver as PO on Vehicle2.
222
+ const isTwoByTwo = drivers.length === 2 && vehicles.length === 2;
223
+ const assignPrimary = (driverIndex, vehicleIndex) => {
224
+ dispatchDiscountState({
225
+ type: mychoiceSdkStore.StoreFormCarDiscountActionTypes.FormCarDiscountVehlinkSelect,
226
+ payload: { driverIndex, vehicleIndex },
227
+ });
228
+ };
229
+ React.useEffect(() => {
230
+ if (!isTwoByTwo)
231
+ return;
232
+ const v1 = vehlinks.find((l) => l.vehicleIndex === 0 && l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn);
233
+ if (!v1 || v1.driverIndex < 0)
234
+ return;
235
+ const otherDriverIndex = drivers.findIndex((_, index) => index !== v1.driverIndex);
236
+ if (otherDriverIndex < 0)
237
+ return;
238
+ const v2 = vehlinks.find((l) => l.vehicleIndex === 1 && l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn);
239
+ if (v2?.driverIndex === otherDriverIndex)
240
+ return;
241
+ assignPrimary(otherDriverIndex, 1);
242
+ }, [isTwoByTwo, vehlinks, drivers]);
213
243
  if (drivers.length <= 1) {
214
244
  return null;
215
245
  }
216
246
  const handlePrimaryDriverChange = (vehicleIndex) => ({ value }) => {
217
- dispatchDiscountState({
218
- type: mychoiceSdkStore.StoreFormCarDiscountActionTypes.FormCarDiscountVehlinkSelect,
219
- payload: {
220
- driverIndex: value,
221
- vehicleIndex,
222
- },
223
- });
247
+ const driverIndex = Number(value);
248
+ assignPrimary(driverIndex, vehicleIndex);
249
+ if (isTwoByTwo && vehicleIndex === 0) {
250
+ const otherDriverIndex = drivers.findIndex((_, index) => index !== driverIndex);
251
+ if (otherDriverIndex >= 0) {
252
+ assignPrimary(otherDriverIndex, 1);
253
+ }
254
+ }
224
255
  };
225
256
  const handleOccDriverChange = (driverIndex) => ({ value }) => {
226
257
  dispatchDiscountState({
@@ -233,30 +264,38 @@ const BlockVehLinks = () => {
233
264
  };
234
265
  // Drivers that are NOT assigned as primary for any vehicle
235
266
  const primaryDriverIndices = vehlinks
236
- .filter((l) => l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn)
267
+ .filter((l) => l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn && l.driverIndex >= 0)
237
268
  .map((l) => l.driverIndex);
238
269
  const unassignedDrivers = drivers
239
270
  .map((driver, index) => ({ driver, index }))
240
271
  .filter(({ index }) => !primaryDriverIndices.includes(index));
241
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(LabelFormBox, { title: "Since there are multiple drivers in this quote, please tell us who drives which vehicle the most. Please provide an answer that most accurately describes your situation." }), vehicles.map((vehicle, vehicleIndex) => {
272
+ const vehiclesToAsk = isTwoByTwo ? vehicles.slice(0, 1) : vehicles;
273
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(LabelFormBox, { title: "Since there are multiple drivers in this quote, please tell us who drives which vehicle the most. Please provide an answer that most accurately describes your situation." }), vehiclesToAsk.map((vehicle, vehicleIndex) => {
242
274
  const { year, make, model } = vehicle;
243
275
  const selectedPrimary = vehlinks.find((l) => l.vehicleIndex === vehicleIndex && l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn);
244
- const allDriverOptions = drivers
276
+ const isPrimaryAnswered = selectedPrimary !== undefined && selectedPrimary.driverIndex >= 0;
277
+ // Show all drivers so the user can freely reselect / re-order primaries.
278
+ const primaryOptions = drivers
245
279
  .map((driver, driverIndex) => ({ name: driver.firstName, value: driverIndex }));
246
- const filteredOptions = allDriverOptions.filter(({ value }) => {
247
- const assignedVehicle = vehlinks.find((l) => l.driverIndex === value && l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn);
248
- return !assignedVehicle || assignedVehicle.vehicleIndex === vehicleIndex;
249
- });
250
- const availablePrimaryOptions = filteredOptions.length > 0 ? filteredOptions : allDriverOptions;
251
- return (jsxRuntime.jsx(SelectFormBox, { title: `Who drives the ${year} ${make} ${model} the most?`, onChange: handlePrimaryDriverChange(vehicleIndex), options: availablePrimaryOptions, defaultValue: selectedPrimary?.driverIndex ?? 0, name: `vehlink-${vehicleIndex}` }, `vehlink-${vehicleIndex}`));
252
- }), drivers.length > vehicles.length && unassignedDrivers.map(({ driver, index: driverIndex }) => {
253
- const selectedVehicle = occVehlinks.find((l) => l.driverIndex === driverIndex);
254
- const vehicleOptions = vehicles.map((vehicle, vehicleIndex) => ({
255
- name: `${vehicle.year} ${vehicle.make} ${vehicle.model}`,
256
- value: vehicleIndex,
257
- }));
258
- return (jsxRuntime.jsx(SelectFormBox, { title: `Which vehicle does ${driver.firstName} drive the most?`, onChange: handleOccDriverChange(driverIndex), options: vehicleOptions, defaultValue: selectedVehicle?.vehicleIndex ?? 0, name: `occ-vehlink-${driverIndex}` }, `occ-vehlink-${driverIndex}`));
259
- })] }));
280
+ const isDuplicatePrimary = !isTwoByTwo
281
+ && isPrimaryAnswered
282
+ && drivers.length >= vehicles.length
283
+ && vehlinks.some((l) => l.vehicleIndex !== vehicleIndex
284
+ && l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn
285
+ && l.driverIndex === selectedPrimary?.driverIndex);
286
+ return (jsxRuntime.jsx(SelectFormBox, { title: `Who is the principal driver of the ${year} ${make} ${model}?`, onChange: handlePrimaryDriverChange(vehicleIndex), options: primaryOptions, defaultValue: isPrimaryAnswered ? selectedPrimary.driverIndex : '', name: `vehlink-${vehicleIndex}`, placeholder: "Select from the list", autoSelectIfValueIsOutOfOptions: false, error: (!isPrimaryAnswered && inValidation) || isDuplicatePrimary, errorMessage: isDuplicatePrimary
287
+ ? 'This driver is already the primary driver of another vehicle. Each vehicle should have a different primary driver.'
288
+ : '' }, `vehlink-${vehicleIndex}`));
289
+ }), drivers.length > vehicles.length && vehicles.length > 1
290
+ && unassignedDrivers.map(({ driver, index: driverIndex }) => {
291
+ const selectedVehicle = occVehlinks.find((l) => l.driverIndex === driverIndex);
292
+ const vehicleOptions = vehicles.map((vehicle, vehicleIndex) => ({
293
+ name: `${vehicle.year} ${vehicle.make} ${vehicle.model}`,
294
+ value: vehicleIndex,
295
+ }));
296
+ const isOccAnswered = selectedVehicle !== undefined && selectedVehicle.vehicleIndex >= 0;
297
+ return (jsxRuntime.jsx(SelectFormBox, { title: `Which vehicle does ${driver.firstName} drive the most?`, onChange: handleOccDriverChange(driverIndex), options: vehicleOptions, defaultValue: isOccAnswered ? selectedVehicle.vehicleIndex : '', name: `occ-vehlink-${driverIndex}`, placeholder: "Select from the list", autoSelectIfValueIsOutOfOptions: false, error: !isOccAnswered && inValidation }, `occ-vehlink-${driverIndex}`));
298
+ })] }));
260
299
  };
261
300
 
262
301
  const BlockNextPageInfo$2 = () => {
@@ -893,7 +932,7 @@ const BlockCarConditionInfo = () => {
893
932
  type: mychoiceSdkStore.StoreFormCarVehicleActionTypes.FormCarDailyDistanceSelect,
894
933
  payload: { distanceDaily: value },
895
934
  });
896
- const yearlyDefault = `${getRecommendedRange(value, primaryUse === mychoiceSdkComponents.VehiclePrimaryUseTypes.Business ? distanceBusiness : 1)}`;
935
+ const yearlyDefault = `${getRecommendedRange(value, primaryUse === mychoiceSdkComponents.VehiclePrimaryUseTypes.Business ? distanceBusiness : undefined)}`;
897
936
  dispatchVehicleState({
898
937
  type: mychoiceSdkStore.StoreFormCarVehicleActionTypes.FormCarYearlyDistanceSelect,
899
938
  payload: { distanceYearly: yearlyDefault },
@@ -916,7 +955,7 @@ const BlockCarConditionInfo = () => {
916
955
  purchaseMonth || '',
917
956
  purchaseYear || '',
918
957
  ], vehicleState.inValidation), error: vehicleState.inValidation, minDate: year ? `${Number(year) - 1}-01-01` : mychoiceSdkComponents.getFormattedDate('', 'yyyy-MM-dd'), maxDate: mychoiceSdkComponents.getFormattedDate('', 'yyyy-MM-dd') }), !(isAlbertaProvince && isTheBig) && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.carWinterTiresCheck, onChange: handleWinterTiresChange, name: "winterTires", defaultValue: getSelectedOption(mychoiceSdkComponents.carWinterTiresCheck, winterTires), description: "Snow. Ice. Freezing temperatures. Winter tires protect you from all these winter weather conditions, and more. It also protects your wallet. Investing in winter tires can save you $50 to $100 on your insurance.", title: "Does your car have winter tires?" })), jsxRuntime.jsx(SelectFormBox, { options: mychoiceSdkComponents.carKeepPlace, name: "parkingLocation", onChange: handleCarParkingLocationChange, defaultValue: getSelectedOption(mychoiceSdkComponents.carKeepPlace, parkingLocation), title: "Where do you keep your car overnight?", placeholder: "Select from the list", description: "For many of us, the answer is \u201Cat home.\u201D If you park your car in various locations throughout the year, then select the most frequently parking spot. Be honest\u2014some insurers will use your overnight parking location to calculate a quote, which could affect your claims in the future.", autoSelectIfValueIsOutOfOptions: false, error: !parkingLocation && vehicleState.inValidation, errorMessage: getErrorMessage(parkingLocation, vehicleState.inValidation) }), jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.carUsagePurpose, onChange: handleCarUsageChange, name: "primaryUse", defaultValue: getSelectedOption(mychoiceSdkComponents.carUsagePurpose, primaryUse) || mychoiceSdkComponents.carUsagePurpose[0].value, hintMessage: primaryUseHintMessage, description: "The way you use your vehicle is a primary factor that insurers use in your policy terms and fees, whether it be personal or business.\n \u2022 Personal is driving from work or school to home.\n \u2022 Business considers other uses like sales calls, pick-ups or deliveries, or other business errands.", title: "What do you use your car for?" }), jsxRuntime.jsx(SelectFormBox, { options: mychoiceSdkComponents.firstDriveDistanceList, name: "distanceDaily", onChange: handleCarDailyDistanceChange, defaultValue: getSelectedOption(mychoiceSdkComponents.firstDriveDistanceList, distanceDaily), title: "How far is your 1-way commute to work or school?", placeholder: "Select", description: "The distance you drive to work or school would be an example of your daily commute. It is one of the most important factors when determining coverage options since it exposes you to traffic each day. The shorter your commute, the less risk you carry of an accident.", autoSelectIfValueIsOutOfOptions: false, error: distanceDaily === undefined && vehicleState.inValidation, errorMessage: getErrorMessage(distanceDaily, vehicleState.inValidation) }), jsxRuntime.jsx(SelectFormBox, { options: mychoiceSdkComponents.yearlyDriveDistanceList, name: "distanceYearly", onChange: handleCarYearlyDistanceChange, defaultValue: getSelectedOption(mychoiceSdkComponents.yearlyDriveDistanceList, distanceYearly), title: "How many total kilometers are driven each year?", placeholder: "Select", hintMessage: distanceDaily !== undefined ? `Based on your daily driven kilometers, we recommend
919
- ${mychoiceSdkComponents.numberWithCommas(getRecommendedRange(distanceDaily, primaryUse === mychoiceSdkComponents.VehiclePrimaryUseTypes.Business ? distanceBusiness : 1))} for your yearly driven kilometers` : '', autoSelectIfValueIsOutOfOptions: false, error: !distanceYearly && vehicleState.inValidation, errorMessage: getErrorMessage(distanceYearly, vehicleState.inValidation) }), primaryUse === 'business' && (jsxRuntime.jsx(SelectFormBox, { options: mychoiceSdkComponents.businessUsePercentOptions, name: "businessUsePercent", onChange: handleBusinessUsePercentChange, defaultValue: getSelectedOption(mychoiceSdkComponents.businessUsePercentOptions, businessUsePercent), title: "What percentage of your total kilometers are driven for business purposes?", placeholder: "Select", autoSelectIfValueIsOutOfOptions: false, error: !businessUsePercent && vehicleState.inValidation, errorMessage: getErrorMessage(businessUsePercent, vehicleState.inValidation) })), showPolicyStartOnVehiclePage && (jsxRuntime.jsx(DateSelectFormBox, { name: "policyStart", dateNames: ['policyStartYear', 'policyStartMonth', 'policyStartDay'], onDateChange: handlePolicyStartDateChange, defaultValue: defaultPolicyStartDate, title: "What is the ideal start date for your new insurance policy?", description: "Select your preferred date for the beginning of your new insurance policy. For instance, you may set the start date for the day that your current insurance expires to ensure that you're continuously covered. Alternatively, select today's date for a quote or new policy.", minDate: mychoiceSdkComponents.addDaysToDate('', 1), maxDate: mychoiceSdkComponents.addDaysToDate('', 90), isDay: true }))] }));
958
+ ${mychoiceSdkComponents.numberWithCommas(getRecommendedRange(distanceDaily, primaryUse === mychoiceSdkComponents.VehiclePrimaryUseTypes.Business ? distanceBusiness : undefined))} for your yearly driven kilometers` : '', autoSelectIfValueIsOutOfOptions: false, error: !distanceYearly && vehicleState.inValidation, errorMessage: getErrorMessage(distanceYearly, vehicleState.inValidation) }), primaryUse === 'business' && (jsxRuntime.jsx(SelectFormBox, { options: mychoiceSdkComponents.businessUsePercentOptions, name: "businessUsePercent", onChange: handleBusinessUsePercentChange, defaultValue: getSelectedOption(mychoiceSdkComponents.businessUsePercentOptions, businessUsePercent), title: "What percentage of your total kilometers are driven for business purposes?", placeholder: "Select", autoSelectIfValueIsOutOfOptions: false, error: !businessUsePercent && vehicleState.inValidation, errorMessage: getErrorMessage(businessUsePercent, vehicleState.inValidation) })), showPolicyStartOnVehiclePage && (jsxRuntime.jsx(DateSelectFormBox, { name: "policyStart", dateNames: ['policyStartYear', 'policyStartMonth', 'policyStartDay'], onDateChange: handlePolicyStartDateChange, defaultValue: defaultPolicyStartDate, title: "What is the ideal start date for your new insurance policy?", description: "Select your preferred date for the beginning of your new insurance policy. For instance, you may set the start date for the day that your current insurance expires to ensure that you're continuously covered. Alternatively, select today's date for a quote or new policy.", minDate: mychoiceSdkComponents.addDaysToDate('', 1), maxDate: mychoiceSdkComponents.addDaysToDate('', 90), isDay: true }))] }));
920
959
  };
921
960
 
922
961
  const VehicleSectionMain = () => {
@@ -947,7 +986,7 @@ const AccidentBenefitsModal = ({ selectedCoverages, onApply, onCancel, selectAll
947
986
  };
948
987
  return (jsxRuntime.jsx("div", { className: "ab-modal-overlay", onClick: onCancel, children: jsxRuntime.jsxs("div", { className: "ab-modal", onClick: (e) => e.stopPropagation(), children: [jsxRuntime.jsxs("div", { className: "ab-modal-header", children: [jsxRuntime.jsx("h3", { children: "Accident Benefits" }), jsxRuntime.jsx("p", { className: "ab-modal-subtitle", children: isMyChoice ? 'Standard Coverage + Optional Enhancements' : 'Standard Coverage + Self-Selected Optional Enhancements' }), jsxRuntime.jsx("p", { className: "ab-modal-body-text", children: isMyChoice
949
988
  ? 'Maximum coverage with flexibility to remove additional benefits.'
950
- : 'Base coverage with flexibility to select additional benefits' })] }), jsxRuntime.jsxs("div", { className: "ab-modal-content", children: [jsxRuntime.jsxs("div", { className: "ab-modal-standard-block ab-modal-standard-block--included", children: [jsxRuntime.jsxs("div", { className: "ab-modal-standard-included-header", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: true, disabled: true, readOnly: true, className: "ab-modal-standard-locked-checkbox" }), jsxRuntime.jsx("h4", { children: isMyChoice ? 'All Coverages Included by Default' : 'Standard Benefits — Included' })] }), !isMyChoice && (jsxRuntime.jsx("p", { className: "ab-modal-standard-subtitle", children: "Medical, Rehabilitation, and Attendant Care" })), jsxRuntime.jsx("p", { className: "ab-modal-standard-description", children: isMyChoice ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: ["Our standard quote automatically includes all optional accident benefits at their minimum coverage limits. We strongly recommend keeping all coverages selected to ensure the most complete protection \u2014 opting out could leave you without critical support when you need it most. For example, deselecting Income Replacement means no weekly payments if an injury prevents you from working, and removing Caregiver Replacement leaves no financial support for dependents in your care.", jsxRuntime.jsx("br", {}), jsxRuntime.jsx("br", {}), "Please speak with a broker partner to discuss higher limits or learn more about how each benefit protects you."] })) : ('Covers medical expenses, therapy and personal care for injuries from an accident, including doctor visits and physiotherapy.') })] }), jsxRuntime.jsxs("div", { className: "ab-modal-optional-block", children: [jsxRuntime.jsxs("label", { className: "ab-modal-select-all", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: allSelected, onChange: handleSelectAll }), jsxRuntime.jsx("span", { children: "Select All Additional Benefits" })] }), jsxRuntime.jsx("div", { className: "ab-modal-options", children: mychoiceSdkComponents.accidentBenefitsOptionalOptions.map((option) => (jsxRuntime.jsxs("label", { className: "ab-modal-option", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: localSelected.includes(option.value), onChange: () => handleToggle(option.value) }), jsxRuntime.jsxs("div", { className: "ab-modal-option-text", children: [jsxRuntime.jsx("strong", { children: option.name }), jsxRuntime.jsx("span", { children: option.description })] })] }, option.value))) }), jsxRuntime.jsxs("div", { className: "ab-modal-minimum-notice", children: [jsxRuntime.jsx("strong", { children: "Minimum Limits Apply" }), jsxRuntime.jsx("p", { children: "All optional benefits selected below will be quoted at their minimum coverage limits. Please speak with your broker if you wish to discuss higher limits." })] })] })] }), jsxRuntime.jsxs("div", { className: "ab-modal-actions", children: [jsxRuntime.jsx("button", { type: "button", className: "ab-modal-btn ab-modal-btn-cancel", onClick: onCancel, children: "Cancel" }), jsxRuntime.jsx("button", { type: "button", className: "ab-modal-btn ab-modal-btn-apply", onClick: () => onApply(localSelected), children: isMyChoiceOnly ? 'Next' : 'Apply' })] })] }) }));
989
+ : 'Base coverage with flexibility to select additional benefits' })] }), jsxRuntime.jsxs("div", { className: "ab-modal-content", children: [jsxRuntime.jsxs("div", { className: "ab-modal-standard-block ab-modal-standard-block--included", children: [jsxRuntime.jsxs("div", { className: "ab-modal-standard-included-header", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: true, disabled: true, readOnly: true, className: "ab-modal-standard-locked-checkbox" }), jsxRuntime.jsx("h4", { children: isMyChoice ? 'All Coverages Included by Default' : 'Standard Benefits — Included' })] }), !isMyChoice && (jsxRuntime.jsx("p", { className: "ab-modal-standard-subtitle", children: "Medical, Rehabilitation, and Attendant Care" })), jsxRuntime.jsx("p", { className: "ab-modal-standard-description", children: isMyChoice ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: ["Our standard quote automatically includes all optional accident benefits at their minimum coverage limits. We strongly recommend keeping all coverages selected to ensure the most complete protection \u2014 opting out could leave you without critical support when you need it most. For example, deselecting Income Replacement means no weekly payments if an injury prevents you from working, and removing Caregiver Replacement leaves no financial support for dependents in your care.", jsxRuntime.jsx("br", {}), jsxRuntime.jsx("br", {}), "Please speak with a broker partner to discuss higher limits or learn more about how each benefit protects you."] })) : ('Covers medical expenses, therapy and personal care for injuries from an accident, including doctor visits and physiotherapy.') })] }), jsxRuntime.jsxs("div", { className: "ab-modal-optional-block", children: [jsxRuntime.jsxs("label", { className: "ab-modal-select-all", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: allSelected, onChange: handleSelectAll }), jsxRuntime.jsx("span", { children: "Select All Additional Benefits" })] }), jsxRuntime.jsx("div", { className: "ab-modal-options", children: mychoiceSdkComponents.accidentBenefitsOptionalOptions.map((option) => (jsxRuntime.jsxs("label", { className: "ab-modal-option", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: localSelected.includes(option.value), onChange: () => handleToggle(option.value) }), jsxRuntime.jsxs("div", { className: "ab-modal-option-text", children: [jsxRuntime.jsx("strong", { children: option.name }), jsxRuntime.jsx("span", { children: option.description })] })] }, option.value))) }), jsxRuntime.jsxs("div", { className: "ab-modal-minimum-notice", children: [jsxRuntime.jsx("strong", { children: "Minimum Limits Apply" }), jsxRuntime.jsx("p", { children: "All optional benefits selected below will be quoted at their minimum coverage limits. Please speak with your broker if you wish to discuss higher limits." })] })] })] }), jsxRuntime.jsxs("div", { className: "ab-modal-actions", children: [jsxRuntime.jsx("button", { type: "button", className: "ab-modal-btn ab-modal-btn-cancel", onClick: onCancel, children: "Cancel" }), jsxRuntime.jsx("button", { type: "button", className: "ab-modal-btn ab-modal-btn-apply", onClick: () => onApply(localSelected), children: isMyChoiceOnly ? 'Ok' : 'Apply' })] })] }) }));
951
990
  };
952
991
 
953
992
  const allAccidentBenefitsCoverageValues = mychoiceSdkComponents.accidentBenefitsOptionalOptions.map((option) => option.value);
@@ -1253,6 +1292,7 @@ const SectionDriverLicence = () => {
1253
1292
  const [driverEducation, setDriverEducation] = React.useState(false);
1254
1293
  const { configState } = mychoiceSdkStore.useStoreFormCarConfig();
1255
1294
  const { driverState, dispatchDriverLicenceState } = mychoiceSdkStore.useStoreFormCarDriverLicence();
1295
+ const { discountState } = mychoiceSdkStore.useStoreFormCarDiscount();
1256
1296
  const { isAlbertaProvince, isOntarioProvince } = mychoiceSdkStore.useProvince();
1257
1297
  const mychoiceCls = mychoiceSdkComponents.isMyChoiceLike(appType) ? 'mychoice' : '';
1258
1298
  const isTheBig = appType === mychoiceSdkComponents.AppTypes.TheBig;
@@ -1264,14 +1304,9 @@ const SectionDriverLicence = () => {
1264
1304
  const driverNameDefault = `Driver ${driverState.activeIndex + 1}`;
1265
1305
  const birthDate = birthYear && birthMonth && birthDay ? `${birthYear}-${birthMonth}-${birthDay}` : '';
1266
1306
  const defaultMinDate = birthDate && firstLicenceAge ? mychoiceSdkComponents.addYearsToDate(birthDate, +firstLicenceAge) : '';
1267
- const getOntarioQ1YearMonth = () => {
1268
- if (licenceType === mychoiceSdkComponents.DriverLicenceTypes.G2)
1269
- return { year: g2LicenceYear, month: g2LicenceMonth };
1270
- if (licenceType === mychoiceSdkComponents.DriverLicenceTypes.G)
1271
- return { year: gLicenceYear, month: gLicenceMonth };
1272
- return { year: g1LicenceYear, month: g1LicenceMonth };
1273
- };
1274
- const { year: ontarioQ1Year, month: ontarioQ1Month } = getOntarioQ1YearMonth();
1307
+ // Ontario Q1 (first-licence date) always lives in the G1 slot, independent of the chosen class.
1308
+ const ontarioQ1Year = g1LicenceYear;
1309
+ const ontarioQ1Month = g1LicenceMonth;
1275
1310
  const ontarioQ1Date = ontarioQ1Year && ontarioQ1Month ? `${ontarioQ1Year}-${ontarioQ1Month}-01` : '';
1276
1311
  const isOnlyG = useOntarioFlow
1277
1312
  ? (!!ontarioQ1Date && mychoiceSdkComponents.checkDateIsSpecial(ontarioQ1Date, configState.minDates.g.specialDate))
@@ -1325,7 +1360,7 @@ const SectionDriverLicence = () => {
1325
1360
  const birthYearNum = parseInt(birthYear || '0', 10);
1326
1361
  if (parseInt(ontarioQ1Year, 10) !== birthYearNum + 16 || ontarioQ1Month !== birthMonth)
1327
1362
  return;
1328
- const q1SlotForCorrection = licenceType || mychoiceSdkComponents.DriverLicenceTypes.G1;
1363
+ const q1SlotForCorrection = mychoiceSdkComponents.DriverLicenceTypes.G1;
1329
1364
  let correctedMonth = parseInt(birthMonth || '1', 10) + 1;
1330
1365
  let correctedYear = birthYearNum + 16;
1331
1366
  if (correctedMonth > 12) {
@@ -1482,8 +1517,9 @@ const SectionDriverLicence = () => {
1482
1517
  if (useOntarioFlow) {
1483
1518
  // When isOnlyG (before Apr 1994), treat as G Full regardless of what licenceType is in the store
1484
1519
  const firstClass = isOnlyG ? mychoiceSdkComponents.DriverLicenceTypes.G : licenceType;
1485
- // Q1 date lives in whichever slot the store wrote to (always ${licenceType}LicenceYear/Month).
1486
- const q1SlotType = licenceType || mychoiceSdkComponents.DriverLicenceTypes.G1;
1520
+ // Q1 (first-licence date) is always stored in the G1 slot, independent of the chosen class,
1521
+ // so switching the class never moves it and the DTC/isOnlyG checks stay consistent.
1522
+ const q1SlotType = mychoiceSdkComponents.DriverLicenceTypes.G1;
1487
1523
  const q1Year = getLicenceYear(q1SlotType);
1488
1524
  const q1Month = getLicenceMonth(q1SlotType);
1489
1525
  const q1Date = toDate(q1Year, q1Month);
@@ -1496,19 +1532,21 @@ const SectionDriverLicence = () => {
1496
1532
  const showGDateAfterG2 = firstClass === mychoiceSdkComponents.DriverLicenceTypes.G2 && receivedG === true;
1497
1533
  const g2Date = toDate(g2LicenceYear, g2LicenceMonth);
1498
1534
  const gDate = toDate(gLicenceYear, gLicenceMonth);
1499
- // G1 branch: ask once, based on the first licence date. Show/hide uses 5-year gate; question text says "3 years".
1535
+ // Thresholds per the licensing flow: G1 < 5 years (4y11m = 59 months); G2/G < 3 years (2y11m = 35 months).
1536
+ const policyStart = discountState.policyStart || today;
1537
+ const q1MonthsFromEffective = q1Date ? mychoiceSdkComponents.getDifferenceInMonths(policyStart, q1Date) : Infinity;
1538
+ // G1 branch: ask once, based on the first licence date (< 5 years / 60 months).
1500
1539
  const showDtcG1Only = firstClass === mychoiceSdkComponents.DriverLicenceTypes.G1
1501
1540
  && !!q1Date
1502
- && mychoiceSdkComponents.getDifferenceInYears('', q1Date) <= 5
1503
- && !showG2Date;
1504
- // Branch B: DTC shown as soon as class=G2 and Q1 is within 5 years (before G question)
1541
+ && q1MonthsFromEffective < 60;
1542
+ // Branch B: G2 first class (< 3 years / 36 months).
1505
1543
  const showDtcG2Only = firstClass === mychoiceSdkComponents.DriverLicenceTypes.G2
1506
1544
  && !!q1Date
1507
- && mychoiceSdkComponents.getDifferenceInYears('', q1Date) <= 5;
1508
- // Branch C G Full: within 5 years of Q1 (G date)
1545
+ && q1MonthsFromEffective < 36;
1546
+ // Branch C G Full: G first class (< 3 years / 36 months).
1509
1547
  const showDtcGFull = firstClass === mychoiceSdkComponents.DriverLicenceTypes.G
1510
1548
  && !!q1Date
1511
- && mychoiceSdkComponents.getDifferenceInYears('', q1Date) <= 5;
1549
+ && q1MonthsFromEffective < 36;
1512
1550
  // ── Validation error messages ──
1513
1551
  const q1MinDate = getG1MinDate();
1514
1552
  const q1ChronoError = driverState.inValidation
@@ -1544,7 +1582,7 @@ const SectionDriverLicence = () => {
1544
1582
  };
1545
1583
  const g2MaxDate = getMax60Date(q1Date);
1546
1584
  const gMaxDate = getMax60Date(q1Date);
1547
- return (jsxRuntime.jsxs("div", { className: `form-section ${mychoiceCls}`, children: [jsxRuntime.jsx(DateSelectFormBox, { name: "firstLicenceDate", dateNames: ['firstLicenceYear', 'firstLicenceMonth'], onDateChange: handleLicenceDateChange(q1SlotType), defaultValue: getDefaultLicenceDate(q1SlotType), title: `When did ${driverName} first receive their drivers license in Canada?`, description: "Select the year and month in which you received your first license to drive an automobile in Canada. This would include a beginners, intermediate or full license.", errorMessage: q1Error, error: driverState.inValidation, minDate: q1MinDate, maxDate: today, disabled: !birthDate }), q1Date && (jsxRuntime.jsx(SelectFormBox, { options: isOnlyG ? ontarioOnlyGOptions : ontarioFirstClassOptions, name: "firstLicenceClass", onChange: handleLicenceTypeChange, defaultValue: getSelectedOption(isOnlyG ? ontarioOnlyGOptions : ontarioFirstClassOptions, licenceType), title: "What class of license was it?", placeholder: "Select from the list", disabled: isOnlyG, description: "Drivers licensed in Ontario under the graduated licensing program would select G1 Beginner. If the driver was licensed outside Ontario or granted an exception for having driving experience from another jurisdiction then select the license class they first received. Select class G Full or equivalent if the driver was licensed in Ontario before 1994 or was licensed in another province. G equivalent classes in Canada are class 5.", autoSelectIfValueIsOutOfOptions: false })), firstClass === mychoiceSdkComponents.DriverLicenceTypes.G1 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [showDtcG1Only && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleReceivedG2Change, name: "receivedG2", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, receivedG2), title: `Did ${driverName} receive a G2 license?` }), showG2Date && (jsxRuntime.jsx(DateSelectFormBox, { name: "g2LicenceDate", dateNames: ['g2LicenceYear', 'g2LicenceMonth'], onDateChange: handleLicenceDateChange(mychoiceSdkComponents.DriverLicenceTypes.G2), defaultValue: getDefaultLicenceDate(mychoiceSdkComponents.DriverLicenceTypes.G2), title: `When did ${driverName} receive this G2 license?`, errorMessage: g2Error, error: driverState.inValidation, minDate: g2MinDate, maxDate: g2MaxDate })), showGQuestionAfterG1 && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleReceivedGChange, name: "receivedG", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, receivedG), title: `Did ${driverName} receive a G license?` })), showGDateAfterG1 && (jsxRuntime.jsx(DateSelectFormBox, { name: "gLicenceDate", dateNames: ['gLicenceYear', 'gLicenceMonth'], onDateChange: handleLicenceDateChange(mychoiceSdkComponents.DriverLicenceTypes.G), defaultValue: getDefaultLicenceDate(mychoiceSdkComponents.DriverLicenceTypes.G), title: `When did ${driverName} receive this G license?`, errorMessage: gError, error: driverState.inValidation, minDate: gMinDate, maxDate: gMaxDate }))] })), firstClass === mychoiceSdkComponents.DriverLicenceTypes.G2 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [showDtcG2Only && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleReceivedGChange, name: "receivedG", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, receivedG), title: `Did ${driverName} receive a G license?` }), showGDateAfterG2 && (jsxRuntime.jsx(DateSelectFormBox, { name: "gLicenceDate", dateNames: ['gLicenceYear', 'gLicenceMonth'], onDateChange: handleLicenceDateChange(mychoiceSdkComponents.DriverLicenceTypes.G), defaultValue: getDefaultLicenceDate(mychoiceSdkComponents.DriverLicenceTypes.G), title: `When did ${driverName} receive this G license?`, errorMessage: gError, error: driverState.inValidation, minDate: gMinDate, maxDate: gMaxDate }))] })), firstClass === mychoiceSdkComponents.DriverLicenceTypes.G && !isOnlyG && showDtcGFull && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), isOnlyG && showDtcGFull && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handlePreviousLicenceChange, name: "previousLicence", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, previousLicence), title: `Has ${driverName} ever had a full license anywhere else in Canada or USA?`, description: "If you have driving experience outside Canada or the United States, it may lower your premium. Your insurer may require proof of insurance in these other locations or some proof of driving experience from the country you indicate (like a copy of a previous driver's licence)." })] }));
1585
+ return (jsxRuntime.jsxs("div", { className: `form-section ${mychoiceCls}`, children: [jsxRuntime.jsx(DateSelectFormBox, { name: "firstLicenceDate", dateNames: ['firstLicenceYear', 'firstLicenceMonth'], onDateChange: handleLicenceDateChange(q1SlotType), defaultValue: getDefaultLicenceDate(q1SlotType), title: `When did ${driverName} first receive their drivers license in Canada?`, description: "Select the year and month in which you received your first license to drive an automobile in Canada. This would include a beginners, intermediate or full license.", errorMessage: q1Error, error: driverState.inValidation, minDate: q1MinDate, maxDate: today, disabled: !birthDate }), q1Date && (jsxRuntime.jsx(SelectFormBox, { options: isOnlyG ? ontarioOnlyGOptions : ontarioFirstClassOptions, name: "firstLicenceClass", onChange: handleLicenceTypeChange, defaultValue: getSelectedOption(isOnlyG ? ontarioOnlyGOptions : ontarioFirstClassOptions, firstClass), title: "What class of license was it?", placeholder: "Select from the list", description: "Drivers licensed in Ontario under the graduated licensing program would select G1 Beginner. If the driver was licensed outside Ontario or granted an exception for having driving experience from another jurisdiction then select the license class they first received. Select class G Full or equivalent if the driver was licensed in Ontario before 1994 or was licensed in another province. G equivalent classes in Canada are class 5.", autoSelectIfValueIsOutOfOptions: false })), firstClass === mychoiceSdkComponents.DriverLicenceTypes.G1 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [showDtcG1Only && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleReceivedG2Change, name: "receivedG2", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, receivedG2), title: `Did ${driverName} receive a G2 license?` }), showG2Date && (jsxRuntime.jsx(DateSelectFormBox, { name: "g2LicenceDate", dateNames: ['g2LicenceYear', 'g2LicenceMonth'], onDateChange: handleLicenceDateChange(mychoiceSdkComponents.DriverLicenceTypes.G2), defaultValue: getDefaultLicenceDate(mychoiceSdkComponents.DriverLicenceTypes.G2), title: `When did ${driverName} receive this G2 license?`, errorMessage: g2Error, error: driverState.inValidation, minDate: g2MinDate, maxDate: g2MaxDate })), showGQuestionAfterG1 && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleReceivedGChange, name: "receivedG", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, receivedG), title: `Did ${driverName} receive a G license?` })), showGDateAfterG1 && (jsxRuntime.jsx(DateSelectFormBox, { name: "gLicenceDate", dateNames: ['gLicenceYear', 'gLicenceMonth'], onDateChange: handleLicenceDateChange(mychoiceSdkComponents.DriverLicenceTypes.G), defaultValue: getDefaultLicenceDate(mychoiceSdkComponents.DriverLicenceTypes.G), title: `When did ${driverName} receive this G license?`, errorMessage: gError, error: driverState.inValidation, minDate: gMinDate, maxDate: gMaxDate }))] })), firstClass === mychoiceSdkComponents.DriverLicenceTypes.G2 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [showDtcG2Only && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleReceivedGChange, name: "receivedG", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, receivedG), title: `Did ${driverName} receive a G license?` }), showGDateAfterG2 && (jsxRuntime.jsx(DateSelectFormBox, { name: "gLicenceDate", dateNames: ['gLicenceYear', 'gLicenceMonth'], onDateChange: handleLicenceDateChange(mychoiceSdkComponents.DriverLicenceTypes.G), defaultValue: getDefaultLicenceDate(mychoiceSdkComponents.DriverLicenceTypes.G), title: `When did ${driverName} receive this G license?`, errorMessage: gError, error: driverState.inValidation, minDate: gMinDate, maxDate: gMaxDate }))] })), firstClass === mychoiceSdkComponents.DriverLicenceTypes.G && !isOnlyG && showDtcGFull && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), isOnlyG && showDtcGFull && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handlePreviousLicenceChange, name: "previousLicence", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, previousLicence), title: `Has ${driverName} ever had a full license anywhere else in Canada or USA?`, description: "If you have driving experience outside Canada or the United States, it may lower your premium. Your insurer may require proof of insurance in these other locations or some proof of driving experience from the country you indicate (like a copy of a previous driver's licence)." })] }));
1548
1586
  }
1549
1587
  return (jsxRuntime.jsxs("div", { className: `form-section ${mychoiceCls}`, children: [jsxRuntime.jsx(InputFormBox, { name: "firstLicenceAge", title: getLicenceAgeTitle(), onChange: handleLicenceAgeChange, type: mychoiceSdkComponents.InputTypes.Number, defaultValue: firstLicenceAge, description: configState.toolTip.licenceAge, hintMessage: birthDate
1550
1588
  ? `${driverName} was licenced in ${Number(birthYear) + Number(firstLicenceAge)} - ${Number(birthYear) + Number(firstLicenceAge) + 1}`
@@ -1571,17 +1609,17 @@ const SectionDriverInsurancePolicy = () => {
1571
1609
  const effectiveMonth = policyStartMonth || String(todayDate.getMonth() + 1).padStart(2, '0');
1572
1610
  const effectiveDay = policyStartDay || String(todayDate.getDate()).padStart(2, '0');
1573
1611
  const yearsInPast = Math.min(todayDate.getFullYear() - parseInt(year, 10), 10);
1574
- options.push({
1575
- value: mychoiceSdkComponents.subMonthsFromDate('', 6),
1576
- name: 'Less than 1 year',
1577
- });
1578
- for (let i = 1; i <= yearsInPast; i += 1) {
1612
+ for (let i = yearsInPast; i >= 1; i -= 1) {
1579
1613
  const pastDate = `${todayDate.getFullYear() - i}-${effectiveMonth}-${effectiveDay}`;
1580
1614
  options.push({
1581
1615
  value: pastDate,
1582
1616
  name: i === 10 ? '10+ Years' : `${i} ${i === 1 ? 'Year' : 'Years'}`,
1583
1617
  });
1584
1618
  }
1619
+ options.push({
1620
+ value: mychoiceSdkComponents.subMonthsFromDate('', 6),
1621
+ name: 'Less than 1 year',
1622
+ });
1585
1623
  }
1586
1624
  return options;
1587
1625
  };
@@ -1867,19 +1905,34 @@ const SectionDriverCancellation = () => {
1867
1905
  }), insuranceCancellationList?.length < 3 && (jsxRuntime.jsx(mychoiceSdkComponents.ButtonBase, { category: mychoiceSdkComponents.CategoryTypes.Filled, onClick: handleAddButtonClick, size: mychoiceSdkComponents.SizeTypes.Medium, color: mychoiceSdkComponents.ColorTypes.Primary, label: "Add another" }))] }))] }));
1868
1906
  };
1869
1907
 
1908
+ const SUSPENSION_YEAR_CAP = 6;
1909
+ const SuspensionDescription = () => {
1910
+ const listStyle = { margin: 0, paddingLeft: '1.25rem', whiteSpace: 'normal' };
1911
+ return (jsxRuntime.jsxs("div", { children: ["There are two main types of licence suspensions:", jsxRuntime.jsx("br", {}), "1. Suspension for Cause (Non-administrative)", jsxRuntime.jsx("br", {}), "A driver's licence is suspended or cancelled because of:", jsxRuntime.jsxs("ul", { style: listStyle, children: [jsxRuntime.jsx("li", { children: "Traffic offences." }), jsxRuntime.jsx("li", { children: "Criminal Code driving offences." }), jsxRuntime.jsx("li", { children: "Accumulating too many demerit points." })] }), "2. Administrative Suspension / Cancellation / Lapse", jsxRuntime.jsx("br", {}), "A driver's licence is suspended, cancelled, or allowed to lapse for reasons not related to driving offences or demerit points, such as:", jsxRuntime.jsxs("ul", { style: listStyle, children: [jsxRuntime.jsx("li", { children: "Roadside licence suspensions." }), jsxRuntime.jsx("li", { children: "Medical conditions." }), jsxRuntime.jsx("li", { children: "Failure to comply with court-ordered obligations." })] })] }));
1912
+ };
1870
1913
  const BlockDriverSuspension = () => {
1871
1914
  const { driverState, dispatchDriverSuspensionState } = mychoiceSdkStore.useStoreFormCarDriverSuspension();
1872
1915
  const { licenceSuspension, licenceSuspensionList = [] } = driverState.items[driverState.activeIndex];
1873
1916
  const { dispatchDriverBaseState } = mychoiceSdkStore.useStoreFormCarDriverBase();
1874
1917
  const { discountState } = mychoiceSdkStore.useStoreFormCarDiscount();
1875
1918
  const { appConfigState: { appType } } = mychoiceSdkStore.useStoreAppConfig();
1919
+ const { isOntarioProvince } = mychoiceSdkStore.useProvince();
1876
1920
  const isTheBig = appType === mychoiceSdkComponents.AppTypes.TheBig;
1877
- const { firstName, birthYear, birthMonth, birthDay, licenceInfo: { firstLicenceAge }, } = driverState.items[driverState.activeIndex];
1921
+ const { firstName, birthYear, birthMonth, birthDay, licenceInfo: { firstLicenceAge, g1LicenceYear, g1LicenceMonth, }, } = driverState.items[driverState.activeIndex];
1878
1922
  const birthDate = birthYear && birthMonth && birthDay ? `${birthYear}-${birthMonth}-${birthDay}` : '';
1879
- const earliestLicenceDate = birthDate && firstLicenceAge ? mychoiceSdkComponents.addYearsToDate(birthDate, +firstLicenceAge) : '';
1923
+ // Ontario flow stores the first-licence (Q1) date in the G1 slot; firstLicenceAge is not collected.
1924
+ const ontarioQ1Date = isOntarioProvince && mychoiceSdkComponents.isMyChoiceLike(appType) && g1LicenceYear && g1LicenceMonth
1925
+ ? `${g1LicenceYear}-${g1LicenceMonth}-01`
1926
+ : '';
1927
+ const earliestLicenceDate = ontarioQ1Date
1928
+ || (birthDate && firstLicenceAge ? mychoiceSdkComponents.addYearsToDate(birthDate, +firstLicenceAge) : '');
1880
1929
  const policyStart = discountState.policyStart || mychoiceSdkComponents.getFormattedDate('', 'yyyy-MM-dd');
1881
- const yearsElapsed = earliestLicenceDate ? Math.min(mychoiceSdkComponents.getDifferenceInYears(policyStart, earliestLicenceDate), 6) : 6;
1930
+ const yearsElapsed = earliestLicenceDate
1931
+ ? Math.min(mychoiceSdkComponents.getDifferenceInYears(policyStart, earliestLicenceDate), SUSPENSION_YEAR_CAP)
1932
+ : SUSPENSION_YEAR_CAP;
1933
+ const suspensionLookbackYears = Math.max(yearsElapsed, 1);
1882
1934
  const suspensionYearLabel = yearsElapsed <= 1 ? 'past year' : `past ${yearsElapsed} years`;
1935
+ const suspensionMinFloor = earliestLicenceDate || mychoiceSdkComponents.getMinDate(birthDate, firstLicenceAge);
1883
1936
  const handleSuspensionChange = ({ value }) => {
1884
1937
  dispatchDriverSuspensionState({
1885
1938
  type: mychoiceSdkStore.StoreFormCarDriverSuspensionActionTypes.FormCarDriverLicenceSuspensionSelect,
@@ -1952,7 +2005,7 @@ const BlockDriverSuspension = () => {
1952
2005
  });
1953
2006
  }
1954
2007
  };
1955
- return (jsxRuntime.jsxs("div", { className: "form-block-container", children: [jsxRuntime.jsx("h2", { className: isTheBig ? 'thebig-bold' : '', children: "Licence Suspensions" }), jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleSuspensionChange, name: "licenceSuspension", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, licenceSuspension), title: `Has ${firstName} had a licence suspension within the ${suspensionYearLabel}?`, description: "There are two main types of licence suspensions: 1. Non-administrated suspension for cause: A driver's licence is suspended or cancelled because of traffic and criminal code driving offences or collecting too many demerit points. 2. Administrative suspension/cancellation/lapse: A driver's licence is suspended, cancelled, or allowed to lapse for reasons other than driving offences or demerit points such as a roadside licence suspension, medical conditions or failure to comply with court\u2011ordered obligations." }), licenceSuspension && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [licenceSuspensionList?.map(({ suspensionReason, suspensionYear, suspensionMonth, reinstatementYear, reinstatementMonth, }, index) => {
2008
+ return (jsxRuntime.jsxs("div", { className: "form-block-container", children: [jsxRuntime.jsx("h2", { className: isTheBig ? 'thebig-bold' : '', children: "Licence Suspensions" }), jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleSuspensionChange, name: "licenceSuspension", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, licenceSuspension), title: `Has ${firstName} had a licence suspension within the ${suspensionYearLabel}?`, description: jsxRuntime.jsx(SuspensionDescription, {}) }), licenceSuspension && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [licenceSuspensionList?.map(({ suspensionReason, suspensionYear, suspensionMonth, reinstatementYear, reinstatementMonth, }, index) => {
1956
2009
  const defaultSuspensionDate = {
1957
2010
  year: suspensionYear,
1958
2011
  month: suspensionMonth,
@@ -1964,7 +2017,7 @@ const BlockDriverSuspension = () => {
1964
2017
  const now = mychoiceSdkComponents.getFormattedDate('', 'yyyy-MM-dd');
1965
2018
  const days = birthDay ? (+birthDay + 1) : 1;
1966
2019
  const endDate = reinstatementYear && reinstatementMonth ? mychoiceSdkStore.addDayToDate(`${reinstatementYear}-${reinstatementMonth}`, days) : now;
1967
- const currentMinDate = mychoiceSdkComponents.getMinDateByYears(mychoiceSdkComponents.getMinDate(birthDate, firstLicenceAge), 6);
2020
+ const currentMinDate = mychoiceSdkComponents.getMinDateByYears(suspensionMinFloor, suspensionLookbackYears);
1968
2021
  const currentEndDate = mychoiceSdkComponents.compareDates(endDate, currentMinDate) < 0 ? currentMinDate : endDate;
1969
2022
  return (jsxRuntime.jsxs("div", { className: "list-block", children: [jsxRuntime.jsx("hr", {}), jsxRuntime.jsxs("div", { className: "list-item", children: [jsxRuntime.jsx(SelectFormBox, { options: mychoiceSdkComponents.licenceSuspensionsReasonOptions, name: `suspensionReason-${index}`, onChange: handleReasonChange(index), defaultValue: suspensionReason, title: "Reason for licence suspension", placeholder: "Select from the list", isRemovable: licenceSuspensionList.length > 1, onIconClick: handleIconClick(index), autoSelectIfValueIsOutOfOptions: false, error: !suspensionReason && driverState.inValidation, errorMessage: getErrorMessage(suspensionReason, driverState.inValidation) }), jsxRuntime.jsx(DateSelectFormBox, { name: `suspensionDate-${index}`, dateNames: [`suspensionYear-${index}`, `suspensionMonth-${index}`], onDateChange: handleSuspensionDateChange(index), defaultValue: defaultSuspensionDate, title: "Start date", errorMessage: getDateErrorMessage(['01', suspensionMonth, suspensionYear], driverState.inValidation), error: driverState.inValidation, minDate: currentMinDate, maxDate: currentEndDate }), jsxRuntime.jsx(DateSelectFormBox, { name: `reinstatementDate-${index}`, dateNames: [`reinstatementYear-${index}`, `reinstatementMonth-${index}`], onDateChange: handleReinstatementDateChange(index), defaultValue: defaultReinstatementDate, title: "End Date", errorMessage: getDateErrorMessage(['01', reinstatementMonth, reinstatementYear], driverState.inValidation), error: driverState.inValidation, minDate: suspensionYear && suspensionMonth
1970
2023
  ? mychoiceSdkStore.addDayToDate(`${suspensionYear}-${suspensionMonth}`, days) : currentMinDate })] })] }, `suspension-${index}`));
@@ -4409,7 +4462,9 @@ const NavigationBottom = ({ createItem, validateForm, formSteps, className, item
4409
4462
  setSteps(filteredSteps);
4410
4463
  }, [isCompleted]);
4411
4464
  const onForwardClick = () => {
4412
- const isValid = !formIsValid ? validateForm && validateForm() : formIsValid;
4465
+ // Always re-run validation so newly shown required fields (e.g. G2 Yes/No) cannot be skipped
4466
+ // after an earlier successful validate left formIsValid=true.
4467
+ const isValid = validateForm ? validateForm() : !!formIsValid;
4413
4468
  if (activeIndex < steps.length && isValid) {
4414
4469
  navigate(`/${appConfigState.localIndex}/${appConfigState.insuranceType}${steps[activeIndex + 1].path}`);
4415
4470
  }
@@ -4443,7 +4498,9 @@ const NavigationBottomTheBig = ({ createItem, validateForm, formSteps, className
4443
4498
  setSteps(filteredSteps);
4444
4499
  }, [isCompleted]);
4445
4500
  const onForwardClick = () => {
4446
- const isValid = !formIsValid ? validateForm && validateForm() : formIsValid;
4501
+ // Always re-run validation so newly shown required fields cannot be skipped after
4502
+ // an earlier successful validate left formIsValid=true.
4503
+ const isValid = validateForm ? validateForm() : !!formIsValid;
4447
4504
  if (activeIndex < steps.length && isValid) {
4448
4505
  navigate(`/${appConfigState.localIndex}/${appConfigState.insuranceType}${steps[activeIndex + 1].path}`);
4449
4506
  }