Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
@@ -0,0 +1,35 @@
import { render } from '@testing-library/react';
import { StepStatus } from '@18f/identity-step-indicator';
import VerifyFlowStepIndicator, { getStepStatus } from './verify-flow-step-indicator';

describe('getStepStatus', () => {
it('returns incomplete if step is after current step', () => {
const result = getStepStatus(1, 0);

expect(result).to.equal(StepStatus.INCOMPLETE);
});

it('returns current if step is current step', () => {
const result = getStepStatus(1, 1);

expect(result).to.equal(StepStatus.CURRENT);
});

it('returns complete if step is before current step', () => {
const result = getStepStatus(0, 1);

expect(result).to.equal(StepStatus.COMPLETE);
});
});

describe('VerifyFlowStepIndicator', () => {
it('renders step indicator for the current step', () => {
const { getByText } = render(<VerifyFlowStepIndicator currentStep="personal_key" />);

const current = getByText('step_indicator.flows.idv.secure_account');
expect(current.closest('.step-indicator__step--current')).to.exist();

const previous = getByText('step_indicator.flows.idv.verify_phone_or_address');
expect(previous.closest('.step-indicator__step--complete')).to.exist();
});
});
80 changes: 80 additions & 0 deletions app/javascript/packages/verify-flow/verify-flow-step-indicator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { StepIndicator, StepIndicatorStep, StepStatus } from '@18f/identity-step-indicator';
import { t } from '@18f/identity-i18n';

// i18n-tasks-use t('step_indicator.flows.idv.getting_started')
// i18n-tasks-use t('step_indicator.flows.idv.verify_id')
// i18n-tasks-use t('step_indicator.flows.idv.verify_info')
// i18n-tasks-use t('step_indicator.flows.idv.verify_phone_or_address')
// i18n-tasks-use t('step_indicator.flows.idv.secure_account')

type VerifyFlowStepIndicatorStep =
| 'getting_started'
| 'verify_id'
| 'verify_info'
| 'verify_phone_or_address'
| 'secure_account';

/**
* Mapping of flow form steps to corresponding step indicator step.
*/
const FLOW_STEP_STEP_MAPPING: Record<string, VerifyFlowStepIndicatorStep> = {
personal_key: 'secure_account',
personal_key_confirm: 'secure_account',
};

/**
* Sequence of step indicator steps.
*/
const STEP_INDICATOR_STEPS: VerifyFlowStepIndicatorStep[] = [
'getting_started',
'verify_id',
'verify_info',
'verify_phone_or_address',
'secure_account',
];

interface VerifyFlowStepIndicatorProps {
/**
* Current step name.
*/
currentStep: string;
}

/**
* Given an index of a step and the current step index, returns the status of the step relative to
* the current step.
*
* @param index Index of step against which to compare current step.
* @param currentStepIndex Index of current step.
*
* @return Step status.
*/
export function getStepStatus(index, currentStepIndex): StepStatus {
if (index === currentStepIndex) {
return StepStatus.CURRENT;
}

if (index < currentStepIndex) {
return StepStatus.COMPLETE;
}

return StepStatus.INCOMPLETE;
}

function VerifyFlowStepIndicator({ currentStep }: VerifyFlowStepIndicatorProps) {
const currentStepIndex = STEP_INDICATOR_STEPS.indexOf(FLOW_STEP_STEP_MAPPING[currentStep]);

return (
<StepIndicator className="margin-x-neg-2 margin-top-neg-4 tablet:margin-x-neg-6 tablet:margin-top-neg-4">
{STEP_INDICATOR_STEPS.map((step, index) => (
<StepIndicatorStep
key={step}
title={t(`step_indicator.flows.idv.${step}`)}
status={getStepStatus(index, currentStepIndex)}
/>
))}
</StepIndicator>
);
}

export default VerifyFlowStepIndicator;
20 changes: 8 additions & 12 deletions app/javascript/packages/verify-flow/verify-flow.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { FormSteps } from '@18f/identity-form-steps';
import { StepIndicator, StepIndicatorStep, StepStatus } from '@18f/identity-step-indicator';
import { t } from '@18f/identity-i18n';
import { Alert } from '@18f/identity-components';
import { trackEvent } from '@18f/identity-analytics';
import VerifyFlowStepIndicator from './verify-flow-step-indicator';
import { STEPS } from './steps';

export interface VerifyFlowValues {
Expand Down Expand Up @@ -67,9 +67,11 @@ export function VerifyFlow({
appName,
onComplete,
}: VerifyFlowProps) {
const [currentStep, setCurrentStep] = useState(STEPS[0].name);

useEffect(() => {
logStepVisited(STEPS[0].name);
}, []);
logStepVisited(currentStep);
}, [currentStep]);

let steps = STEPS;
if (enabledStepNames) {
Expand All @@ -78,13 +80,7 @@ export function VerifyFlow({

return (
<>
<StepIndicator className="margin-x-neg-2 margin-top-neg-4 tablet:margin-x-neg-6 tablet:margin-top-neg-4">
<StepIndicatorStep title="Getting Started" status={StepStatus.COMPLETE} />
<StepIndicatorStep title="Verify your ID" status={StepStatus.COMPLETE} />
<StepIndicatorStep title="Verify your personal details" status={StepStatus.COMPLETE} />
<StepIndicatorStep title="Verify phone or address" status={StepStatus.COMPLETE} />
<StepIndicatorStep title="Secure your account" status={StepStatus.CURRENT} />
</StepIndicator>
<VerifyFlowStepIndicator currentStep={currentStep} />
<Alert type="success" className="margin-bottom-4">
{t('idv.messages.confirm')}
</Alert>
Expand All @@ -95,7 +91,7 @@ export function VerifyFlow({
basePath={basePath}
titleFormat={`%{step} - ${appName}`}
onStepSubmit={logStepSubmitted}
onStepChange={logStepVisited}
onStepChange={setCurrentStep}
onComplete={onComplete}
/>
</>
Expand Down