Passed
Push — task/update-profile-experience ( 9cba2e...f7db59 )
by Tristan
07:12
created

resources/assets/js/components/ApplicantProfile/Experience/EducationExperienceProfileModal.tsx   A

Complexity

Total Complexity 5
Complexity/F 0

Size

Lines of Code 151
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 5
eloc 120
mnd 5
bc 5
fnc 0
dl 0
loc 151
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import React, { FunctionComponent } from "react";
2
import { Formik, Form } from "formik";
3
import { useIntl } from "react-intl";
4
import * as Yup from "yup";
5
import {
6
  ProfileSkillSubform,
7
  SkillFormValues,
8
  submitDataToFormSkills,
9
  validationShape as skillValidationShape,
10
} from "./ProfileSkillSubform";
11
import {
12
  Skill,
13
  ExperienceEducation,
14
  ExperienceSkill,
15
} from "../../../models/types";
16
import { ExperienceSubmitData } from "./ExperienceModalCommon";
17
import {
18
  ExperienceModalHeader,
19
  ExperienceDetailsIntro,
20
  ExperienceModalFooter,
21
} from "../../Application/ExperienceModals/ExperienceModalCommon";
22
import Modal from "../../Modal";
23
import {
24
  EducationDetailsSubform,
25
  EducationDetailsFormValues,
26
  newExperienceEducation,
27
  experienceToDetails,
28
  educationExperienceValidationShape,
29
  detailsToExperience,
30
  messages,
31
  FormEducationType,
32
  FormEducationStatus,
33
} from "../../Application/ExperienceModals/EducationExperienceModal";
34
35
type EducationExperienceFormValues = SkillFormValues &
36
  EducationDetailsFormValues;
37
38
const dataToFormValues = (
39
  data: ExperienceSubmitData<ExperienceEducation>,
40
  allSkills: Skill[],
41
  creatingNew: boolean,
42
): EducationExperienceFormValues => {
43
  return {
44
    ...experienceToDetails(data.experience, creatingNew),
45
    ...submitDataToFormSkills(data, allSkills),
46
  };
47
};
48
49
interface ProfileEducationModalProps {
50
  modalId: string;
51
  experienceEducation: ExperienceEducation | null;
52
  educationTypes: FormEducationType[];
53
  educationStatuses: FormEducationStatus[];
54
  experienceableId: number;
55
  experienceableType: ExperienceEducation["experienceable_type"];
56
  userSkills: Skill[];
57
  experienceSkills: ExperienceSkill[];
58
  parentElement: Element | null;
59
  visible: boolean;
60
  onModalCancel: () => void;
61
  onModalConfirm: (experience: ExperienceEducation) => Promise<void>;
62
}
63
64
export const ProfileEducationModal: FunctionComponent<ProfileEducationModalProps> = ({
65
  modalId,
66
  experienceEducation,
67
  educationTypes,
68
  educationStatuses,
69
  experienceableId,
70
  experienceableType,
71
  userSkills,
72
  experienceSkills,
73
  parentElement,
74
  visible,
75
  onModalCancel,
76
  onModalConfirm,
77
}) => {
78
  const intl = useIntl();
79
80
  const originalExperience =
81
    experienceEducation ??
82
    newExperienceEducation(experienceableId, experienceableType);
83
84
  const relevantExperienceSkills = experienceSkills.filter(
85
    (expSkill) =>
86
      expSkill.experience_id === experienceEducation?.id &&
87
      expSkill.experience_type === "experience_education",
88
  );
89
90
  const validationSchema = Yup.object().shape({
91
    ...educationExperienceValidationShape(intl),
92
    ...skillValidationShape(intl),
93
  });
94
95
  const initialFormValues = dataToFormValues(
96
    {
97
      experience: originalExperience,
98
      savedSkills: relevantExperienceSkills.map((expSkill) => ({
99
        skillId: expSkill.skill_id,
100
        justification: expSkill.justification ?? "",
101
      })),
102
    },
103
    userSkills,
104
    experienceEducation === null,
105
  );
106
107
  return (
108
    <Modal
109
      id={modalId}
110
      parentElement={parentElement}
111
      visible={visible}
112
      onModalCancel={onModalCancel}
113
      onModalConfirm={onModalCancel}
114
      className="application-experience-dialog"
115
    >
116
      <ExperienceModalHeader
117
        title={intl.formatMessage(messages.modalTitle)}
118
        iconClass="fa-book"
119
      />
120
      <Formik
121
        enableReinitialize
122
        initialValues={initialFormValues}
123
        onSubmit={async (values, actions): Promise<void> => {
124
          await onModalConfirm(detailsToExperience(values, originalExperience));
125
          actions.setSubmitting(false);
126
          actions.resetForm();
127
        }}
128
        validationSchema={validationSchema}
129
      >
130
        {(formikProps): React.ReactElement => (
131
          <Form>
132
            <Modal.Body>
133
              <ExperienceDetailsIntro
134
                description={intl.formatMessage(messages.modalDescription)}
135
              />
136
              <EducationDetailsSubform
137
                educationTypes={educationTypes}
138
                educationStatuses={educationStatuses}
139
              />
140
              <ProfileSkillSubform keyPrefix="education" skills={userSkills} />
141
            </Modal.Body>
142
            <ExperienceModalFooter buttonsDisabled={formikProps.isSubmitting} />
143
          </Form>
144
        )}
145
      </Formik>
146
    </Modal>
147
  );
148
};
149
150
export default ProfileEducationModal;
151