Passed
Push — dev ( 28c92f...84bed1 )
by
unknown
04:40
created

resources/assets/js/components/Application/Experience/BaseExperienceAccordion.tsx   A

Complexity

Total Complexity 2
Complexity/F 0

Size

Lines of Code 331
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 2
eloc 265
mnd 2
bc 2
fnc 0
dl 0
loc 331
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import React, { ReactElement, useState } from "react";
2
import { FormattedMessage, defineMessages } from "react-intl";
3
import { Locales } from "../../../helpers/localize";
4
import { readableDate } from "../../../helpers/dates";
5
6
export interface ExperienceSkill {
7
  id: number;
8
  name: string;
9
  claim: string;
10
}
11
12
export const titleBarDateRange = (
13
  startDate: Date,
14
  endDate: Date | null,
15
  isActive: boolean,
16
  locale: Locales,
17
): React.ReactElement => (
18
  <p data-c-margin="top(quarter)" data-c-colour="c1" data-c-font-size="small">
19
    {isActive || endDate === null ? (
20
      <FormattedMessage
21
        id="experiencePersonalAccordion.startDateToCurrent"
22
        defaultMessage="{startDate} - Current"
23
        description="Shows the date range for the title bar (assuming activity is ongoing)."
24
        values={{
25
          startDate: readableDate(locale, startDate),
26
        }}
27
      />
28
    ) : (
29
      <FormattedMessage
30
        id="experiencePersonalAccordion.startDateToEndDate"
31
        defaultMessage="{startDate} - {endDate}"
32
        description="Shows the date range for the title bar (assuming activity has an end date)."
33
        values={{
34
          startDate: readableDate(locale, startDate),
35
          endDate: readableDate(locale, endDate),
36
        }}
37
      />
38
    )}
39
  </p>
40
);
41
42
export const baseExperienceMessages = defineMessages({
43
  notApplicable: {
44
    id: "baseExperienceAccordion.notApplicable",
45
    defaultMessage: "N/A",
46
    description: "Used for any un-set fields in experience accordions.",
47
  },
48
  experienceTypeLabel: {
49
    id: "baseExperienceAccordion.experienceTypeLabel",
50
    defaultMessage: "Type of Experience:",
51
  },
52
  startDateLabel: {
53
    id: "baseExperienceAccordion.startDateLabel",
54
    defaultMessage: "Start Date:",
55
  },
56
  endDateLabel: {
57
    id: "baseExperienceAccordion.endDateLabel",
58
    defaultMessage: "End Date:",
59
  },
60
  ongoing: {
61
    id: "baseExperienceAccordion.ongoing",
62
    defaultMessage: "Ongoing",
63
  },
64
});
65
66
interface BaseExperienceAccordionProps {
67
  iconClass: string;
68
  title: ReactElement | string;
69
  relevantSkills: ExperienceSkill[];
70
  irrelevantSkillCount: number;
71
  isEducationJustification: boolean;
72
  details: ReactElement;
73
  showSkillDetails: boolean;
74
  showButtons: boolean;
75
  handleDelete: () => void;
76
  handleEdit: () => void;
77
}
78
79
export const BaseExperienceAccordion: React.FC<BaseExperienceAccordionProps> = ({
80
  iconClass,
81
  title,
82
  relevantSkills,
83
  irrelevantSkillCount,
84
  isEducationJustification,
85
  details,
86
  showSkillDetails,
87
  showButtons,
88
  handleDelete,
89
  handleEdit,
90
}) => {
91
  const [isExpanded, setIsExpanded] = useState(false);
92
93
  const relevantSkillCount = relevantSkills.length;
94
  return (
95
    <div
96
      data-c-accordion=""
97
      data-c-background="white(100)"
98
      data-c-card=""
99
      data-c-margin="bottom(.5)"
100
      className={`${isExpanded && "active"}`}
101
    >
102
      <button
103
        tabIndex={0}
104
        aria-expanded={isExpanded}
105
        data-c-accordion-trigger=""
106
        type="button"
107
        onClick={(): void => {
108
          setIsExpanded(!isExpanded);
109
        }}
110
      >
111
        <div data-c-grid="">
112
          <div data-c-grid-item="base(1of4) tl(1of6) equal-col">
113
            <div className="experience-type-indicator">
114
              <i
115
                className={`fas ${iconClass}`}
116
                data-c-color="c1"
117
                data-c-font-size="h4"
118
              />
119
            </div>
120
          </div>
121
          <div data-c-grid-item="base(3of4) tl(5of6)">
122
            <div data-c-padding="all(1)">
123
              <div data-c-grid="middle">
124
                <div data-c-grid-item="tl(3of4)">{title}</div>
125
                <div data-c-grid-item="tl(1of4)" data-c-align="base(left)">
126
                  <FormattedMessage
127
                    id="baseExperienceAccordion.skillCount"
128
                    defaultMessage="{skillCount, plural, =0 {No related skills} one {# related skill} other {# related skills}} {isEducationJustification, select, true {/ Education Requirement} false {}}"
129
                    description="Displays the number of required skills this relates to, and whether it's used to meed education requirements."
130
                    values={{
131
                      skillCount: relevantSkillCount,
132
                      isEducationJustification,
133
                    }}
134
                  />
135
                </div>
136
              </div>
137
            </div>
138
          </div>
139
        </div>
140
        <span data-c-visibility="invisible">
141
          <FormattedMessage
142
            id="baseExperienceAccordion.clickToView"
143
            defaultMessage="Click to view."
144
            description="Instructions for interacting with accordion, for accessibility devices."
145
          />
146
        </span>
147
        <i
148
          aria-hidden="true"
149
          className="fas fa-angle-down"
150
          data-c-accordion-add=""
151
          data-c-colour="black"
152
        />
153
        <i
154
          aria-hidden="true"
155
          className="fas fa-angle-up"
156
          data-c-accordion-remove=""
157
          data-c-colour="black"
158
        />
159
      </button>
160
      <div
161
        aria-hidden="true"
162
        data-c-accordion-content=""
163
        data-c-background="gray(10)"
164
        data-c-padding="bottom(2)"
165
      >
166
        <hr data-c-hr="thin(gray)" data-c-margin="bottom(2)" />
167
        <div data-c-padding="lr(2)">
168
          <div data-c-grid="gutter(all, 1)">
169
            <div data-c-grid-item="base(1of1)">
170
              <div data-c-grid="gutter(all, 1)">
171
                <div data-c-grid-item="base(1of1)">
172
                  <h4 data-c-color="c2" data-c-font-weight="bold">
173
                    <FormattedMessage
174
                      id="baseExperienceAccordion.detailsTitle"
175
                      defaultMessage="Details of this Experience"
176
                      description="Subtitle of the details section."
177
                    />
178
                  </h4>
179
                </div>
180
                {details}
181
              </div>
182
            </div>
183
            <div data-c-grid-item="base(1of1)">
184
              <h4
185
                data-c-color="c2"
186
                data-c-font-weight="bold"
187
                data-c-margin="top(1) bottom(.5)"
188
              >
189
                <FormattedMessage
190
                  id="baseExperienceAccordion.skillsTitle"
191
                  defaultMessage="Skills for this Job"
192
                  description="Subtitle of the skills section."
193
                />
194
              </h4>
195
              <div data-c-grid="gutter(all, 1)">
196
                {showSkillDetails ? (
197
                  relevantSkills.map((skill) => (
198
                    <div key={skill.id} data-c-grid-item="base(1of1)">
199
                      <p>
200
                        <span
201
                          data-c-tag="c1"
202
                          data-c-radius="pill"
203
                          data-c-font-size="small"
204
                        >
205
                          {skill.name}
206
                        </span>
207
                      </p>
208
                      <p data-c-font-style="italic" data-c-margin="top(.5)">
209
                        {skill.claim}
210
                      </p>
211
                    </div>
212
                  ))
213
                ) : (
214
                  <div data-c-grid-item="base(1of1)">
215
                    {relevantSkills.map((skill) => (
216
                      <span
217
                        key={skill.id}
218
                        data-c-tag="c1"
219
                        data-c-radius="pill"
220
                        data-c-font-size="small"
221
                      >
222
                        {skill.name}
223
                      </span>
224
                    ))}
225
                  </div>
226
                )}
227
                {irrelevantSkillCount > 0 && (
228
                  <div data-c-grid-item="base(1of1)">
229
                    <p
230
                      data-c-font-size="small"
231
                      data-c-color="gray"
232
                      data-c-margin="bottom(1)"
233
                    >
234
                      <FormattedMessage
235
                        id="baseExperienceAccordion.irrelevantSkillCount"
236
                        defaultMessage="There {skillCount, plural, one {is <b>#</b> other unrelated skill} other {are <b>#</b> other unrelated skills}} attached to this experience. You can see {skillCount, plural, one {it} other {them}} on your profile."
237
                        description="Say how many skills unrelated to this job are associated with this experience."
238
                        values={{
239
                          skillCount: irrelevantSkillCount,
240
                          b: (...chunks) => (
241
                            <span data-c-font-weight="bold">{chunks}</span>
242
                          ),
243
                        }}
244
                      />
245
                    </p>
246
                  </div>
247
                )}
248
                {irrelevantSkillCount === 0 && relevantSkillCount === 0 && (
249
                  <div data-c-grid-item="base(1of1)">
250
                    <p data-c-color="gray" data-c-margin="bottom(1)">
251
                      <FormattedMessage
252
                        id="baseExperienceAccordion.noSkills"
253
                        defaultMessage="You don't have any skills attached to this experience."
254
                        description="Message to show if experience has no associated skills at all."
255
                      />
256
                    </p>
257
                  </div>
258
                )}
259
              </div>
260
            </div>
261
            {isEducationJustification && (
262
              <div data-c-grid-item="base(1of1)">
263
                <h4
264
                  data-c-color="c2"
265
                  data-c-font-weight="bold"
266
                  data-c-margin="bottom(.5)"
267
                >
268
                  <i
269
                    className="fas fa-check-circle"
270
                    data-c-margin="right(.25)"
271
                    data-c-color="go"
272
                  />
273
                  <FormattedMessage
274
                    id="baseExperienceAccordion.educationRequirement"
275
                    defaultMessage="Education Requirement"
276
                  />
277
                </h4>
278
                <p data-c-margin="bottom(1)">
279
                  <FormattedMessage
280
                    id="baseExperienceAccordion.educationRequirmentDescription"
281
                    defaultMessage="You've selected this experience as an indicator of how you meet the education requirements for this job."
282
                    description="Explanation of what it means that this experience meets an education requirement."
283
                  />
284
                </p>
285
              </div>
286
            )}
287
          </div>
288
        </div>
289
        {showButtons && (
290
          <div data-c-padding="top(1) lr(2)">
291
            <div data-c-grid="gutter(all, 1) middle">
292
              <div
293
                data-c-grid-item="tp(1of2)"
294
                data-c-align="base(center) tp(left)"
295
              >
296
                <button
297
                  data-c-button="outline(c1)"
298
                  data-c-radius="rounded"
299
                  type="button"
300
                  onClick={handleDelete}
301
                >
302
                  <FormattedMessage
303
                    id="baseExperienceAccordion.deleteButton"
304
                    defaultMessage="Delete Experience"
305
                  />
306
                </button>
307
              </div>
308
              <div
309
                data-c-grid-item="tp(1of2)"
310
                data-c-align="base(center) tp(right)"
311
              >
312
                <button
313
                  data-c-button="solid(c1)"
314
                  data-c-radius="rounded"
315
                  type="button"
316
                  onClick={handleEdit}
317
                >
318
                  <FormattedMessage
319
                    id="baseExperienceAccordion.editButton"
320
                    defaultMessage="Edit Experience"
321
                  />
322
                </button>
323
              </div>
324
            </div>
325
          </div>
326
        )}
327
      </div>
328
    </div>
329
  );
330
};
331