Skip to content

Commit 098c918

Browse files
authored
Merge pull request #1673 from topcoder-platform/feat/challenge-reviewer-v6
Feat/challenge reviewer v6
2 parents 2f7bad2 + c0799c2 commit 098c918

File tree

12 files changed

+863
-9
lines changed

12 files changed

+863
-9
lines changed

config/constants/development.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ module.exports = {
2626
RESOURCE_ROLES_API_URL: `${DEV_API_HOSTNAME}/v6/resource-roles`,
2727
SUBMISSIONS_API_URL: `${DEV_API_HOSTNAME}/v6/submissions`,
2828
REVIEW_TYPE_API_URL: `${DEV_API_HOSTNAME}/v6/reviewTypes`,
29+
SCORECARDS_API_URL: `${DEV_API_HOSTNAME}/v6/scorecards`,
2930
SUBMISSION_REVIEW_APP_URL: `https://submission-review.${DOMAIN}/challenges`,
3031
STUDIO_URL: `https://studio.${DOMAIN}`,
3132
CONNECT_APP_URL: `https://connect.${DOMAIN}`,

config/constants/production.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ module.exports = {
2727
RESOURCE_ROLES_API_URL: `${PROD_API_HOSTNAME}/v5/resource-roles`,
2828
SUBMISSIONS_API_URL: `${PROD_API_HOSTNAME}/v5/submissions`,
2929
REVIEW_TYPE_API_URL: `${PROD_API_HOSTNAME}/v5/reviewTypes`,
30+
SCORECARDS_API_URL: `${PROD_API_HOSTNAME}/v5/scorecards`, //update to use v6
3031
SUBMISSION_REVIEW_APP_URL: `https://submission-review.${DOMAIN}/challenges`,
3132
STUDIO_URL: `https://studio.${DOMAIN}`,
3233
CONNECT_APP_URL: `https://connect.${DOMAIN}`,

src/actions/challenges.js

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import {
2020
createChallenge as createChallengeAPI,
2121
createResource as createResourceAPI,
2222
deleteResource as deleteResourceAPI,
23-
updateChallengeSkillsApi
23+
updateChallengeSkillsApi,
24+
fetchDefaultReviewers,
25+
fetchScorecards
2426
} from '../services/challenges'
2527
import { searchProfilesByUserIds } from '../services/user'
2628
import {
@@ -765,3 +767,53 @@ export function updateChallengeSkills (challengeId, skills) {
765767
}
766768
}
767769
}
770+
771+
/**
772+
* Load scorecards
773+
* @param {Object} filters filters for scorecards
774+
*/
775+
export function loadScorecards (filters = {}) {
776+
return async (dispatch) => {
777+
try {
778+
const scorecards = await fetchScorecards(filters)
779+
dispatch({
780+
type: LOAD_CHALLENGE_METADATA_SUCCESS,
781+
metadataKey: 'scorecards',
782+
metadataValue: scorecards.scoreCards || []
783+
})
784+
} catch (error) {
785+
console.error('Error loading scorecards:', error)
786+
// Return empty array on error to maintain consistency
787+
dispatch({
788+
type: LOAD_CHALLENGE_METADATA_SUCCESS,
789+
metadataKey: 'scorecards',
790+
metadataValue: []
791+
})
792+
}
793+
}
794+
}
795+
796+
/**
797+
* Load default reviewers
798+
* @param {Object} filters filters for default reviewers
799+
*/
800+
export function loadDefaultReviewers (filters = {}) {
801+
return async (dispatch) => {
802+
try {
803+
const defaultReviewers = await fetchDefaultReviewers(filters)
804+
dispatch({
805+
type: LOAD_CHALLENGE_METADATA_SUCCESS,
806+
metadataKey: 'defaultReviewers',
807+
metadataValue: defaultReviewers
808+
})
809+
} catch (error) {
810+
console.error('Error loading default reviewers:', error)
811+
// Return empty array on error to maintain consistency
812+
dispatch({
813+
type: LOAD_CHALLENGE_METADATA_SUCCESS,
814+
metadataKey: 'defaultReviewers',
815+
metadataValue: []
816+
})
817+
}
818+
}
819+
}
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
@import '../../../styles/includes';
2+
3+
.row {
4+
box-sizing: border-box;
5+
display: flex;
6+
flex-direction: row;
7+
margin: 30px 30px 0 30px;
8+
align-content: space-between;
9+
justify-content: flex-start;
10+
11+
.field {
12+
@include upto-sm {
13+
display: block;
14+
padding-bottom: 10px;
15+
}
16+
17+
label {
18+
@include roboto-bold();
19+
font-size: 16px;
20+
line-height: 19px;
21+
font-weight: 500;
22+
color: $tc-gray-80;
23+
}
24+
25+
&.col1 {
26+
max-width: 185px;
27+
min-width: 185px;
28+
margin-right: 14px;
29+
white-space: nowrap;
30+
display: flex;
31+
align-items: center;
32+
}
33+
34+
&.col2 {
35+
align-self: flex-end;
36+
margin-bottom: auto;
37+
margin-top: auto;
38+
display: flex;
39+
flex-direction: column;
40+
width: 600px;
41+
}
42+
}
43+
}
44+
45+
.description {
46+
color: #666;
47+
margin-bottom: 20px;
48+
font-size: 14px;
49+
line-height: 1.4;
50+
}
51+
52+
.noReviewers {
53+
text-align: center;
54+
padding: 30px;
55+
color: #999;
56+
font-style: italic;
57+
background-color: #f5f5f5;
58+
border-radius: 4px;
59+
margin-bottom: 20px;
60+
}
61+
62+
.defaultReviewerNote {
63+
margin-top: 20px;
64+
padding: 15px;
65+
background-color: #e3f2fd;
66+
border: 1px solid #bbdefb;
67+
border-radius: 4px;
68+
}
69+
70+
.defaultReviewerNote p {
71+
margin: 0 0 15px 0;
72+
color: #1976d2;
73+
font-style: normal;
74+
}
75+
76+
.reviewerForm {
77+
background-color: white;
78+
border: 1px solid #ddd;
79+
border-radius: 4px;
80+
padding: 20px;
81+
margin-bottom: 20px;
82+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
83+
}
84+
85+
.reviewerHeader {
86+
display: flex;
87+
justify-content: space-between;
88+
align-items: center;
89+
margin-bottom: 20px;
90+
padding-bottom: 10px;
91+
border-bottom: 1px solid #eee;
92+
}
93+
94+
.reviewerHeader h4 {
95+
margin: 0;
96+
color: #333;
97+
font-size: 16px;
98+
font-weight: 600;
99+
}
100+
101+
.formRow {
102+
display: flex;
103+
flex-wrap: wrap;
104+
gap: 20px;
105+
margin-bottom: 15px;
106+
}
107+
108+
.formGroup {
109+
flex: 1;
110+
min-width: 200px;
111+
}
112+
113+
.formGroup label {
114+
display: block;
115+
margin-bottom: 5px;
116+
font-weight: 500;
117+
color: #555;
118+
font-size: 14px;
119+
}
120+
121+
.formGroup input,
122+
.formGroup select {
123+
width: 100%;
124+
padding: 8px 12px;
125+
border: 1px solid #ccc;
126+
border-radius: 4px;
127+
font-size: 14px;
128+
background-color: white;
129+
}
130+
131+
.formGroup input:focus,
132+
.formGroup select:focus {
133+
outline: none;
134+
border-color: #0066cc;
135+
box-shadow: 0 0 0 2px rgba(0, 102, 204, 0.2);
136+
}
137+
138+
.addButton {
139+
text-align: center;
140+
margin-top: 20px;
141+
}
142+
143+
.summary {
144+
background-color: #f8f9fa;
145+
border: 1px solid #dee2e6;
146+
border-radius: 4px;
147+
padding: 20px;
148+
margin: 20px 0;
149+
}
150+
151+
.summary h4 {
152+
margin: 0 0 15px 0;
153+
color: #333;
154+
font-size: 16px;
155+
font-weight: 600;
156+
}
157+
158+
.summaryRow {
159+
display: flex;
160+
justify-content: space-between;
161+
align-items: center;
162+
padding: 8px 0;
163+
border-bottom: 1px solid #eee;
164+
}
165+
166+
.summaryRow:last-child {
167+
border-bottom: none;
168+
font-weight: 600;
169+
color: #0066cc;
170+
}
171+
172+
.summaryRow span:first-child {
173+
color: #666;
174+
}
175+
176+
.summaryRow span:last-child {
177+
font-weight: 500;
178+
}
179+
180+
.loading {
181+
text-align: center;
182+
padding: 40px;
183+
color: #666;
184+
font-style: italic;
185+
}
186+
187+
.error {
188+
color: $tc-red;
189+
background-color: #ffebee;
190+
padding: 15px;
191+
border-radius: 4px;
192+
border: 1px solid #ffcdd2;
193+
margin-bottom: 20px;
194+
}
195+
196+
.validationErrors {
197+
background-color: #fff3cd;
198+
border: 1px solid #ffeaa7;
199+
border-radius: 4px;
200+
padding: 10px;
201+
margin-bottom: 15px;
202+
}
203+
204+
.validationError {
205+
color: #856404;
206+
font-size: 13px;
207+
margin-bottom: 5px;
208+
}
209+
210+
.validationError:last-child {
211+
margin-bottom: 0;
212+
}
213+
214+
// Responsive adjustments
215+
@media (max-width: 768px) {
216+
.formRow {
217+
flex-direction: column;
218+
gap: 15px;
219+
}
220+
221+
.formGroup {
222+
min-width: 100%;
223+
}
224+
225+
.reviewerHeader {
226+
flex-direction: column;
227+
align-items: flex-start;
228+
gap: 10px;
229+
}
230+
}

0 commit comments

Comments
 (0)