Passed
Push — feature/application-urls ( 540418...63f49f )
by Tristan
04:48 queued 10s
created

Experience.tsx ➔ modalButtonProps   A

Complexity

Conditions 1

Size

Total Lines 29
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 24
dl 0
loc 29
rs 9.304
c 0
b 0
f 0
cc 1
1
/* eslint-disable camelcase */
2
/* eslint-disable @typescript-eslint/camelcase */
3
import * as React from "react";
4
import { FormattedMessage, useIntl, IntlShape } from "react-intl";
5
import {
6
  Skill,
7
  ExperienceEducation,
8
  ExperienceWork,
9
  ExperienceCommunity,
10
  Experience,
11
  ExperiencePersonal,
12
  ExperienceAward,
13
  ExperienceSkill,
14
  Criteria,
15
} from "../../../models/types";
16
import { localizeFieldNonNull, getLocale } from "../../../helpers/localize";
17
import {
18
  SkillTypeId,
19
  CriteriaTypeId,
20
  getKeyByValue,
21
  ClassificationId,
22
} from "../../../models/lookupConstants";
23
import EducationExperienceModal, {
24
  messages as educationMessages,
25
  EducationType,
26
  EducationStatus,
27
  EducationExperienceSubmitData,
28
} from "../ExperienceModals/EducationExperienceModal";
29
30
import WorkExperienceModal, {
31
  messages as workMessages,
32
  WorkExperienceSubmitData,
33
} from "../ExperienceModals/WorkExperienceModal";
34
import CommunityExperienceModal, {
35
  messages as communityMessages,
36
  CommunityExperienceSubmitData,
37
} from "../ExperienceModals/CommunityExperienceModal";
38
import PersonalExperienceModal, {
39
  messages as personalMessages,
40
  PersonalExperienceSubmitData,
41
} from "../ExperienceModals/PersonalExperienceModal";
42
import AwardExperienceModal, {
43
  messages as awardMessages,
44
  AwardRecipientType,
45
  AwardRecognitionType,
46
  AwardExperienceSubmitData,
47
} from "../ExperienceModals/AwardExperienceModal";
48
import { ExperienceEducationAccordion } from "../ExperienceAccordions/ExperienceEducationAccordion";
49
import { ExperienceWorkAccordion } from "../ExperienceAccordions/ExperienceWorkAccordion";
50
import { ExperienceCommunityAccordion } from "../ExperienceAccordions/ExperienceCommunityAccordion";
51
import { ExperiencePersonalAccordion } from "../ExperienceAccordions/ExperiencePersonalAccordion";
52
import { ExperienceAwardAccordion } from "../ExperienceAccordions/ExperienceAwardAccordion";
53
import {
54
  getSkillOfCriteria,
55
  getSkillsOfExperience,
56
  getDisconnectedRequiredSkills,
57
} from "../helpers";
58
import { navigationMessages, experienceMessages } from "../applicationMessages";
59
import { notEmpty, removeDuplicatesById } from "../../../helpers/queries";
60
61
export function modalButtonProps(
62
  intl: IntlShape,
63
): { [key: string]: { id: Experience["type"]; title: string; icon: string } } {
64
  return {
65
    education: {
66
      id: "experience_education",
67
      title: intl.formatMessage(educationMessages.modalTitle),
68
      icon: "fas fa-book",
69
    },
70
    work: {
71
      id: "experience_work",
72
      title: intl.formatMessage(workMessages.modalTitle),
73
      icon: "fas fa-briefcase",
74
    },
75
    community: {
76
      id: "experience_community",
77
      title: intl.formatMessage(communityMessages.modalTitle),
78
      icon: "fas fa-people-carry",
79
    },
80
    personal: {
81
      id: "experience_personal",
82
      title: intl.formatMessage(personalMessages.modalTitle),
83
      icon: "fas fa-mountain",
84
    },
85
    award: {
86
      id: "experience_award",
87
      title: intl.formatMessage(awardMessages.modalTitle),
88
      icon: "fas fa-trophy",
89
    },
90
  };
91
}
92
93
export const ModalButton: React.FunctionComponent<{
94
  id: Experience["type"];
95
  title: string;
96
  icon: string;
97
  openModal: (id: Experience["type"]) => void;
98
}> = ({ id, title, icon, openModal }) => {
99
  return (
100
    <div key={id} data-c-grid-item="base(1of2) tp(1of3) tl(1of5)">
101
      <button
102
        className="application-experience-trigger"
103
        data-c-card
104
        data-c-background="c1(100)"
105
        data-c-radius="rounded"
106
        title={title}
107
        data-c-dialog-id={id}
108
        data-c-dialog-action="open"
109
        type="button"
110
        onClick={(): void => openModal(id)}
111
      >
112
        <i className={icon} aria-hidden="true" />
113
        <span data-c-font-size="regular" data-c-font-weight="bold">
114
          {title}
115
        </span>
116
      </button>
117
    </div>
118
  );
119
};
120
121
const applicationExperienceAccordion = (
122
  experience: Experience,
123
  irrelevantSkillCount: number,
124
  relevantSkills: ExperienceSkill[],
125
  skills: Skill[],
126
  handleEdit: () => void,
127
  handleDelete: () => Promise<void>,
128
): React.ReactElement | null => {
129
  switch (experience.type) {
130
    case "experience_education":
131
      return (
132
        <ExperienceEducationAccordion
133
          key={`${experience.id}-${experience.type}`}
134
          experience={experience}
135
          handleDelete={handleDelete}
136
          handleEdit={handleEdit}
137
          irrelevantSkillCount={irrelevantSkillCount}
138
          relevantSkills={relevantSkills}
139
          skills={skills}
140
          showButtons
141
          showSkillDetails
142
        />
143
      );
144
    case "experience_work":
145
      return (
146
        <ExperienceWorkAccordion
147
          key={`${experience.id}-${experience.type}`}
148
          experience={experience}
149
          handleDelete={handleDelete}
150
          handleEdit={handleEdit}
151
          irrelevantSkillCount={irrelevantSkillCount}
152
          relevantSkills={relevantSkills}
153
          skills={skills}
154
          showButtons
155
          showSkillDetails
156
        />
157
      );
158
    case "experience_community":
159
      return (
160
        <ExperienceCommunityAccordion
161
          key={`${experience.id}-${experience.type}`}
162
          experience={experience}
163
          handleDelete={handleDelete}
164
          handleEdit={handleEdit}
165
          irrelevantSkillCount={irrelevantSkillCount}
166
          relevantSkills={relevantSkills}
167
          skills={skills}
168
          showButtons
169
          showSkillDetails
170
        />
171
      );
172
    case "experience_personal":
173
      return (
174
        <ExperiencePersonalAccordion
175
          key={`${experience.id}-${experience.type}`}
176
          experience={experience}
177
          handleEdit={handleEdit}
178
          handleDelete={handleDelete}
179
          irrelevantSkillCount={irrelevantSkillCount}
180
          relevantSkills={relevantSkills}
181
          skills={skills}
182
          showButtons
183
          showSkillDetails
184
        />
185
      );
186
    case "experience_award":
187
      return (
188
        <ExperienceAwardAccordion
189
          key={`${experience.id}-${experience.type}`}
190
          experience={experience}
191
          handleDelete={handleDelete}
192
          handleEdit={handleEdit}
193
          irrelevantSkillCount={irrelevantSkillCount}
194
          relevantSkills={relevantSkills}
195
          skills={skills}
196
          showButtons
197
          showSkillDetails
198
        />
199
      );
200
    default:
201
      return null;
202
  }
203
};
204
205
export type ExperienceSubmitData =
206
  | EducationExperienceSubmitData
207
  | WorkExperienceSubmitData
208
  | CommunityExperienceSubmitData
209
  | PersonalExperienceSubmitData
210
  | AwardExperienceSubmitData;
211
212
interface ExperienceProps {
213
  experiences: Experience[];
214
  educationStatuses: EducationStatus[];
215
  educationTypes: EducationType[];
216
  experienceSkills: ExperienceSkill[];
217
  criteria: Criteria[];
218
  skills: Skill[];
219
  jobId: number;
220
  jobClassificationId: number | null;
221
  jobEducationRequirements: string | null;
222
  recipientTypes: AwardRecipientType[];
223
  recognitionTypes: AwardRecognitionType[];
224
  handleDeleteExperience: (
225
    id: number,
226
    type: Experience["type"],
227
  ) => Promise<void>;
228
  handleSubmitExperience: (data: ExperienceSubmitData) => Promise<void>;
229
}
230
231
export const MyExperience: React.FunctionComponent<ExperienceProps> = ({
232
  experiences,
233
  educationStatuses,
234
  educationTypes,
235
  experienceSkills,
236
  criteria,
237
  skills,
238
  handleSubmitExperience,
239
  handleDeleteExperience,
240
  jobId,
241
  jobClassificationId,
242
  jobEducationRequirements,
243
  recipientTypes,
244
  recognitionTypes,
245
}) => {
246
  const intl = useIntl();
247
  const locale = getLocale(intl.locale);
248
249
  const jobClassification =
250
    jobClassificationId !== null
251
      ? getKeyByValue(ClassificationId, jobClassificationId)
252
      : "";
253
254
  const [experienceData, setExperienceData] = React.useState<
255
    | (Experience & {
256
        savedOptionalSkills: Skill[];
257
        savedRequiredSkills: Skill[];
258
      })
259
    | null
260
  >(null);
261
262
  const [isModalVisible, setIsModalVisible] = React.useState<{
263
    id: Experience["type"] | "";
264
    visible: boolean;
265
  }>({
266
    id: "",
267
    visible: false,
268
  });
269
270
  const filteredSkills = criteria.reduce(
271
    (result, criterion): { essential: Skill[]; asset: Skill[] } => {
272
      const skillOfCriterion = getSkillOfCriteria(criterion, skills);
273
      if (skillOfCriterion) {
274
        if (criterion.criteria_type_id === CriteriaTypeId.Essential) {
275
          result.essential.push(skillOfCriterion);
276
        }
277
        if (criterion.criteria_type_id === CriteriaTypeId.Asset) {
278
          result.asset.push(skillOfCriterion);
279
        }
280
      }
281
      return result;
282
    },
283
    { essential: [], asset: [] } as { essential: Skill[]; asset: Skill[] },
284
  );
285
286
  const essentialSkills = removeDuplicatesById(filteredSkills.essential);
287
  const assetSkills = removeDuplicatesById(filteredSkills.asset);
288
289
  const disconnectedRequiredSkills = getDisconnectedRequiredSkills(
290
    experiences,
291
    experienceSkills,
292
    essentialSkills,
293
  );
294
295
  const openModal = (id: Experience["type"]): void => {
296
    setIsModalVisible({ id, visible: true });
297
  };
298
299
  const closeModal = (): void => {
300
    setExperienceData(null);
301
    setIsModalVisible({ id: "", visible: false });
302
  };
303
304
  const submitExperience = (data) =>
305
    handleSubmitExperience(data).then(closeModal);
306
307
  const editExperience = (
308
    experience: Experience,
309
    savedOptionalSkills: Skill[],
310
    savedRequiredSkills: Skill[],
311
  ): void => {
312
    setExperienceData({
313
      ...experience,
314
      savedOptionalSkills,
315
      savedRequiredSkills,
316
    });
317
    setIsModalVisible({ id: experience.type, visible: true });
318
  };
319
320
  const deleteExperience = (experience: Experience): Promise<void> =>
321
    handleDeleteExperience(experience.id, experience.type).then(closeModal);
322
323
  const softSkills = removeDuplicatesById(
324
    [...assetSkills, ...essentialSkills].filter(
325
      (skill) => skill.skill_type_id === SkillTypeId.Soft,
326
    ),
327
  );
328
329
  const modalButtons = modalButtonProps(intl);
330
331
  const modalRoot = document.getElementById("modal-root");
332
333
  return (
334
    <>
335
      <div data-c-container="medium">
336
        <h2 data-c-heading="h2" data-c-margin="top(3) bottom(1)">
337
          {intl.formatMessage(experienceMessages.heading)}
338
        </h2>
339
        <p data-c-margin="bottom(1)">
340
          <FormattedMessage
341
            id="application.experience.preamble"
342
            defaultMessage="Use the buttons below to add experiences you want to share with the manager. Experiences you have added in the past also appear below, and you can edit them to link them to skills required for this job when necessary."
343
            description="First section of text on the experience step of the Application Timeline."
344
          />
345
        </p>
346
347
        <div data-c-grid="gutter(all, 1)">
348
          {essentialSkills.length > 0 && (
349
            <div data-c-grid-item="tl(1of2)">
350
              <p data-c-margin="bottom(.5)">
351
                <FormattedMessage
352
                  id="application.experience.essentialSkillsListIntro"
353
                  description="Text before the list of essential skills on the experience step of the Application Timeline."
354
                  defaultMessage="This job <span>requires</span> the following skills:"
355
                  values={{
356
                    span: (chunks): React.ReactElement => (
357
                      <span data-c-font-weight="bold" data-c-color="c2">
358
                        {chunks}
359
                      </span>
360
                    ),
361
                  }}
362
                />
363
              </p>
364
              <ul data-c-margin="bottom(1)">
365
                {essentialSkills.map((skill) => (
366
                  <li key={skill.id}>
367
                    {localizeFieldNonNull(locale, skill, "name")}
368
                  </li>
369
                ))}
370
              </ul>
371
            </div>
372
          )}
373
          {assetSkills.length > 0 && (
374
            <div data-c-grid-item="tl(1of2)">
375
              <p data-c-margin="bottom(.5)">
376
                <FormattedMessage
377
                  id="application.experience.assetSkillsListIntro"
378
                  defaultMessage="These skills are beneficial, but not required:"
379
                  description="Text before the list of asset skills on the experience step of the Application Timeline."
380
                />
381
              </p>
382
              <ul data-c-margin="bottom(1)">
383
                {assetSkills.map((skill) => (
384
                  <li key={skill.id}>
385
                    {localizeFieldNonNull(locale, skill, "name")}
386
                  </li>
387
                ))}
388
              </ul>
389
            </div>
390
          )}
391
        </div>
392
        <p data-c-color="gray" data-c-margin="bottom(2)">
393
          <FormattedMessage
394
            id="application.experience.softSkillsList"
395
            defaultMessage="Don't forget, {skill} will be evaluated later in the hiring process."
396
            description="List of soft skills that will be evaluated later."
397
            values={{
398
              skill: (
399
                <>
400
                  {softSkills.map((skill, index) => {
401
                    const and = " and ";
402
                    const lastElement = index === softSkills.length - 1;
403
                    return (
404
                      <React.Fragment key={skill.id}>
405
                        {lastElement && softSkills.length > 1 && and}
406
                        <span key={skill.id} data-c-font-weight="bold">
407
                          {localizeFieldNonNull(locale, skill, "name")}
408
                        </span>
409
                        {!lastElement && softSkills.length > 2 && ", "}
410
                      </React.Fragment>
411
                    );
412
                  })}
413
                </>
414
              ),
415
            }}
416
          />
417
        </p>
418
        {/* Experience Modal Buttons */}
419
        <div data-c-grid="gutter(all, 1)">
420
          {Object.values(modalButtons).map((buttonProps) => {
421
            const { id, title, icon } = buttonProps;
422
            return (
423
              <ModalButton
424
                key={id}
425
                id={id}
426
                title={title}
427
                icon={icon}
428
                openModal={openModal}
429
              />
430
            );
431
          })}
432
        </div>
433
        {/* Experience Accordion List */}
434
        {experiences && experiences.length > 0 ? (
435
          <div className="experience-list" data-c-margin="top(2)">
436
            <div data-c-accordion-group>
437
              {experiences.map((experience) => {
438
                const savedOptionalSkills = getSkillsOfExperience(
439
                  experienceSkills,
440
                  experience,
441
                  assetSkills,
442
                );
443
                const savedRequiredSkills = getSkillsOfExperience(
444
                  experienceSkills,
445
                  experience,
446
                  essentialSkills,
447
                );
448
                const relevantSkills: ExperienceSkill[] = savedRequiredSkills
449
                  .map((skill) => {
450
                    return experienceSkills.find(
451
                      ({ experience_id, experience_type, skill_id }) =>
452
                        experience_id === experience.id &&
453
                        skill_id === skill.id &&
454
                        experience_type === experience.type,
455
                    );
456
                  })
457
                  .filter(notEmpty);
458
459
                const handleEdit = () =>
460
                  editExperience(
461
                    experience,
462
                    savedOptionalSkills,
463
                    savedRequiredSkills,
464
                  );
465
                const handleDelete = () => deleteExperience(experience);
466
467
                const errorAccordion = () => (
468
                  <div
469
                    data-c-background="gray(10)"
470
                    data-c-radius="rounded"
471
                    data-c-border="all(thin, solid, gray)"
472
                    data-c-margin="top(1)"
473
                    data-c-padding="all(1)"
474
                  >
475
                    <div data-c-align="base(center)">
476
                      <p data-c-color="stop">
477
                        {intl.formatMessage(
478
                          experienceMessages.errorRenderingExperience,
479
                        )}
480
                      </p>
481
                    </div>
482
                  </div>
483
                );
484
485
                // Number of skills attached to Experience but are not part of the jobs skill criteria.
486
                const irrelevantSkillCount =
487
                  experienceSkills.filter(
488
                    (experienceSkill) =>
489
                      experienceSkill.experience_id === experience.id &&
490
                      experienceSkill.experience_type === experience.type,
491
                  ).length -
492
                  (savedOptionalSkills.length + savedRequiredSkills.length);
493
494
                return (
495
                  applicationExperienceAccordion(
496
                    experience,
497
                    irrelevantSkillCount,
498
                    relevantSkills,
499
                    skills,
500
                    handleEdit,
501
                    handleDelete,
502
                  ) ?? errorAccordion()
503
                );
504
              })}
505
            </div>
506
          </div>
507
        ) : (
508
          <div
509
            data-c-background="gray(10)"
510
            data-c-radius="rounded"
511
            data-c-border="all(thin, solid, gray)"
512
            data-c-margin="top(2)"
513
            data-c-padding="all(1)"
514
          >
515
            <div data-c-align="base(center)">
516
              <p data-c-color="gray">
517
                <FormattedMessage
518
                  id="application.experience.noExperiences"
519
                  defaultMessage="Looks like you don't have any experience added yet. Use the buttons above to add experience. Don't forget that experience will always be saved to your profile so that you can use it on future applications!"
520
                  description="Message displayed when application has no experiences."
521
                />
522
              </p>
523
            </div>
524
          </div>
525
        )}
526
        {disconnectedRequiredSkills && disconnectedRequiredSkills.length > 0 && (
527
          <p data-c-color="stop" data-c-margin="top(2)">
528
            <FormattedMessage
529
              id="application.experience.unconnectedSkills"
530
              defaultMessage="The following required skill(s) are not connected to your experience:"
531
              description="Message showing list of required skills that are not connected to a experience."
532
            />{" "}
533
            {disconnectedRequiredSkills.map((skill) => (
534
              <React.Fragment key={skill.id}>
535
                <span
536
                  data-c-tag="stop"
537
                  data-c-radius="pill"
538
                  data-c-font-size="small"
539
                >
540
                  {localizeFieldNonNull(locale, skill, "name")}
541
                </span>{" "}
542
              </React.Fragment>
543
            ))}
544
          </p>
545
        )}
546
      </div>
547
548
      <div data-c-dialog-overlay={isModalVisible.visible ? "active" : ""} />
549
      <EducationExperienceModal
550
        educationStatuses={educationStatuses}
551
        educationTypes={educationTypes}
552
        experienceEducation={experienceData as ExperienceEducation}
553
        experienceableId={experienceData?.experienceable_id ?? 0}
554
        experienceableType={
555
          experienceData?.experienceable_type ?? "application"
556
        }
557
        jobId={jobId}
558
        jobClassification={jobClassification}
559
        jobEducationRequirements={jobEducationRequirements}
560
        modalId={modalButtons.education.id}
561
        onModalCancel={closeModal}
562
        onModalConfirm={submitExperience}
563
        optionalSkills={assetSkills}
564
        parentElement={modalRoot}
565
        requiredSkills={essentialSkills}
566
        savedOptionalSkills={experienceData?.savedOptionalSkills ?? []}
567
        savedRequiredSkills={experienceData?.savedRequiredSkills ?? []}
568
        visible={
569
          isModalVisible.visible &&
570
          isModalVisible.id === modalButtons.education.id
571
        }
572
      />
573
      <WorkExperienceModal
574
        experienceWork={experienceData as ExperienceWork}
575
        experienceableId={experienceData?.experienceable_id ?? 0}
576
        experienceableType={
577
          experienceData?.experienceable_type ?? "application"
578
        }
579
        jobId={jobId}
580
        jobClassification={jobClassification}
581
        jobEducationRequirements={jobEducationRequirements}
582
        modalId={modalButtons.work.id}
583
        onModalCancel={closeModal}
584
        onModalConfirm={submitExperience}
585
        optionalSkills={assetSkills}
586
        parentElement={modalRoot}
587
        requiredSkills={essentialSkills}
588
        savedOptionalSkills={experienceData?.savedOptionalSkills ?? []}
589
        savedRequiredSkills={experienceData?.savedRequiredSkills ?? []}
590
        visible={
591
          isModalVisible.visible && isModalVisible.id === modalButtons.work.id
592
        }
593
      />
594
      <CommunityExperienceModal
595
        experienceCommunity={experienceData as ExperienceCommunity}
596
        experienceableId={experienceData?.experienceable_id ?? 0}
597
        experienceableType={
598
          experienceData?.experienceable_type ?? "application"
599
        }
600
        jobId={jobId}
601
        jobClassification={jobClassification}
602
        jobEducationRequirements={jobEducationRequirements}
603
        modalId={modalButtons.community.id}
604
        onModalCancel={closeModal}
605
        onModalConfirm={submitExperience}
606
        optionalSkills={assetSkills}
607
        parentElement={modalRoot}
608
        requiredSkills={essentialSkills}
609
        savedOptionalSkills={experienceData?.savedOptionalSkills ?? []}
610
        savedRequiredSkills={experienceData?.savedRequiredSkills ?? []}
611
        visible={
612
          isModalVisible.visible &&
613
          isModalVisible.id === modalButtons.community.id
614
        }
615
      />
616
      <PersonalExperienceModal
617
        experiencePersonal={experienceData as ExperiencePersonal}
618
        experienceableId={experienceData?.experienceable_id ?? 0}
619
        experienceableType={
620
          experienceData?.experienceable_type ?? "application"
621
        }
622
        jobId={jobId}
623
        jobClassification={jobClassification}
624
        jobEducationRequirements={jobEducationRequirements}
625
        modalId={modalButtons.personal.id}
626
        onModalCancel={closeModal}
627
        onModalConfirm={submitExperience}
628
        optionalSkills={assetSkills}
629
        parentElement={modalRoot}
630
        requiredSkills={essentialSkills}
631
        savedOptionalSkills={experienceData?.savedOptionalSkills ?? []}
632
        savedRequiredSkills={experienceData?.savedRequiredSkills ?? []}
633
        visible={
634
          isModalVisible.visible &&
635
          isModalVisible.id === modalButtons.personal.id
636
        }
637
      />
638
      <AwardExperienceModal
639
        experienceAward={experienceData as ExperienceAward}
640
        experienceableId={experienceData?.experienceable_id ?? 0}
641
        experienceableType={
642
          experienceData?.experienceable_type ?? "application"
643
        }
644
        jobId={jobId}
645
        jobClassification={jobClassification}
646
        jobEducationRequirements={jobEducationRequirements}
647
        modalId={modalButtons.award.id}
648
        onModalCancel={closeModal}
649
        onModalConfirm={submitExperience}
650
        optionalSkills={assetSkills}
651
        parentElement={modalRoot}
652
        recipientTypes={recipientTypes}
653
        recognitionTypes={recognitionTypes}
654
        requiredSkills={essentialSkills}
655
        savedOptionalSkills={experienceData?.savedOptionalSkills ?? []}
656
        savedRequiredSkills={experienceData?.savedRequiredSkills ?? []}
657
        visible={
658
          isModalVisible.visible && isModalVisible.id === modalButtons.award.id
659
        }
660
      />
661
    </>
662
  );
663
};
664
665
interface ExperienceStepProps {
666
  experiences: Experience[];
667
  educationStatuses: EducationStatus[];
668
  educationTypes: EducationType[];
669
  experienceSkills: ExperienceSkill[];
670
  criteria: Criteria[];
671
  skills: Skill[];
672
  jobId: number;
673
  jobClassificationId: number | null;
674
  jobEducationRequirements: string | null;
675
  recipientTypes: AwardRecipientType[];
676
  recognitionTypes: AwardRecognitionType[];
677
  handleDeleteExperience: (
678
    id: number,
679
    type: Experience["type"],
680
  ) => Promise<void>;
681
  handleSubmitExperience: (data: ExperienceSubmitData) => Promise<void>;
682
  handleContinue: () => void;
683
  handleQuit: () => void;
684
  handleReturn: () => void;
685
}
686
687
export const ExperienceStep: React.FunctionComponent<ExperienceStepProps> = ({
688
  experiences,
689
  educationStatuses,
690
  educationTypes,
691
  experienceSkills,
692
  criteria,
693
  skills,
694
  handleSubmitExperience,
695
  handleDeleteExperience,
696
  jobId,
697
  jobClassificationId,
698
  jobEducationRequirements,
699
  recipientTypes,
700
  recognitionTypes,
701
  handleContinue,
702
  handleQuit,
703
  handleReturn,
704
}) => {
705
  const intl = useIntl();
706
  return (
707
    <>
708
      <MyExperience
709
        experiences={experiences}
710
        educationStatuses={educationStatuses}
711
        educationTypes={educationTypes}
712
        experienceSkills={experienceSkills}
713
        criteria={criteria}
714
        skills={skills}
715
        jobId={jobId}
716
        jobClassificationId={jobClassificationId}
717
        jobEducationRequirements={jobEducationRequirements}
718
        recipientTypes={recipientTypes}
719
        recognitionTypes={recognitionTypes}
720
        handleSubmitExperience={handleSubmitExperience}
721
        handleDeleteExperience={handleDeleteExperience}
722
      />
723
      <div data-c-container="medium" data-c-padding="tb(2)">
724
        <hr data-c-hr="thin(c1)" data-c-margin="bottom(2)" />
725
        <div data-c-grid="gutter">
726
          <div
727
            data-c-alignment="base(centre) tp(left)"
728
            data-c-grid-item="tp(1of2)"
729
          >
730
            <button
731
              data-c-button="outline(c2)"
732
              data-c-radius="rounded"
733
              type="button"
734
              onClick={(): void => handleReturn()}
735
            >
736
              {intl.formatMessage(navigationMessages.return)}
737
            </button>
738
          </div>
739
          <div
740
            data-c-alignment="base(centre) tp(right)"
741
            data-c-grid-item="tp(1of2)"
742
          >
743
            <button
744
              data-c-button="outline(c2)"
745
              data-c-radius="rounded"
746
              type="button"
747
              onClick={(): void => handleQuit()}
748
            >
749
              {intl.formatMessage(navigationMessages.quit)}
750
            </button>
751
            <button
752
              data-c-button="solid(c1)"
753
              data-c-radius="rounded"
754
              data-c-margin="left(1)"
755
              type="button"
756
              onClick={(): void => handleContinue()}
757
            >
758
              {intl.formatMessage(navigationMessages.continue)}
759
            </button>
760
          </div>
761
        </div>
762
      </div>
763
    </>
764
  );
765
};
766
767
export default ExperienceStep;
768