@mychoice/mychoice-sdk-modules 2.2.31 → 2.2.33

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/esm/index.js CHANGED
@@ -355,25 +355,23 @@ const BlockNextPageInfo$2 = () => {
355
355
 
356
356
  const BlockSubmit$2 = ({ className, label, buttonSize, isRecalc = false, onSubmitClick, }) => {
357
357
  const { quoteState: { isRequested, quoteConfirm } } = useStoreFormCarQuote();
358
- const { discountState: { isValid } } = useStoreFormCarDiscount();
359
358
  const { appConfigState: { localIndex, insuranceType } } = useStoreAppConfig();
360
359
  const navigate = useNavigate();
361
360
  const { postRequestQuote } = CarQuoteDataHandler();
362
361
  const { carDiscountFormValidate } = useValidationCarDiscount();
363
362
  const handleGetQuotesClick = () => {
364
363
  onSubmitClick?.();
365
- if (!isValid) {
366
- carDiscountFormValidate(false, () => postRequestQuote(isRecalc, quoteConfirm));
367
- }
368
- else if (isRecalc) {
369
- postRequestQuote(isRecalc, quoteConfirm);
370
- }
371
- else if (!isRequested) {
372
- postRequestQuote(false, quoteConfirm);
373
- }
374
- else {
375
- navigate(`/${localIndex || defaultLocalIndex}/${insuranceType}/quotes`);
376
- }
364
+ carDiscountFormValidate(false, () => {
365
+ if (isRecalc) {
366
+ postRequestQuote(isRecalc, quoteConfirm);
367
+ }
368
+ else if (!isRequested) {
369
+ postRequestQuote(false, quoteConfirm);
370
+ }
371
+ else {
372
+ navigate(`/${localIndex || defaultLocalIndex}/${insuranceType}/quotes`);
373
+ }
374
+ });
377
375
  };
378
376
  return (jsx(ButtonBase, { className: className, size: buttonSize, category: CategoryTypes.Filled, onClick: handleGetQuotesClick, color: ColorTypes.Primary, label: label }));
379
377
  };
@@ -1335,8 +1333,6 @@ const SectionDriverInfo = () => {
1335
1333
 
1336
1334
  // Max months between consecutive Ontario GDL licence classes (spec 1-2 e/f)
1337
1335
  const ON_MAX_MONTHS_BETWEEN_CLASSES = 60;
1338
- const ON_MIN_MONTHS_G1_TO_G2 = 8;
1339
- const ON_MIN_MONTHS_G1_TO_G = 20;
1340
1336
  const SectionDriverLicence = () => {
1341
1337
  const { appConfigState: { appType }, } = useStoreAppConfig();
1342
1338
  const [driverEducation, setDriverEducation] = useState(false);
@@ -1367,7 +1363,7 @@ const SectionDriverLicence = () => {
1367
1363
  const policyEffectiveDate = policyStartYear && policyStartMonth && policyStartDay
1368
1364
  ? `${policyStartYear}-${policyStartMonth}-${policyStartDay}`
1369
1365
  : policyStart || today;
1370
- const { g, g1, g2, minLicenceAge } = configState.licenceConfig;
1366
+ const { g, g1, g2, minLicenceAge, } = configState.licenceConfig;
1371
1367
  const licenceTypeOptions = [
1372
1368
  { value: g.name, name: g.title },
1373
1369
  { value: g1.name, name: g1.title },
@@ -1555,22 +1551,31 @@ const SectionDriverLicence = () => {
1555
1551
  && q1Month === birthMonth
1556
1552
  ? `${q1Year}-${birthMonth}-${birthDay}`
1557
1553
  : q1Date;
1554
+ const q1IntervalDate = q1Date;
1558
1555
  const q1MonthsFromEffective = q1BirthdayDate
1559
1556
  ? getDifferenceInMonths(policyEffectiveDate, q1BirthdayDate)
1560
1557
  : Infinity;
1561
- // A G2 requires at least 8 months after G1; a G requires another 12 months.
1562
- const canHaveG2 = !!q1Date && q1MonthsFromEffective >= ON_MIN_MONTHS_G1_TO_G2;
1563
- const canHaveG = !!q1Date && q1MonthsFromEffective >= ON_MIN_MONTHS_G1_TO_G;
1558
+ const q1IntervalMonthsFromEffective = q1IntervalDate
1559
+ ? getDifferenceInMonths(policyEffectiveDate, q1IntervalDate)
1560
+ : Infinity;
1561
+ const q1HasStarted = !!q1IntervalDate && q1IntervalMonthsFromEffective >= 0;
1562
+ const canHaveG2 = q1HasStarted;
1563
+ const canHaveGAfterG2 = !!g2Date && getDifferenceInMonths(policyEffectiveDate, g2Date) >= 0;
1564
+ const canHaveGWithoutG2 = q1HasStarted;
1565
+ const canHaveG = firstClass === DriverLicenceTypes.G2
1566
+ ? q1HasStarted
1567
+ : ((receivedG2 === true && canHaveGAfterG2)
1568
+ || (receivedG2 === false && canHaveGWithoutG2));
1564
1569
  // ── path booleans ──
1565
1570
  const showG2Question = firstClass === DriverLicenceTypes.G1 && canHaveG2;
1566
1571
  const showG2Date = showG2Question && receivedG2 === true;
1567
- // G question shows after G2 date entered (G1G2 path) OR after No-G2 answer (G1No G2 path)
1572
+ // G question shows after G2 date entered (G1->G2 path) OR after No-G2 answer (G1->No G2 path)
1568
1573
  const showGQuestionAfterG1 = firstClass === DriverLicenceTypes.G1
1569
- && canHaveG
1570
- && (receivedG2 === false || showG2Date);
1574
+ && canHaveG;
1571
1575
  const showGQuestionAfterG2 = firstClass === DriverLicenceTypes.G2 && canHaveG;
1572
1576
  const showGDateAfterG1 = showGQuestionAfterG1 && receivedG === true;
1573
1577
  const showGDateAfterG2 = showGQuestionAfterG2 && receivedG === true;
1578
+ const isDirectGWithoutG2 = firstClass === DriverLicenceTypes.G1 && receivedG2 === false;
1574
1579
  // G1 branch: ask once, based on the first licence date (< 5 years / 60 months).
1575
1580
  const showDtcG1Only = firstClass === DriverLicenceTypes.G1
1576
1581
  && !!q1Date
@@ -1583,6 +1588,21 @@ const SectionDriverLicence = () => {
1583
1588
  const showDtcGFull = firstClass === DriverLicenceTypes.G
1584
1589
  && !!q1Date
1585
1590
  && q1MonthsFromEffective < 36;
1591
+ // G preceding date: G2 date if on G1->G2->G path, else Q1 date.
1592
+ const gPrecedingDate = receivedG2 === true && g2Date ? g2Date : q1IntervalDate;
1593
+ // ── Min dates (capped to the policy effective date so a future policy remains selectable) ──
1594
+ const capMinDateToPolicy = (minDate) => (minDate && compareDates(minDate, policyEffectiveDate) > 0 ? policyEffectiveDate : minDate);
1595
+ const g2MinRaw = q1IntervalDate;
1596
+ const gMinRaw = (() => {
1597
+ if (!gPrecedingDate)
1598
+ return '';
1599
+ if ((showGDateAfterG1 && showG2Date) || firstClass === DriverLicenceTypes.G2) {
1600
+ return gPrecedingDate;
1601
+ }
1602
+ return gPrecedingDate;
1603
+ })();
1604
+ const g2MinDate = capMinDateToPolicy(g2MinRaw);
1605
+ const gMinDate = capMinDateToPolicy(gMinRaw);
1586
1606
  // ── Validation error messages ──
1587
1607
  const q1MinDate = getG1MinDate();
1588
1608
  const q1ChronoError = driverState.inValidation
@@ -1592,24 +1612,19 @@ const SectionDriverLicence = () => {
1592
1612
  ? 'License dates cannot be in the future' : '';
1593
1613
  const q1Error = q1FutureError || q1ChronoError || getDateErrorMessage(['01', q1Month, q1Year], driverState.inValidation);
1594
1614
  const g2ChronoError = driverState.inValidation
1595
- ? validateLicenceDate(g2LicenceYear, g2LicenceMonth, q1BirthdayDate)
1615
+ ? validateLicenceDate(g2LicenceYear, g2LicenceMonth, q1IntervalDate)
1596
1616
  : '';
1597
- const g260MonthError = validate60Months(q1BirthdayDate?.slice(0, 4), q1BirthdayDate?.slice(5, 7), g2LicenceYear, g2LicenceMonth);
1617
+ const g260MonthError = validate60Months(q1IntervalDate?.slice(0, 4), q1IntervalDate?.slice(5, 7), g2LicenceYear, g2LicenceMonth);
1598
1618
  const g2FutureError = g2Date && compareDates(g2Date, policyEffectiveDate) > 0 ? 'License dates cannot be in the future' : '';
1599
1619
  const g2Error = g2FutureError || g260MonthError || g2ChronoError || getDateErrorMessage(['01', g2LicenceMonth, g2LicenceYear], driverState.inValidation);
1600
- // G preceding date: G2 date if on G1→G2→G path, else Q1 date
1601
- const gPrecedingDate = showGDateAfterG1 && showG2Date ? g2Date : q1BirthdayDate;
1602
1620
  const gChronoError = driverState.inValidation
1603
1621
  ? validateLicenceDate(gLicenceYear, gLicenceMonth, gPrecedingDate)
1604
1622
  : '';
1605
- const g60MonthError = validate60Months(q1BirthdayDate?.slice(0, 4), q1BirthdayDate?.slice(5, 7), gLicenceYear, gLicenceMonth);
1623
+ const g60MonthError = isDirectGWithoutG2
1624
+ ? ''
1625
+ : validate60Months(gPrecedingDate?.slice(0, 4), gPrecedingDate?.slice(5, 7), gLicenceYear, gLicenceMonth);
1606
1626
  const gFutureError = gDate && compareDates(gDate, policyEffectiveDate) > 0 ? 'License dates cannot be in the future' : '';
1607
1627
  const gError = gFutureError || g60MonthError || gChronoError || getDateErrorMessage(['01', gLicenceMonth, gLicenceYear], driverState.inValidation);
1608
- // ── Min dates (capped to the policy effective date so a future policy remains selectable) ──
1609
- const g2MinRaw = q1BirthdayDate && compareDates(q1BirthdayDate, gTwoMin) > 0 ? q1BirthdayDate : gTwoMin;
1610
- const g2MinDate = compareDates(g2MinRaw, policyEffectiveDate) > 0 ? policyEffectiveDate : g2MinRaw;
1611
- const gMinRaw = gPrecedingDate && compareDates(gPrecedingDate, gMin) > 0 ? gPrecedingDate : gMin;
1612
- const gMinDate = compareDates(gMinRaw, policyEffectiveDate) > 0 ? policyEffectiveDate : gMinRaw;
1613
1628
  const getMonthPickerMinDate = (minDate) => {
1614
1629
  if (!minDate || getFormattedDate(minDate, 'dd') === '01')
1615
1630
  return minDate;
@@ -1623,8 +1638,8 @@ const SectionDriverLicence = () => {
1623
1638
  const max60 = addMonthsToDate(refDate, ON_MAX_MONTHS_BETWEEN_CLASSES);
1624
1639
  return compareDates(policyEffectiveDate, max60) > 0 ? max60 : policyEffectiveDate;
1625
1640
  };
1626
- const g2MaxDate = getMax60Date(q1BirthdayDate);
1627
- const gMaxDate = getMax60Date(q1BirthdayDate);
1641
+ const g2MaxDate = getMax60Date(q1IntervalDate);
1642
+ const gMaxDate = isDirectGWithoutG2 ? policyEffectiveDate : getMax60Date(gPrecedingDate);
1628
1643
  return (jsxs("div", { className: `form-section ${mychoiceCls}`, children: [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: policyEffectiveDate, disabled: !birthDate }), q1Date && (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 === DriverLicenceTypes.G1 && (jsxs(Fragment, { children: [showDtcG1Only && (jsx(SwitchButtonBox, { items: yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), showG2Question && (jsx(SwitchButtonBox, { items: yesNoOptions, onChange: handleReceivedG2Change, name: "receivedG2", defaultValue: getSelectedOption(yesNoOptions, receivedG2), title: `Did ${driverName} receive a G2 license?` })), showG2Date && (jsx(DateSelectFormBox, { name: "g2LicenceDate", dateNames: ['g2LicenceYear', 'g2LicenceMonth'], onDateChange: handleLicenceDateChange(DriverLicenceTypes.G2), defaultValue: getDefaultLicenceDate(DriverLicenceTypes.G2), title: `When did ${driverName} receive this G2 license?`, errorMessage: g2Error, error: driverState.inValidation, minDate: g2PickerMinDate, maxDate: g2MaxDate })), showGQuestionAfterG1 && (jsx(SwitchButtonBox, { items: yesNoOptions, onChange: handleReceivedGChange, name: "receivedG", defaultValue: getSelectedOption(yesNoOptions, receivedG), title: `Did ${driverName} receive a G license?` })), showGDateAfterG1 && (jsx(DateSelectFormBox, { name: "gLicenceDate", dateNames: ['gLicenceYear', 'gLicenceMonth'], onDateChange: handleLicenceDateChange(DriverLicenceTypes.G), defaultValue: getDefaultLicenceDate(DriverLicenceTypes.G), title: `When did ${driverName} receive this G license?`, errorMessage: gError, error: driverState.inValidation, minDate: gPickerMinDate, maxDate: gMaxDate }))] })), firstClass === DriverLicenceTypes.G2 && (jsxs(Fragment, { children: [showDtcG2Only && (jsx(SwitchButtonBox, { items: yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), showGQuestionAfterG2 && (jsx(SwitchButtonBox, { items: yesNoOptions, onChange: handleReceivedGChange, name: "receivedG", defaultValue: getSelectedOption(yesNoOptions, receivedG), title: `Did ${driverName} receive a G license?` })), showGDateAfterG2 && (jsx(DateSelectFormBox, { name: "gLicenceDate", dateNames: ['gLicenceYear', 'gLicenceMonth'], onDateChange: handleLicenceDateChange(DriverLicenceTypes.G), defaultValue: getDefaultLicenceDate(DriverLicenceTypes.G), title: `When did ${driverName} receive this G license?`, errorMessage: gError, error: driverState.inValidation, minDate: gPickerMinDate, maxDate: gMaxDate }))] })), firstClass === DriverLicenceTypes.G && !isOnlyG && showDtcGFull && (jsx(SwitchButtonBox, { items: yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), isOnlyG && showDtcGFull && (jsx(SwitchButtonBox, { items: yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), jsx(SwitchButtonBox, { items: yesNoOptions, onChange: handlePreviousLicenceChange, name: "previousLicence", defaultValue: getSelectedOption(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)." })] }));
1629
1644
  }
1630
1645
  return (jsxs("div", { className: `form-section ${mychoiceCls}`, children: [jsx(InputFormBox, { name: "firstLicenceAge", title: getLicenceAgeTitle(), onChange: handleLicenceAgeChange, type: InputTypes.Number, defaultValue: firstLicenceAge, description: configState.toolTip.licenceAge, hintMessage: birthDate
@@ -2363,7 +2378,8 @@ const SectionDiscountInfo$1 = () => {
2363
2378
  const { validateEmail, errorMessage } = useHandlerCarQuoterEmail();
2364
2379
  const { validatePhone, errorMessage: phoneErrorMessage } = useHandlerCarQuoterPhone();
2365
2380
  const { multiplePoliciesDiscount, appInstallDiscount, caaMemberDiscount, quoterInfo, emailTo: { email, emailStatus }, } = discountState;
2366
- const { firstName, lastName, phone, phoneStatus, driverLicense = '', caslConsent } = quoterInfo;
2381
+ const { firstName, lastName, phone, phoneStatus, driverLicense = '', caslConsent, } = quoterInfo;
2382
+ const phoneIsIncomplete = (phone || '').replace(/\D/g, '').length !== 10;
2367
2383
  const handleMultiplePolicyChange = ({ value }) => {
2368
2384
  dispatchDiscountState({
2369
2385
  type: StoreFormCarDiscountActionTypes.FormCarDiscountMultiplePoliciesSelect,
@@ -2422,10 +2438,10 @@ const SectionDiscountInfo$1 = () => {
2422
2438
  });
2423
2439
  };
2424
2440
  return (jsxs("div", { className: `form-section ${mychoiceCls}`, children: [isTheBig ? (jsx(LabelFormBox, { title: "You are seconds away from receiving your car insurance quotes,\n please provide your email after completing the discount section so we\n can send you your personalized free car insurance quotes!" })) : (jsxs(Fragment, { children: [jsx("h2", { className: "section-title", children: "A little extra info for discounts and connecting you with our partners." }), jsx("span", { className: "info-title-message", children: "You are seconds away from receiving your car insurance quotes, please provide your email after completing the discount section so we can send you your personalized free car insurance quotes!" })] })), jsx(BlockVehLinks, {}), jsx(SwitchButtonBox, { items: yesNoOptions, onChange: handleMultiplePolicyChange, name: "multiplePoliciesDiscount", defaultValue: getSelectedOption(yesNoOptions, multiplePoliciesDiscount), title: "You could receive a 10-15% discount for bundling insurance with multiple policies with the same insurance company. Does that interest you?", description: "Bundling your home and auto insurance can save you significantly on insurance premiums as a whole package. Do you want to learn more about the benefits of multiple policies for home, tenant, condo, or car insurance? All you have to do is select yes.." }), !isTheBig && !isAlbertaProvince && (jsx(SwitchButtonBox, { items: yesNoOptions, onChange: handleCaaMemberChange, name: "caaMemberDiscount", defaultValue: getSelectedOption(yesNoOptions, caaMemberDiscount), title: "Please indicate if you are a member of CAA, you could save up to an additional 20%." })), jsx(SwitchButtonBox, { items: yesNoOptions, onChange: handleAppInstallChange, name: "appInstallDiscount", defaultValue: getSelectedOption(yesNoOptions, appInstallDiscount), title: "You could receive up to a 30% discount by using an app to track driving habits. Does that interest you?", description: "Get rewarded for safe driving with the click of a button. If you install the app, you may be eligible for a 30% discount on your insurance premiums. Typically, you receive 10% of the discount upfront and the balance after six months of good driving." }), isTheBig ? (jsxs("div", { className: "input-form-box-container", children: [jsx(LabelFormBox, { title: "Complete this form to see all your personalized\n quotes on the next page, you will also be able to:" }), jsxs("ol", { className: "ordered-block", children: [jsx("li", { children: "See what rates insurance carriers are offering" }), jsx("li", { children: "Get in touch with us and secure your rate" }), jsx("li", { children: "Potentially save more by speaking with a broker" })] })] })) : (jsx("h2", { children: "Complete the form below to see which companies are offering your quotes." })), jsx(InputFormBox, { name: "firstName", title: "First Name", onChange: handleFirstNameChange, defaultValue: firstName, placeholder: "Your First Name", error: !firstName && discountState.inValidation, errorMessage: getErrorMessage(firstName, discountState.inValidation) }), jsx(InputFormBox, { name: "lastname", title: "Last Name", onChange: handleLastNameChange, defaultValue: lastName, placeholder: "Your Last Name", error: !lastName && discountState.inValidation, errorMessage: getErrorMessage(lastName, discountState.inValidation) }), isTheBig && (jsx(InputFormLicenceBox, { ...getDynamicLicenceBoxProps({ ...allProvinces }), name: "driverLicense", title: "Driver Licence Number (Optional)", onChange: handleDriverLicenseChange, defaultValue: driverLicense, description: "Enter your drivers licence number in to receive a more accurate, prequalified quote from our broker partners. This will enable you to provide less details over the phone if you choose to have a broker contact you. This is an optional input." })), jsx(InputFormPhoneBox, { name: "phone", onChange: handlePhoneNumberChange, defaultValue: phone, title: "Phone Number", placeholder: "(855) 325-8444", validationStatus: phoneStatus, error: phoneStatus === ValidationStatusTypes.Declined
2425
- || (phoneStatus === ValidationStatusTypes.Initial && discountState.inValidation)
2426
- || (!phone && discountState.inValidation), errorMessage: phoneStatus === ValidationStatusTypes.Declined
2441
+ || (phoneIsIncomplete && discountState.inValidation), errorMessage: phoneStatus === ValidationStatusTypes.Declined
2427
2442
  ? phoneErrorMessage
2428
- : getErrorMessage(phone, discountState.inValidation) || (discountState.inValidation ? 'Enter a valid phone number.' : '') }), jsx(InputFormEmailBox, { validationStatus: emailStatus, errorMessage: emailStatus === ValidationStatusTypes.Declined
2443
+ : getErrorMessage(phone, discountState.inValidation)
2444
+ || (phoneIsIncomplete && discountState.inValidation ? 'Enter a valid phone number.' : '') }), jsx(InputFormEmailBox, { validationStatus: emailStatus, errorMessage: emailStatus === ValidationStatusTypes.Declined
2429
2445
  ? errorMessage
2430
2446
  : getErrorMessage(email, discountState.inValidation), error: emailStatus === ValidationStatusTypes.Declined || (!email && discountState.inValidation), name: "email", title: "Please share your email address with us, we'll use it to send you a copy of your quotes.", description: "We will provide you with your insurance quotes immediately after this form completion. If you are not ready to apply today, don\u2019t worry as we will be emailing your quotes to you if you\u2019d like to complete at a later date with the help of one of our trusted broker partners.", onChange: handleEmailChange, defaultValue: email, placeholder: getPlaceholderEmail(appType) }), isTheBig && (jsx(CheckboxForm, { className: "casl-consent", name: "caslConsent", label: "Yes, I consent to receiving emails from the Billyard Insurance Group.\n I understand that I can unsubscribe at any time", onChange: handleCaslConsentChange, defaultValue: caslConsent })), jsx(BlockSubmit$2, { className: isTheBig ? 'thebig-bold' : 'mychoice' }), jsx(BlockNextPageInfo$2, {})] }));
2431
2447
  };