Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
fbce6d0
content updates, minor refactors and tests
jack-ryan-nava-pbc Apr 28, 2023
6debd20
Whacking with linter
jack-ryan-nava-pbc Apr 28, 2023
7b1d9d8
changelog: User-facing improvements, In-person Proofing, Put Prepare …
jack-ryan-nava-pbc Apr 28, 2023
427f765
Fix verify info spec presentation order
jack-ryan-nava-pbc Apr 29, 2023
5419e34
Merge branch 'main' of github.com:18F/identity-idp into jryan/lg-8948…
jack-ryan-nava-pbc May 1, 2023
599cf3a
get rid of dirty ternary
jack-ryan-nava-pbc May 1, 2023
ae30a8a
Updating specs
jack-ryan-nava-pbc May 1, 2023
6fa61a3
remove unnecessary else statement
jack-ryan-nava-pbc May 2, 2023
d8e65fa
Merge branch 'main' of github.com:18F/identity-idp into jryan/lg-8948…
jack-ryan-nava-pbc May 3, 2023
607e114
use fsm for prepare step
jack-ryan-nava-pbc May 3, 2023
e76720e
appeasing linter
jack-ryan-nava-pbc May 3, 2023
6eddae3
adding prepare submit event to analytics and addressing tims questions
jack-ryan-nava-pbc May 4, 2023
7ed29d3
add back in space
jack-ryan-nava-pbc May 4, 2023
d08e591
Merge branch 'main' of github.com:18F/identity-idp into jryan/lg-8948…
jack-ryan-nava-pbc May 4, 2023
fc9c1ca
fix ordering of prepare and location steps in spec
jack-ryan-nava-pbc May 4, 2023
a6754e7
remove unnecessary useRef call
jack-ryan-nava-pbc May 4, 2023
9de64b1
Merge branch 'main' of github.com:18F/identity-idp into jryan/lg-8948…
jack-ryan-nava-pbc May 5, 2023
11394b6
update page order in spec
jack-ryan-nava-pbc May 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,16 @@ function DocumentCapture({ isAsyncForm = false, onStepChange = () => {} }: Docum
inPersonURL === undefined
? []
: ([
{
name: 'location',
form: InPersonLocationPostOfficeSearchStep,
title: t('in_person_proofing.headings.po_search.location'),
},
{
name: 'prepare',
form: InPersonPrepareStep,
title: t('in_person_proofing.headings.prepare'),
},
{
name: 'location',
form: InPersonLocationPostOfficeSearchStep,
title: t('in_person_proofing.headings.po_search.location'),
},
flowPath === 'hybrid' && {
name: 'switch_back',
form: InPersonSwitchBackStep,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function InPersonCallToAction({ altHeading, altPrompt, altButtonText }: InPerson
isWide
className="margin-top-3 margin-bottom-1"
onClick={() => {
setStepName('location');
setStepName('prepare');
trackEvent('IdV: verify in person troubleshooting option clicked', {
in_person_cta_variant: inPersonCtaVariantActive,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useState, useEffect, useCallback, useRef, useContext } from 'react';
import { useI18n } from '@18f/identity-react-i18n';
import { Alert, PageHeading } from '@18f/identity-components';
import { request } from '@18f/identity-request';
import { forceRedirect } from '@18f/identity-url';
import BackButton from './back-button';
import AnalyticsContext from '../context/analytics';
import AddressSearch, {
Expand All @@ -12,20 +13,22 @@ import AddressSearch, {
} from './address-search';
import InPersonLocations, { FormattedLocation } from './in-person-locations';
import { InPersonContext } from '../context';
import UploadContext from '../context/upload';

function InPersonLocationPostOfficeSearchStep({ onChange, toPreviousStep, registerField }) {
const { inPersonCtaVariantActive } = useContext(InPersonContext);
const { inPersonCtaVariantActive, inPersonURL } = useContext(InPersonContext);
const { t } = useI18n();
const [inProgress, setInProgress] = useState<boolean>(false);
const [isLoadingLocations, setLoadingLocations] = useState<boolean>(false);
const [autoSubmit, setAutoSubmit] = useState<boolean>(false);
const { setSubmitEventMetadata } = useContext(AnalyticsContext);
const { trackEvent } = useContext(AnalyticsContext);
const [locationResults, setLocationResults] = useState<FormattedLocation[] | null | undefined>(
null,
);
const [foundAddress, setFoundAddress] = useState<LocationQuery | null>(null);
const [apiError, setApiError] = useState<Error | null>(null);
const [disabledAddressSearch, setDisabledAddressSearch] = useState<boolean>(false);
const { flowPath } = useContext(UploadContext);

// ref allows us to avoid a memory leak
const mountedRef = useRef(false);
Expand All @@ -40,13 +43,12 @@ function InPersonLocationPostOfficeSearchStep({ onChange, toPreviousStep, regist
// useCallBack here prevents unnecessary rerenders due to changing function identity
const handleLocationSelect = useCallback(
async (e: any, id: number) => {
if (flowPath !== 'hybrid') {
e.preventDefault();
}
Comment on lines +46 to +48

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this related to what we were seeing in the hybrid test failures? Unsure what this is needed for.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, so as far as I can tell this is the one change that was breaking that test. I need to do more digging, but my understanding of the React FSM is that it's listening for submit events specifically. We were preventing that and then doing a click, so I think that was it.

const selectedLocation = locationResults![id]!;
const { streetAddress, formattedCityStateZip } = selectedLocation;
const selectedLocationAddress = `${streetAddress}, ${formattedCityStateZip}`;
setSubmitEventMetadata({
selected_location: selectedLocationAddress,
in_person_cta_variant: inPersonCtaVariantActive,
});
onChange({ selectedLocationAddress });
if (autoSubmit) {
setDisabledAddressSearch(true);
Expand All @@ -57,8 +59,6 @@ function InPersonLocationPostOfficeSearchStep({ onChange, toPreviousStep, regist
}, 250);
return;
}
// prevent navigation from continuing
e.preventDefault();
if (inProgress) {
return;
}
Expand All @@ -69,16 +69,22 @@ function InPersonLocationPostOfficeSearchStep({ onChange, toPreviousStep, regist
json: selected,
method: 'PUT',
});
// In try block set success of request. If the request is successful, fire remaining code?
if (mountedRef.current) {
setAutoSubmit(true);
setImmediate(() => {
// continue with navigation
e.target.disabled = false;
e.target.click();
trackEvent('IdV: location submitted', {
selected_location: selectedLocationAddress,
in_person_cta_variant: inPersonCtaVariantActive,
});
forceRedirect(inPersonURL!);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the behavior of these trackEvent and forceRedirect calls during hybrid flow?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good q. So trackEvent could get called twice, once on the typical submission event and then here at line 77. And then the forceRedirect behavior is probably being overridden.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Options: I could wrap the trackEvent and forceRedirect in an if check analogous to what I do for the event.preventDefault; or I could try to take advantage of the e.click() behavior that pre-existed my changes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opted for wrapping the forceRedirect trackEvent calls in an if check @NavaTim

// allow process to be re-triggered in case submission did not work as expected
setAutoSubmit(false);
});
}
} catch {
setAutoSubmit(false);
} finally {
if (mountedRef.current) {
setInProgress(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,52 +1,51 @@
import { useContext, useState } from 'react';
import type { MouseEventHandler } from 'react';
import { Alert, Link, PageHeading, ProcessList, ProcessListItem } from '@18f/identity-components';
import { Link, PageHeading, ProcessList, ProcessListItem } from '@18f/identity-components';
import { removeUnloadProtection } from '@18f/identity-url';
import { getConfigValue } from '@18f/identity-config';
import { useI18n } from '@18f/identity-react-i18n';
import { FormStepsButton } from '@18f/identity-form-steps';
import { SpinnerButton } from '@18f/identity-spinner-button';
import useHistoryParam from '@18f/identity-form-steps/use-history-param';
import UploadContext from '../context/upload';
import MarketingSiteContext from '../context/marketing-site';
import AnalyticsContext from '../context/analytics';
import BackButton from './back-button';
import InPersonTroubleshootingOptions from './in-person-troubleshooting-options';
import { InPersonContext } from '../context';

function InPersonPrepareStep({ toPreviousStep, value }) {
function InPersonPrepareStep({ toPreviousStep }) {
const { t } = useI18n();
const [isSubmitting, setIsSubmitting] = useState(false);
const { inPersonURL } = useContext(InPersonContext);
const { flowPath } = useContext(UploadContext);
const { trackEvent } = useContext(AnalyticsContext);
const { trackEvent, setSubmitEventMetadata } = useContext(AnalyticsContext);
const { securityAndPrivacyHowItWorksURL } = useContext(MarketingSiteContext);
const { selectedLocationAddress } = value;
const [, setStepName] = useHistoryParam(undefined);
const { inPersonURL, inPersonCtaVariantActive } = useContext(InPersonContext);

const onContinue: MouseEventHandler = async (event) => {
const onContinue: MouseEventHandler = (event) => {
event.preventDefault();

if (!isSubmitting) {
setIsSubmitting(true);
removeUnloadProtection();
await trackEvent('IdV: prepare submitted');
window.location.href = inPersonURL!;
setSubmitEventMetadata({ in_person_cta_variant: inPersonCtaVariantActive });
trackEvent('IdV: prepare submitted');
setStepName('location');
}
};

return (
<>
{selectedLocationAddress && (
<Alert type="success" className="margin-bottom-4">
{t('in_person_proofing.body.prepare.alert_selected_post_office', {
full_address: selectedLocationAddress,
})}
</Alert>
)}
<PageHeading>{t('in_person_proofing.headings.prepare')}</PageHeading>

<p>{t('in_person_proofing.body.prepare.verify_step_about')}</p>

<ProcessList className="margin-bottom-4">
<ProcessListItem
heading={t('in_person_proofing.body.prepare.verify_step_post_office')}
headingUnstyled
/>
<ProcessListItem
heading={t('in_person_proofing.body.prepare.verify_step_enter_pii')}
headingUnstyled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ function InPersonTroubleshootingOptions({
text: t('idv.troubleshooting.options.learn_more_verify_in_person'),
isExternal: true,
},
{
url: getHelpCenterURL({
category: 'verify-your-identity',
article: 'phone-number',
location,
}),
text: t('idv.troubleshooting.options.learn_more_verify_by_phone_in_person'),
isExternal: true,
},
spName && {
url: getFailureToProofURL(location),
text: t('idv.troubleshooting.options.get_help_at_sp', { sp_name: spName }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ function ReviewIssuesStep({
actionOnClick={onWarningPageDismissed}
altActionText={t('in_person_proofing.body.cta.button_variant')}
altActionOnClick={onInPersonSelected}
altHref="#location"
altHref="#prepare"
location="doc_auth_review_issues"
remainingAttempts={remainingAttempts}
troubleshootingOptions={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type AnalyticsContextProviderProps = Pick<AnalyticsContextValue, 'trackEvent'> &

const DEFAULT_EVENT_METADATA: Record<string, any> = {};

export const LOGGED_STEPS: string[] = ['location', 'prepare', 'switch_back'];
export const LOGGED_STEPS: string[] = ['prepare', 'location', 'switch_back'];

const AnalyticsContext = createContext<AnalyticsContextValue>({
trackEvent: () => Promise.resolve(),
Expand All @@ -71,7 +71,7 @@ export function AnalyticsContextProvider({ children, trackEvent }: AnalyticsCont

const extraAnalyticsAttributes = (stepName) => {
const extra: EventMetadata = { ...DEFAULT_EVENT_METADATA };
if (stepName === 'location') {
if (stepName === 'prepare' || stepName === 'location') {
extra.in_person_cta_variant = inPersonCtaVariantActive;
}
return extra;
Expand Down
3 changes: 1 addition & 2 deletions app/javascript/packages/form-steps/form-steps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -396,14 +396,13 @@ function FormSteps({
}

onStepSubmit(step?.name);

const nextStepIndex = stepIndex + 1;
const isComplete =
stepCanComplete !== undefined ? stepCanComplete : nextStepIndex === steps.length;
if (isComplete) {
onComplete(values);
} else {
const { name: nextStepName } = steps[nextStepIndex];
const { name: nextStepName } = steps[nextStepIndex] ?? steps[steps.length - 1];
Comment thread
JackRyan1989 marked this conversation as resolved.
Outdated
setStepName(nextStepName);
}
// unset stepCanComplete so the next step that needs to can set it
Expand Down
1 change: 1 addition & 0 deletions config/locales/idv/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ en:
learn_more_address_verification_options: Learn more about verifying by phone or mail
learn_more_verify_by_mail: Learn more about verifying your address by mail
learn_more_verify_by_phone: Learn more about what phone number to use
learn_more_verify_by_phone_in_person: Learn more about verifying your phone number
learn_more_verify_in_person: Learn more about verifying in person
supported_documents: See a list of accepted state‑issued IDs
verify_by_mail: Verify your address by mail instead
Expand Down
1 change: 1 addition & 0 deletions config/locales/idv/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ es:
learn_more_verify_by_mail: Obtenga más información sobre la verificación de su
dirección por correo
learn_more_verify_by_phone: Más información sobre qué número de teléfono usar
learn_more_verify_by_phone_in_person: Más información sobre cómo verificar su número de teléfono
learn_more_verify_in_person: Más información sobre la verificación en persona
supported_documents: Vea la lista de documentos de identidad emitidos por el
estado que son aceptados
Expand Down
1 change: 1 addition & 0 deletions config/locales/idv/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ fr:
learn_more_address_verification_options: En savoir plus sur la vérification par téléphone ou par courrier
learn_more_verify_by_mail: En savoir plus sur la vérification de votre adresse par courrier
learn_more_verify_by_phone: Apprenez-en plus sur quel numéro de téléphone utiliser
learn_more_verify_by_phone_in_person: En savoir plus sur la vérification de votre numéro de téléphone
learn_more_verify_in_person: En savoir plus sur la vérification en personne
supported_documents: Voir la liste des pièces d’identité acceptées et délivrées par l’État
verify_by_mail: Vérifiez plutôt votre adresse par courrier
Expand Down
6 changes: 3 additions & 3 deletions config/locales/in_person_proofing/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ en:
%{address}.
none_found_tip: You can search using a different address, or add photos of your
ID to try and verify your identity online again.
po_search_about: If you are having trouble adding your ID, you may be able to
verify your identity in person at a local United States Post Office.
po_search_about: You can verify your identity in person at a local participating
United States Post Office.
results_description:
one: There is one participating Post Office within 50 miles of %{address}.
other: There are %{count} participating Post Offices within 50 miles of
Expand All @@ -66,7 +66,6 @@ en:
retail_hours_weekday: 'Monday to Friday:'
selection: 'This is the location you selected:'
prepare:
alert_selected_post_office: You’ve selected the Post Office at %{full_address}.
privacy_disclaimer: '%{app_name} is a secure, government website. We and the
U.S. Postal Service use your data to verify your identity.'
privacy_disclaimer_link: Learn more about privacy and security.
Expand All @@ -76,6 +75,7 @@ en:
verify_step_enter_phone: Enter your primary phone number or the number that you use most often.
verify_step_enter_pii: Enter your name, date of birth, state‑issued ID number,
address and Social Security number.
verify_step_post_office: Find a participating Post Office near you.
state_id:
alert_message: 'Your state‑issued ID must not be expired. Accepted forms of ID are:'
id_types:
Expand Down
2 changes: 1 addition & 1 deletion config/locales/in_person_proofing/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ es:
retail_hours_weekday: 'De Lunes a Viernes:'
selection: 'Esta es la oficina que seleccionó:'
prepare:
Comment thread
JackRyan1989 marked this conversation as resolved.
alert_selected_post_office: Ha seleccionado la oficina de correos a %{full_address}.
privacy_disclaimer: '%{app_name} es un sitio web seguro del gobierno. Nosotros y
el Servicio Postal de los Estados Unidos utilizamos sus datos para
verificar su identidad.'
Expand All @@ -86,6 +85,7 @@ es:
verify_step_enter_pii: Ingrese su nombre, fecha de nacimiento, número de
identificación emitido por el estado, dirección y número de la
Seguridad Social.
verify_step_post_office: Encuentre una Oficina de Correos participantes cercana a usted.
state_id:
alert_message: 'Su identificación emitida por el estado no debe estar vencida.
Se aceptan las siguientes formas de identificación:'
Expand Down
7 changes: 3 additions & 4 deletions config/locales/in_person_proofing/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,8 @@ fr:
none_found_tip: Vous pouvez effectuer une recherche en utilisant une autre
adresse, ou ajouter des photos de votre pièce d’identité pour
essayer de vérifier à nouveau votre identité en ligne.
po_search_about: Si vous avez des difficultés à ajouter votre pièce d’identité,
vous pouvez vérifier votre identité en personne dans un bureau de
poste américain proche.
po_search_about: Vous pouvez vérifier votre identité en personne dans un bureau
de poste américain local participant.
results_description:
one: Il y a 1 bureau de poste participant dans un rayon de 50 miles autour de
%{address}.
Expand All @@ -74,7 +73,6 @@ fr:
retail_hours_weekday: 'Lundi à Vendredi:'
selection: 'Il s’agit du bureau que vous avez sélectionné:'
prepare:
alert_selected_post_office: Vous avez sélectionné le bureau de poste à %{full_address}.
privacy_disclaimer: '%{app_name} est un site gouvernemental sécurisé. Nous et le
service postal américain utilisons vos données pour vérifier votre
identité.'
Expand All @@ -87,6 +85,7 @@ fr:
verify_step_enter_pii: Saisissez votre nom, votre date de naissance, votre
document d’identité délivré par l’État, votre adresse et votre numéro
de sécurité sociale.
verify_step_post_office: Trouver un bureau de poste participant.
state_id:
alert_message: 'Votre carte d’identité délivrée par l’État ne doit pas être
périmée. Les pièces d’identité acceptées sont:'
Expand Down
Loading