diff --git a/app/controllers/verify_controller.rb b/app/controllers/verify_controller.rb index 2dd69f93193..b60c4f9968a 100644 --- a/app/controllers/verify_controller.rb +++ b/app/controllers/verify_controller.rb @@ -3,5 +3,15 @@ class VerifyController < ApplicationController check_or_render_not_found -> { IdentityConfig.store.idv_api_enabled }, only: [:show] - def show; end + def show + @app_data = app_data + end + + private + + def app_data + { + initial_values: { 'personalKey' => '0000-0000-0000-0000' }, + } + end end diff --git a/app/javascript/packages/form-steps/form-steps.spec.tsx b/app/javascript/packages/form-steps/form-steps.spec.tsx index e285ac112f5..bc3466eed0d 100644 --- a/app/javascript/packages/form-steps/form-steps.spec.tsx +++ b/app/javascript/packages/form-steps/form-steps.spec.tsx @@ -218,6 +218,18 @@ describe('FormSteps', () => { expect(event.returnValue).to.be.true(); }); + context('promptOnNavigate prop is set to false', () => { + it('does not prompt on navigate', () => { + render(); + + const event = new window.Event('beforeunload', { cancelable: true, bubbles: false }); + window.dispatchEvent(event); + + expect(event.defaultPrevented).to.be.false(); + expect(event.returnValue).to.be.true(); + }); + }); + it('pushes step to URL', () => { const { getByText } = render(); diff --git a/app/javascript/packages/form-steps/form-steps.tsx b/app/javascript/packages/form-steps/form-steps.tsx index fd85c979560..de5d15b1420 100644 --- a/app/javascript/packages/form-steps/form-steps.tsx +++ b/app/javascript/packages/form-steps/form-steps.tsx @@ -125,6 +125,12 @@ interface FormStepsProps { * Callback triggered on step change. */ onStepChange?: () => void; + + /** + * Whether to prompt the user about unsaved changes when navigating away from an in-progress form. + * Defaults to true. + */ + promptOnNavigate?: boolean; } /** @@ -164,6 +170,7 @@ function FormSteps({ initialValues = {}, initialActiveErrors = [], autoFocus, + promptOnNavigate = true, }: FormStepsProps) { const [values, setValues] = useState(initialValues); const [activeErrors, setActiveErrors] = useState(initialActiveErrors); @@ -278,7 +285,7 @@ function FormSteps({ return (
- {Object.keys(values).length > 0 && } + {promptOnNavigate && Object.keys(values).length > 0 && } {stepErrors.map((error) => ( {error.message} diff --git a/app/javascript/packages/verify-flow/index.tsx b/app/javascript/packages/verify-flow/index.tsx index ab6998d8e5a..231fdb83107 100644 --- a/app/javascript/packages/verify-flow/index.tsx +++ b/app/javascript/packages/verify-flow/index.tsx @@ -1,6 +1,14 @@ import { FormSteps } from '@18f/identity-form-steps'; import { STEPS } from './steps'; -export function VerifyFlow() { - return ; +export interface VerifyFlowValues { + personalKey?: string; +} + +interface VerifyFlowProps { + initialValues?: Partial; +} + +export function VerifyFlow({ initialValues = {} }: VerifyFlowProps) { + return ; } diff --git a/app/javascript/packages/verify-flow/steps/personal-key/personal-key-step.tsx b/app/javascript/packages/verify-flow/steps/personal-key/personal-key-step.tsx index dea2992bca1..9e66aac0936 100644 --- a/app/javascript/packages/verify-flow/steps/personal-key/personal-key-step.tsx +++ b/app/javascript/packages/verify-flow/steps/personal-key/personal-key-step.tsx @@ -1,13 +1,43 @@ import { PageHeading, Button } from '@18f/identity-components'; import { t } from '@18f/identity-i18n'; +import { formatHTML } from '@18f/identity-react-i18n'; import { FormStepsContinueButton } from '@18f/identity-form-steps'; +import type { FormStepComponentProps } from '@18f/identity-form-steps'; +import type { VerifyFlowValues } from '../..'; + +interface PersonalKeyStepProps extends FormStepComponentProps {} + +function PersonalKeyStep({ value }: PersonalKeyStepProps) { + const personalKey = value.personalKey!; -function PersonalKeyStep() { return ( <> {t('headings.personal_key')}

{t('instructions.personal_key.info')}

-
+
+
+

{t('users.personal_key.header')}

+
+
+ {personalKey.split('-').map((segment) => ( + + {segment} + + ))} +
+
+

+ {formatHTML( + t('users.personal_key.generated_on_html', { + date: `${new Intl.DateTimeFormat([], { + dateStyle: 'long', + }).format()}`, + }), + { strong: 'strong' }, + )} +

+
+
diff --git a/app/javascript/packs/verify-flow.tsx b/app/javascript/packs/verify-flow.tsx index c278366cc4f..32a0f51a014 100644 --- a/app/javascript/packs/verify-flow.tsx +++ b/app/javascript/packs/verify-flow.tsx @@ -2,4 +2,9 @@ import { render } from 'react-dom'; import { VerifyFlow } from '@18f/identity-verify-flow'; const appRoot = document.getElementById('app-root')!; -render(, appRoot); +let initialValues; +try { + initialValues = JSON.parse(appRoot.dataset.initialValues!); +} catch {} + +render(, appRoot); diff --git a/app/views/verify/show.html.erb b/app/views/verify/show.html.erb index 64cc1697522..6757719b1a4 100644 --- a/app/views/verify/show.html.erb +++ b/app/views/verify/show.html.erb @@ -1,2 +1,2 @@ -
+<%= content_tag(:div, '', id: 'app-root', data: @app_data) %> <% javascript_packs_tag_once 'verify-flow' %>