diff --git a/apps/protoform/src/app/credit-cards/address/page.tsx b/apps/protoform/src/app/credit-cards/address/page.tsx index 84da25774..041cfab7b 100644 --- a/apps/protoform/src/app/credit-cards/address/page.tsx +++ b/apps/protoform/src/app/credit-cards/address/page.tsx @@ -7,6 +7,7 @@ import { FormEvent, useEffect, useState } from 'react'; import { BackButton } from '@/components/back-button/back-button'; import { Cta } from '@/components/cta/cta'; import { CustomHeading } from '@/components/custom-heading/custom-heading'; +import { ErrorValidationAlert, ValidationErrorType } from '@/components/error-validation-alert/error-validation-alert'; import { useSidebar } from '@/components/sidebar/context'; import { defaultError } from '@/constants/form-contsants'; import { getFormData } from '@/utils/getFormData'; @@ -18,6 +19,7 @@ export default function Address() { const { data, setData } = useCreditCard(); const [addressError, setAddressError] = useState(''); const [housingLengthError, setHousingLengthError] = useState(''); + const [validationErrors, setValidationErrors] = useState([]); const handleSubmit = (e: FormEvent) => { e.preventDefault(); @@ -25,6 +27,10 @@ export default function Address() { if (!address || !housingLength) { setAddressError(!address ? defaultError : ''); setHousingLengthError(!housingLength ? defaultError : ''); + setValidationErrors([ + ...(!address ? [{ id: 'address', label: 'Address' }] : []), + ...(!housingLength ? [{ id: 'housingLength', label: 'Housing length' }] : []), + ]); } else { setData({ ...data, address, housingLength }); router.push('/credit-cards/review-and-submit'); @@ -40,11 +46,14 @@ export default function Address() { return (
router.push('/credit-cards/name-and-contact')}>Back to Name & contact - Address -
+ + Address + + {validationErrors.length >= 1 && } + - + - + )} - router.push('/credit-cards/home-life')} - secondary="Back" - tertiaryOnClick={() => router.push('/')} - tertiary="Cancel" - > + router.push('/')} tertiary="Cancel"> Next diff --git a/apps/protoform/src/app/credit-cards/home-life/page.tsx b/apps/protoform/src/app/credit-cards/home-life/page.tsx index 8b2ebd23c..9581ff118 100644 --- a/apps/protoform/src/app/credit-cards/home-life/page.tsx +++ b/apps/protoform/src/app/credit-cards/home-life/page.tsx @@ -7,6 +7,7 @@ import { FormEvent, useEffect, useState } from 'react'; import { BackButton } from '@/components/back-button/back-button'; import { Cta } from '@/components/cta/cta'; import { CustomHeading } from '@/components/custom-heading/custom-heading'; +import { ErrorValidationAlert, ValidationErrorType } from '@/components/error-validation-alert/error-validation-alert'; import { useSidebar } from '@/components/sidebar/context'; import { defaultError } from '@/constants/form-contsants'; import { getFormData } from '@/utils/getFormData'; @@ -22,7 +23,9 @@ export default function HomeLife() { const [housingError, setHousingError] = useState(''); const [sharedExpensesError, setSharedExpensesError] = useState(''); const [sharedExpenses, setSharedExpenses] = useState(''); + const [validationErrors, setValidationErrors] = useState([]); + // eslint-disable-next-line sonarjs/cognitive-complexity const handleSubmit = (e: FormEvent) => { e.preventDefault(); const { housing, dependants, expenseFreq, expenses } = getFormData(e.currentTarget) as { @@ -38,6 +41,13 @@ export default function HomeLife() { setExpenseFreqError(!expenseFreq ? defaultError : ''); setExpensesError(!expenses ? defaultError : ''); setSharedExpensesError(!sharedExpenses ? defaultError : ''); + setValidationErrors([ + ...(!housing ? [{ id: 'housing', label: 'Housing situation' }] : []), + ...(!dependants ? [{ id: 'dependants', label: 'Dependants' }] : []), + ...(!expenseFreq ? [{ id: 'expenseFreq', label: 'Expense frequency' }] : []), + ...(!expenses ? [{ id: 'expenses', label: 'Expenses' }] : []), + ...(!sharedExpenses ? [{ id: 'sharedExpenses', label: 'Shared expenses' }] : []), + ]); } else { setData({ ...data, housing, dependants, expenseFreq, expenses, sharedExpenses }); router.push('/credit-cards/credit-limit'); @@ -53,11 +63,19 @@ export default function HomeLife() { return (
router.push('/credit-cards/loans-and-cards')}>Back to Loans and cards - Home life -
+ + Home life + + {validationErrors.length >= 1 && } + - + + } > @@ -120,13 +145,7 @@ export default function HomeLife() { - router.push('/credit-cards/loans-and-cards')} - secondary="Back" - tertiaryOnClick={() => router.push('/')} - tertiary="Cancel" - > + router.push('/')} tertiary="Cancel"> Next diff --git a/apps/protoform/src/app/credit-cards/income-and-savings/page.tsx b/apps/protoform/src/app/credit-cards/income-and-savings/page.tsx index 5bd4b248b..33bbded3b 100644 --- a/apps/protoform/src/app/credit-cards/income-and-savings/page.tsx +++ b/apps/protoform/src/app/credit-cards/income-and-savings/page.tsx @@ -7,6 +7,7 @@ import { FormEvent, useEffect, useState } from 'react'; import { BackButton } from '@/components/back-button/back-button'; import { Cta } from '@/components/cta/cta'; import { CustomHeading } from '@/components/custom-heading/custom-heading'; +import { ErrorValidationAlert, ValidationErrorType } from '@/components/error-validation-alert/error-validation-alert'; import { useSidebar } from '@/components/sidebar/context'; import { defaultError } from '@/constants/form-contsants'; import { getFormData } from '@/utils/getFormData'; @@ -19,6 +20,7 @@ export default function IncomeAndSavings() { const [incomeError, setIncomeError] = useState(''); const [freqError, setFreqError] = useState(''); const [balanceError, setBalanceError] = useState(''); + const [validationErrors, setValidationErrors] = useState([]); const handleSubmit = (e: FormEvent) => { e.preventDefault(); @@ -31,6 +33,11 @@ export default function IncomeAndSavings() { setIncomeError(!income ? defaultError : ''); setBalanceError(!totalBal ? defaultError : ''); setFreqError(!incomeFreq ? defaultError : ''); + setValidationErrors([ + ...(!totalBal ? [{ id: 'totalBal', label: 'Total balances in savings / investment accounts' }] : []), + ...(!income ? [{ id: 'income', label: 'Income / salary / pension' }] : []), + ...(!incomeFreq ? [{ id: 'incomeFreq', label: 'Income frequency' }] : []), + ]); } else { setData({ ...data, totalBal, incomeFreq, income }); router.push('/credit-cards/loans-and-cards'); @@ -46,8 +53,11 @@ export default function IncomeAndSavings() { return (
router.push('/credit-cards')}>Back to Quick contact - Income & savings -
+ + Income & savings + + {validationErrors.length >= 1 && } + @@ -55,13 +65,14 @@ export default function IncomeAndSavings() { label="Income / salary / pension (after tax)" hint="Enter a dollar value and choose a frequency" errorMessage={incomeError || freqError} + instanceId="income" before="$" after={ - - + + - } size="large" @@ -76,6 +87,7 @@ export default function IncomeAndSavings() { size="large" label="Total balances in savings / investment accounts (if any)" hint="Enter a dollar value" + instanceId="totalBal" errorMessage={balanceError} before="$" > @@ -83,13 +95,7 @@ export default function IncomeAndSavings() { - router.push('/credit-cards')} - secondary="Back" - tertiaryOnClick={() => router.push('/')} - tertiary="Cancel" - > + router.push('/')} tertiary="Cancel"> Next diff --git a/apps/protoform/src/app/credit-cards/loans-and-cards/page.tsx b/apps/protoform/src/app/credit-cards/loans-and-cards/page.tsx index 18259e30a..5d3c45fab 100644 --- a/apps/protoform/src/app/credit-cards/loans-and-cards/page.tsx +++ b/apps/protoform/src/app/credit-cards/loans-and-cards/page.tsx @@ -7,6 +7,7 @@ import { FormEvent, useEffect, useState } from 'react'; import { BackButton } from '@/components/back-button/back-button'; import { Cta } from '@/components/cta/cta'; import { CustomHeading } from '@/components/custom-heading/custom-heading'; +import { ErrorValidationAlert, ValidationErrorType } from '@/components/error-validation-alert/error-validation-alert'; import { useSidebar } from '@/components/sidebar/context'; import { defaultError } from '@/constants/form-contsants'; import { getFormData } from '@/utils/getFormData'; @@ -21,7 +22,9 @@ export default function IncomeAndSavings() { const [repaymentFrequencyError, setRepaymentFrequencyError] = useState(''); const [totalBalanceError, setTotalBalanceError] = useState(''); const [otherCards, setOtherCards] = useState(''); + const [validationErrors, setValidationErrors] = useState([]); + // eslint-disable-next-line sonarjs/cognitive-complexity const handleSubmit = (e: FormEvent) => { e.preventDefault(); const { repaymentFreq, repayments, totalBal } = getFormData(e.currentTarget) as { @@ -34,6 +37,14 @@ export default function IncomeAndSavings() { setRepaymentsError(!repayments ? defaultError : ''); setTotalBalanceError(otherCards === 'Yes' && !totalBal ? defaultError : ''); setOtherCardError(!otherCards ? defaultError : ''); + setValidationErrors([ + ...(!repaymentFreq ? [{ id: 'repaymentFreq', label: 'Repayment frequency' }] : []), + ...(!repayments ? [{ id: 'repayments', label: 'Your loan repayments' }] : []), + ...(otherCards === 'Yes' && !totalBal + ? [{ id: 'totalBal', label: 'Total balances of non-Westpac cards' }] + : []), + ...(!otherCards ? [{ id: 'otherCards', label: 'Do you have any non-Westpac credit cards?' }] : []), + ]); } else { setData({ ...data, repaymentFreq, repayments, totalBal, nonWestpacCards: otherCards }); router.push('/credit-cards/home-life'); @@ -51,21 +62,30 @@ export default function IncomeAndSavings() { router.push('/credit-cards/income-and-savings')}> Back to Income and savings - Loans & cards -
+ + Loans & cards + + {validationErrors.length >= 1 && } + + } size="large" @@ -79,6 +99,7 @@ export default function IncomeAndSavings() { label="Do you have any non-Westpac credit cards?" hintMessage="Including store and charge cards, lines of credit" size="large" + id="otherCards" block={{ initial: true, md: false }} errorMessage={otherCardError} defaultValue={data.nonWestpacCards} @@ -92,6 +113,7 @@ export default function IncomeAndSavings() { {otherCards === 'Yes' && ( )} - router.push('/credit-cards/income-and-savings')} - secondary="Back" - tertiaryOnClick={() => router.push('/')} - tertiary="Cancel" - > + router.push('/')} tertiary="Cancel"> Next diff --git a/apps/protoform/src/app/credit-cards/name-and-contact/page.tsx b/apps/protoform/src/app/credit-cards/name-and-contact/page.tsx index dce4edf57..3fd112b85 100644 --- a/apps/protoform/src/app/credit-cards/name-and-contact/page.tsx +++ b/apps/protoform/src/app/credit-cards/name-and-contact/page.tsx @@ -7,6 +7,7 @@ import { FormEvent, useEffect, useState } from 'react'; import { BackButton } from '@/components/back-button/back-button'; import { Cta } from '@/components/cta/cta'; import { CustomHeading } from '@/components/custom-heading/custom-heading'; +import { ErrorValidationAlert, ValidationErrorType } from '@/components/error-validation-alert/error-validation-alert'; import { useSidebar } from '@/components/sidebar/context'; import { defaultError } from '@/constants/form-contsants'; import { getFormData } from '@/utils/getFormData'; @@ -23,6 +24,7 @@ export default function NameAndContact() { const [dobMonthError, setDobMonthError] = useState(''); const [dobYearError, setDobYearError] = useState(''); const [mobileError, setMobileError] = useState(''); + const [validationErrors, setValidationErrors] = useState([]); // eslint-disable-next-line sonarjs/cognitive-complexity const handleSubmit = (e: FormEvent) => { @@ -47,6 +49,13 @@ export default function NameAndContact() { setDobMonthError(!dobMonth ? defaultError : ''); setDobYearError(!dobYear ? defaultError : ''); setMobileError(!mobileNumber ? defaultError : ''); + setValidationErrors([ + ...(!title ? [{ id: 'title', label: 'Title' }] : []), + ...(!givenName ? [{ id: 'givenName', label: 'Given name' }] : []), + ...(!familyName ? [{ id: 'familyName', label: 'Family name' }] : []), + ...(!dobDay || !dobMonth || !dobYear ? [{ id: 'dob', label: 'Date of birth' }] : []), + ...(!mobileNumber ? [{ id: 'mobileNumber', label: 'Mobile number' }] : []), + ]); } else { setData({ ...data, title, givenName, middleName, familyName, dobDay, dobMonth, dobYear, mobileNumber }); router.push('/credit-cards/address'); @@ -62,11 +71,14 @@ export default function NameAndContact() { return (
router.push('/credit-cards/credit-limit')}>Back to Credit limit - Name & contact -
+ + Name & contact + + {validationErrors.length >= 1 && } + - + @@ -89,7 +101,7 @@ export default function NameAndContact() { - + @@ -99,6 +111,7 @@ export default function NameAndContact() { size="large" label="Date of birth" hint="For example 31 3 1980" + instanceId="dob" errorMessage={dobDayError || dobMonthError || dobYearError} > @@ -138,18 +151,13 @@ export default function NameAndContact() { hint="We’ll send a verification code to your divhone later, to create your account." errorMessage={mobileError} before="AUS +61" + instanceId="mobileNumber" > - router.push('/credit-cards')} - secondary="Back" - tertiaryOnClick={() => router.push('/')} - tertiary="Cancel" - > + router.push('/')} tertiary="Cancel"> Next diff --git a/apps/protoform/src/app/credit-cards/page.tsx b/apps/protoform/src/app/credit-cards/page.tsx index a54bcb8ea..2f067c104 100644 --- a/apps/protoform/src/app/credit-cards/page.tsx +++ b/apps/protoform/src/app/credit-cards/page.tsx @@ -7,6 +7,7 @@ import { FormEvent, useEffect, useState } from 'react'; import { BackButton } from '@/components/back-button/back-button'; import { Cta } from '@/components/cta/cta'; import { CustomHeading } from '@/components/custom-heading/custom-heading'; +import { ErrorValidationAlert, ValidationErrorType } from '@/components/error-validation-alert/error-validation-alert'; import { useSidebar } from '@/components/sidebar/context'; import { getFormData } from '@/utils/getFormData'; @@ -19,6 +20,7 @@ export default function CreditCards() { const { data, setData } = useCreditCard(); const [nameError, setNameError] = useState(''); const [emailError, setEmailError] = useState(''); + const [validationErrors, setValidationErrors] = useState([]); const handleSubmit = (e: FormEvent) => { e.preventDefault(); @@ -26,6 +28,10 @@ export default function CreditCards() { if (!name || !email) { setNameError(!name ? defaultError : ''); setEmailError(!email ? defaultError : ''); + setValidationErrors([ + ...(!name ? [{ id: 'name', label: 'Given name' }] : []), + ...(!email ? [{ id: 'email', label: 'Email address' }] : []), + ]); } else { setData({ ...data, name, email }); router.push('/credit-cards/income-and-savings'); @@ -41,19 +47,28 @@ export default function CreditCards() { return (
router.push('/')}>Back to dashboard - Quick Contact + + Quick Contact + We will save your application for 14 days in case you want to retrieve and complete it later. + {validationErrors.length >= 1 && }
- + - + diff --git a/apps/protoform/src/app/credit-cards/review-and-submit/page.tsx b/apps/protoform/src/app/credit-cards/review-and-submit/page.tsx index c1329259b..10459736c 100644 --- a/apps/protoform/src/app/credit-cards/review-and-submit/page.tsx +++ b/apps/protoform/src/app/credit-cards/review-and-submit/page.tsx @@ -82,20 +82,14 @@ export default function Address() { return (
router.push('/credit-cards/address')}>Back to Address - Review and submit + Review and submit

Help protect your application

Before continuing we’ll send you a one-time passcode to your mobile for added security.

- router.push('/credit-cards/address')} - secondary="Back" - tertiaryOnClick={() => router.push('/')} - tertiary="Cancel" - > + router.push('/')} tertiary="Cancel"> Send SMS code
diff --git a/apps/protoform/src/app/layout.tsx b/apps/protoform/src/app/layout.tsx index b6d683189..74dd1d2e7 100644 --- a/apps/protoform/src/app/layout.tsx +++ b/apps/protoform/src/app/layout.tsx @@ -1,9 +1,8 @@ -import { Footer, Link } from '@westpac/ui'; -import { PadlockIcon } from '@westpac/ui/icon'; import { type Metadata } from 'next'; import './globals.css'; import { ContentWrapper } from '@/components/content-wrapper/content-wrapper'; +import { CustomFooter } from '@/components/custom-footer/custom-footer'; import { CustomHeader } from '@/components/custom-header/custom-header'; import { SidebarContextProvider } from '@/components/sidebar/context'; import { Sidebar } from '@/components/sidebar/sidebar'; @@ -26,53 +25,10 @@ export default function RootLayout({ {children} + -
-
- -

- Our site and your transactions are secure. You can read our{' '} - - security information - - . © 2024 Westpac Banking Corporation ABN 33 007 457 141 AFSL and Australian credit licence 233714. -

-
-
); } - -{ - /*
-
- {children} -
-
-
-
- -

- Our site and your transactions are secure. You can read our{' '} - - security information - - . © 2024 Westpac Banking Corporation ABN 33 007 457 141 AFSL and Australian credit licence 233714. -

-
-
*/ -} diff --git a/apps/protoform/src/app/page.tsx b/apps/protoform/src/app/page.tsx index c264e9772..530599d27 100644 --- a/apps/protoform/src/app/page.tsx +++ b/apps/protoform/src/app/page.tsx @@ -1,11 +1,21 @@ +'use client'; + import { List, ListItem } from '@westpac/ui'; import Link from 'next/link'; +import { useEffect } from 'react'; import { CustomHeading } from '@/components/custom-heading/custom-heading'; +import { RopeDataSetter } from '@/components/rope-data-setter/rope-data-setter'; +import { useSidebar } from '@/components/sidebar/context'; export default function Home() { + const { setOpen } = useSidebar(); + useEffect(() => { + setOpen(false); + }, [setOpen]); return (
+ Protoform diff --git a/apps/protoform/src/components/content-wrapper/content-wrapper.tsx b/apps/protoform/src/components/content-wrapper/content-wrapper.tsx index 55aa80030..f8af428bf 100644 --- a/apps/protoform/src/components/content-wrapper/content-wrapper.tsx +++ b/apps/protoform/src/components/content-wrapper/content-wrapper.tsx @@ -2,15 +2,17 @@ import { Grid, GridContainer, GridItem } from '@westpac/ui'; import { clsx } from 'clsx'; -import { usePathname } from 'next/navigation'; import { ReactNode } from 'react'; +import { useSidebar } from '../sidebar/context'; + export function ContentWrapper({ children }: { children: ReactNode }) { - const pathname = usePathname(); + const { open } = useSidebar(); + return (
diff --git a/apps/protoform/src/components/cta/cta.tsx b/apps/protoform/src/components/cta/cta.tsx index 6e13dc646..5e683afb5 100644 --- a/apps/protoform/src/components/cta/cta.tsx +++ b/apps/protoform/src/components/cta/cta.tsx @@ -20,7 +20,7 @@ export function Cta({ }) { return (
- {secondary && ( diff --git a/apps/protoform/src/components/custom-footer/custom-footer.tsx b/apps/protoform/src/components/custom-footer/custom-footer.tsx new file mode 100644 index 000000000..b7b5c28d1 --- /dev/null +++ b/apps/protoform/src/components/custom-footer/custom-footer.tsx @@ -0,0 +1,35 @@ +'use client'; + +import { Footer, Link } from '@westpac/ui'; +import { SecurityIcon } from '@westpac/ui/icon'; +import { clsx } from 'clsx'; + +import { useSidebar } from '../sidebar/context'; + +export function CustomFooter() { + const { open } = useSidebar(); + return ( +
+
+ +

+ Our site and your transactions are secure. You can read our{' '} + + security information + + . © 2024 Westpac Banking Corporation ABN 33 007 457 141 AFSL and Australian credit licence 233714. +

+
+
+ ); +} diff --git a/apps/protoform/src/components/custom-header/custom-header.tsx b/apps/protoform/src/components/custom-header/custom-header.tsx index 2d9e79b24..a428bd395 100644 --- a/apps/protoform/src/components/custom-header/custom-header.tsx +++ b/apps/protoform/src/components/custom-header/custom-header.tsx @@ -25,7 +25,7 @@ export function CustomHeader() { fixed={!isMobile ? true : false} leftIcon={isMobile ? 'arrow' : undefined} leftOnClick={() => router.back()} - logoOnClick={() => router.push('/')} + logoLink="/" className="" > )}
- {open && ( + + <> <> - <> -
-
-

{`Step ${currStep} of ${totalSteps}`}

+
+
+
+

{`Step ${currStep} of ${totalSteps}`}

- - {ropeData && } - {children} + */} +
+ {ropeData && } + {children} +
- - - )} +