Skip to content

Commit 0cb7cae

Browse files
authored
Travel Pay / add content to review page & unsupported claim type page (#34044)
* add README * fix cypress test * bare-bones basics of smoc * simple it up some more * fix cypress test for breadcrumb link * add feature toggle redirect, combine handlers * destructure props * add spacing on how to base route page * wrap explainer page in feature flipper * remove unneccessary divs and fragments * update help text content * add mocked data for appt + user * add date util fn, add content to intro page * add appt to submit wrapper * update cypress test * tidying after merging main * add smoc specific cypress test + mock data * add unit tests + mock appt data; add appt to intro prop types * update appt start time * onNext > onStart * fix linting errors * update text in unit test to match updated appt date * update question pages + submit wrapper * update cypress test * handle no address * update address unit test * pageIndex should be 3 * update mileage page and test * remove address check from onNext * update vehicle page and test * remove preventDefault from cant file page * update cantFile state * update cantFile page name * try moving cy.clock to the before block * comment out extra show login modal test * comment out the other cy.clock usage * remove general handlers; add agreement check * update review page, add travel agreement content, update smoc cypress test * flesh out review page unit test * add data-testids, test for modal * add content to unspported claim type page + test * onSubmit needs to be last in props list? * improve review page test * shift focus to error message if trying to submit without checking the agreement box * use scrollToFirstError * remove modal, update review unit test * add user with null addresses to mock data
1 parent 66291db commit 0cb7cae

File tree

9 files changed

+481
-54
lines changed

9 files changed

+481
-54
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
3+
const TravelAgreementContent = () => {
4+
return (
5+
<>
6+
<ul>
7+
<li>I have incurred a cost in relation to the travel claim.</li>
8+
<li>
9+
I have neither obtained transportation at Government expense nor
10+
through the use of Government request, tickets, or tokens, and have
11+
not used any Government-owned convenience or incurred any expenses
12+
which may be presented as charges against the Department of Veterans
13+
Affairs for transportation, meals, or lodgings in connection with my
14+
authorized travel that is not herein claimed.
15+
</li>
16+
<li>
17+
I have not received other transportation resources at no cost to me.
18+
</li>
19+
<li>I am the only person claiming for the travel listed.</li>
20+
<li>
21+
I have not previously received payment for the transportation claimed.
22+
</li>
23+
</ul>
24+
</>
25+
);
26+
};
27+
28+
export default TravelAgreementContent;
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,144 @@
1-
import React from 'react';
1+
import React, { useEffect } from 'react';
22
import PropTypes from 'prop-types';
33

4-
const ReviewPage = ({ handlers }) => {
4+
import {
5+
VaCheckbox,
6+
VaButtonPair,
7+
} from '@department-of-veterans-affairs/component-library/dist/react-bindings';
8+
import { focusElement, scrollToTop } from 'platform/utilities/ui';
9+
10+
import { formatDateTime } from '../../../util/dates';
11+
import TravelAgreementContent from '../../TravelAgreementContent';
12+
13+
const ReviewPage = ({
14+
appointment,
15+
address,
16+
onSubmit,
17+
setPageIndex,
18+
setYesNo,
19+
isAgreementChecked,
20+
setIsAgreementChecked,
21+
}) => {
22+
useEffect(() => {
23+
focusElement('h1');
24+
scrollToTop('topScrollElement');
25+
}, []);
26+
27+
const [formattedDate, formattedTime] = formatDateTime(
28+
appointment.vaos.apiData.start,
29+
);
30+
31+
const onBack = () => {
32+
setYesNo({
33+
mileage: '',
34+
vehicle: '',
35+
address: '',
36+
});
37+
setPageIndex(1);
38+
};
39+
540
return (
641
<div>
7-
<h1 className="vad-u-margin-top--0">Review your travel claim</h1>
42+
<h1 tabIndex="-1">Review your travel claim</h1>
843
<p>Confirm the information is correct before you submit your claim.</p>
944

10-
<div className="vads-u-margin-y--2">
11-
<va-button text="Back" onClick={e => handlers.onBack(e)} />
12-
<va-button text="Submit" onClick={e => handlers.onSubmit(e)} />
13-
</div>
45+
<h2 className="vads-u-margin-bottom--0">Claims</h2>
46+
<hr className="vads-u-margin-y--1" />
47+
<h3 className="vads-u-font-size--h4 vads-u-font-family--sans vads-u-margin-bottom--0 vads-u-margin-top--2">
48+
What you’re claiming
49+
</h3>
50+
<p className="vads-u-margin-y--0">
51+
Mileage-only reimbursement for your appointment at{' '}
52+
{appointment.vaos.apiData.location.attributes.name}{' '}
53+
{appointment.vaos?.apiData?.practitioners
54+
? `with ${appointment.vaos.apiData.practitioners[0].name.given.join(
55+
' ',
56+
)} ${appointment.vaos.apiData.practitioners[0].name.family}`
57+
: ''}{' '}
58+
on {formattedDate}, {formattedTime}.
59+
</p>
60+
61+
<h2 className="vads-u-margin-bottom--0">Travel method</h2>
62+
<hr className="vads-u-margin-y--1" />
63+
<h3 className="vads-u-font-size--h4 vads-u-font-family--sans vads-u-margin-bottom--0 vads-u-margin-top--2">
64+
How you traveled
65+
</h3>
66+
<p className="vads-u-margin-y--0">In your own vehicle</p>
67+
68+
<h2 className="vads-u-margin-bottom--0">Starting address</h2>
69+
<hr className="vads-u-margin-y--1" />
70+
<h3 className="vads-u-font-size--h4 vads-u-font-family--sans vads-u-margin-bottom--0 vads-u-margin-top--2">
71+
Where you traveled from
72+
</h3>
73+
<p className="vads-u-margin-bottom--3 vads-u-margin-top--0">
74+
{address.addressLine1}
75+
<br />
76+
{address.addressLine2 && (
77+
<>
78+
{address.addressLine2}
79+
<br />
80+
</>
81+
)}
82+
{address.addressLine3 && (
83+
<>
84+
{address.addressLine3}
85+
<br />
86+
</>
87+
)}
88+
{`${address.city}, ${address.stateCode} ${address.zipCode}`}
89+
<br />
90+
</p>
91+
92+
<va-card background>
93+
<h3 className="vad-u-margin-bottom--2 vads-u-margin-top--0">
94+
Beneficiary travel agreement
95+
</h3>
96+
<p>
97+
<strong>Penalty statement:</strong> There are severe criminal and
98+
civil penalties, including a fine, imprisonment, or both, for
99+
knowingly submitting a false, fictitious, or fraudulent claim.
100+
</p>
101+
<p>
102+
By submitting this claim, you agree to the beneficiary travel
103+
agreement.
104+
</p>
105+
<TravelAgreementContent />
106+
<VaCheckbox
107+
className="vads-u-margin-x--1 vads-u-margin-y--2"
108+
checked={isAgreementChecked}
109+
name="accept-agreement"
110+
description={null}
111+
error={
112+
!isAgreementChecked
113+
? 'You must accept the beneficiary travel agreement before continuing.'
114+
: null
115+
}
116+
hint={null}
117+
label="I confirm that the information is true and correct to the best of my knowledge and belief. I’ve read and I accept the beneficiary travel agreement."
118+
onVaChange={() => setIsAgreementChecked(!isAgreementChecked)}
119+
required
120+
/>
121+
</va-card>
122+
123+
<VaButtonPair
124+
class="vads-u-margin-top--2"
125+
leftButtonText="File claim"
126+
rightButtonText="Start over"
127+
onPrimaryClick={onSubmit}
128+
onSecondaryClick={onBack}
129+
/>
14130
</div>
15131
);
16132
};
17133

18134
ReviewPage.propTypes = {
19-
handlers: PropTypes.shape({
20-
onBack: PropTypes.func,
21-
onSubmit: PropTypes.func,
22-
}),
135+
address: PropTypes.object,
136+
appointment: PropTypes.object,
137+
isAgreementChecked: PropTypes.bool,
138+
setIsAgreementChecked: PropTypes.func,
139+
setPageIndex: PropTypes.func,
140+
setYesNo: PropTypes.func,
141+
onSubmit: PropTypes.func,
23142
};
24143

25144
export default ReviewPage;

src/applications/travel-pay/components/submit-flow/pages/UnsupportedClaimTypePage.jsx

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
1-
import React from 'react';
1+
import React, { useEffect } from 'react';
22
import PropTypes from 'prop-types';
33

4+
import { focusElement, scrollToTop } from 'platform/utilities/ui';
5+
6+
import { HelpTextGeneral, HelpTextModalities } from '../../HelpText';
7+
48
const UnsupportedClaimTypePage = ({
59
pageIndex,
610
setIsUnsupportedClaimType,
711
setPageIndex,
812
}) => {
13+
useEffect(() => {
14+
focusElement('h1');
15+
scrollToTop('topScrollElement');
16+
}, []);
17+
918
const onBack = () => {
1019
setIsUnsupportedClaimType(false);
1120
setPageIndex(pageIndex);
@@ -14,8 +23,15 @@ const UnsupportedClaimTypePage = ({
1423
return (
1524
<div>
1625
<h1 tabIndex="-1">
17-
We can’t file this type of travel reimbursement claim
26+
We can’t file this type of travel reimbursement claim in this tool at
27+
this time
1828
</h1>
29+
<HelpTextModalities />
30+
<h2 className="vads-u-font-size--h4">
31+
How can I get help with my claim?
32+
</h2>
33+
<HelpTextGeneral />
34+
<br />
1935
<va-button class="vads-u-margin-y--2" text="Back" onClick={onBack} />
2036
</div>
2137
);

src/applications/travel-pay/containers/SubmitFlowWrapper.jsx

+24-19
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
isProfileLoading,
1111
isLoggedIn,
1212
} from 'platform/user/selectors';
13+
import { scrollToFirstError } from 'platform/utilities/ui';
1314

1415
import IntroductionPage from '../components/submit-flow/pages/IntroductionPage';
1516
import MileagePage from '../components/submit-flow/pages/MileagePage';
@@ -24,7 +25,7 @@ import SubmissionErrorPage from '../components/submit-flow/pages/SubmissionError
2425
import { appointment1 } from '../services/mocks/appointments';
2526

2627
const SubmitFlowWrapper = ({ homeAddress, mailingAddress }) => {
27-
// TODO: Placeholders until backend integration is complete
28+
// TODO: Placeholders until backend integration
2829
// API call based on the URL Params, but for now is hard coded
2930
const appointment = appointment1;
3031
// This will actually be handled by the redux action, but for now it lives here
@@ -38,26 +39,20 @@ const SubmitFlowWrapper = ({ homeAddress, mailingAddress }) => {
3839

3940
const [pageIndex, setPageIndex] = useState(0);
4041
const [isUnsupportedClaimType, setIsUnsupportedClaimType] = useState(false);
42+
const [isAgreementChecked, setIsAgreementChecked] = useState(false);
4143

42-
const handlers = {
43-
onNext: e => {
44-
e.preventDefault();
45-
setPageIndex(pageIndex + 1);
46-
},
47-
onBack: e => {
48-
e.preventDefault();
49-
setPageIndex(pageIndex - 1);
50-
},
51-
onSubmit: e => {
52-
e.preventDefault();
53-
// Placeholder until actual submit is hooked up
44+
const onSubmit = () => {
45+
if (!isAgreementChecked) {
46+
scrollToFirstError();
47+
return;
48+
}
49+
// Placeholder until actual submit is hooked up
5450

55-
// Uncomment to simulate successful submission
56-
// setPageIndex(pageIndex + 1);
51+
// Uncomment to simulate successful submission
52+
// setPageIndex(pageIndex + 1);
5753

58-
// Uncomment to simulate an error
59-
setIsSubmissionError(true);
60-
},
54+
// Uncomment to simulate an error
55+
setIsSubmissionError(true);
6156
};
6257

6358
const pageList = [
@@ -113,7 +108,17 @@ const SubmitFlowWrapper = ({ homeAddress, mailingAddress }) => {
113108
},
114109
{
115110
page: 'review',
116-
component: <ReviewPage handlers={handlers} />,
111+
component: (
112+
<ReviewPage
113+
appointment={appointment}
114+
address={homeAddress || mailingAddress}
115+
onSubmit={onSubmit}
116+
setYesNo={setYesNo}
117+
setPageIndex={setPageIndex}
118+
isAgreementChecked={isAgreementChecked}
119+
setIsAgreementChecked={setIsAgreementChecked}
120+
/>
121+
),
117122
},
118123
{
119124
page: 'confirm',

src/applications/travel-pay/services/mocks/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const delay = require('mocker-api/lib/delay');
33
const TOGGLE_NAMES = require('../../../../platform/utilities/feature-toggles/featureFlagNames.json');
44
const travelClaims = require('./travel-claims-31.json');
55
const user = require('./user.json');
6+
// const noAddressUser = require('./user-no-address.json');
67

78
const responses = {
89
'GET /v0/user': user,

0 commit comments

Comments
 (0)