diff --git a/app/directives/tc-banner/tc-banner.directive.js b/app/directives/tc-banner/tc-banner.directive.js new file mode 100644 index 000000000..d0b564eeb --- /dev/null +++ b/app/directives/tc-banner/tc-banner.directive.js @@ -0,0 +1,56 @@ +import angular from 'angular' +import _ from 'lodash' + +(function() { + 'use strict' + + angular.module('tcUIComponents') + .directive('tcBanner', tcBanner) + + tcBanner.$inject = ['CONSTANTS', 'BannerDataService'] + + function tcBanner(CONSTANTS, BannerDataService) { + return { + restrict: 'E', + transclude: true, + template: require('./tc-banner')(), + scope: { + bannerName: '@', + theme: '@' + }, + link : function(scope, element, attrs) { + var rootDiv = angular.element(element.children()[0]) + var contentDiv = _.find(rootDiv.children(), function(el) { + return angular.element(el).hasClass('content') + }) + scope.transcluded = angular.element(contentDiv)[0].children.length > 0 + }, + controller: ['$scope', '$attrs', '$element', '$parse', '$rootScope', function($scope, $attrs, $element, $parse, $rootScope) { + $scope.DOMAIN = CONSTANTS.domain + var vm = this + vm.title = null + vm.description = null + vm.img = null + vm.theme = _.get($scope, 'theme', null) + vm.ctas = null + + activate() + + vm.handleClick = function(_link) { + $rootScope.$broadcast(_link.eventName) + } + + function activate() { + var banner = BannerDataService.getBanner($scope.bannerName) + if (banner) { + vm.title = banner.title + vm.img = banner.img + vm.description = banner.description + vm.ctas = banner.ctas + } + } + }], + controllerAs: 'vm' + } + } +})() diff --git a/app/directives/tc-banner/tc-banner.jade b/app/directives/tc-banner/tc-banner.jade new file mode 100644 index 000000000..e1e541b95 --- /dev/null +++ b/app/directives/tc-banner/tc-banner.jade @@ -0,0 +1,11 @@ +.tc-banner-placeholder(class="{{vm.theme}}") + .image + img(ng-src="{{vm.img}}") + .title(ng-bind="vm.title") + .content(ng-transclude, ng-show="transcluded") + .description(ng-bind="vm.description") + .ctas + .cta(ng-repeat="link in vm.ctas") + a(class="{{link.cssClass}}", title="{{link.title}}", ng-href="{{link.url}}", ng-if="link.url") {{link.title}} + a(class="{{link.cssClass}}", title="{{link.title}}", ui-sref="{{link.state}}", ng-if="link.state") {{link.title}} + a(class="{{link.cssClass}}", title="{{link.title}}", ng-click="vm.handleClick(link)", ng-if="link.eventName") {{link.title}} diff --git a/app/index.js b/app/index.js index 8febaa723..5db926381 100644 --- a/app/index.js +++ b/app/index.js @@ -113,6 +113,7 @@ require('../assets/css/directives/design-challenge-user-place.scss') require('../assets/css/directives/challenge-tile.scss') require('../assets/css/directives/challenge-links.directive.scss') require('../assets/css/directives/badge-tooltip.scss') +require('../assets/css/directives/tc-banner.scss') require('../assets/css/community/statistics.scss') require('../assets/css/community/members.scss') require('../assets/css/community/community.scss') diff --git a/app/my-dashboard/my-dashboard.jade b/app/my-dashboard/my-dashboard.jade index 4e7b91215..e452d9e3d 100644 --- a/app/my-dashboard/my-dashboard.jade +++ b/app/my-dashboard/my-dashboard.jade @@ -5,6 +5,9 @@ .challenges(id="challenges", ui-view="my-challenges") + .tco + tc-banner(theme="black", banner-name="tco16") + .srms(id="srms", ui-view="srms", ng-show="dashboard.showSRMs") .programs(id="community", ui-view="programs") diff --git a/app/services/bannerDataService.js b/app/services/bannerDataService.js new file mode 100644 index 000000000..5edb77bf5 --- /dev/null +++ b/app/services/bannerDataService.js @@ -0,0 +1,42 @@ +import angular from 'angular' + +(function() { + 'use strict' + + angular.module('tc.services').factory('BannerDataService', BannerDataService) + + BannerDataService.$inject = ['CONSTANTS'] + + function BannerDataService(CONSTANTS) { + var bannersData = null + _init() + + var service = { + getBanner: getBanner + } + + return service + + function getBanner(stateName) { + if (bannersData[stateName]) { + return bannersData[stateName] + } + return null + } + + function _init() { + bannersData = { + 'tco16': { + title: '2016 Topcoder Open', + img: require('../../assets/images/nav/ico-tco16.svg'), + description: 'The Topcoder Open (TCO) is our annual online and onsite tournament to celebrate and reward the community.', + ctas: [{ + title: 'About TCO', + url: 'http://tco16.topcoder.com', + cssClass: 'tc-btn tc-btn-s tco-cta' + }] + } + } + } + } +})() diff --git a/assets/css/directives/tc-banner.scss b/assets/css/directives/tc-banner.scss new file mode 100644 index 000000000..b9b11d802 --- /dev/null +++ b/assets/css/directives/tc-banner.scss @@ -0,0 +1,127 @@ +@import 'topcoder/tc-includes'; + +$tco-color: #F47A20; +$tco-color-dark: #ea690b; + +.tc-banner-placeholder { + display: flex; + flex-direction: column; + align-items: center; + color: $gray-darkest; + padding: 20px 10px 20px 10px; + @media only screen and (min-width: 768px) { + padding: 30px 20px 30px 20px; + } + + .image { + margin-bottom: 15px; + + img { + width: 186px; + } + } + + .title { + @include sofia-pro-medium; + font-size: 24px; + line-height: 29px; + text-align: center; + text-transform: uppercase; + } + + .content { + margin-top: 20px; + @media only screen and (min-width: 768px) { + margin-top: 30px; + } + } + + .description { + max-width: 650px; + margin-top: 20px; + @include merriweather-sans-regular; + font-size: 15px; + line-height: 24px; + text-align: center; + @media only screen and (min-width: 768px) { + margin-top: 30px; + } + @media only screen and (min-width: 900px) { + max-width: 856px; + } + } + + .ctas { + text-align: center; + display: flex; + flex-direction: column; + margin-top: 20px; + @media only screen and (min-width: 768px) { + margin-top: 30px; + } + + .cta { + &:not(:first-child) { + margin-top: 30px; + } + } + + a { + text-transform: uppercase; + display: block; + @include sofia-pro-medium; + + &.primary-cta { + } + + &.secondary-cta { + font-size: 12px; + line-height: 12px; + color: $accent-gray; + } + + &.tco-cta { + border: 1px solid $tco-color; + background-color: $tco-color; + + &:focus { + border: 1px solid $tco-color; + background-color: $tco-color; + } + + &:hover { + background-color: $tco-color-dark; + border-color: $tco-color-dark; + } + + &:active { + background-color: $tco-color-dark; + border-color: $tco-color-dark; + } + } + } + } +} + +// themes + +// black +.tc-banner-placeholder.black { + background-color: #222222; + .title { + @include sofia-pro-bold; + color: $white; + } + + .description { + color: $white; + } + + .ctas { + .cta { + .learn-more { + color: $gray-lighter; + } + } + } +} diff --git a/assets/css/my-dashboard/my-dashboard.scss b/assets/css/my-dashboard/my-dashboard.scss index 956a9762e..9a4c48a00 100644 --- a/assets/css/my-dashboard/my-dashboard.scss +++ b/assets/css/my-dashboard/my-dashboard.scss @@ -11,7 +11,7 @@ background-color: $white; } - .challenges, .srms, .programs, .community-updates { + .challenges, .srms, .programs, .tco, .community-updates { @include module-l; margin-top: 1px; width: 100%; @@ -23,7 +23,7 @@ } } - .challenges, .srms, .programs, .community-updates { + .challenges, .srms, .programs, .tco, .community-updates { @media only screen and (min-width: 900px) { padding-top: 0px; }