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

resources/assets/js/components/ApplicantProfile/ProfileExperiencePage.tsx   A

Complexity

Total Complexity 4
Complexity/F 0

Size

Lines of Code 161
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 4
eloc 131
mnd 4
bc 4
fnc 0
dl 0
loc 161
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import React, { FunctionComponent, useEffect, useState } from "react";
2
import ReactDOM from "react-dom";
3
import { useDispatch, useSelector } from "react-redux";
4
import { useIntl } from "react-intl";
5
import RootContainer from "../RootContainer";
6
import ProfileExperience from "./ProfileExperience";
7
import {
8
  useFetchExperienceConstants,
9
  useFetchSkills,
10
} from "../../hooks/applicationHooks";
11
import { RootState } from "../../store/store";
12
import {
13
  getExperienceByApplicant,
14
  getExperienceSkillsByApplicant,
15
  getUpdatingByApplicant,
16
} from "../../store/Experience/experienceSelector";
17
import { Experience, ExperienceSkill } from "../../models/types";
18
import {
19
  createExperience,
20
  deleteExperience,
21
  deleteExperienceSkill,
22
  fetchExperienceByApplicant,
23
  updateExperience,
24
  updateExperienceSkill,
25
} from "../../store/Experience/experienceActions";
26
import { loadingMessages } from "../Application/applicationMessages";
27
28
const ProfileExperiencePage: FunctionComponent<{ applicantId: number }> = ({
29
  applicantId,
30
}) => {
31
  const intl = useIntl();
32
  const dispatch = useDispatch();
33
34
  const skills = useFetchSkills(dispatch);
35
36
  const experiencesByType = useSelector((state: RootState) =>
37
    getExperienceByApplicant(state, { applicantId }),
38
  );
39
  const experiences: Experience[] = [
40
    ...experiencesByType.award,
41
    ...experiencesByType.community,
42
    ...experiencesByType.education,
43
    ...experiencesByType.personal,
44
    ...experiencesByType.work,
45
  ];
46
  // Fetch Experiences.
47
  const experiencesUpdating = useSelector((state: RootState) =>
48
    getUpdatingByApplicant(state, { applicantId }),
49
  );
50
  const [experiencesFetched, setExperiencesFetched] = useState(false);
51
  useEffect(() => {
52
    // Only load experiences if they have never been fetched by this component (!experiencesFetched),
53
    //  have never been fetched by another component (length === 0),
54
    //  and are not currently being fetched (!experiencesUpdating).
55
    if (
56
      !experiencesFetched &&
57
      !experiencesUpdating &&
58
      experiences.length === 0
59
    ) {
60
      setExperiencesFetched(true);
61
      dispatch(fetchExperienceByApplicant(applicantId));
62
    }
63
  }, [
64
    applicantId,
65
    dispatch,
66
    experiences.length,
67
    experiencesFetched,
68
    experiencesUpdating,
69
  ]);
70
  const experienceSkills = useSelector((state: RootState) =>
71
    getExperienceSkillsByApplicant(state, { applicantId }),
72
  );
73
  const {
74
    awardRecipientTypes,
75
    awardRecognitionTypes,
76
    educationTypes,
77
    educationStatuses,
78
  } = useFetchExperienceConstants(dispatch);
79
80
  const handleCreateExperience = async (data: Experience): Promise<void> => {
81
    return dispatch(createExperience(data, applicantId));
82
  };
83
  const handleUpdateExperience = async (data: Experience): Promise<void> => {
84
    return dispatch(updateExperience(data));
85
  };
86
  const handleDeleteExperience = async (
87
    id: number,
88
    type: Experience["type"],
89
  ): Promise<void> => {
90
    return dispatch(deleteExperience(id, type));
91
  };
92
  const handleUpdateExperienceSkill = async (
93
    expSkill: ExperienceSkill,
94
  ): Promise<void> => {
95
    return dispatch(updateExperienceSkill(expSkill));
96
  };
97
  const handleDeleteExperienceSkill = async (
98
    expSkill: ExperienceSkill,
99
  ): Promise<void> => {
100
    return dispatch(
101
      deleteExperienceSkill(
102
        expSkill.id,
103
        expSkill.experience_id,
104
        expSkill.experience_type,
105
      ),
106
    );
107
  };
108
109
  const experienceConstantsLoaded =
110
    awardRecipientTypes.length > 0 &&
111
    awardRecognitionTypes.length > 0 &&
112
    educationTypes.length > 0 &&
113
    educationStatuses.length > 0;
114
  const experiencesLoaded = experiencesFetched && !experiencesUpdating;
115
  const showComponent =
116
    experienceConstantsLoaded && skills.length > 0 && experiencesLoaded;
117
118
  return (
119
    <>
120
      {showComponent ? (
121
        <ProfileExperience
122
          experiences={experiences}
123
          experienceSkills={experienceSkills}
124
          skills={skills}
125
          educationStatuses={educationStatuses}
126
          educationTypes={educationTypes}
127
          handleCreateExperience={handleCreateExperience}
128
          handleUpdateExperience={handleUpdateExperience}
129
          handleDeleteExperience={handleDeleteExperience}
130
          handleUpdateExperienceSkill={handleUpdateExperienceSkill}
131
          handleDeleteExperienceSkill={handleDeleteExperienceSkill}
132
          recipientTypes={awardRecipientTypes}
133
          recognitionTypes={awardRecognitionTypes}
134
        />
135
      ) : (
136
        <h2
137
          data-c-heading="h2"
138
          data-c-align="center"
139
          data-c-padding="top(2) bottom(2)"
140
        >
141
          {intl.formatMessage(loadingMessages.loading)}
142
        </h2>
143
      )}
144
      <div id="modal-root" data-clone />
145
    </>
146
  );
147
};
148
149
if (document.getElementById("profile-experience")) {
150
  const root = document.getElementById("profile-experience");
151
  if (root && "applicantId" in root.dataset) {
152
    const applicantId = Number(root.dataset.applicantId as string);
153
    ReactDOM.render(
154
      <RootContainer>
155
        <ProfileExperiencePage applicantId={applicantId} />
156
      </RootContainer>,
157
      root,
158
    );
159
  }
160
}
161