Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 89724f4

Browse files
Merge pull request #151 from topcoder-platform/gigs-optimize-b
Gigs Optimization Update Changes
2 parents c6226e8 + 925a300 commit 89724f4

File tree

20 files changed

+386
-24
lines changed

20 files changed

+386
-24
lines changed

Diff for: package-lock.json

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
"react-date-range": "^1.1.3",
8282
"react-dom": "^16.12.0",
8383
"react-dropzone": "^11.3.2",
84+
"react-loading": "^2.0.3",
8485
"react-redux": "^7.2.3",
8586
"react-responsive-modal": "^6.1.0",
8687
"react-select": "^1.3.0",

Diff for: src/App.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ const App = () => {
112112
</div>
113113
<div className="sidebar-footer">
114114
<a
115-
className="button button-primary"
115+
className="button"
116116
href="https://discussions.topcoder.com/discussion/8870/new-beta-site-discuss?new=1"
117117
target="_blank"
118118
>

Diff for: src/actions/myGigs.js

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createActions } from "redux-actions";
2-
import { PER_PAGE } from "../constants";
2+
import { PER_PAGE, CHECKING_GIG_TIMES } from "../constants";
33
import service from "../services/myGigs";
44

55
/**
@@ -30,9 +30,24 @@ async function updateProfile(profile) {
3030
return service.updateProfile(profile);
3131
}
3232

33+
async function startCheckingGigs(externalId) {
34+
let i = 0;
35+
while (i < CHECKING_GIG_TIMES) {
36+
const res = await service.startCheckingGigs(externalId);
37+
if (res && !res.synced) {
38+
i++;
39+
continue;
40+
} else {
41+
return {};
42+
}
43+
}
44+
return {};
45+
}
46+
3347
export default createActions({
3448
GET_MY_GIGS: getMyGigs,
3549
LOAD_MORE_MY_GIGS: loadMoreMyGigs,
3650
GET_PROFILE: getProfile,
3751
UPDATE_PROFILE: updateProfile,
52+
START_CHECKING_GIGS: startCheckingGigs,
3853
});

Diff for: src/api/app-constants.js

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
const Scopes = {
66
// JobApplication
77
READ_JOBAPPLICATION: "read:earn-jobApplications",
8+
READ_JOB: "read:earn-job",
89
READ_PROFILE: "read:earn-profile",
910
WRITE_PROFILE: "write:earn-profile",
1011
ALL_PROFILE: "all:earn-profile",

Diff for: src/api/controllers/JobApplicationController.js

+6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ async function getMyJobApplications(req, res) {
1515
res.send(result.result);
1616
}
1717

18+
async function getJob(req, res) {
19+
const result = await service.getJob(req.authUser, req.query);
20+
res.send(result);
21+
}
22+
1823
module.exports = {
1924
getMyJobApplications,
25+
getJob,
2026
};

Diff for: src/api/docs/swagger.yaml

+62
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,60 @@ paths:
8888
application/json:
8989
schema:
9090
$ref: "#/components/schemas/Error"
91+
/job:
92+
get:
93+
tags:
94+
- Job
95+
description: |
96+
Check whether the Job Application info has been synced.
97+
98+
**Authorization** All topcoder members are allowed.
99+
security:
100+
- bearerAuth: []
101+
parameters:
102+
- in: query
103+
name: externalId
104+
required: true
105+
schema:
106+
type: string
107+
description: The Job External Id
108+
responses:
109+
"200":
110+
description: OK
111+
content:
112+
application/json:
113+
schema:
114+
$ref: "#/components/schemas/JobSynced"
115+
"400":
116+
description: Bad request
117+
content:
118+
application/json:
119+
schema:
120+
$ref: "#/components/schemas/Error"
121+
"401":
122+
description: Not authenticated
123+
content:
124+
application/json:
125+
schema:
126+
$ref: "#/components/schemas/Error"
127+
"403":
128+
description: Forbidden
129+
content:
130+
application/json:
131+
schema:
132+
$ref: "#/components/schemas/Error"
133+
"404":
134+
description: Not Found
135+
content:
136+
application/json:
137+
schema:
138+
$ref: "#/components/schemas/Error"
139+
"500":
140+
description: Internal Server Error
141+
content:
142+
application/json:
143+
schema:
144+
$ref: "#/components/schemas/Error"
91145
/profile:
92146
get:
93147
tags:
@@ -187,6 +241,14 @@ components:
187241
scheme: bearer
188242
bearerFormat: JWT
189243
schemas:
244+
JobSynced:
245+
required:
246+
- synced
247+
properties:
248+
synced:
249+
type: boolean
250+
description: "Whether the job application has been synced"
251+
example: true
190252
JobApplication:
191253
required:
192254
- title

Diff for: src/api/routes/JobApplicationRoutes.js

+8
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,12 @@ module.exports = {
1212
scopes: [constants.Scopes.READ_JOBAPPLICATION],
1313
},
1414
},
15+
"/job": {
16+
get: {
17+
controller: "JobApplicationController",
18+
method: "getJob",
19+
auth: "jwt",
20+
scopes: [constants.Scopes.READ_JOB],
21+
},
22+
},
1523
};

Diff for: src/api/services/JobApplicationService.js

+47-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ async function getMyJobApplications(currentUser, criteria) {
6161
min: job.minSalary,
6262
max: job.maxSalary,
6363
frequency: job.rateType,
64-
currency: job.currency,
64+
// currency: job.currency,
65+
currency: "$",
6566
},
6667
hoursPerWeek: job.hoursPerWeek,
6768
location: job.jobLocation,
@@ -96,6 +97,51 @@ getMyJobApplications.schema = Joi.object()
9697
})
9798
.required();
9899

100+
async function getJob(currentUser, criteria) {
101+
const emptyResult = {
102+
synced: false,
103+
};
104+
// we expect logged-in users
105+
if (currentUser.isMachine) {
106+
return emptyResult;
107+
}
108+
// get user id by calling taas-api with current user's token
109+
const { id: userId } = await helper.getCurrentUserDetails(
110+
currentUser.jwtToken
111+
);
112+
if (!userId) {
113+
throw new errors.NotFoundError(
114+
`Id for user: ${currentUser.userId} not found`
115+
);
116+
}
117+
// get job based on the jobExternalId
118+
const { result: jobs } = await helper.getJobs(criteria);
119+
if (jobs && jobs.length) {
120+
const candidates = jobs[0].candidates || [];
121+
const newJob = candidates.find((item) => item.userId == userId);
122+
if (newJob) {
123+
return {
124+
synced: true,
125+
};
126+
}
127+
}
128+
return {
129+
synced: false,
130+
};
131+
}
132+
133+
getJob.schema = Joi.object()
134+
.keys({
135+
currentUser: Joi.object().required(),
136+
criteria: Joi.object()
137+
.keys({
138+
externalId: Joi.string(),
139+
})
140+
.required(),
141+
})
142+
.required();
143+
99144
module.exports = {
100145
getMyJobApplications,
146+
getJob,
101147
};

Diff for: src/components/Empty/index.jsx

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from "react";
2+
import { EMPTY_GIGS_TEXT } from "../../constants";
3+
import Button from "../Button";
4+
import "./styles.scss";
5+
6+
const Empty = () => {
7+
return (
8+
<div styleName="empty-wrapper">
9+
<div styleName="empty-inner">
10+
<h6>{EMPTY_GIGS_TEXT}</h6>
11+
<span>Interested in getting a gig?</span>
12+
<Button
13+
isPrimary
14+
size="lg"
15+
onClick={() => {
16+
window.location.href = `${process.env.URL.BASE}/gigs`;
17+
}}
18+
>
19+
VIEW GIGS
20+
</Button>
21+
</div>
22+
</div>
23+
);
24+
};
25+
26+
export default Empty;

Diff for: src/components/Empty/styles.scss

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
@import "styles/variables";
2+
@import "styles/mixins";
3+
@import "styles/animations";
4+
5+
.empty-wrapper {
6+
width: 100%;
7+
border-radius: $border-radius-lg;
8+
background-color: #ffffff;
9+
padding: 81px 0px 330px 0px;
10+
min-width: 650px;
11+
.empty-inner {
12+
display: flex;
13+
flex-direction: column;
14+
justify-content: center;
15+
align-items: center;
16+
& > h6 {
17+
font-size: 20px;
18+
color: $tc-black;
19+
line-height: 24px;
20+
@include barlow-semibold;
21+
}
22+
& > span {
23+
font-size: 16px;
24+
color: $tc-black;
25+
line-height: 26px;
26+
margin-top: 30px;
27+
@include roboto-regular;
28+
}
29+
& > button {
30+
margin-top: 20px;
31+
letter-spacing: 0.8px;
32+
}
33+
}
34+
}

Diff for: src/components/Loading/index.jsx

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React from "react";
2+
import ReactLoading from "react-loading";
3+
import PT from "prop-types";
4+
import "./styles.scss";
5+
6+
const Loading = (props) => {
7+
const { color, type, height, width } = props;
8+
return (
9+
<div styleName="loading-wrapper">
10+
<div styleName="loading-inner">
11+
<div>
12+
<ReactLoading
13+
type={type}
14+
color={color}
15+
height={height}
16+
width={width}
17+
/>
18+
</div>
19+
<h6>LOADING</h6>
20+
<span>We are processing your gigs data</span>
21+
</div>
22+
</div>
23+
);
24+
};
25+
26+
Loading.defaultProps = {
27+
color: "#0ab88a",
28+
type: "spin",
29+
width: 35,
30+
height: 35,
31+
};
32+
33+
Loading.propTypes = {
34+
color: PT.string,
35+
type: PT.string,
36+
width: PT.number,
37+
height: PT.number,
38+
};
39+
40+
export default Loading;

Diff for: src/components/Loading/styles.scss

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
@import "styles/variables";
2+
@import "styles/mixins";
3+
@import "styles/animations";
4+
5+
.loading-wrapper {
6+
width: 100%;
7+
border-radius: $border-radius-lg;
8+
background-color: rgba(42,42,42, 0.07);
9+
padding: 223px 0px;
10+
.loading-inner {
11+
display: flex;
12+
flex-direction: column;
13+
justify-content: center;
14+
align-items: center;
15+
& > h6 {
16+
margin-top: 15px;
17+
font-size: 20px;
18+
color: $tc-turquoise-dark1;
19+
line-height: 24px;
20+
@include barlow-bold;
21+
}
22+
& > span {
23+
font-size: 16px;
24+
color: $tc-gray1;
25+
line-height: 26px;
26+
margin-top: 5px;
27+
@include roboto-regular;
28+
}
29+
svg {
30+
path:first-child {
31+
fill: $tc-gray4;
32+
opacity: 1;
33+
}
34+
path:last-child {
35+
animation: rotate 0.8s linear infinite;
36+
transform-origin: 50% 50%;
37+
}
38+
}
39+
}
40+
}

Diff for: src/constants/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -351,4 +351,6 @@ export const GIG_STATUS_TOOLTIP = {
351351
};
352352

353353
export const EMPTY_GIGS_TEXT =
354-
"Looks like you haven't applied to any gig opportunities yet.";
354+
"LOOKS LIKE YOU HAVEN'T APPLIED TO ANY GIG OPPORTUNITIES YET.";
355+
356+
export const CHECKING_GIG_TIMES = 3;

Diff for: src/containers/MyGigs/JobListing/JobCard/index.jsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,11 @@ const JobCard = ({ job }) => {
6565
job.paymentRangeTo &&
6666
job.currency && (
6767
<>
68-
{job.currency}{" "}
68+
{job.currency}
6969
{formatMoneyValue(job.paymentRangeFrom, "")}
7070
{" - "}
7171
{formatMoneyValue(job.paymentRangeTo, "")}
72+
{" (USD)"}
7273
{" / "}
7374
{job.paymentRangeRateType}
7475
</>

0 commit comments

Comments
 (0)