From 35fc794d520b74312b5782209164cb819eb91e1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Albert=20Loftsson?= Date: Thu, 10 Oct 2024 10:41:11 +0000 Subject: [PATCH 1/4] start on advanced driving-license --- .../src/fields/Alert.tsx | 2 +- .../AdvancedLicense/AdvancedLicense.tsx | 146 ++++++++++++++++++ .../src/fields/AdvancedLicense/index.tsx | 1 + .../driving-license/src/fields/index.ts | 1 + .../src/forms/prerequisites/getForm.ts | 11 +- .../sectionAdvancedLicenseSelection.ts | 35 +++++ .../prerequisites/sectionApplicationFor.ts | 13 ++ .../driving-license/src/lib/constants.ts | 118 ++++++++++++++ .../driving-license/src/lib/dataSchema.ts | 16 +- .../src/lib/drivingLicenseTemplate.ts | 4 +- .../src/lib/getApplicationFeatureFlags.ts | 2 + .../driving-license/src/lib/messages.ts | 115 ++++++++++++++ .../src/lib/utils/formUtils.ts | 8 + 13 files changed, 467 insertions(+), 5 deletions(-) create mode 100644 libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx create mode 100644 libs/application/templates/driving-license/src/fields/AdvancedLicense/index.tsx create mode 100644 libs/application/templates/driving-license/src/forms/prerequisites/sectionAdvancedLicenseSelection.ts diff --git a/libs/application/templates/driving-license-duplicate/src/fields/Alert.tsx b/libs/application/templates/driving-license-duplicate/src/fields/Alert.tsx index 97547f2646d6..da86370f043b 100644 --- a/libs/application/templates/driving-license-duplicate/src/fields/Alert.tsx +++ b/libs/application/templates/driving-license-duplicate/src/fields/Alert.tsx @@ -27,7 +27,7 @@ export const Alert: FC> = ({ }) => { const { formatMessage } = useLocale() const { title, type, message, heading } = field.props as Field - console.log('message', formatText(message, application, formatMessage)) + return ( {heading && ( diff --git a/libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx b/libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx new file mode 100644 index 000000000000..c21683dce18e --- /dev/null +++ b/libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx @@ -0,0 +1,146 @@ +import React, { FC, useEffect, useState } from 'react' + +import { Box, Checkbox, Text } from '@island.is/island-ui/core' +import { FieldBaseProps } from '@island.is/application/types' +import { useFormContext } from 'react-hook-form' +import { + organizedAdvancedLicenseMap, + AdvancedLicense as AdvancedLicenseEnum, +} from '../../lib/constants' +import { useLocale } from '@island.is/localization' +import { m } from '../../lib/messages' +import { joinWithAnd } from '../../lib/utils' + +const AdvancedLicense: FC> = ({ + application, +}) => { + const { formatMessage } = useLocale() + const { setValue, watch } = useFormContext() + + const advancedLicenseValue = watch('advancedLicense') ?? [] + + const [selectedLicenses, setSelectedLicenses] = + useState>(advancedLicenseValue) + + useEffect(() => { + if (selectedLicenses.length > 0) { + setValue('advancedLicense', selectedLicenses) + } + }, [selectedLicenses, setValue]) + + return ( + + {Object.entries(organizedAdvancedLicenseMap).map(([, options], index) => { + const s1arr = options.map((option) => { + return option.code + }) + + const s1 = joinWithAnd(s1arr) + + const s2 = options.find((x) => x.minAge)?.minAge + + const requiredAgeText = + s1 && + s2 && + formatMessage(m[`applicationForAdvancedAgeRequired`]) + ?.replace('%1', s1) + ?.replace('%2', String(s2)) + + return ( + + {requiredAgeText && ( + + + {requiredAgeText} + + + )} + {options.map((option, index) => { + const name = `field-${option.code}` + + return ( + + + {formatMessage( + m[`applicationForAdvancedLicenseTitle${option.code}`], + )} + + { + const checked = e.target.checked + + setSelectedLicenses((prev) => { + return prev.includes(option.code) + ? prev + .filter((item) => item !== option.code) + .filter( + (item) => item !== option.professional?.code, + ) + : [...prev, option.code] + }) + }} + /> + {option?.professional && ( + + { + setSelectedLicenses((prev) => { + if (e.target.checked && option.professional?.code) { + return [...prev, option.professional.code] + } + + return prev.filter( + (item) => item !== option.professional?.code, + ) + }) + }} + /> + + )} + + ) + })} + + ) + })} + + ) +} + +export { AdvancedLicense } diff --git a/libs/application/templates/driving-license/src/fields/AdvancedLicense/index.tsx b/libs/application/templates/driving-license/src/fields/AdvancedLicense/index.tsx new file mode 100644 index 000000000000..d4aca673acae --- /dev/null +++ b/libs/application/templates/driving-license/src/fields/AdvancedLicense/index.tsx @@ -0,0 +1 @@ +export { AdvancedLicense } from './AdvancedLicense' diff --git a/libs/application/templates/driving-license/src/fields/index.ts b/libs/application/templates/driving-license/src/fields/index.ts index 6f42ecaa4bb4..6bcd3cc0f60a 100644 --- a/libs/application/templates/driving-license/src/fields/index.ts +++ b/libs/application/templates/driving-license/src/fields/index.ts @@ -4,5 +4,6 @@ export { EligibilitySummary } from './EligibilitySummary' export { SubmitAndDecline } from './SubmitAndDecline' export { LinkExistingApplication } from './LinkExistingApplication' export { PaymentPending } from './PaymentPending' +export { AdvancedLicense } from './AdvancedLicense' export { QualityPhoto } from './QualityPhoto' export { default as HealthRemarks } from './HealthRemarks' diff --git a/libs/application/templates/driving-license/src/forms/prerequisites/getForm.ts b/libs/application/templates/driving-license/src/forms/prerequisites/getForm.ts index 9bf9a5b197a7..72f2db07ff35 100644 --- a/libs/application/templates/driving-license/src/forms/prerequisites/getForm.ts +++ b/libs/application/templates/driving-license/src/forms/prerequisites/getForm.ts @@ -8,12 +8,14 @@ import { sectionApplicationFor } from './sectionApplicationFor' import { sectionRequirements } from './sectionRequirements' import { sectionExistingApplication } from './sectionExistingApplication' import { sectionDigitalLicenseInfo } from './sectionDigitalLicenseInfo' +import { sectionAdvancedLicenseSelection } from './sectionAdvancedLicenseSelection' export const getForm = ({ allowFakeData = false, allowPickLicense = false, allowBELicense = false, allow65Renewal = false, + allowAdvanced = false, }): Form => buildForm({ id: 'DrivingLicenseApplicationPrerequisitesForm', @@ -31,8 +33,15 @@ export const getForm = ({ sectionExternalData, sectionExistingApplication, ...(allowPickLicense - ? [sectionApplicationFor(allowBELicense, allow65Renewal)] + ? [ + sectionApplicationFor( + allowBELicense, + allow65Renewal, + allowAdvanced, + ), + ] : []), + sectionAdvancedLicenseSelection, sectionDigitalLicenseInfo, sectionRequirements, ], diff --git a/libs/application/templates/driving-license/src/forms/prerequisites/sectionAdvancedLicenseSelection.ts b/libs/application/templates/driving-license/src/forms/prerequisites/sectionAdvancedLicenseSelection.ts new file mode 100644 index 000000000000..769811f4ad58 --- /dev/null +++ b/libs/application/templates/driving-license/src/forms/prerequisites/sectionAdvancedLicenseSelection.ts @@ -0,0 +1,35 @@ +import { + buildCustomField, + buildMultiField, + buildSubSection, + getValueViaPath, +} from '@island.is/application/core' +import { m } from '../../lib/messages' +import { LicenseTypes } from '../../lib/constants' + +export const sectionAdvancedLicenseSelection = buildSubSection({ + id: 'sectionAdvancedLicenseSelection', + title: m.applicationForAdvancedLicenseTitle, + condition: (answers) => { + const applicationFor = getValueViaPath( + answers, + 'applicationFor', + ) + + return applicationFor === LicenseTypes.B_ADVANCED + }, + children: [ + buildMultiField({ + id: 'advancedLicenseSelectionFields', + title: m.applicationForAdvancedLicenseTitle, + description: m.applicationForAdvancedLicenseDescription, + children: [ + buildCustomField({ + id: 'advancedLicense', + title: 'Advanced License', + component: 'AdvancedLicense', + }), + ], + }), + ], +}) diff --git a/libs/application/templates/driving-license/src/forms/prerequisites/sectionApplicationFor.ts b/libs/application/templates/driving-license/src/forms/prerequisites/sectionApplicationFor.ts index cf6ba528b6bb..571231ab2c73 100644 --- a/libs/application/templates/driving-license/src/forms/prerequisites/sectionApplicationFor.ts +++ b/libs/application/templates/driving-license/src/forms/prerequisites/sectionApplicationFor.ts @@ -7,6 +7,7 @@ import { import { m } from '../../lib/messages' import { DrivingLicense } from '../../lib/types' import { + B_ADVANCED, B_FULL, B_FULL_RENEWAL_65, B_TEMP, @@ -17,6 +18,7 @@ import { export const sectionApplicationFor = ( allowBELicense = false, allow65Renewal = false, + allowAdvanced = false, ) => buildSubSection({ id: 'applicationFor', @@ -112,6 +114,17 @@ export const sectionApplicationFor = ( }) } + if (allowAdvanced) { + options = options.concat({ + label: m.applicationForAdvancedLicenseTitle, + subLabel: m.applicationForAdvancedLicenseDescription, + value: B_ADVANCED, + disabled: !categories?.some( + (c) => c.nr.toUpperCase() === 'B' && c.validToCode !== 8, + ), + }) + } + return options }, }), diff --git a/libs/application/templates/driving-license/src/lib/constants.ts b/libs/application/templates/driving-license/src/lib/constants.ts index 0e4e00652e02..54e39c3b52dc 100644 --- a/libs/application/templates/driving-license/src/lib/constants.ts +++ b/libs/application/templates/driving-license/src/lib/constants.ts @@ -8,9 +8,127 @@ export enum ApiActions { export const B_FULL = 'B-full' export const B_TEMP = 'B-temp' export const B_FULL_RENEWAL_65 = 'B-full-renewal-65' +export const B_ADVANCED = 'B-advanced' export const BE = 'BE' export const DELIVERY_FEE = 'deliveryFee' +export enum LicenseTypes { + 'B_FULL' = 'B-full', + 'B_TEMP' = 'B-temp', + 'B_FULL_RENEWAL_65' = 'B-full-renewal-65', + 'BE' = 'BE', + 'B_ADVANCED' = 'B-advanced', +} + +export enum Pickup { + 'POST' = 'post', + 'DISTRICT' = 'district', +} + +export enum MainAdvancedLicense { + 'C1' = 'C1', + 'D1' = 'D1', + 'C' = 'C', + 'D' = 'D', + 'C1E' = 'C1E', + 'D1E' = 'D1E', + 'CE' = 'CE', + 'DE' = 'DE', +} + +export enum ProfessionalAdvancedLicense { + 'C1A' = 'C1A', + 'D1A' = 'D1A', + 'CA' = 'CA', + 'DA' = 'DA', +} + +export const AdvancedLicense = { + ...MainAdvancedLicense, + ...ProfessionalAdvancedLicense, +} as const + +type AdvancedLicenseMapItem = { + minAge: number + group: keyof typeof MainAdvancedLicense + code: keyof typeof MainAdvancedLicense + professional?: { + minAge: number + code: keyof typeof ProfessionalAdvancedLicense + } +} + +export const advancedLicenseMap: AdvancedLicenseMapItem[] = [ + { + code: 'C1', + group: 'C1', + minAge: 18, + professional: { + code: 'C1A', + minAge: 18, + }, + }, + { + code: 'C1E', + group: 'C1', + minAge: 18, + }, + { + code: 'D1', + group: 'D1', + minAge: 21, + professional: { + code: 'D1A', + minAge: 21, + }, + }, + { + code: 'D1E', + group: 'D1', + minAge: 18, + }, + { + code: 'C', + group: 'C', + minAge: 21, + professional: { + code: 'CA', + minAge: 21, + }, + }, + { + code: 'CE', + group: 'C', + minAge: 18, + }, + { + code: 'D', + group: 'D', + minAge: 21, + professional: { + code: 'DA', + minAge: 23, + }, + }, + { + code: 'DE', + group: 'D', + minAge: 18, + }, +] + +export const organizedAdvancedLicenseMap = advancedLicenseMap.reduce< + Record +>((acc, item) => { + if (!acc[item.group]) { + acc[item.group] = [] + } + + acc[item.group].push(item) + + return acc +}, {}) + export const CHARGE_ITEM_CODES: Record = { [B_TEMP]: 'AY114', [B_FULL]: 'AY110', diff --git a/libs/application/templates/driving-license/src/lib/dataSchema.ts b/libs/application/templates/driving-license/src/lib/dataSchema.ts index 82d68194a468..82b32ab65483 100644 --- a/libs/application/templates/driving-license/src/lib/dataSchema.ts +++ b/libs/application/templates/driving-license/src/lib/dataSchema.ts @@ -1,5 +1,14 @@ import { z } from 'zod' -import { YES, NO, B_FULL_RENEWAL_65, BE, B_TEMP, B_FULL } from './constants' +import { + YES, + NO, + B_FULL_RENEWAL_65, + BE, + B_TEMP, + B_FULL, + B_ADVANCED, + AdvancedLicense, +} from './constants' import { parsePhoneNumberFromString } from 'libphonenumber-js' import { Pickup } from './types' @@ -36,7 +45,10 @@ export const dataSchema = z.object({ ]), requirementsMet: z.boolean().refine((v) => v), certificate: z.array(z.enum([YES, NO])).nonempty(), - applicationFor: z.enum([B_FULL, B_TEMP, BE, B_FULL_RENEWAL_65]), + applicationFor: z.enum([B_FULL, B_TEMP, BE, B_FULL_RENEWAL_65, B_ADVANCED]), + advancedLicense: z + .array(z.enum(Object.keys(AdvancedLicense) as [string, ...string[]])) + .nonempty(), email: z.string().email(), phone: z.string().refine((v) => isValidPhoneNumber(v)), drivingInstructor: z.string().min(1), diff --git a/libs/application/templates/driving-license/src/lib/drivingLicenseTemplate.ts b/libs/application/templates/driving-license/src/lib/drivingLicenseTemplate.ts index d7c7a9ea2d27..56ea5c57742f 100644 --- a/libs/application/templates/driving-license/src/lib/drivingLicenseTemplate.ts +++ b/libs/application/templates/driving-license/src/lib/drivingLicenseTemplate.ts @@ -53,7 +53,7 @@ import { Pickup } from './types' const getCodes = (application: Application) => { const applicationFor = getValueViaPath< - 'B-full' | 'B-temp' | 'BE' | 'B-full-renewal-65' + 'B-full' | 'B-temp' | 'BE' | 'B-full-renewal-65' | 'B-advanced' >(application.answers, 'applicationFor', 'B-full') const pickup = getValueViaPath(application.answers, 'pickup') @@ -142,6 +142,8 @@ const template: ApplicationTemplate< featureFlags[DrivingLicenseFeatureFlags.ALLOW_BE_LICENSE], allow65Renewal: featureFlags[DrivingLicenseFeatureFlags.ALLOW_65_RENEWAL], + allowAdvanced: + featureFlags[DrivingLicenseFeatureFlags.ALLOW_ADVANCED], }) }, write: 'all', diff --git a/libs/application/templates/driving-license/src/lib/getApplicationFeatureFlags.ts b/libs/application/templates/driving-license/src/lib/getApplicationFeatureFlags.ts index 9a7186289db8..2905a9b30d89 100644 --- a/libs/application/templates/driving-license/src/lib/getApplicationFeatureFlags.ts +++ b/libs/application/templates/driving-license/src/lib/getApplicationFeatureFlags.ts @@ -5,6 +5,7 @@ export enum DrivingLicenseFeatureFlags { ALLOW_LICENSE_SELECTION = 'applicationTemplateDrivingLicenseAllowLicenseSelection', ALLOW_BE_LICENSE = 'isBEApplicationEnabled', ALLOW_65_RENEWAL = 'is65RenewalApplicationEnabled', + ALLOW_ADVANCED = 'isDrivingLicenseAdvancedEnabled', } export const getApplicationFeatureFlags = async ( @@ -15,6 +16,7 @@ export const getApplicationFeatureFlags = async ( DrivingLicenseFeatureFlags.ALLOW_LICENSE_SELECTION, DrivingLicenseFeatureFlags.ALLOW_BE_LICENSE, DrivingLicenseFeatureFlags.ALLOW_65_RENEWAL, + DrivingLicenseFeatureFlags.ALLOW_ADVANCED, ] return ( diff --git a/libs/application/templates/driving-license/src/lib/messages.ts b/libs/application/templates/driving-license/src/lib/messages.ts index 07431e977201..5e6f8bea1202 100644 --- a/libs/application/templates/driving-license/src/lib/messages.ts +++ b/libs/application/templates/driving-license/src/lib/messages.ts @@ -878,6 +878,121 @@ export const m = defineMessages({ description: 'Health declaration answers indicate that health certificate is required and BE application does not support health certificate requirement', }, + applicationForAdvancedLicenseTitle: { + id: 'dl.application:applicationForAdvancedLicenseTitle', + defaultMessage: 'Umsókn um aukin ökuréttindi', + description: 'Option title for selecting advanced driving license', + }, + applicationForAdvancedLicenseDescription: { + id: 'dl.application:applicationForAdvancedLicenseDescription', + defaultMessage: 'Umsókn um aukin ökuréttindi.', + description: 'Option description for selecting advanced driving license', + }, + applicationForAdvancedAgeRequired: { + id: 'dl.application:applicationForAdvancedAgeFor', + defaultMessage: 'Réttindaaldur fyrir %1 er %2 ára', + description: 'Required age for %1 is %2 years', + }, + applicationForAdvancedLicenseTitleC1: { + id: 'dl.application:applicationForAdvancedLicenseTitleC1', + defaultMessage: 'C1 titill', + description: 'C1 title', + }, + applicationForAdvancedLicenseLabelC1: { + id: 'dl.application:applicationForAdvancedLicenseLabelC1', + defaultMessage: 'C1 lýsing', + description: 'C1 description', + }, + applicationForAdvancedLicenseLabelC1A: { + id: 'dl.application:applicationForAdvancedLicenseLabelC1A', + defaultMessage: 'C1A lýsing', + description: 'C1A description', + }, + applicationForAdvancedLicenseTitleD1: { + id: 'dl.application:applicationForAdvancedLicenseTitleD1', + defaultMessage: 'D1 titill', + description: 'D1 title', + }, + applicationForAdvancedLicenseLabelD1: { + id: 'dl.application:applicationForAdvancedLicenseLabelD1', + defaultMessage: 'D1 lýsing', + description: 'D1 description', + }, + applicationForAdvancedLicenseLabelD1A: { + id: 'dl.application:applicationForAdvancedLicenseLabelD1A', + defaultMessage: 'D1A lýsing', + description: 'D1A description', + }, + applicationForAdvancedLicenseTitleC: { + id: 'dl.application:applicationForAdvancedLicenseTitleC', + defaultMessage: 'C titill', + description: 'C title', + }, + applicationForAdvancedLicenseLabelC: { + id: 'dl.application:applicationForAdvancedLicenseLabelC', + defaultMessage: 'C lýsing', + description: 'C description', + }, + applicationForAdvancedLicenseLabelCA: { + id: 'dl.application:applicationForAdvancedLicenseLabelCA', + defaultMessage: 'CA lýsing', + description: 'CA description', + }, + applicationForAdvancedLicenseTitleD: { + id: 'dl.application:applicationForAdvancedLicenseTitleD', + defaultMessage: 'D titill', + description: 'D title', + }, + applicationForAdvancedLicenseLabelD: { + id: 'dl.application:applicationForAdvancedLicenseLabelD', + defaultMessage: 'D lýsing', + description: 'D description', + }, + applicationForAdvancedLicenseLabelDA: { + id: 'dl.application:applicationForAdvancedLicenseLabelDA', + defaultMessage: 'DA lýsing', + description: 'DA description', + }, + applicationForAdvancedLicenseTitleC1E: { + id: 'dl.application:applicationForAdvancedLicenseTitleC1E', + defaultMessage: 'C1E titill', + description: 'C1E title', + }, + applicationForAdvancedLicenseLabelC1E: { + id: 'dl.application:applicationForAdvancedLicenseLabelC1E', + defaultMessage: 'C1E lýsing', + description: 'C1E description', + }, + applicationForAdvancedLicenseTitleD1E: { + id: 'dl.application:applicationForAdvancedLicenseTitleD1E', + defaultMessage: 'D1E titill', + description: 'D1E title', + }, + applicationForAdvancedLicenseLabelD1E: { + id: 'dl.application:applicationForAdvancedLicenseLabelD1E', + defaultMessage: 'D1E lýsing', + description: 'D1E description', + }, + applicationForAdvancedLicenseTitleCE: { + id: 'dl.application:applicationForAdvancedLicenseTitleCE', + defaultMessage: 'CE titill', + description: 'CE title', + }, + applicationForAdvancedLicenseLabelCE: { + id: 'dl.application:applicationForAdvancedLicenseLabelCE', + defaultMessage: 'CE lýsing', + description: 'CE description', + }, + applicationForAdvancedLicenseTitleDE: { + id: 'dl.application:applicationForAdvancedLicenseTitleDE', + defaultMessage: 'DE titill', + description: 'DE title', + }, + applicationForAdvancedLicenseLabelDE: { + id: 'dl.application:applicationForAdvancedLicenseLabelDE', + defaultMessage: 'DE lýsing', + description: 'DE description', + }, }) export const requirementsMessages = defineMessages({ diff --git a/libs/application/templates/driving-license/src/lib/utils/formUtils.ts b/libs/application/templates/driving-license/src/lib/utils/formUtils.ts index 00a0b876c073..41d0a473768c 100644 --- a/libs/application/templates/driving-license/src/lib/utils/formUtils.ts +++ b/libs/application/templates/driving-license/src/lib/utils/formUtils.ts @@ -86,3 +86,11 @@ export const hasHealthRemarks = (externalData: ExternalData) => { ).length > 0 ) } + +export const joinWithAnd = (arr: string[], andString = 'og'): string => { + if (arr.length === 0) return '' + if (arr.length === 1) return arr[0] + if (arr.length === 2) return arr.join(` ${andString} `) + + return `${arr.slice(0, -1).join(', ')}, ${andString} ${arr[arr.length - 1]}` +} From 25e9e21c2df1abb165f9978b368587a4dc8294b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Albert=20Loftsson?= Date: Wed, 30 Oct 2024 16:31:02 +0000 Subject: [PATCH 2/4] code rabbit comment changes --- .../src/fields/AdvancedLicense/AdvancedLicense.tsx | 13 +++++++++---- .../src/forms/prerequisites/getForm.ts | 2 +- .../sectionAdvancedLicenseSelection.ts | 2 +- .../driving-license/src/lib/dataSchema.ts | 2 +- .../templates/driving-license/src/lib/messages.ts | 4 ++-- .../driving-license/src/lib/utils/formUtils.ts | 14 ++++++++++---- 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx b/libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx index c21683dce18e..6c7d3b373c1b 100644 --- a/libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx +++ b/libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx @@ -42,12 +42,17 @@ const AdvancedLicense: FC> = ({ const requiredAgeText = s1 && s2 && - formatMessage(m[`applicationForAdvancedAgeRequired`]) - ?.replace('%1', s1) - ?.replace('%2', String(s2)) + formatMessage(m[`applicationForAdvancedAgeRequired`], { + licenses: s1, + age: String(s2), + }) return ( - + {requiredAgeText && ( diff --git a/libs/application/templates/driving-license/src/forms/prerequisites/getForm.ts b/libs/application/templates/driving-license/src/forms/prerequisites/getForm.ts index 72f2db07ff35..1b33b409a53a 100644 --- a/libs/application/templates/driving-license/src/forms/prerequisites/getForm.ts +++ b/libs/application/templates/driving-license/src/forms/prerequisites/getForm.ts @@ -41,7 +41,7 @@ export const getForm = ({ ), ] : []), - sectionAdvancedLicenseSelection, + ...(allowAdvanced ? [sectionAdvancedLicenseSelection] : []), sectionDigitalLicenseInfo, sectionRequirements, ], diff --git a/libs/application/templates/driving-license/src/forms/prerequisites/sectionAdvancedLicenseSelection.ts b/libs/application/templates/driving-license/src/forms/prerequisites/sectionAdvancedLicenseSelection.ts index 769811f4ad58..fe3afd760c0c 100644 --- a/libs/application/templates/driving-license/src/forms/prerequisites/sectionAdvancedLicenseSelection.ts +++ b/libs/application/templates/driving-license/src/forms/prerequisites/sectionAdvancedLicenseSelection.ts @@ -16,7 +16,7 @@ export const sectionAdvancedLicenseSelection = buildSubSection({ 'applicationFor', ) - return applicationFor === LicenseTypes.B_ADVANCED + return applicationFor != null && applicationFor === LicenseTypes.B_ADVANCED }, children: [ buildMultiField({ diff --git a/libs/application/templates/driving-license/src/lib/dataSchema.ts b/libs/application/templates/driving-license/src/lib/dataSchema.ts index 82b32ab65483..9a7d6ccbac65 100644 --- a/libs/application/templates/driving-license/src/lib/dataSchema.ts +++ b/libs/application/templates/driving-license/src/lib/dataSchema.ts @@ -47,7 +47,7 @@ export const dataSchema = z.object({ certificate: z.array(z.enum([YES, NO])).nonempty(), applicationFor: z.enum([B_FULL, B_TEMP, BE, B_FULL_RENEWAL_65, B_ADVANCED]), advancedLicense: z - .array(z.enum(Object.keys(AdvancedLicense) as [string, ...string[]])) + .array(z.enum(Object.values(AdvancedLicense) as [string, ...string[]])) .nonempty(), email: z.string().email(), phone: z.string().refine((v) => isValidPhoneNumber(v)), diff --git a/libs/application/templates/driving-license/src/lib/messages.ts b/libs/application/templates/driving-license/src/lib/messages.ts index 5e6f8bea1202..e791358839a1 100644 --- a/libs/application/templates/driving-license/src/lib/messages.ts +++ b/libs/application/templates/driving-license/src/lib/messages.ts @@ -890,8 +890,8 @@ export const m = defineMessages({ }, applicationForAdvancedAgeRequired: { id: 'dl.application:applicationForAdvancedAgeFor', - defaultMessage: 'Réttindaaldur fyrir %1 er %2 ára', - description: 'Required age for %1 is %2 years', + defaultMessage: 'Réttindaaldur fyrir {licenses} er {age} ára', + description: 'Required age for {licenses} is {age} years', }, applicationForAdvancedLicenseTitleC1: { id: 'dl.application:applicationForAdvancedLicenseTitleC1', diff --git a/libs/application/templates/driving-license/src/lib/utils/formUtils.ts b/libs/application/templates/driving-license/src/lib/utils/formUtils.ts index 41d0a473768c..2d1192d6357b 100644 --- a/libs/application/templates/driving-license/src/lib/utils/formUtils.ts +++ b/libs/application/templates/driving-license/src/lib/utils/formUtils.ts @@ -88,9 +88,15 @@ export const hasHealthRemarks = (externalData: ExternalData) => { } export const joinWithAnd = (arr: string[], andString = 'og'): string => { - if (arr.length === 0) return '' - if (arr.length === 1) return arr[0] - if (arr.length === 2) return arr.join(` ${andString} `) + const validStrings = arr.filter( + (str) => typeof str === 'string' && str.trim().length > 0, + ) + + if (validStrings.length === 0) return '' + if (validStrings.length === 1) return validStrings[0] + if (validStrings.length === 2) return validStrings.join(` ${andString} `) - return `${arr.slice(0, -1).join(', ')}, ${andString} ${arr[arr.length - 1]}` + return `${validStrings.slice(0, -1).join(', ')}, ${andString} ${ + validStrings[validStrings.length - 1] + }` } From c43faab31d1ed60262a9596a00c2b329335fa9a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Albert=20Loftsson?= Date: Thu, 31 Oct 2024 10:58:59 +0000 Subject: [PATCH 3/4] more comment changes --- .../AdvancedLicense/AdvancedLicense.tsx | 26 ++++++++++++------- .../src/forms/prerequisites/getForm.ts | 10 ++++++- .../driving-license/src/lib/dataSchema.ts | 5 +++- .../driving-license/src/lib/messages.ts | 5 ++++ 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx b/libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx index 6c7d3b373c1b..f163a23b3882 100644 --- a/libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx +++ b/libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx @@ -1,6 +1,6 @@ import React, { FC, useEffect, useState } from 'react' -import { Box, Checkbox, Text } from '@island.is/island-ui/core' +import { Box, Checkbox, ErrorMessage, Text } from '@island.is/island-ui/core' import { FieldBaseProps } from '@island.is/application/types' import { useFormContext } from 'react-hook-form' import { @@ -12,20 +12,23 @@ import { m } from '../../lib/messages' import { joinWithAnd } from '../../lib/utils' const AdvancedLicense: FC> = ({ - application, + errors, }) => { const { formatMessage } = useLocale() const { setValue, watch } = useFormContext() + const requiredMessage = (errors as { advancedLicense?: string }) + ?.advancedLicense + ? formatMessage(m.applicationForAdvancedRequiredError) + : '' + const advancedLicenseValue = watch('advancedLicense') ?? [] const [selectedLicenses, setSelectedLicenses] = useState>(advancedLicenseValue) useEffect(() => { - if (selectedLicenses.length > 0) { - setValue('advancedLicense', selectedLicenses) - } + setValue('advancedLicense', selectedLicenses) }, [selectedLicenses, setValue]) return ( @@ -88,9 +91,7 @@ const AdvancedLicense: FC> = ({ backgroundColor="blue" labelVariant="medium" checked={advancedLicenseValue.includes(option.code)} - onChange={(e) => { - const checked = e.target.checked - + onChange={() => { setSelectedLicenses((prev) => { return prev.includes(option.code) ? prev @@ -102,9 +103,9 @@ const AdvancedLicense: FC> = ({ }) }} /> - {option?.professional && ( + {option?.professional?.code && ( > = ({ ) })} + {!selectedLicenses?.length && requiredMessage && ( + +
{requiredMessage}
+
+ )}
) } diff --git a/libs/application/templates/driving-license/src/forms/prerequisites/getForm.ts b/libs/application/templates/driving-license/src/forms/prerequisites/getForm.ts index 1b33b409a53a..28d94b416070 100644 --- a/libs/application/templates/driving-license/src/forms/prerequisites/getForm.ts +++ b/libs/application/templates/driving-license/src/forms/prerequisites/getForm.ts @@ -10,13 +10,21 @@ import { sectionExistingApplication } from './sectionExistingApplication' import { sectionDigitalLicenseInfo } from './sectionDigitalLicenseInfo' import { sectionAdvancedLicenseSelection } from './sectionAdvancedLicenseSelection' +interface DrivingLicenseFormConfig { + allowFakeData?: boolean + allowPickLicense?: boolean + allowBELicense?: boolean + allow65Renewal?: boolean + allowAdvanced?: boolean +} + export const getForm = ({ allowFakeData = false, allowPickLicense = false, allowBELicense = false, allow65Renewal = false, allowAdvanced = false, -}): Form => +}: DrivingLicenseFormConfig): Form => buildForm({ id: 'DrivingLicenseApplicationPrerequisitesForm', title: '', diff --git a/libs/application/templates/driving-license/src/lib/dataSchema.ts b/libs/application/templates/driving-license/src/lib/dataSchema.ts index 9a7d6ccbac65..981719fbf325 100644 --- a/libs/application/templates/driving-license/src/lib/dataSchema.ts +++ b/libs/application/templates/driving-license/src/lib/dataSchema.ts @@ -48,7 +48,10 @@ export const dataSchema = z.object({ applicationFor: z.enum([B_FULL, B_TEMP, BE, B_FULL_RENEWAL_65, B_ADVANCED]), advancedLicense: z .array(z.enum(Object.values(AdvancedLicense) as [string, ...string[]])) - .nonempty(), + .nonempty() + .refine((value) => { + return value.length > 0 + }), email: z.string().email(), phone: z.string().refine((v) => isValidPhoneNumber(v)), drivingInstructor: z.string().min(1), diff --git a/libs/application/templates/driving-license/src/lib/messages.ts b/libs/application/templates/driving-license/src/lib/messages.ts index e791358839a1..6c791ddfd668 100644 --- a/libs/application/templates/driving-license/src/lib/messages.ts +++ b/libs/application/templates/driving-license/src/lib/messages.ts @@ -993,6 +993,11 @@ export const m = defineMessages({ defaultMessage: 'DE lýsing', description: 'DE description', }, + applicationForAdvancedRequiredError: { + id: 'dl.application:applicationForAdvancedRequiredError', + defaultMessage: 'Þú verður að velja að minnsta kosti einn valmöguleika', + description: 'You must select at least one option', + }, }) export const requirementsMessages = defineMessages({ From 66b64a52a6151051aa57207f36f7d0ec52a3f331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Albert=20Loftsson?= Date: Thu, 31 Oct 2024 11:40:49 +0000 Subject: [PATCH 4/4] change --- .../src/fields/AdvancedLicense/AdvancedLicense.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx b/libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx index f163a23b3882..88dfc817adfc 100644 --- a/libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx +++ b/libs/application/templates/driving-license/src/fields/AdvancedLicense/AdvancedLicense.tsx @@ -63,12 +63,12 @@ const AdvancedLicense: FC> = ({
)} - {options.map((option, index) => { + {options.map((option) => { const name = `field-${option.code}` return (