Passed
Push — feature/connect-application-st... ( 3c62e3...cf7200 )
by Tristan
09:55
created

resources/assets/js/components/Application/Review/Review.tsx   A

Complexity

Total Complexity 9
Complexity/F 0

Size

Lines of Code 761
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 9
eloc 628
mnd 9
bc 9
fnc 0
dl 0
loc 761
rs 9.972
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import React, { useState } from "react";
2
import { useIntl, FormattedMessage, defineMessages } from "react-intl";
3
import {
4
  Application,
5
  User,
6
  Job,
7
  Criteria,
8
  Experience,
9
  Skill,
10
  ExperienceSkill,
11
  JobPosterQuestion,
12
  JobApplicationAnswer,
13
} from "../../../models/types";
14
import { languageRequirementDescription } from "../../../models/localizedConstants";
15
import { LanguageRequirementId } from "../../../models/lookupConstants";
16
import {
17
  basicInfoMessages,
18
  experienceMessages,
19
  fitMessages,
20
} from "../applicationMessages";
21
import defaultBasicMessages, {
22
  citizenshipDeclaration,
23
  languageRequirementLabel,
24
  veteranStatus,
25
} from "../BasicInfo/basicInfoMessages";
26
import ExperienceAwardAccordion from "../ExperienceAccordions/ExperienceAwardAccordion";
27
import ExperienceCommunityAccordion from "../ExperienceAccordions/ExperienceCommunityAccordion";
28
import ExperienceEducationAccordion from "../ExperienceAccordions/ExperienceEducationAccordion";
29
import ExperiencePersonalAccordion from "../ExperienceAccordions/ExperiencePersonalAccordion";
30
import ExperienceWorkAccordion from "../ExperienceAccordions/ExperienceWorkAccordion";
31
import SkillAccordion from "./SkillAccordion";
32
import {
33
  Locales,
34
  localizeFieldNonNull,
35
  getLocale,
36
  localizeField,
37
} from "../../../helpers/localize";
38
import { getSkillOfCriteria, getIrrelevantSkillCount } from "../helpers";
39
import { getSkillLevelName } from "../../../models/jobUtil";
40
41
const messages = defineMessages({
42
  edit: {
43
    id: "application.review.edit",
44
    defaultMessage: "Edit",
45
    description: "Link text for editing a section.",
46
  },
47
  editTitle: {
48
    id: "application.review.editTitle",
49
    defaultMessage: "Edit this section.",
50
    description: "Link title for editing a section.",
51
  },
52
  communicationEn: {
53
    id: "application.review.communication.english",
54
    defaultMessage: "I prefer to communicate in English.",
55
    description:
56
      "Text displayed when a user selects 'en' in their profile for communication preference.",
57
  },
58
  communicationFr: {
59
    id: "application.review.communication.french",
60
    defaultMessage: "I prefer to communicate in French.",
61
    description:
62
      "Text displayed when a user selects 'fr' in their profile for communication preference.",
63
  },
64
  communicationNotSet: {
65
    id: "application.review.communication.notSet",
66
    defaultMessage:
67
      "You haven't set a communication language preference in your profile yet.",
68
    description:
69
      "Text displayed if a user has not yet selected a communication preference in their profile.",
70
  },
71
});
72
73
interface ExperienceAccordionProps {
74
  experience: Experience;
75
  experienceSkills: ExperienceSkill[];
76
  irrelevantSkillCount: number;
77
  skills: Skill[];
78
  locale: Locales;
79
}
80
81
const ExperienceAccordion: React.FC<ExperienceAccordionProps> = ({
82
  experience,
83
  experienceSkills,
84
  irrelevantSkillCount,
85
  skills,
86
  locale,
87
}) => {
88
  switch (experience.type) {
89
    case "experience_award":
90
      return (
91
        <ExperienceAwardAccordion
92
          title={experience.title}
93
          recipient={localizeFieldNonNull(
94
            locale,
95
            experience,
96
            "award_recipient_type",
97
          )}
98
          issuer={experience.issued_by}
99
          scope={localizeFieldNonNull(
100
            locale,
101
            experience,
102
            "award_recognition_type",
103
          )}
104
          awardedDate={experience.awarded_date}
105
          relevantSkills={experienceSkills}
106
          skills={skills}
107
          irrelevantSkillCount={irrelevantSkillCount}
108
          isEducationJustification={experience.is_education_requirement}
109
          showSkillDetails
110
          showButtons={false}
111
          handleEdit={(): void => {}}
112
          handleDelete={(): void => {}}
113
        />
114
      );
115
    case "experience_community":
116
      return (
117
        <ExperienceCommunityAccordion
118
          title={experience.title}
119
          group={experience.group}
120
          project={experience.project}
121
          startDate={experience.start_date}
122
          endDate={experience.end_date}
123
          isActive={experience.is_active}
124
          relevantSkills={experienceSkills}
125
          skills={skills}
126
          irrelevantSkillCount={irrelevantSkillCount}
127
          isEducationJustification={experience.is_education_requirement}
128
          showSkillDetails
129
          showButtons={false}
130
          handleEdit={(): void => {}}
131
          handleDelete={(): void => {}}
132
        />
133
      );
134
    case "experience_education":
135
      return (
136
        <ExperienceEducationAccordion
137
          educationType={localizeFieldNonNull(
138
            locale,
139
            experience,
140
            "education_type",
141
          )}
142
          areaOfStudy={experience.area_of_study}
143
          institution={experience.institution}
144
          status={localizeFieldNonNull(locale, experience, "education_status")}
145
          startDate={experience.start_date}
146
          endDate={experience.end_date}
147
          isActive={experience.is_active}
148
          thesisTitle={experience.thesis_title}
149
          relevantSkills={experienceSkills}
150
          skills={skills}
151
          irrelevantSkillCount={irrelevantSkillCount}
152
          isEducationJustification={experience.is_education_requirement}
153
          showSkillDetails
154
          showButtons={false}
155
          handleDelete={(): void => {}}
156
          handleEdit={(): void => {}}
157
        />
158
      );
159
    case "experience_personal":
160
      return (
161
        <ExperiencePersonalAccordion
162
          title={experience.title}
163
          description={experience.description}
164
          isShareable={experience.is_shareable}
165
          startDate={experience.start_date}
166
          endDate={experience.end_date}
167
          isActive={experience.is_active}
168
          relevantSkills={experienceSkills}
169
          skills={skills}
170
          irrelevantSkillCount={irrelevantSkillCount}
171
          isEducationJustification={experience.is_education_requirement}
172
          showSkillDetails
173
          showButtons={false}
174
          handleEdit={(): void => {}}
175
          handleDelete={(): void => {}}
176
        />
177
      );
178
    case "experience_work":
179
      return (
180
        <ExperienceWorkAccordion
181
          title={experience.title}
182
          organization={experience.organization}
183
          group={experience.group}
184
          startDate={experience.start_date}
185
          endDate={experience.end_date}
186
          isActive={experience.is_active}
187
          relevantSkills={experienceSkills}
188
          skills={skills}
189
          irrelevantSkillCount={irrelevantSkillCount}
190
          isEducationJustification={experience.is_education_requirement}
191
          showSkillDetails
192
          showButtons={false}
193
          handleEdit={(): void => {}}
194
          handleDelete={(): void => {}}
195
        />
196
      );
197
    default:
198
      return null;
199
  }
200
};
201
202
type ExperienceView = "experience" | "skills" | "education";
203
204
interface ReviewProps {
205
  application: Application;
206
  criteria: Criteria[];
207
  experiences: Experience[];
208
  experienceSkills: ExperienceSkill[];
209
  job: Job;
210
  jobQuestions: JobPosterQuestion[];
211
  jobApplicationAnswers: JobApplicationAnswer[];
212
  skills: Skill[];
213
  user: User;
214
  handleContinue: () => void;
215
  handleQuit: () => void;
216
  handleReturn: () => void;
217
}
218
219
const Review: React.FC<ReviewProps> = ({
220
  application,
221
  criteria,
222
  experiences,
223
  experienceSkills,
224
  job,
225
  jobQuestions,
226
  jobApplicationAnswers,
227
  skills,
228
  user,
229
  handleContinue,
230
  handleQuit,
231
  handleReturn,
232
}) => {
233
  const intl = useIntl();
234
  const locale = getLocale(intl.locale);
235
  const [experienceView, setExperienceView] = useState<ExperienceView>(
236
    "experience",
237
  );
238
239
  const handleViewClick = (e: React.MouseEvent<HTMLButtonElement>): void => {
240
    const viewType: ExperienceView = e.currentTarget.getAttribute(
241
      "data-experience-view",
242
    ) as ExperienceView;
243
    if (viewType !== null) {
244
      setExperienceView(viewType);
245
    }
246
  };
247
248
  return (
249
    <div data-c-container="medium">
250
      <h2 data-c-heading="h2" data-c-margin="top(3) bottom(1)">
251
        <FormattedMessage
252
          id="application.review.heading"
253
          defaultMessage="Review Your Application"
254
          description="Main page heading for the Review page."
255
        />
256
      </h2>
257
      <p data-c-margin="bottom(1)">
258
        <FormattedMessage
259
          id="application.review.subheadingOne"
260
          defaultMessage="Take one last look at your information before you submit it."
261
          description="First line of the subheading for the Review page."
262
        />
263
      </p>
264
      <p data-c-margin="bottom(1)">
265
        <FormattedMessage
266
          id="application.review.subheadingTwo"
267
          defaultMessage="Make sure everything you've said is as honest and accurate as possible."
268
          description="Second line of the subheading for the Review page."
269
        />
270
      </p>
271
      <p>
272
        <FormattedMessage
273
          id="application.review.subheadingThree"
274
          defaultMessage={`Ask yourself, "If I was a manager, and I knew nothing about the applicant other than this application, would I think they could do a good job?"`}
275
          description="Third line of the subheading for the Review page."
276
        />
277
      </p>
278
      <div data-c-grid="gutter(all, 1) middle" data-c-padding="top(3)">
279
        <div data-c-grid-item="tp(2of3) tl(4of5)">
280
          <h3 data-c-font-size="h3">
281
            {intl.formatMessage(basicInfoMessages.heading)}
282
          </h3>
283
        </div>
284
        <div
285
          data-c-grid-item="tp(1of3) tl(1of5)"
286
          data-c-align="base(center) tp(right)"
287
        >
288
          <a
289
            href="https://talent.test/demo/application-02"
290
            title={intl.formatMessage(messages.editTitle)}
291
            data-c-color="c2"
292
            data-c-font-weight="bold"
293
          >
294
            {intl.formatMessage(messages.edit)}
295
          </a>
296
        </div>
297
      </div>
298
      <hr data-c-hr="thin(gray)" data-c-margin="top(1)" />
299
      <p
300
        data-c-font-weight="bold"
301
        data-c-color="c2"
302
        data-c-margin="top(1) bottom(.5)"
303
      >
304
        {intl.formatMessage(basicInfoMessages.citizenshipLabel)}
305
      </p>
306
      <p>
307
        {intl.formatMessage(
308
          citizenshipDeclaration(application.citizenship_declaration_id),
309
        )}
310
      </p>
311
      <p
312
        data-c-font-weight="bold"
313
        data-c-color="c2"
314
        data-c-margin="top(1) bottom(.5)"
315
      >
316
        {intl.formatMessage(basicInfoMessages.veteranStatusLabel)}
317
      </p>
318
      <p>{intl.formatMessage(veteranStatus(application.veteran_status_id))}</p>
319
      <p
320
        data-c-font-weight="bold"
321
        data-c-color="c2"
322
        data-c-margin="top(1) bottom(.5)"
323
      >
324
        {intl.formatMessage(basicInfoMessages.languageRequirementsHeading)}
325
      </p>
326
      <p data-c-margin="bottom(.5)">
327
        {job.language_requirement_id &&
328
          intl.formatMessage(
329
            languageRequirementDescription(job.language_requirement_id),
330
          )}
331
      </p>
332
      {job.language_requirement_id &&
333
        application.language_requirement_confirmed && (
334
          <p data-c-margin="bottom(.5)">
335
            <i
336
              className="fas fa-check"
337
              data-c-color="go"
338
              data-c-margin="right(.25)"
339
            />
340
            {intl.formatMessage(
341
              languageRequirementLabel(job.language_requirement_id),
342
            )}
343
          </p>
344
        )}
345
      {(job.language_requirement_id ===
346
        LanguageRequirementId.bilingualIntermediate ||
347
        job.language_requirement_id ===
348
          LanguageRequirementId.bilingualAdvanced) &&
349
        application.language_test_confirmed && (
350
          <p>
351
            <i
352
              className="fas fa-check"
353
              data-c-color="go"
354
              data-c-margin="right(.25)"
355
            />
356
            {intl.formatMessage(defaultBasicMessages.languageTestLabel)}
357
          </p>
358
        )}
359
      <div data-c-grid="gutter(all, 1) middle" data-c-padding="top(3)">
360
        <div data-c-grid-item="tp(2of3) tl(4of5)">
361
          <h3 data-c-font-size="h3">
362
            {intl.formatMessage(experienceMessages.heading)}
363
          </h3>
364
        </div>
365
        <div
366
          data-c-grid-item="tp(1of3) tl(1of5)"
367
          data-c-align="base(center) tp(right)"
368
        >
369
          <a
370
            href="https://talent.test/demo/application-04"
371
            title={intl.formatMessage(messages.editTitle)}
372
            data-c-color="c2"
373
            data-c-font-weight="bold"
374
          >
375
            {intl.formatMessage(messages.edit)}
376
          </a>
377
        </div>
378
      </div>
379
      <hr data-c-hr="thin(gray)" data-c-margin="tb(1)" />
380
      <p data-c-padding="bottom(.5)" data-c-font-weight="bold">
381
        <FormattedMessage
382
          id="application.review.changeViewHeading"
383
          defaultMessage="Change Your View:"
384
          description="Heading for the Review section with the buttons to change the layout."
385
        />
386
      </p>
387
      <div data-c-padding="bottom(1)">
388
        <button
389
          data-c-button={`${
390
            experienceView === "experience" ? "solid" : "outline"
391
          }(c1)`}
392
          type="button"
393
          data-c-radius="rounded"
394
          className="gtag-application-review-all-experience"
395
          data-experience-view="experience"
396
          onClick={handleViewClick}
397
        >
398
          <FormattedMessage
399
            id="application.review.experienceViewButton"
400
            defaultMessage="All Experience"
401
            description="Button text for the experience view of the Review page."
402
          />
403
        </button>{" "}
404
        <button
405
          data-c-button={`${
406
            experienceView === "skills" ? "solid" : "outline"
407
          }(c1)`}
408
          type="button"
409
          data-c-radius="rounded"
410
          className="gtag-application-review-skill-experience"
411
          data-experience-view="skills"
412
          onClick={handleViewClick}
413
        >
414
          <FormattedMessage
415
            id="application.review.skillsViewButton"
416
            defaultMessage="Skills for This Job"
417
            description="Button text for the skills view of the Review page."
418
          />
419
        </button>{" "}
420
        <button
421
          data-c-button={`${
422
            experienceView === "education" ? "solid" : "outline"
423
          }(c1)`}
424
          type="button"
425
          data-c-radius="rounded"
426
          className="gtag-application-review-education-experience"
427
          data-experience-view="education"
428
          onClick={handleViewClick}
429
        >
430
          <FormattedMessage
431
            id="application.review.educationViewButton"
432
            defaultMessage="Education Requirements for This Job"
433
            description="Button text for the education view of the Review page."
434
          />
435
        </button>
436
      </div>
437
      {experienceView === "experience" && (
438
        <div className="experience-list">
439
          <p data-c-margin="bottom(1)">
440
            <FormattedMessage
441
              id="application.review.experienceViewHeading"
442
              defaultMessage="This view is a summary of all the experiences you will be sending as a part of your application."
443
              description="Heading for the experience view section of the Review page."
444
            />
445
          </p>
446
          <div data-c-accordion-group="">
447
            {experiences.map((experience) => {
448
              const irrelevantSkillCount = getIrrelevantSkillCount(
449
                criteria,
450
                experience,
451
                experienceSkills,
452
              );
453
              const relevantSkills = experienceSkills.filter(
454
                (experienceSkill) =>
455
                  experienceSkill.experience_type === experience.type &&
456
                  experienceSkill.experience_id === experience.id,
457
              );
458
              return (
459
                <ExperienceAccordion
460
                  key={`${experience.type}-${experience.id}`}
461
                  experience={experience}
462
                  experienceSkills={relevantSkills}
463
                  skills={skills}
464
                  irrelevantSkillCount={irrelevantSkillCount}
465
                  locale={locale}
466
                />
467
              );
468
            })}
469
          </div>
470
        </div>
471
      )}
472
      {experienceView === "skills" && (
473
        <div className="experience-list">
474
          <p data-c-margin="bottom(1)">
475
            <FormattedMessage
476
              id="application.review.skillsViewHeading"
477
              defaultMessage="This view organizes your experiences by the skills required for this job."
478
              description="Heading for the skills view section of the Review page."
479
            />
480
          </p>
481
          <div data-c-accordion-group="">
482
            {criteria.map((criterion) => {
483
              const skillOfCriterion = getSkillOfCriteria(criterion, skills);
484
485
              if (skillOfCriterion !== null) {
486
                const skillLevel = intl.formatMessage(
487
                  getSkillLevelName(criterion, skillOfCriterion),
488
                );
489
490
                const experiencesOfCriterion = experienceSkills.filter(
491
                  (experienceSkill) =>
492
                    experienceSkill.skill_id === criterion.skill_id,
493
                );
494
495
                const relevantExperiences = experiences.filter((experience) =>
496
                  experiencesOfCriterion.some(
497
                    (experienceSkill) =>
498
                      experienceSkill.experience_id === experience.id &&
499
                      experienceSkill.experience_type === experience.type,
500
                  ),
501
                );
502
503
                return (
504
                  <SkillAccordion
505
                    key={criterion.id}
506
                    skill={skillOfCriterion}
507
                    skillLevel={skillLevel}
508
                    experiences={relevantExperiences}
509
                    experienceSkills={experiencesOfCriterion}
510
                  />
511
                );
512
              }
513
              return null;
514
            })}
515
          </div>
516
        </div>
517
      )}
518
      {experienceView === "education" && (
519
        <div className="experience-list">
520
          <p data-c-margin="bottom(1)">
521
            <FormattedMessage
522
              id="application.review.educationViewHeading"
523
              defaultMessage="This view is a summary of all the experiences you have selected that help you meet the education requirements outlined below."
524
              description="Heading for the education view section of the Review page."
525
            />
526
          </p>
527
          <div
528
            data-c-background="gray(20)"
529
            data-c-radius="rounded"
530
            data-c-padding="all(1)"
531
            data-c-margin="bottom(1)"
532
          >
533
            <p>{localizeField(locale, job, "education")}</p>
534
          </div>
535
          <div data-c-accordion-group="">
536
            {experiences
537
              .filter((experience) => experience.is_education_requirement)
538
              .map((educationExperience) => {
539
                const irrelevantSkillCount = getIrrelevantSkillCount(
540
                  criteria,
541
                  educationExperience,
542
                  experienceSkills,
543
                );
544
                const relevantSkills = experienceSkills.filter(
545
                  (experienceSkill) =>
546
                    experienceSkill.experience_type ===
547
                      educationExperience.type &&
548
                    experienceSkill.experience_id === educationExperience.id,
549
                );
550
                return (
551
                  <ExperienceAccordion
552
                    key={`${educationExperience.type}-${educationExperience.id}-edu`}
553
                    experience={educationExperience}
554
                    experienceSkills={relevantSkills}
555
                    skills={skills}
556
                    irrelevantSkillCount={irrelevantSkillCount}
557
                    locale={locale}
558
                  />
559
                );
560
              })}
561
          </div>
562
        </div>
563
      )}
564
      <div data-c-grid="gutter(all, 1) middle" data-c-padding="top(3)">
565
        <div data-c-grid-item="tp(2of3) tl(4of5)">
566
          <h3 data-c-font-size="h3">
567
            {intl.formatMessage(fitMessages.heading)}
568
          </h3>
569
        </div>
570
        <div
571
          data-c-grid-item="tp(1of3) tl(1of5)"
572
          data-c-align="base(center) tp(right)"
573
        >
574
          <a
575
            href="https://talent.test/demo/application-07"
576
            title={intl.formatMessage(messages.editTitle)}
577
            data-c-color="c2"
578
            data-c-font-weight="bold"
579
          >
580
            {intl.formatMessage(messages.edit)}
581
          </a>
582
        </div>
583
      </div>
584
      <hr data-c-hr="thin(gray)" data-c-margin="top(1)" />
585
      {jobQuestions.map((jobQuestion, index) => {
586
        const answer = jobApplicationAnswers.find(
587
          (appAnswer) => appAnswer.job_poster_questions_id === jobQuestion.id,
588
        );
589
        return (
590
          <>
591
            <p
592
              data-c-font-weight="bold"
593
              data-c-color="c2"
594
              data-c-margin="top(1) bottom(.5)"
595
            >
596
              {intl.formatMessage(fitMessages.questionLabel, {
597
                index: index + 1,
598
              })}{" "}
599
              {localizeField(locale, jobQuestion, "question")}
600
            </p>
601
            <p>
602
              {answer ? (
603
                answer.answer
604
              ) : (
605
                <FormattedMessage
606
                  id="application.review.missingAnswer"
607
                  defaultMessage="Not yet answered."
608
                  description="Message displayed if the applicant did not yet answer one of the Fit questions."
609
                />
610
              )}
611
            </p>
612
          </>
613
        );
614
      })}
615
      <div data-c-grid="gutter(all, 1) middle" data-c-padding="top(3)">
616
        <div data-c-grid-item="tp(2of3) tl(4of5)">
617
          <h3 data-c-font-size="h3">
618
            <FormattedMessage
619
              id="application.review.accountSettingsHeading"
620
              defaultMessage="Account Settings"
621
            />
622
          </h3>
623
        </div>
624
        <div
625
          data-c-grid-item="tp(1of3) tl(1of5)"
626
          data-c-align="base(center) tp(right)"
627
        >
628
          <a
629
            href="https://talent.test/demo/application-07"
630
            title={intl.formatMessage(messages.editTitle)}
631
            data-c-color="c2"
632
            data-c-font-weight="bold"
633
          >
634
            {intl.formatMessage(messages.edit)}
635
          </a>
636
        </div>
637
      </div>
638
      <hr data-c-hr="thin(gray)" data-c-margin="top(1)" />
639
      <p
640
        data-c-font-weight="bold"
641
        data-c-color="c2"
642
        data-c-margin="top(1) bottom(.5)"
643
      >
644
        <FormattedMessage
645
          id="application.review.contactLabel"
646
          defaultMessage="Contact & Communication"
647
        />
648
      </p>
649
      {user.contact_language === "en" && (
650
        <p data-c-margin="bottom(.5)">
651
          <i
652
            className="fas fa-check"
653
            data-c-color="go"
654
            data-c-margin="right(.25)"
655
          />
656
          {intl.formatMessage(messages.communicationEn)}
657
        </p>
658
      )}
659
      {user.contact_language === "fr" && (
660
        <p data-c-margin="bottom(.5)">
661
          <i
662
            className="fas fa-check"
663
            data-c-color="go"
664
            data-c-margin="right(.25)"
665
          />
666
          {intl.formatMessage(messages.communicationFr)}
667
        </p>
668
      )}
669
      {user.contact_language !== "en" && user.contact_language !== "fr" && (
670
        <p data-c-margin="bottom(.5)">
671
          <i
672
            className="fas fa-times"
673
            data-c-color="stop"
674
            data-c-margin="right(.25)"
675
          />
676
          {intl.formatMessage(messages.communicationNotSet)}
677
        </p>
678
      )}
679
      <p data-c-margin="bottom(.5)">
680
        <i
681
          className={`fas fa-${user.job_alerts ? "check" : "times"}`}
682
          data-c-color={user.job_alerts ? "go" : "stop"}
683
          data-c-margin="right(.25)"
684
        />
685
        <FormattedMessage
686
          id="application.review.userContact"
687
          defaultMessage="I would like Talent Cloud to contact me at {email} about related jobs."
688
          values={{
689
            email: user.email,
690
          }}
691
        />
692
      </p>
693
      <p>
694
        <i
695
          className="fas fa-check"
696
          data-c-color="go"
697
          data-c-margin="right(.25)"
698
        />
699
        <FormattedMessage
700
          id="application.review.userShare"
701
          defaultMessage="I would like Talent Cloud to share my application with other Government of Canada managers looking for similar sets of skills."
702
        />
703
      </p>
704
      <div data-c-container="medium" data-c-padding="tb(2)">
705
        <hr data-c-hr="thin(c1)" data-c-margin="bottom(2)" />
706
        <div data-c-grid="gutter">
707
          <div
708
            data-c-alignment="base(centre) tp(left)"
709
            data-c-grid-item="tp(1of2)"
710
          >
711
            <button
712
              data-c-button="outline(c2)"
713
              data-c-radius="rounded"
714
              type="button"
715
              onClick={(): void => handleReturn()}
716
            >
717
              <FormattedMessage
718
                id="application.review.returnButtonLabel"
719
                defaultMessage="Return to Previous Step"
720
                description="The text displayed on the Return button of the Applicant Timeline form."
721
              />
722
            </button>
723
          </div>
724
          <div
725
            data-c-alignment="base(centre) tp(right)"
726
            data-c-grid-item="tp(1of2)"
727
          >
728
            <button
729
              data-c-button="outline(c2)"
730
              data-c-radius="rounded"
731
              type="button"
732
              onClick={(): void => handleQuit()}
733
            >
734
              <FormattedMessage
735
                id="application.review.quitButtonLabel"
736
                defaultMessage="Quit"
737
                description="The text displayed on the Quit button of the Applicant Timeline form."
738
              />
739
            </button>
740
            <button
741
              data-c-button="solid(c1)"
742
              data-c-radius="rounded"
743
              data-c-margin="left(1)"
744
              type="button"
745
              onClick={(): void => handleContinue()}
746
            >
747
              <FormattedMessage
748
                id="application.review.submitButtonLabel"
749
                defaultMessage="Continue"
750
                description="The text displayed on the Continue button for the Job Details form."
751
              />
752
            </button>
753
          </div>
754
        </div>
755
      </div>
756
    </div>
757
  );
758
};
759
760
export default Review;
761