Passed
Push — task/comments-api ( c7d753...19d8e5 )
by Yonathan
32:15 queued 19:33
created

resources/assets/js/components/JobCard.tsx   A

Complexity

Total Complexity 7
Complexity/F 0

Size

Lines of Code 245
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 7
eloc 184
dl 0
loc 245
rs 10
c 0
b 0
f 0
mnd 7
bc 7
fnc 0
bpm 0
cpm 0
noi 0
1
import React from "react";
2
import { useIntl, defineMessages, FormattedMessage } from "react-intl";
3
import { JobStatus } from "../models/lookupConstants";
4
5
interface Link {
6
  url: string | null;
7
  text: string;
8
  title: string;
9
}
10
11
interface Activity {
12
  count: number;
13
  new: Link;
14
}
15
16
const statuses = defineMessages({
17
  Approved: {
18
    id: "jobCard.status.approved",
19
    description: "Text displayed for a Job Status of Approved.",
20
    defaultMessage: "Approved",
21
  },
22
  Closed: {
23
    id: "jobCard.status.closed",
24
    description: "Text displayed for a Job Status of Closed.",
25
    defaultMessage: "Closed",
26
  },
27
  Complete: {
28
    id: "jobCard.status.complete",
29
    description: "Text displayed for a Job Status of Complete.",
30
    defaultMessage: "Complete",
31
  },
32
  Draft: {
33
    id: "jobCard.status.draft",
34
    description: "Text displayed for a Job Status of Draft.",
35
    defaultMessage: "Draft",
36
  },
37
  Published: {
38
    id: "jobCard.status.published",
39
    description: "Text displayed for a Job Status of Published.",
40
    defaultMessage: "Published",
41
  },
42
  Review: {
43
    id: "jobCard.status.review",
44
    description: "Text displayed for a Job Status of In Review.",
45
    defaultMessage: "In Review",
46
  },
47
});
48
49
interface StatusPillProps {
50
  status: JobStatus;
51
  text: string;
52
}
53
54
const StatusPill: React.FC<StatusPillProps> = ({ text, status }) => (
55
  <span
56
    data-c-tag={status === JobStatus.Published ? "go" : "c1"}
57
    data-c-font-size="small"
58
    data-c-radius="pill"
59
    data-c-margin="right(half)"
60
  >
61
    {text}
62
  </span>
63
);
64
65
interface JobCardProps {
66
  activity: Activity;
67
  applicants: number;
68
  classification: string;
69
  draft: Link;
70
  managerTime: number;
71
  owned: boolean;
72
  preview: Link;
73
  screeningPlan: Link;
74
  summary: Link;
75
  status: JobStatus;
76
  title: string;
77
  userTime: number;
78
}
79
80
const JobCard: React.FC<JobCardProps> = ({
81
  activity,
82
  applicants,
83
  classification,
84
  draft,
85
  managerTime,
86
  owned,
87
  preview,
88
  screeningPlan,
89
  status,
90
  summary,
91
  title,
92
  userTime,
93
}) => {
94
  const intl = useIntl();
95
  return (
96
    <div
97
      data-c-card=""
98
      data-c-background="white(100)"
99
      data-c-radius="rounded"
100
      data-tc-status="in review"
101
      data-c-padding="all(normal)"
102
      data-c-margin="bottom(normal)"
103
    >
104
      <div data-c-grid="gutter middle">
105
        <div data-c-grid-item="tl(5of10)">
106
          <h2 data-c-margin="bottom(normal)" data-c-font-size="h3">
107
            {`${classification} - `}
108
            <span data-c-font-weight="bold" data-c-margin="right(normal)">
109
              {title}
110
            </span>
111
            <StatusPill
112
              text={intl.formatMessage(statuses[status])}
113
              status={status}
114
            />
115
          </h2>
116
117
          <p data-c-font-size="small" data-c-margin="top(normal)">
118
            {draft.url !== null ? (
119
              <a
120
                href={draft.url}
121
                title={draft.title}
122
                data-c-margin="right(half)"
123
              >
124
                {draft.text}
125
              </a>
126
            ) : (
127
              <span data-c-color="gray" data-c-margin="right(half)">
128
                {draft.text}
129
              </span>
130
            )}
131
            {preview.url !== null ? (
132
              <a
133
                href={preview.url}
134
                title={preview.title}
135
                data-c-margin="right(half)"
136
              >
137
                {preview.text}
138
              </a>
139
            ) : (
140
              <span data-c-color="gray" data-c-margin="right(half)">
141
                {preview.text}
142
              </span>
143
            )}
144
            {screeningPlan.url !== null ? (
145
              <a
146
                href={screeningPlan.url}
147
                title={screeningPlan.title}
148
                data-c-margin="right(half)"
149
              >
150
                {screeningPlan.text}
151
              </a>
152
            ) : (
153
              <span data-c-color="gray" data-c-margin="right(half)">
154
                {screeningPlan.text}
155
              </span>
156
            )}
157
            <span data-c-color="gray" data-c-margin="right(half)">
158
              <FormattedMessage
159
                id="jobCard.applicants"
160
                defaultMessage={`{applicants, plural,
161
                  =0 {No Applicants}
162
                  one {# Applicant}
163
                  other {# Applicants}
164
                }`}
165
                description="Text displaying how many applicants have applied to this Job."
166
                values={{
167
                  applicants,
168
                }}
169
              />
170
            </span>
171
          </p>
172
        </div>
173
        <div data-c-grid-item="tl(3of10)">
174
          <div data-c-grid="gutter">
175
            <div data-c-grid-item="base(1of1)">
176
              <p data-c-font-size="small">
177
                <FormattedMessage
178
                  id="jobCard.managerTime"
179
                  defaultMessage={`Time with Manager: {managerTime, plural,
180
                    one {# day}
181
                    other {# days}
182
                  }`}
183
                  description="Text displaying how long a job post has been claimed by a manager."
184
                  values={{
185
                    managerTime,
186
                  }}
187
                />
188
              </p>
189
              <p data-c-font-size="small" className={owned ? "pulse" : ""}>
190
                <FormattedMessage
191
                  id="jobCard.userTime"
192
                  defaultMessage={`Time with you: <s>{userTime, plural,
193
                    one {# day}
194
                    other {# days}
195
                  }</s>`}
196
                  description="Text displaying how long a job has been claimed by the current user."
197
                  values={{
198
                    s: (msg): JSX.Element => <span>{msg}</span>,
199
                    userTime,
200
                  }}
201
                />
202
              </p>
203
              {activity.count > 0 && activity.new.url !== null ? (
204
                <a
205
                  href={activity.new.url}
206
                  title={activity.new.title}
207
                  data-c-font-size="small"
208
                  data-c-margin="top(half)"
209
                  data-c-color="stop"
210
                >
211
                  {`${activity.new.text} (${activity.count})`}
212
                </a>
213
              ) : (
214
                <p
215
                  data-c-font-size="small"
216
                  data-c-margin="top(half)"
217
                  data-c-color="gray"
218
                >
219
                  <FormattedMessage
220
                    id="jobCard.noActivity"
221
                    defaultMessage="No New Activity"
222
                    description="Fallback text for no new activity on a Job."
223
                  />
224
                </p>
225
              )}
226
            </div>
227
          </div>
228
        </div>
229
        <div data-c-grid-item="tl(2of10)" data-c-align="base(center)">
230
          <a
231
            href={summary.url !== null ? summary.url : "#"}
232
            title={summary.title}
233
            data-c-button="solid(c1)"
234
            data-c-radius="rounded"
235
          >
236
            {summary.text}
237
          </a>
238
        </div>
239
      </div>
240
    </div>
241
  );
242
};
243
244
export default JobCard;
245