From c5bbc6f984159da57029d1135d125560af6bbdf1 Mon Sep 17 00:00:00 2001 From: Nick Litwin Date: Wed, 14 Oct 2015 14:15:06 -0700 Subject: [PATCH 1/2] Implement carousel with buttons on screen size above 767px --- app/index.jade | 3 + .../subtrack-stats.controller.js | 34 +++- .../subtrack-stats/subtrack-stats.jade | 13 ++ app/topcoder.module.js | 3 +- assets/css/my-dashboard/subtrack-stats.scss | 192 +++++++++++------- bower.json | 3 +- 6 files changed, 161 insertions(+), 87 deletions(-) diff --git a/app/index.jade b/app/index.jade index 9ae2e74a7..2cd6d8e45 100644 --- a/app/index.jade +++ b/app/index.jade @@ -20,6 +20,7 @@ html link(rel='stylesheet', href='../bower_components/ng-notifications-bar/dist/ngNotificationsBar.min.css') link(rel='stylesheet', href='../bower_components/ngDialog/css/ngDialog.css') link(rel='stylesheet', href='../bower_components/ngDialog/css/ngDialog-theme-default.css') + link(rel='stylesheet', href='../bower_components/angular-carousel/dist/angular-carousel.css') //- endbower // endbuild @@ -123,6 +124,8 @@ html script(src='../bower_components/ngDialog/js/ngDialog.js') script(src='../bower_components/lodash/lodash.js') script(src='../bower_components/restangular/dist/restangular.js') + script(src='../bower_components/angular-touch/angular-touch.js') + script(src='../bower_components/angular-carousel/dist/angular-carousel.js') //- endbower //- inject:nonBowerScripts script(src="/scripts/auth0-angular.js") diff --git a/app/my-dashboard/subtrack-stats/subtrack-stats.controller.js b/app/my-dashboard/subtrack-stats/subtrack-stats.controller.js index f95994f8f..3503689d9 100644 --- a/app/my-dashboard/subtrack-stats/subtrack-stats.controller.js +++ b/app/my-dashboard/subtrack-stats/subtrack-stats.controller.js @@ -3,12 +3,9 @@ angular.module('tc.myDashboard').controller('SubtrackStatsController', SubtrackStatsController); - SubtrackStatsController.$inject = [ - 'ProfileService', - 'userIdentity' - ]; + SubtrackStatsController.$inject = ['ProfileService', 'userIdentity', '$window']; - function SubtrackStatsController(ProfileService, userIdentity) { + function SubtrackStatsController(ProfileService, userIdentity, $window) { var vm = this; vm.loading = true; @@ -21,10 +18,13 @@ .then(function(stats) { var trackRanks = ProfileService.getRanks(stats); var subtrackRanks = compileSubtracks(trackRanks); - processStats(subtrackRanks); + processStats(subtrackRanks); vm.subtrackRanks = subtrackRanks; vm.hasRanks = !!vm.subtrackRanks.length; + + buildCarouselSlide(); + vm.loading = false; }) .catch(function(err) { @@ -65,5 +65,27 @@ } }); } + + function buildCarouselSlide(numItemsPerSlide) { + var subtrackRanksCollection = []; + var slide = []; + // Might be able to change number of subtracks per slide based + // on screen size if the width of each subtrack is consistent: + // http://stackoverflow.com/questions/26252038/multi-item-responsive-carousel + numItemsPerSlide = numItemsPerSlide || 4; + + console.log('origin collection: ', vm.subtrackRanks); + for(var i = 0; i < vm.subtrackRanks.length; i++) { + if (slide.length === numItemsPerSlide) { + // When slide is full, push it to collection and make a new slide [] + subtrackRanksCollection.push(slide); + slide = []; + } + slide.push(vm.subtrackRanks[i]); + } + subtrackRanksCollection.push(slide); + vm.subtrackRanksCollection = subtrackRanksCollection; + console.log(vm.subtrackRanksCollection); + } } })(); diff --git a/app/my-dashboard/subtrack-stats/subtrack-stats.jade b/app/my-dashboard/subtrack-stats/subtrack-stats.jade index 4f8297aff..55b8db163 100644 --- a/app/my-dashboard/subtrack-stats/subtrack-stats.jade +++ b/app/my-dashboard/subtrack-stats/subtrack-stats.jade @@ -13,3 +13,16 @@ p.rating(ng-if="subtrack.track === 'DESIGN'", style="color: #21B2F1") {{subtrack.stat | number}} p {{subtrack.statType}} + + ul(rn-carousel, rn-carousel-controls) + li(ng-repeat="subtracks in vm.subtrackRanksCollection") + .track(ng-repeat="subtrack in subtracks", ui-sref="profile.subtrack({userHandle: vm.handle, track: subtrack.track, subTrack: subtrack.subTrack})") + .flex-wrapper + p.subtrack {{subtrack.subTrack | underscoreStrip}} + + p.rating(ng-if="subtrack.track !== 'DESIGN'", style="color: {{subtrack.stat | ratingColor}}") {{subtrack.stat | number}} + span(style="background-color: {{subtrack.stat | ratingColor}}", ng-if="subtrack.track === 'DEVELOP' || subtrack.track === 'DATA_SCIENCE'") + + p.rating(ng-if="subtrack.track === 'DESIGN'", style="color: #21B2F1") {{subtrack.stat | number}} + + p {{subtrack.statType}} diff --git a/app/topcoder.module.js b/app/topcoder.module.js index 5981f3b43..f5fee601d 100644 --- a/app/topcoder.module.js +++ b/app/topcoder.module.js @@ -29,7 +29,8 @@ 'dcbImgFallback', 'toaster', 'angular-intro', - 'ngMessages' + 'ngMessages', + 'angular-carousel' ]; angular.module('topcoder', dependencies).run(appRun); diff --git a/assets/css/my-dashboard/subtrack-stats.scss b/assets/css/my-dashboard/subtrack-stats.scss index e1f580ab4..daa445f4f 100644 --- a/assets/css/my-dashboard/subtrack-stats.scss +++ b/assets/css/my-dashboard/subtrack-stats.scss @@ -6,103 +6,137 @@ .tracks { @include horizontal-scroll; @media only screen and (min-width: 768px) { - display: flex; - flex-flow: row wrap; - justify-content: center; - overflow: visible; - white-space: normal; + display: none; } + } - .track { - position: relative; - display: inline-block; - margin-right: 65px; - padding: 20px 0; - @media only screen and (min-width: 768px) { - display: flex; - flex-direction: column; - align-items: center; - margin-right: 35px; - padding: 30px 20px; - cursor: pointer; - - &:hover { - background-color: $gray-lightest; - - .subtrack { - color: $gray-darkest; - border-bottom-color: $gray-darkest; - } - - p:last-child { - color: $gray-darkest; - } - } - + ul { + display: block; + height: 148px; + width: 665px; + margin: 0 auto; + @media only screen and (max-width: 767px) { + display: none; + } + li { + div:last-child { + margin-right: 0; } + } + } - &:first-child { - margin-left: 20px; - } + .rn-carousel-controls { + position: relative; + @media only screen and (max-width: 767px) { + display: none; + } - &:last-child { - margin-right: 20px; - } + .rn-carousel-control { + height: 148px; + width: 80px; + line-height: 148px; + top: -148px; + background-color: $gray-lightest; + color: $accent-gray; + text-align: center; + } - .flex-wrapper { - display: flex; - flex-direction: column; - align-items: center; - } + .rn-carousel-control-prev { + left: 0; + } + .rn-carousel-control-next { + right: 0; + } - &:not(:first-child):before { - content: ''; - display: block; - position: absolute; - top: 32px; - left: -30px; - @include forward-slash(1px, 60px, 0, 2px, 30deg); - background-color: #D1D3D4; - @media only screen and (min-width: 768px) { - top: 42px; - left: -18px; + } + + .track { + position: relative; + display: inline-block; + margin-right: 65px; + padding: 20px 0; + @media only screen and (min-width: 768px) { + width: 130px; + margin-right: 35px; + padding: 30px 20px; + cursor: pointer; + + &:hover { + background-color: $gray-lightest; + + .subtrack { + color: $gray-darkest; + border-bottom-color: $gray-darkest; + } + + p:last-child { + color: $gray-darkest; } } + } - p { - @include sofia-pro-regular; - font-size: 12px; - color: $accent-gray; + &:first-child { + margin-left: 20px; + } - &:last-child { - text-transform: uppercase; - } + &:last-child { + margin-right: 20px; + } + + .flex-wrapper { + display: flex; + flex-direction: column; + align-items: center; + } + + + &:not(:first-child):before { + content: ''; + display: block; + position: absolute; + top: 32px; + left: -30px; + @include forward-slash(1px, 60px, 0, 2px, 30deg); + background-color: #D1D3D4; + @media only screen and (min-width: 768px) { + top: 42px; + left: -18px; } + } + + p { + @include sofia-pro-regular; + font-size: 12px; + color: $accent-gray; - .subtrack { - padding-bottom: 7px; - border-bottom: 1px solid #D1D3D4; + &:last-child { + text-transform: uppercase; } + } - .rating { - position: relative; - margin-top: 17px; - margin-bottom: 7px; - font-size: 32px; - @media only screen and (max-width: 767px) { - margin-top: 10px; - } + .subtrack { + padding-bottom: 7px; + border-bottom: 1px solid #D1D3D4; + } - span { - position: absolute; - top: 5px; - right: -10px; - width: 6px; - height: 6px; - background-color: #5E9EF1; - } + .rating { + position: relative; + margin-top: 17px; + margin-bottom: 7px; + font-size: 32px; + @media only screen and (max-width: 767px) { + margin-top: 10px; + } + + span { + position: absolute; + top: 5px; + right: -10px; + width: 6px; + height: 6px; + background-color: #5E9EF1; } } } diff --git a/bower.json b/bower.json index 37c40f6ad..d63fcb82c 100644 --- a/bower.json +++ b/bower.json @@ -46,7 +46,8 @@ "ng-busy": "~0.2.0", "ng-notifications-bar": "~0.0.15", "ngDialog": "0.5.1", - "restangular": "~1.5.1" + "restangular": "~1.5.1", + "angular-carousel": "~1.0.1" }, "devDependencies": { "bardjs": "~0.1.4", From 4def3feaf963a0d05e3830e39be30b2dbdcae0bb Mon Sep 17 00:00:00 2001 From: Nick Litwin Date: Wed, 14 Oct 2015 14:16:51 -0700 Subject: [PATCH 2/2] Clean up --- .../subtrack-stats/subtrack-stats.controller.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/my-dashboard/subtrack-stats/subtrack-stats.controller.js b/app/my-dashboard/subtrack-stats/subtrack-stats.controller.js index 3503689d9..7d2886f34 100644 --- a/app/my-dashboard/subtrack-stats/subtrack-stats.controller.js +++ b/app/my-dashboard/subtrack-stats/subtrack-stats.controller.js @@ -3,9 +3,9 @@ angular.module('tc.myDashboard').controller('SubtrackStatsController', SubtrackStatsController); - SubtrackStatsController.$inject = ['ProfileService', 'userIdentity', '$window']; + SubtrackStatsController.$inject = ['ProfileService', 'userIdentity']; - function SubtrackStatsController(ProfileService, userIdentity, $window) { + function SubtrackStatsController(ProfileService, userIdentity) { var vm = this; vm.loading = true; @@ -46,7 +46,6 @@ } else { return result; - } }, []); } @@ -66,6 +65,7 @@ }); } + // This function aids in showing multiple items (subtracks) per slide function buildCarouselSlide(numItemsPerSlide) { var subtrackRanksCollection = []; var slide = []; @@ -74,7 +74,6 @@ // http://stackoverflow.com/questions/26252038/multi-item-responsive-carousel numItemsPerSlide = numItemsPerSlide || 4; - console.log('origin collection: ', vm.subtrackRanks); for(var i = 0; i < vm.subtrackRanks.length; i++) { if (slide.length === numItemsPerSlide) { // When slide is full, push it to collection and make a new slide [] @@ -85,7 +84,6 @@ } subtrackRanksCollection.push(slide); vm.subtrackRanksCollection = subtrackRanksCollection; - console.log(vm.subtrackRanksCollection); } } })();