From 097612c0de9750fe7d5b75daf6a82db1f45cae88 Mon Sep 17 00:00:00 2001
From: Andreas Ellewsen <ae@uio.no>
Date: Mon, 13 Dec 2021 14:31:19 +0100
Subject: [PATCH] Modify register step form for guests

- Passport Country now displays two letter code after
   selection.
- A heading has been added for identity information.
- An error message is now displayed if the user inputs both national id
   and passport information.

Resolves: GREG-120
---
 frontend/public/locales/en/common.json        |   3 +
 frontend/public/locales/nb/common.json        |   3 +
 frontend/public/locales/nn/common.json        |   3 +
 .../src/routes/guest/register/index.test.tsx  |   2 +-
 .../routes/guest/register/steps/register.tsx  | 176 +++++++++++-------
 5 files changed, 115 insertions(+), 72 deletions(-)

diff --git a/frontend/public/locales/en/common.json b/frontend/public/locales/en/common.json
index fc1eda76..cd7f9f96 100644
--- a/frontend/public/locales/en/common.json
+++ b/frontend/public/locales/en/common.json
@@ -100,6 +100,7 @@
     "startDateMustBeSet": "Start date must be set",
     "startDateMustBeBeforeEndDate": "Start date has to be before end date",
     "passportNationalityAndNumber": "Both passport nationality and number need to be set",
+    "doubleIdentity": "*You have input both national ID and passport. Please choose only one.",
     "nationalIdOrPassport": "National ID or passport information need to be entered"
   },
   "button": {
@@ -134,6 +135,8 @@
   "registerNewGuest": "Register new guest",
   "guestOverview": "Guest overview",
   "guestRegisterWizardText": {
+    "identityHeader": "Identify yourself ",
+    "identityBody": "Enter national identity number if you have one. Otherwise use passport information.",
     "yourContactInformation": "Your contact information",
     "contactInformationDescription": "Fill in your mobile phone number.",
     "yourGuestPeriod": "Your guest period",
diff --git a/frontend/public/locales/nb/common.json b/frontend/public/locales/nb/common.json
index 79d565aa..0b21b590 100644
--- a/frontend/public/locales/nb/common.json
+++ b/frontend/public/locales/nb/common.json
@@ -100,6 +100,7 @@
     "startDateMustBeSet": "Startdato må være satt",
     "startDateMustBeBeforeEndDate": "Startdato må være før sluttdato",
     "passportNationalityAndNumber": "Både passnasjonalitet og nummer må være satt",
+    "doubleIdentity": "*Du har fylt inn begge feltene over. Bruk kun ett av de.",
     "nationalIdOrPassport": "Fødselsnummer/D-nummer eller passinformasjon må spesifiseres"
   },
   "button": {
@@ -134,6 +135,8 @@
   "registerNewGuest": "Registrer ny gjest",
   "guestOverview": "Oversikt over gjest",
   "guestRegisterWizardText": {
+    "identityHeader": "Identifiser deg ",
+    "identityBody": "Fyll inn fødselsnummer hvis du har. <1>Eller</1> nasjonalitet og passnummer.",
     "yourContactInformation": "Din kontaktinfo",
     "contactInformationDescription": "Fyll inn ditt mobilnummer.",
     "yourGuestPeriod": "Din gjesteperiode",
diff --git a/frontend/public/locales/nn/common.json b/frontend/public/locales/nn/common.json
index c49aa0b3..a16fe804 100644
--- a/frontend/public/locales/nn/common.json
+++ b/frontend/public/locales/nn/common.json
@@ -101,6 +101,7 @@
     "startDateMustBeSet": "Startdato må vere satt",
     "startDateMustBeBeforeEndDate": "Startdato må vere før sluttdato",
     "passportNationalityAndNumber": "Både passnasjonalitet og nummer må vere satt",
+    "doubleIdentity": "*Du har fylt inn begge feltene over. Bruk kun ett av de.",
     "nationalIdOrPassport": "Fødselsnummer/D-nummer eller passinformasjon må spesifiserast"
   },
   "button": {
@@ -135,6 +136,8 @@
   "registerNewGuest": "Registrer ny gjest",
   "guestOverview": "Oversikt over gjest",
   "guestRegisterWizardText": {
+    "identityHeader": "Identifiser deg ",
+    "identityBody": "Fyll inn fødselsnummer hvis du har. <1>Eller</1> nasjonalitet og passnummer.",
     "yourContactInformation": "Din kontaktinfo",
     "contactInformationDescription": "Fyll inn ditt mobilnummer.",
     "yourGuestPeriod": "Din gjesteperiode",
diff --git a/frontend/src/routes/guest/register/index.test.tsx b/frontend/src/routes/guest/register/index.test.tsx
index 0ac01aee..8b09debb 100644
--- a/frontend/src/routes/guest/register/index.test.tsx
+++ b/frontend/src/routes/guest/register/index.test.tsx
@@ -50,7 +50,7 @@ test('Field showing values correctly', async () => {
   await screen.findByDisplayValue(testData.person.fnr)
 
   // Passport nationality. The i18n-mock sets up en as the i18n.language property, so look for the English name
-  await screen.findByText('Denmark')
+  await screen.findByText('DK')
   await screen.findByDisplayValue('123456')
   await screen.findByDisplayValue(testData.person.date_of_birth)
 
diff --git a/frontend/src/routes/guest/register/steps/register.tsx b/frontend/src/routes/guest/register/steps/register.tsx
index 3b4fbb35..cc4366c8 100644
--- a/frontend/src/routes/guest/register/steps/register.tsx
+++ b/frontend/src/routes/guest/register/steps/register.tsx
@@ -1,5 +1,6 @@
 import {
   Box,
+  Divider,
   MenuItem,
   Select,
   SelectChangeEvent,
@@ -16,7 +17,7 @@ import React, {
   useImperativeHandle,
   useState,
 } from 'react'
-import { useTranslation } from 'react-i18next'
+import { useTranslation, Trans } from 'react-i18next'
 import {
   CountryCallingCode,
   CountryCode,
@@ -81,6 +82,7 @@ const GuestRegisterStep = forwardRef(
       console.log('submit data is', data)
       const result = await trigger()
       console.log('trigger result is', result)
+      const tohandler = data
       if (
         !data.nationalIdNumber &&
         !data.passportNumber &&
@@ -92,6 +94,22 @@ const GuestRegisterStep = forwardRef(
         return
       }
 
+      // Users should only input NIN or passport
+      if (data.passportNumber && data.nationalIdNumber) {
+        setIdErrorState(t('validation.doubleIdentity'))
+        return
+      }
+      // Reset passportNationality if NIN is set and passport is empty
+      if (
+        data.nationalIdNumber &&
+        !data.passportNumber &&
+        data.passportNationality
+      ) {
+        setValue('passportNationality', '')
+        setPassportNationality('')
+        tohandler.passportNationality = ''
+      }
+
       // if one on the passport fields are set, check that both are set
       if (
         (data.passportNumber && !data.passportNationality) ||
@@ -105,7 +123,7 @@ const GuestRegisterStep = forwardRef(
       console.log('register submit errors', errors)
 
       if (!Object.keys(errors).length) {
-        nextHandler(data)
+        nextHandler(tohandler)
       }
     }
     const onSubmit = handleSubmit<GuestRegisterData>(submit)
@@ -173,21 +191,41 @@ const GuestRegisterStep = forwardRef(
 
     useImperativeHandle(ref, () => ({ doSubmit: () => onSubmit() }))
 
+    const passportCountries = Object.keys(getAlpha2Codes())
+      .map((countryAlphaCode: string) => {
+        const countryTuple: [string, string] = [
+          countryAlphaCode,
+          getName(countryAlphaCode, i18n.language),
+        ]
+        return countryTuple
+      })
+      .filter(
+        (countryTuple: [string, string]) =>
+          // All countries are expected to have a name, this filtering
+          // is here to make some tests run in an environment where the
+          // internationalization is not set up
+          countryTuple[1] !== undefined
+      )
+      .sort(
+        (countryTuple1: [string, string], countryTuple2: [string, string]) =>
+          countryTuple1[1].localeCompare(countryTuple2[1])
+      )
     return (
       <>
-        <Typography
-          variant="h5"
-          sx={{
-            paddingTop: '1rem',
-            paddingBottom: '1rem',
-          }}
-        >
-          {t('guestRegisterWizardText.yourContactInformation')}
-        </Typography>
-        <Typography sx={{ paddingBottom: '2rem' }}>
-          {t('guestRegisterWizardText.contactInformationDescription')}
-        </Typography>
         <Box sx={{ maxWidth: '30rem' }}>
+          <Typography
+            variant="h5"
+            sx={{
+              paddingTop: '1rem',
+              paddingBottom: '1rem',
+            }}
+          >
+            {t('guestRegisterWizardText.yourContactInformation')}
+          </Typography>
+          <Typography sx={{ paddingBottom: '2rem' }}>
+            {t('guestRegisterWizardText.contactInformationDescription')}
+            <Divider sx={{ border: '1px solid' }} />
+          </Typography>
           <form onSubmit={onSubmit}>
             <Stack spacing={2}>
               {/* The name is only editable if it is it is not coming from some trusted source */}
@@ -395,6 +433,15 @@ const GuestRegisterStep = forwardRef(
               {initialGuestData.authentication_method ===
                 AuthenticationMethod.Invite && (
                 <>
+                  <Typography variant="h5" sx={{ paddingTop: '1rem' }}>
+                    {t('guestRegisterWizardText.identityHeader')}
+                  </Typography>
+                  <Typography sx={{ paddingBottom: '1rem' }}>
+                    <Trans i18nKey="common:guestRegisterWizardText.identityBody">
+                      Placeholder with <strong>asd</strong> text
+                    </Trans>
+                    <Divider sx={{ border: '1px solid' }} />
+                  </Typography>
                   {/* The guest should fill in one of national ID number or passport number */}
                   <Controller
                     name="nationalIdNumber"
@@ -419,68 +466,54 @@ const GuestRegisterStep = forwardRef(
                       />
                     )}
                   />
-
-                  <Controller
-                    name="passportNumber"
-                    control={control}
-                    render={({ field }) => (
-                      <TextField
-                        id="passportNumber"
-                        data-testid="passport_number_input"
-                        value={field.value}
-                        label={t('input.passportNumber')}
-                        onChange={field.onChange}
-                      />
-                    )}
-                  />
-
-                  <Select
+                  <Box
                     sx={{
-                      maxHeight: '2.5rem',
-                    }}
-                    id="passport-nationality-id"
-                    labelId="passport-nationality-label"
-                    label={t('input.passportNationality')}
-                    displayEmpty
-                    value={passportNationality ?? ''}
-                    onChange={handlePassportNationalityChange}
-                    renderValue={(selected: any) => {
-                      if (!selected || selected.length === 0) {
-                        return t('input.passportNationality')
-                      }
-                      return getName(selected, i18n.language)
+                      display: 'flex',
+                      flexDirection: 'row',
                     }}
                   >
-                    <MenuItem disabled value="">
-                      {t('input.passportNationality')}
-                    </MenuItem>
-                    {Object.keys(getAlpha2Codes())
-                      .map((countryAlphaCode: string) => {
-                        const countryTuple: [string, string] = [
-                          countryAlphaCode,
-                          getName(countryAlphaCode, i18n.language),
-                        ]
-                        return countryTuple
-                      })
-                      .filter(
-                        (countryTuple: [string, string]) =>
-                          // All countries are expected to have a name, this filtering
-                          // is here to make some tests run in an environment where the
-                          // internationalization is not set up
-                          countryTuple[1] !== undefined
-                      )
-                      .sort(
-                        (
-                          countryTuple1: [string, string],
-                          countryTuple2: [string, string]
-                        ) => countryTuple1[1].localeCompare(countryTuple2[1])
-                      )
-                      .map((countryTuple) => (
-                        <MenuItem key={countryTuple[0]} value={countryTuple[0]}>
-                          {countryTuple[1]}
+                    <Select
+                      sx={{
+                        maxHeight: '2.5rem',
+                        minWidth: '5rem',
+                        marginRight: '0.5rem',
+                      }}
+                      id="passport-nationality-id"
+                      labelId="passport-nationality-label"
+                      label={t('input.passportNationality')}
+                      displayEmpty
+                      value={passportNationality ?? ''}
+                      onChange={handlePassportNationalityChange}
+                      renderValue={(selected: any) => {
+                        if (!selected || selected.length === 0) {
+                          return t('input.passportNationality')
+                        }
+                        return selected
+                      }}
+                    >
+                      <MenuItem disabled value="">
+                        {t('input.passportNationality')}
+                      </MenuItem>
+                      {passportCountries.map((countryTuple) => (
+                        <MenuItem key={countryTuple[1]} value={countryTuple[0]}>
+                          {`${countryTuple[1]} (${countryTuple[0]})`}
                         </MenuItem>
                       ))}
-                  </Select>
+                    </Select>
+                    <Controller
+                      name="passportNumber"
+                      control={control}
+                      render={({ field }) => (
+                        <TextField
+                          id="passportNumber"
+                          data-testid="passport_number_input"
+                          value={field.value}
+                          label={t('input.passportNumber')}
+                          onChange={field.onChange}
+                        />
+                      )}
+                    />
+                  </Box>
                   {idErrorState && (
                     <Typography color="error">{idErrorState}</Typography>
                   )}
@@ -502,6 +535,7 @@ const GuestRegisterStep = forwardRef(
               </Typography>
               <Typography sx={{ paddingBottom: '1rem' }}>
                 {t('guestRegisterWizardText.guestPeriodDescription')}
+                <Divider sx={{ border: '1px solid' }} />
               </Typography>
               <TextField
                 id="ou-unit"
-- 
GitLab