Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stepper QA #2 #1112

Merged
merged 6 commits into from
Nov 15, 2024
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
4 changes: 2 additions & 2 deletions __tests__/pages/questions.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ describe('index page', () => {
useRouter = jest.spyOn(nextRouter, 'useRouter')
useRouter.mockImplementation(() => ({
route: '/questions',
pathname: '/questions?income=20000',
query: { income: '20000' },
pathname: '/questions',
query: { income: '20000', step: 'marital' },
asPath: '',
locale: 'en',
locales: ['en', 'fr'],
Expand Down
2 changes: 1 addition & 1 deletion components/Layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export const Layout: React.VFC<{
logoAltText: tsln.logoAltText,
}}
/>
{router.pathname !== '/questions' && (
{!router.pathname.includes('/questions') && (
<>
<h1 id="applicationTitle" className="h1 mt-8 mb-2">
{title}
Expand Down
7 changes: 2 additions & 5 deletions components/ResultsPage/YourAnswers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import { MonthsYears } from '../../utils/api/definitions/types'
import { Accordion } from '../Forms/Accordion'
import { fieldDefinitions } from '../../utils/api/definitions/fields'
import { FieldCategory } from '../../utils/api/definitions/enums'
import { useSessionStorage } from 'react-use'
import { keyToStepMap } from '../StepperPage/utils'
import { useRouter } from 'next/router'

type CategorizedInputs = {
Expand All @@ -37,7 +35,6 @@ export const YourAnswers: React.VFC<{
})
return initialState
})
const [_activeStep, setActiveStep] = useSessionStorage('step')

const toggleAccordion = (category) => {
setAccordionStates((prevStates) => ({
Expand All @@ -61,8 +58,8 @@ export const YourAnswers: React.VFC<{

const handlePageChange = (key: string) => (e) => {
e.preventDefault()
setActiveStep(keyToStepMap[key] || 0)
router.push(`/questions#${key}`)
const category = fieldDefinitions[key]?.category?.key
router.push(`/questions?step=${category}#${key}`)
}

/**
Expand Down
32 changes: 29 additions & 3 deletions components/StepperPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,29 @@ interface StepperPageProps {
setPageTitle: (title: string) => void
}

const defaultStep = 'marital'
const formSteps = ['marital', 'age', 'income', 'residence']

const StepperPage: React.FC<StepperPageProps> = ({ setPageTitle }) => {
const router = useRouter()
const langx = useRouter().locale as Language
const language =
langx === Language.EN || langx === Language.FR ? langx : Language.EN

const tsln = useTranslation<WebTranslations>()

const { step } = router.query

useEffect(() => {
// Redirect to the default step if no step is specified or the step is invalid
if (
!step ||
typeof step !== 'string' ||
!Object.values(formSteps).includes(step)
) {
router.replace(`/questions?step=${defaultStep}`)
}
}, [])

const allFieldConfigs: FieldConfig[] = FieldsHandler.getAllFieldData(language)
const [inputs, setInputs]: [
FieldInputsObject,
Expand Down Expand Up @@ -112,7 +127,9 @@ const StepperPage: React.FC<StepperPageProps> = ({ setPageTitle }) => {

const [steps, setSteps] = useState(getSteps(tsln))
const totalSteps = Object.keys(steps).length
const [activeStep, setActiveStep] = useSessionStorage('step', 1)
const [activeStep, setActiveStep] = useState(
formSteps.indexOf(step as string) + 1
)
const [isLastStep, setIsLastStep] = useState(false)

const [errorsVisible, setErrorsVisible]: [
Expand Down Expand Up @@ -153,6 +170,10 @@ const StepperPage: React.FC<StepperPageProps> = ({ setPageTitle }) => {
setFieldsMetaData(getFieldsMetaData(activeStep))
}, [ageDate])

useEffect(() => {
setActiveStep(formSteps.indexOf(step as string) + 1)
}, [step])

useEffect(() => {
const focusedElement = document.activeElement
if (focusedElement instanceof HTMLButtonElement) {
Expand Down Expand Up @@ -398,6 +419,8 @@ const StepperPage: React.FC<StepperPageProps> = ({ setPageTitle }) => {
if (isLastStep) {
submitForm()
} else {
const nextStep = formSteps[activeStep]
router.push(`/questions?step=${nextStep}`)
setActiveStep(activeStep + 1)
}
} else {
Expand Down Expand Up @@ -425,7 +448,10 @@ const StepperPage: React.FC<StepperPageProps> = ({ setPageTitle }) => {
id: 'previous',
text: tsln.stepper.previousStep,
onClick: () => {
setActiveStep(Math.max(activeStep - 1, 1))
if (activeStep > 1) {
router.push(`/questions?step=${formSteps[activeStep - 2]}`)
setActiveStep(Math.max(activeStep - 1, 1))
}
},
}}
nextProps={{
Expand Down
4 changes: 2 additions & 2 deletions i18n/api/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,13 @@ const en: Translations = {
[FieldKey.INCOME_AVAILABLE]:
'Providing your income will give you more accurate results.',
[FieldKey.INCOME]:
'<p class="text-multi-neutrals-grey90a">Add all types of income after deductions, including:</p> <ul><li>pensions (including <dfn><abbr title="Canada Pension Plan">CPP</abbr></dfn> and <dfn><abbr title="Québec Pension Plan">QPP</abbr></dfn>)</li><li>benefits</li><li>salaries</li><li>retirement fund withdrawals (including <dfn><abbr title="Registered Retirement Savings Plans">RRSPs</abbr></dfn>).</li></ul> <p class="mt-4 text-multi-neutrals-grey90a">Do not include payments from the:</p> <ul><li>Old Age Security pension</li><li>Guaranteed Income Supplement</li><li>Allowance</li><li>Allowance for the Survivor</li></ul>',
'<p class="text-multi-neutrals-grey90a">Add all types of income after deductions, including:</p> <ul><li>pensions (including <dfn><abbr title="Canada Pension Plan">CPP</abbr></dfn> and <dfn><abbr title="Québec Pension Plan">QPP</abbr></dfn>)</li><li>benefits</li><li>salaries</li><li>retirement fund withdrawals (including <dfn><abbr title="Registered Retirement Savings Plans">RRSPs</abbr></dfn>)</li></ul> <p class="mt-4 text-multi-neutrals-grey90a">Do not include payments from the:</p> <ul><li>Old Age Security pension</li><li>Guaranteed Income Supplement</li><li>Allowance</li><li>Allowance for the Survivor</li></ul>',
[FieldKey.INCOME_WORK]:
'Enter any salary from a job or self-employment that you included in your annual net income. ',
[FieldKey.INV_SEPARATED]:
'For example, because your partner lives in a care home or lives in a separate home to be close to work or medical help.',
[FieldKey.PARTNER_INCOME]:
'<p class="text-multi-neutrals-grey90a">Add all types of income after deductions, including:</p> <ul><li>pensions (including <dfn><abbr title="Canada Pension Plan">CPP</abbr></dfn> and <dfn><abbr title="Québec Pension Plan">QPP</abbr></dfn>)</li><li>benefits</li><li>salaries</li><li>retirement fund withdrawals (including <dfn><abbr title="Registered Retirement Savings Plans">RRSPs</abbr></dfn>).</li></ul> <p class="mt-4 text-multi-neutrals-grey90a">Do not include payments from the:</p> <ul><li>Old Age Security pension</li><li>Guaranteed Income Supplement</li><li>Allowance</li><li>Allowance for the Survivor</li></ul>',
'<p class="text-multi-neutrals-grey90a">Add all types of income after deductions, including:</p> <ul><li>pensions (including <dfn><abbr title="Canada Pension Plan">CPP</abbr></dfn> and <dfn><abbr title="Québec Pension Plan">QPP</abbr></dfn>)</li><li>benefits</li><li>salaries</li><li>retirement fund withdrawals (including <dfn><abbr title="Registered Retirement Savings Plans">RRSPs</abbr></dfn>)</li></ul> <p class="mt-4 text-multi-neutrals-grey90a">Do not include payments from the:</p> <ul><li>Old Age Security pension</li><li>Guaranteed Income Supplement</li><li>Allowance</li><li>Allowance for the Survivor</li></ul>',
[FieldKey.PARTNER_INCOME_WORK]:
'Enter any salary from a job or self-employment that you included in your partner’s annual net income.',
[FieldKey.OAS_DEFER]:
Expand Down
2 changes: 1 addition & 1 deletion i18n/web/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ const en: WebTranslations = {
resultsPage: {
header: 'Table of estimated monthly amounts',
general:
'The following is only an estimate of your eligibility and monthly payments <strong>based on current rates</strong>. Amounts may increase with the cost of living. Changes in your circumstances may also impact your results.',
'The following is only an estimate of your eligibility and monthly payments <strong>based on current rates</strong>. Amounts may increase with the cost of living. <p class="mt-4">You must be a citizen or legal resident of Canada to receive these benefits.</p>',
onThisPage: 'On this page',
tableHeader1: 'Benefit',
tableHeader2: 'Estimated monthly amount (CAD)',
Expand Down
2 changes: 1 addition & 1 deletion i18n/web/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ const fr: WebTranslations = {
},
resultsPage: {
header: "Tableau des résultats d'estimation",
general: `Les résultats suivants ne sont qu'une estimation de votre admissibilité et de vos paiements mensuels <strong>basée sur les montants actuels</strong>. Ceux-ci peuvent augmenter avec le coût de la vie. Des changements dans votre situation pourraient aussi modifier vos résultats`,
general: `Les résultats suivants ne sont qu'une estimation de votre admissibilité et de vos paiements mensuels <strong>basée sur les montants actuels</strong>. Ceux-ci peuvent augmenter avec le coût de la vie. <p class="mt-4">Vous devez être citoyen ou résident autorisé du Canada pour recevoir ces prestations.</p>`,
onThisPage: 'Sur cette page',
tableHeader1: 'Prestations',
tableHeader2: 'Montant mensuel estimé (CAD)',
Expand Down
1 change: 0 additions & 1 deletion pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ const Home: NextPage<{ adobeAnalyticsUrl: string }> = ({
text={tsln.startBenefitsEstimator}
style="primary"
onClick={(e) => {
sessionStorage.setItem('step', '1')
router.push('/questions')
}}
custom="w-auto justify-center mb-4"
Expand Down
19 changes: 18 additions & 1 deletion pages/questions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ import { useRouter } from 'next/router'
import StepperPage from '../../components/StepperPage'
import React from 'react'

const defaultStep = 'marital' // Define the first step here
const steps = ['marital', 'age', 'income', 'residence']

const Stepper: NextPage<{ adobeAnalyticsUrl: string }> = ({
adobeAnalyticsUrl,
}) => {
const router = useRouter()
const tsln = useTranslation<WebTranslations>()
const language = useRouter().locale
const [pageTitle, setPageTitle] = useState(tsln.questionPageTitle)

useEffect(() => {
Expand All @@ -22,6 +25,20 @@ const Stepper: NextPage<{ adobeAnalyticsUrl: string }> = ({
}
}, []) // eslint-disable-line react-hooks/exhaustive-deps

const { step } = router.query

useEffect(() => {
// Redirect to the default step if no step is specified or the step is invalid
if (!step || typeof step !== 'string' || !steps.includes(step)) {
router.replace(`/questions?step=${defaultStep}`)
}
}, [step, router])

// Prevent rendering during redirect. Do not try to render when no step in URL.
if (!step || typeof step !== 'string' || !steps.includes(step)) {
return null
}

return (
<>
<Head>
Expand Down
6 changes: 3 additions & 3 deletions utils/api/benefitHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export class BenefitHandler {
this.rawInput.partnerLivingCountry
)

if (this.input.partner.age > partnerEliObj.ageOfEligibility) {
if (this.input.partner.age >= partnerEliObj.ageOfEligibility) {
if (this.input.partner.age < 75) {
this.input.partner.age = partnerEliObj.ageOfEligibility
this.input.partner.yearsInCanadaSince18 =
Expand All @@ -146,8 +146,8 @@ export class BenefitHandler {

if (this.input.client.receiveOAS && !this.input.client.livedOnlyInCanada) {
const yearsInCanada =
Number(this.input.client.yearsInCanadaSinceOAS) ||
Number(this.input.client.yearsInCanadaSince18)
Number(this.input.client.yearsInCanadaSince18) ||
Number(this.input.client.yearsInCanadaSinceOAS)
const oasDefer =
this.input.client.oasDeferDuration || '{"months":0, "years":0}'

Expand Down
15 changes: 6 additions & 9 deletions utils/api/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export function buildQuery(
partnerLockResidence
) {
const newQuery = { ...query }
const [userAge, partnerAge] = ageSet // 68, 65
const [userAge, partnerAge] = ageSet

// CLIENT
newQuery['age'] = String(userAge)
Expand Down Expand Up @@ -156,19 +156,16 @@ export function buildQuery(
addKeyValue(newQuery, 'partnerBenefitStatus', 'helpMe')
}

if (
query.partnerLivedOnlyInCanada === 'false' &&
query.partnerYearsInCanadaSince18
) {
const partnerRes =
query.partnerYearsInCanadaSince18 || query.partnerYearsInCanadaSinceOAS
if (query.partnerLivedOnlyInCanada === 'false' && partnerRes) {
const increaseResidence = !partnerAlreadyOasEligible
// const ageLimit = partnerAge < 65 ? 65 : partnerAge

const partnerNewYrsInCanada =
query.partnerLivingCountry === 'CAN'
? Number(partnerAge) -
Number(query.partnerAge) +
Number(query.partnerYearsInCanadaSince18)
: query.partnerYearsInCanadaSince18
? Number(partnerAge) - Number(query.partnerAge) + Number(partnerRes)
: partnerRes

newQuery['partnerYearsInCanadaSince18'] = String(
Math.floor(
Expand Down
Loading