Passed
Push — task/update-build-badge ( b9b78a )
by
unknown
06:16
created

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

Complexity

Total Complexity 5
Complexity/F 0

Size

Lines of Code 184
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 5
eloc 145
mnd 5
bc 5
fnc 0
dl 0
loc 184
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import * as React from "react";
2
import { defineMessages, FormattedMessage, useIntl } from "react-intl";
3
import { Link } from "../../../models/app";
4
import { getLocale } from "../../../helpers/localize";
5
import { navigate } from "../../../helpers/router";
6
import { readableTimeFromNow } from "../../../helpers/dates";
7
import { ProgressBarStatus } from "../../../models/lookupConstants";
8
9
export const stepNames = defineMessages({
10
  welcome: {
11
    id: "application.progressBar.welcome",
12
    defaultMessage: "Welcome",
13
  },
14
  step01: {
15
    id: "application.progressBar.step01",
16
    defaultMessage: "Step 1/6",
17
  },
18
  step02: {
19
    id: "application.progressBar.step02",
20
    defaultMessage: "Step 2/6",
21
  },
22
  step03: {
23
    id: "application.progressBar.step03",
24
    defaultMessage: "Step 3/6",
25
  },
26
  step04: {
27
    id: "application.progressBar.step04",
28
    defaultMessage: "Step 4/6",
29
  },
30
  step05: {
31
    id: "application.progressBar.step05",
32
    defaultMessage: "Step 5/6",
33
  },
34
  step06: {
35
    id: "application.progressBar.step06",
36
    defaultMessage: "Step 6/6",
37
  },
38
});
39
40
// Returns the list item element that corresponds to the steps status.
41
const createStep = (
42
  link: Link,
43
  status: ProgressBarStatus,
44
  loading: boolean,
45
): React.ReactElement => {
46
  switch (status) {
47
    case "complete":
48
      return (
49
        <li key={link.title}>
50
          <span data-c-visibility="invisible">
51
            <FormattedMessage
52
              id="application.progressbar.completedStepLabel"
53
              defaultMessage="Completed: "
54
              description="Visually hidden text used to indicate the completed steps."
55
            />
56
          </span>
57
          <a
58
            href={link.url}
59
            title={link.title}
60
            onClick={(e) => {
61
              e.preventDefault();
62
              navigate(link.url);
63
            }}
64
          >
65
            <span data-c-visibility="invisible">{link.text}</span>
66
            <i
67
              className={`${
68
                loading ? "blinking-animation" : ""
69
              } fas fa-check-circle`}
70
              data-c-color="go"
71
            />
72
          </a>
73
        </li>
74
      );
75
    case "current":
76
      return (
77
        <li key={link.title} title={link.title}>
78
          <span data-c-visibility="invisible">
79
            <FormattedMessage
80
              id="application.progressbar.currentStepLabel"
81
              defaultMessage="Current: "
82
              description="Visually hidden text used to indicate the current steps."
83
            />
84
          </span>
85
          <span data-c-visibility="invisible">{link.text}</span>
86
          <i
87
            className={`${loading ? "blinking-animation" : ""} far fa-circle`}
88
            data-c-color="white"
89
          />
90
        </li>
91
      );
92
    case "error":
93
      return (
94
        <li key={link.title}>
95
          <span data-c-visibility="invisible">
96
            <FormattedMessage
97
              id="application.progressbar.errorStepLabel"
98
              defaultMessage="Error: "
99
              description="Visually hidden text used to indicate the steps with errors."
100
            />
101
          </span>
102
          <a
103
            href={link.url}
104
            title={link.title}
105
            onClick={(e) => {
106
              e.preventDefault();
107
              navigate(link.url);
108
            }}
109
          >
110
            <span data-c-visibility="invisible">{link.text}</span>
111
            <i
112
              className={`${
113
                loading ? "blinking-animation" : ""
114
              } fas fa-exclamation-circle`}
115
              data-c-color="stop"
116
            />
117
          </a>
118
        </li>
119
      );
120
    default:
121
      return (
122
        <li key={link.title} title={link.title}>
123
          <span data-c-visibility="invisible">{link.text}</span>
124
          <i className="fas fa-circle" data-c-color="white" />
125
        </li>
126
      );
127
  }
128
};
129
130
export interface ProgressBarProps {
131
  /** The closing date of the job poster. */
132
  closeDateTime: Date | null;
133
  /** The current step number. This is required for the informational steps, since they do not use a list item. */
134
  currentTitle: string;
135
  /** List of the steps. */
136
  steps: { link: Link; status: ProgressBarStatus; loading: boolean }[];
137
}
138
139
export const ProgressBar: React.FunctionComponent<ProgressBarProps> = ({
140
  steps,
141
  closeDateTime,
142
  currentTitle,
143
}) => {
144
  const intl = useIntl();
145
  const locale = getLocale(intl.locale);
146
147
  return (
148
    <div data-c-background="black(100)" data-c-padding="tb(1)">
149
      <div data-c-container="large">
150
        <div data-c-grid="gutter(all, 1)">
151
          <div data-c-grid-item="tl(1of2)" data-c-align="base(center) tl(left)">
152
            <span data-c-color="white">{currentTitle}</span>
153
            <ol className="applicant-application-progress-bar">
154
              {steps.map(
155
                ({ link, status, loading }): React.ReactElement =>
156
                  createStep(link, status, loading),
157
              )}
158
            </ol>
159
          </div>
160
          <div
161
            data-c-grid-item="tl(1of2)"
162
            data-c-align="base(center) tl(right)"
163
          >
164
            <span data-c-color="white">
165
              <FormattedMessage
166
                id="application.progressbar.applicationDeadline"
167
                defaultMessage="Application Deadline: {timeLeft}"
168
                description="Label for the application deadline"
169
                values={{
170
                  timeLeft: closeDateTime
171
                    ? readableTimeFromNow(locale, closeDateTime)
172
                    : "",
173
                }}
174
              />
175
            </span>
176
          </div>
177
        </div>
178
      </div>
179
    </div>
180
  );
181
};
182
183
export default ProgressBar;
184