Skip to content

Commit ca7b7e6

Browse files
committed
Merge branch 'dev' into listings-contest
2 parents 5b61ee2 + 1d65f44 commit ca7b7e6

18 files changed

+201
-28
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ In order to test a logged in user, you must make an entry in your `/etc/hosts` f
2020
- To create the build: `npm run build`
2121
- To run code linting: `npm run lint`
2222
- To run the tests: `npm test`
23+
24+
## Running against Production backend
25+
To run this App against the production backend, you should configure your system in a way that a call to `local.topcoder.com` redirects to `localhost:3000` where the App is running. Then you just `npm run start-prod`, go to `local.topcoder.com` and use your credentials for the production web site (and, sure, be careful with what you are doing, it all will go through the production TopCoder API).
26+
27+
To make the mentioned configuration on Ubuntu 16.04 you:
28+
- Add `127.0.0.1 local.topcoder.com` to your `/etc/hosts`
29+
- `$ sudo apt install libcap2-bin`
30+
- `$ which node` to figure out your `path/to/node`
31+
- `$ sudo setcap cap_net_bind_service=+ep /path/to/node`
32+
- Now run the App.
33+
34+
*Disclaimer: I have no idea, what setcap does here, and how safe it is, but it does the job. Feel free to add your comments / modify this section, if you know more about it. Also, if you know how to make such configuration on other OS, please add it here.*
2335

2436
## Test Users
2537
- general member user accounts:

app/directives/challenge-tile/challenge-tile.jade

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
.phase-action(ng-show="challenge.userAction", ng-switch="challenge.userAction")
2323
a.tc-btn.tc-btn-s.tc-btn-wide.tc-btn-ghost.submit(ng-switch-when="Submit", ng-href="{{challenge|challengeLinks:'submit'}}") Submit
24+
a.tc-btn.tc-btn-s.tc-btn-wide.tc-btn-ghost.submit(ng-switch-when="Appeal", ng-href="{{challenge|challengeLinks:'viewScorecards'}}") View Scorecards
25+
a.tc-btn.tc-btn-s.tc-btn-wide.tc-btn-ghost.submit(ng-switch-when="Appeal", ng-href="{{challenge|challengeLinks:'completeAppeals'}}") Complete Appeals
2426

2527
.submitted(ng-switch-when="Submitted") Submitted
2628

@@ -97,6 +99,8 @@
9799

98100
.phase-action(ng-switch="challenge.userAction")
99101
a.tc-btn.tc-btn-s.tc-btn-wide.tc-btn-ghost.submit(ng-switch-when="Submit", ng-href="{{challenge|challengeLinks:'submit'}}") Submit
102+
a.tc-btn.tc-btn-s.tc-btn-wide.tc-btn-ghost.submit(ng-switch-when="Appeal", ng-href="{{challenge|challengeLinks:'viewScorecards'}}") View Scorecards
103+
a.tc-btn.tc-btn-s.tc-btn-wide.tc-btn-ghost.submit(ng-switch-when="Appeal", ng-href="{{challenge|challengeLinks:'completeAppeals'}}") Complete Appeals
100104

101105
.submitted(ng-switch-when="Submitted") Submitted
102106

app/filters/challengeLinks.filter.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ import _ from 'lodash'
6969
return String.supplant('https://{subdomain}.{domain}/challenge-details/{id}/?type={track}', data)
7070
case 'detail':
7171
return String.supplant('https://{subdomain}.{domain}/challenge-details/{id}/?type={track}', data)
72+
case 'viewScorecards':
73+
return String.supplant('https://software.{domain}/review/actions/ViewProjectDetails?pid={id}', data)
74+
case 'completeAppeals':
75+
return String.supplant('https://software.{domain}/review/actions/EarlyAppeals?pid={id}', data)
7276
}
7377
}
7478
}

app/listings/listings.controller.js

100644100755
Lines changed: 86 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import _ from 'lodash'
12
import angular from 'angular'
3+
import { loadUser } from '../services/userv3.service.js'
24

35
(function () {
46
'use strict'
@@ -9,21 +11,96 @@ import angular from 'angular'
911
'TcAuthService', 'UserService', 'UserStatsService', 'ProfileService', 'ChallengeService', 'ExternalAccountService',
1012
'ngDialog', '$anchorScroll'
1113
]
12-
13-
function ListingsCtrl($location, $scope, CONSTANTS, logger, $q, TcAuthService, UserService, UserStatsService, ProfileService, ChallengeService, ExternalAccountService, ngDialog, $anchorScroll) {
14+
15+
function ListingsCtrl($location, $scope, CONSTANTS, logger, $q, TcAuthService,
16+
UserService, UserStatsService,ProfileService, ChallengeService, ExternalAccountService, ngDialog, $anchorScroll) {
17+
var vm = this
18+
var handle
19+
vm.neverParticipated = false
20+
vm.loading = true
21+
vm.userHasChallenges = true
22+
vm.challengeView = 'tile'
1423

1524
activate()
1625

17-
$scope.listingProps = {
18-
filterFromUrl: $location.hash(),
19-
onSaveFilterToUrl: function(filter) {
20-
$location.hash(filter)
21-
}
22-
}
23-
2426
function activate() {
27+
$scope.myChallenges = []
28+
$scope.reactProps = { isAuth: false, myChallenges: [] }
2529
logger.debug('Calling ListingsController activate()')
30+
vm.myChallenges = []
31+
loadUser().then(function(token) {
32+
handle = UserService.getUserIdentity().handle
33+
34+
// update auth flag and get challenges
35+
if(TcAuthService.isAuthenticated()) {
36+
getChallenges(handle)
37+
}
38+
}, function(error) {
39+
// do nothing, just show non logged in state of navigation bar
40+
})
41+
}
42+
43+
function getChallenges(handle) {
44+
var marathonMatchParams = {
45+
limit: 8,
46+
filter: 'status=active'
47+
}
48+
49+
var challengeParams = {
50+
limit: 8,
51+
orderBy: 'submissionEndDate',
52+
filter: 'status=active'
53+
}
54+
55+
$q.all([
56+
ChallengeService.getUserMarathonMatches(handle, marathonMatchParams),
57+
ChallengeService.getUserChallenges(handle, challengeParams)
58+
]).then(function(challenges){
59+
var marathonMatches = challenges[0]
60+
var devDesignChallenges = challenges[1]
61+
62+
if (!marathonMatches.length && !devDesignChallenges.length) {
63+
vm.userHasChallenges = false
64+
_checkForParticipation().then(function() {
65+
vm.loading = false
66+
})
67+
} else {
68+
ChallengeService.processActiveDevDesignChallenges(devDesignChallenges)
69+
ChallengeService.processActiveMarathonMatches(marathonMatches)
70+
var userChallenges = marathonMatches.concat(devDesignChallenges)
71+
72+
userChallenges = _.sortBy(userChallenges, function(n) {
73+
return n.registrationEndDate
74+
})
75+
vm.myChallenges = userChallenges.reverse().slice(0, 8)
76+
77+
// update myChallenges
78+
$scope.reactProps = {
79+
config: CONSTANTS,
80+
filterFromUrl: $location.hash(),
81+
isAuth: true,
82+
myChallenges: vm.myChallenges,
83+
onSaveFilterToUrl: function(filter) {
84+
$location.hash(filter)
85+
}
86+
}
87+
88+
vm.userHasChallenges = true
89+
vm.loading = false
90+
}
91+
})
92+
.catch(function(err) {
93+
logger.error('Error getting challenges and marathon matches', err)
94+
95+
vm.userHasChallenges = true
96+
vm.loading = false
97+
})
98+
}
2699

100+
function _checkForParticipation() {
101+
return ChallengeService.checkChallengeParticipation(handle, function(participated) {
102+
vm.neverParticipated = !participated
103+
})
27104
}
28105
}
29106

app/listings/listings.jade

100644100755
Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,12 @@
1-
react-component(name="ChallengeFiltersExample" props="listingProps")
1+
react-component(name="ChallengeFiltersExample" props="reactProps" watch-depth="reference")
2+
3+
script.
4+
(function() {
5+
var s = document.createElement("script");
6+
s.type = "text/javascript";
7+
s.async = true;
8+
s.src = '//api.usersnap.com/load/'+
9+
'3e7c8f0c-6cf6-41b6-9f2c-e8e4e60dfc59.js';
10+
var x = document.getElementsByTagName('script')[0];
11+
x.parentNode.insertBefore(s, x);
12+
})();

app/listings/listings.module.js

100644100755
File mode changed.

app/listings/listings.routes.js

100644100755
File mode changed.

app/my-dashboard/my-dashboard.jade

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,22 @@
66
.challenges(id="challenges", ui-view="my-challenges")
77

88
.tco.tco17
9-
.tc-banner-placeholder.predix
10-
.subtitle Ready for the future? The Industrial Internet is here
11-
.description Get hands-on with the Predix platform and the Industrial Internet
12-
a(href="http://predix.topcoder.com/").cta.tc-btn-white.tc-btn-radius Learn More
9+
.tc-banner-placeholder.cognitive
10+
.container
11+
.img
12+
.description Learn about Cognitive technologies and get hands on experience as a member of the Topcoder Cognitive Community.
13+
a(href="https://cognitive.topcoder.com").cta.tc-btn-white.tc-btn-radius Learn More
1314

14-
//- .ttl
15-
//- tc-banner(theme="black", banner-name="ttl")
1615
.tco.tco17
1716
.tc-banner-placeholder.black.bg-image
1817
.title 2017 Topcoder Open
1918
.subtitle The Ultimate Programming & Design tournament
2019
.description Earn your way to the USA!
2120
a(href="http://tco17.topcoder.com/").cta.tc-btn-white.tc-btn-radius Learn More
22-
23-
.tco
24-
tc-banner(theme="black", banner-name="tco16")
2521

2622
.srms(id="srms", ui-view="srms", ng-show="dashboard.showSRMs")
2723

2824
.programs(id="community", ui-view="programs")
2925

3026
.community-updates(ui-view="community-updates")
27+

app/services/blog.service.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ import X2JS from 'xml2js'
1919

2020
// fetch blog rss feed
2121
$http.get(CONSTANTS.BLOG_LOCATION)
22-
.then(function(data) {
22+
.then(function(response) {
23+
var data = response.data
2324
// parse the blog rss feed using x2js
2425
var parseString = X2JS.parseString
2526
parseString(data.trim(), function (err, res) {

app/services/challenge.service.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ import moment from 'moment'
105105
}
106106
})
107107
}
108+
if (challenge.userCurrentPhase === 'Appeals') {
109+
challenge.userAction = 'Appeal'
110+
}
108111

109112
if (challenge.userCurrentPhaseEndTime) {
110113
var fullTime = challenge.userCurrentPhaseEndTime

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy