Commit 427d64e0d04f6fdb24f4ce22ecfbcb9981cacb3e

Authored by Leonardo Merlin
1 parent 252bbec3

Sync

src/app/components/proposal-box/proposal-box.directive.js
@@ -32,6 +32,8 @@ @@ -32,6 +32,8 @@
32 vm.focus = vm.focus || false; 32 vm.focus = vm.focus || false;
33 vm.STATE = null; 33 vm.STATE = null;
34 vm.errorOnSkip = false; 34 vm.errorOnSkip = false;
  35 + vm.showAuthMessage = null;
  36 + vm.voteProposalRedirectURI = null;
35 }; 37 };
36 38
37 ProposalBoxController.prototype.addListeners = function () { 39 ProposalBoxController.prototype.addListeners = function () {
@@ -43,9 +45,10 @@ @@ -43,9 +45,10 @@
43 } 45 }
44 46
45 if(data.error){ 47 if(data.error){
46 - vm.errorOnSkip = true; 48 + vm.errorOnSkip = data.error;
47 } 49 }
48 }); 50 });
  51 +
49 vm.$scope.$on('proposal-box:vote-response', function(event, data){ 52 vm.$scope.$on('proposal-box:vote-response', function(event, data){
50 vm.$log.debug('proposal-box:vote-response'); 53 vm.$log.debug('proposal-box:vote-response');
51 vm.$log.debug('event', event); 54 vm.$log.debug('event', event);
@@ -57,10 +60,18 @@ @@ -57,10 +60,18 @@
57 60
58 if(data.error) { 61 if(data.error) {
59 vm.STATE = vm.VOTE_STATUS.ERROR; 62 vm.STATE = vm.VOTE_STATUS.ERROR;
60 -  
61 } 63 }
  64 +
62 vm.message = data.message; 65 vm.message = data.message;
63 }); 66 });
  67 +
  68 + vm.$scope.$watch('vm.voteProposalRedirectURI', function(newValue, oldValue){
  69 + if(newValue && newValue !== oldValue){
  70 + var slug = vm.topic.slug;
  71 + var proposal_id = vm.proposal.id;
  72 + vm.voteProposalRedirectURI = 'state=programa&task=vote-proposal&slug=' + slug + '&proposal_id=' + proposal_id;
  73 + }
  74 + });
64 }; 75 };
65 76
66 ProposalBoxController.prototype.showContent = function (slug) { 77 ProposalBoxController.prototype.showContent = function (slug) {
@@ -85,7 +96,7 @@ @@ -85,7 +96,7 @@
85 vm.$log.debug('Sending vote', value); 96 vm.$log.debug('Sending vote', value);
86 }else{ 97 }else{
87 vm.$log.info('Must be logged in...'); 98 vm.$log.info('Must be logged in...');
88 - 99 + vm.showAuthMessage = true;
89 } 100 }
90 }; 101 };
91 102
src/app/components/proposal-box/proposal-box.html
1 <div class="proposal-box" ng-class="[{'focus': (vm.focus || (vm.STATE === vm.VOTE_STATUS.LOADING) )}, vm.category.slug]"> 1 <div class="proposal-box" ng-class="[{'focus': (vm.focus || (vm.STATE === vm.VOTE_STATUS.LOADING) )}, vm.category.slug]">
2 - <div ng-show="(vm.STATE === vm.VOTE_STATUS.SUCCESS) || (vm.STATE === vm.VOTE_STATUS.ERROR)">  
3 - FEEDBACK  
4 - </div>  
5 - <div ng-hide="(vm.STATE === vm.VOTE_STATUS.SUCCESS) || (vm.STATE === vm.VOTE_STATUS.ERROR)">  
6 - <div ng-show="vm.STATE === vm.VOTE_STATUS.LOADING">  
7 - <div class="proposal-loading">  
8 - <div class="shadow"></div>  
9 - <div class="text text-center" ng-show="!vm.errorOnSkip">  
10 - Carregando... 2 + <!-- <div ng-hide="(vm.STATE === vm.VOTE_STATUS.SUCCESS) || (vm.STATE === vm.VOTE_STATUS.ERROR)"> -->
  3 + <div>
  4 + <div ng-show="(vm.STATE === vm.VOTE_STATUS.SUCCESS) || (vm.STATE === vm.VOTE_STATUS.ERROR)">
  5 + <div class="proposal-message-panel">
  6 + <div class="row">
  7 + <div class="row-height">
  8 + <div class="col-sm-12 col-sm-height col-middle">
  9 + <div class="inside inside-full-height">
  10 + <div class="content text-center show-message">
  11 + <div class="row">
  12 + <div class="col-xs-12">
  13 + <div class="message-icon color-fg-white" ng-class="{'success': (vm.STATE === vm.VOTE_STATUS.SUCCESS), 'error': vm.STATE === vm.VOTE_STATUS.ERROR}">
  14 + <span ng-if="vm.STATE === vm.VOTE_STATUS.SUCCESS" class="glyphicon glyphicon-ok" aria-hidden="true"></span>
  15 + <span ng-if="vm.STATE === vm.VOTE_STATUS.ERROR" class="glyphicon glyphicon-remove" aria-hidden="true"></span>
  16 + </div>
  17 + </div>
  18 + </div>
  19 + <div class="row">
  20 + <div class="col-xs-12">
  21 + <p style="padding-top:20px;">{{vm.message}}</p>
  22 + </div>
  23 + </div>
  24 + </div>
  25 + </div>
  26 + </div>
  27 + </div>
11 </div> 28 </div>
12 - <div class="text" ng-show="vm.errorOnSkip">  
13 - Erro ao carregar nova proposta. 29 + </div>
  30 + </div>
  31 + <div ng-show="vm.showAuthMessage">
  32 + <div class="proposal-message-panel">
  33 + <div class="row">
  34 + <div class="row-height">
  35 + <div class="col-sm-12 col-sm-height col-middle">
  36 + <div class="inside inside-full-height">
  37 + <div class="content text-center">
  38 + <p>Você precisa estar logado para votar na proposta</p>
  39 + <br>
  40 + <p>
  41 + <!-- <a ui-sref="entrar({redirect_uri: vm.voteProposalRedirectURI})">Clique aqui</a> para ir para a página de login. -->
  42 + <a ui-sref="entrar({redirect_uri: vm.voteProposalRedirectURI})">Clique aqui para ir para a página de login</a>
  43 + </p>
  44 + </div>
  45 + </div>
  46 + </div>
  47 + </div>
  48 + </div>
  49 + </div>
  50 + </div>
  51 + <div ng-show="vm.STATE === vm.VOTE_STATUS.LOADING">
  52 + <div class="proposal-message-panel">
  53 + <div class="row">
  54 + <div class="row-height">
  55 + <div class="col-sm-12 col-sm-height col-middle">
  56 + <div class="inside inside-full-height">
  57 + <div class="content text-center">
  58 + <div ng-show="!vm.errorOnSkip">
  59 + <p>Carregando...</p>
  60 + </div>
  61 + <div ng-show="!vm.errorOnSkip">
  62 + <p>Erro ao carregar nova proposta proposta.</p>
  63 + <p>{{vm.errorOnSkip}}</p>
  64 + </div>
  65 + </div>
  66 + </div>
  67 + </div>
  68 + </div>
14 </div> 69 </div>
15 </div> 70 </div>
16 </div> 71 </div>
@@ -20,43 +75,43 @@ @@ -20,43 +75,43 @@
20 </div> 75 </div>
21 <div class="proposal-box--middle"> 76 <div class="proposal-box--middle">
22 <div class="proposal-box--content"> 77 <div class="proposal-box--content">
23 - <div class="proposal-box--content-inner">{{vm.proposal.abstract}}</div>  
24 - </div>  
25 - <div ng-hide="vm.canVote" class="proposal-box--join">  
26 - <button class="btn btn-link color-theme-common-fg" ng-click="vm.showContent(vm.topic.slug)">  
27 - Participe  
28 - <span class="glyphicon glyphicon-menu-right color-theme-common-fg" aria-hidde="true"></span>  
29 - </button>  
30 - </div>  
31 - <div ng-show="vm.canVote" class="proposal-box--actions text-center">  
32 - <div class="row">  
33 - <div class="col-xs-4">  
34 - <div class="action vote_for" ng-click="vm.vote(vm.VOTE_OPTIONS.UP)">  
35 - <div class="icon-circle">  
36 - <span class="glyphicon glyphicon-ok" aria-hidden="true"></span> 78 + <div class="proposal-box--content-inner">{{vm.proposal.abstract}}</div>
  79 + </div>
  80 + <div ng-hide="vm.canVote" class="proposal-box--join">
  81 + <button class="btn btn-link color-theme-common-fg" ng-click="vm.showContent(vm.topic.slug)">
  82 + Participe
  83 + <span class="glyphicon glyphicon-menu-right color-theme-common-fg" aria-hidde="true"></span>
  84 + </button>
  85 + </div>
  86 + <div ng-show="vm.canVote" class="proposal-box--actions text-center">
  87 + <div class="row">
  88 + <div class="col-xs-4">
  89 + <div class="action vote_for" ng-click="vm.vote(vm.VOTE_OPTIONS.UP)">
  90 + <div class="icon-circle">
  91 + <span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
  92 + </div>
  93 + <div class="action-label">Apoio</div>
37 </div> 94 </div>
38 - <div class="action-label">Apoio</div>  
39 </div> 95 </div>
40 - </div>  
41 - <div class="col-xs-4">  
42 - <div class="action skip" ng-click="vm.skip()">  
43 - <div class="icon-circle">  
44 - <span class="glyphicon glyphicon-share-alt" aria-hidden="true"></span> 96 + <div class="col-xs-4">
  97 + <div class="action skip" ng-click="vm.skip()">
  98 + <div class="icon-circle">
  99 + <span class="glyphicon glyphicon-share-alt" aria-hidden="true"></span>
  100 + </div>
  101 + <div class="action-label">Pular</div>
45 </div> 102 </div>
46 - <div class="action-label">Pular</div>  
47 </div> 103 </div>
48 - </div>  
49 - <div class="col-xs-4">  
50 - <div class="action vote_against" ng-click="vm.vote(vm.VOTE_OPTIONS.DOWN)">  
51 - <div class="icon-circle">  
52 - <span class="glyphicon glyphicon-remove" aria-hidden="true"></span> 104 + <div class="col-xs-4">
  105 + <div class="action vote_against" ng-click="vm.vote(vm.VOTE_OPTIONS.DOWN)">
  106 + <div class="icon-circle">
  107 + <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
  108 + </div>
  109 + <div class="action-label">Não Apoio</div>
53 </div> 110 </div>
54 - <div class="action-label">Não Apoio</div>  
55 </div> 111 </div>
56 </div> 112 </div>
57 </div> 113 </div>
58 </div> 114 </div>
59 - </div>  
60 <div class="proposal-box--bottom text-center"> 115 <div class="proposal-box--bottom text-center">
61 <div class="proposal-box--share"> 116 <div class="proposal-box--share">
62 <span>COMPARTILHE ESSA <b>PROPOSTA</b></span> 117 <span>COMPARTILHE ESSA <b>PROPOSTA</b></span>
@@ -66,12 +121,12 @@ @@ -66,12 +121,12 @@
66 </div> 121 </div>
67 </div> 122 </div>
68 <div class="proposal-box--ranking"> 123 <div class="proposal-box--ranking">
69 - <div class="proposal-box--ranking-inner">  
70 - <span class="icon icon-small icon-ranking" aria-hidden="true"></span>  
71 - <span>Colocação nos resultados:</span>  
72 - <span>{{vm.proposal.ranking_position}}º</span>  
73 - </div>  
74 - </div> 124 + <div class="proposal-box--ranking-inner">
  125 + <span class="icon icon-small icon-ranking" aria-hidden="true"></span>
  126 + <span>Colocação nos resultados:</span>
  127 + <span>{{vm.proposal.ranking_position}}º</span>
  128 + </div>
  129 + </div>
75 </div> 130 </div>
76 </div> 131 </div>
77 </div> 132 </div>
src/app/components/proposal-box/proposal-box.scss
@@ -72,29 +72,25 @@ @@ -72,29 +72,25 @@
72 } 72 }
73 } 73 }
74 74
75 - .proposal-loading {  
76 -  
77 - .text {  
78 - position: absolute;  
79 - color: #fff; 75 + .proposal-message-panel {
  76 + position: absolute;
  77 + width: 100%;
  78 + height: 100%;
  79 + top: 0;
  80 + left: 0;
  81 + z-index: 1000;
  82 + background-color: #f5f5f5;
  83 + background-color: rgba(245, 245, 245, 0.9);
  84 +
  85 + .row { height: 100%; }
  86 + .inside { position: relative; }
  87 +
  88 + .content {
  89 + color: #262626;
80 font-size: 24px; 90 font-size: 24px;
  91 + font-weight: bold;
81 line-height: 24px; 92 line-height: 24px;
82 - z-index: 1000;  
83 - width: 100%  
84 - top: 50%;  
85 - left: 0;  
86 - margin-top: -12px;  
87 - }  
88 -  
89 - .shadow {  
90 - content: "";  
91 - position: absolute;  
92 - z-index: 999;  
93 - width: 100%;  
94 - height: 100%;  
95 - top: 0;  
96 - left: 0;  
97 - background-color: rgba(0,0,0,.4); 93 + padding: 10px 30px;
98 } 94 }
99 } 95 }
100 96
src/app/components/util-service/utils.service.js
@@ -72,7 +72,7 @@ @@ -72,7 +72,7 @@
72 } 72 }
73 73
74 // Otherwise, use expected error message. 74 // Otherwise, use expected error message.
75 - return $q.reject(error.data.message); 75 + return $q.reject(error.data);
76 } 76 }
77 } 77 }
78 })(); 78 })();
src/app/index.constants.js
@@ -38,9 +38,9 @@ @@ -38,9 +38,9 @@
38 LOADING: 0x100 38 LOADING: 0x100
39 }) 39 })
40 .constant('VOTE_OPTIONS', { 40 .constant('VOTE_OPTIONS', {
41 - UP: 0x1,  
42 - DOWN: 0x10,  
43 - SKIP: 0x100 41 + UP: 1,
  42 + DOWN: -1,
  43 + SKIP: 0
44 }) 44 })
45 .constant('USER_ROLES', { 45 .constant('USER_ROLES', {
46 all: '*', 46 all: '*',
src/app/index.route.js
@@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
23 } 23 }
24 }) 24 })
25 .state('entrar', { 25 .state('entrar', {
26 - url: '/entrar?redirect_uri', 26 + url: '/entrar?redirect_uri&message',
27 ncyBreadcrumb: {label: 'Entrar'}, 27 ncyBreadcrumb: {label: 'Entrar'},
28 views: { 28 views: {
29 'header': { templateUrl: 'app/pages/header/header.html' }, 29 'header': { templateUrl: 'app/pages/header/header.html' },
src/app/pages/auth/auth.controller.js
@@ -159,7 +159,8 @@ @@ -159,7 +159,8 @@
159 case 'programa': 159 case 'programa':
160 vm.$state.go(state, { 160 vm.$state.go(state, {
161 slug: vm.params.slug, 161 slug: vm.params.slug,
162 - task: vm.params.task 162 + task: vm.params.task,
  163 + proposal_id: vm.params.proposal_id,
163 }); 164 });
164 break; 165 break;
165 default: 166 default:
src/app/pages/auth/signin.html
@@ -152,9 +152,8 @@ @@ -152,9 +152,8 @@
152 <div class="checkbox"> 152 <div class="checkbox">
153 <label for="user_terms_accepted"> 153 <label for="user_terms_accepted">
154 <input type="checkbox" id="user_terms_accepted" name="user_terms_accepted" value="aceito" ng-model="pageSignin.signup.user_terms_accepted" required> 154 <input type="checkbox" id="user_terms_accepted" name="user_terms_accepted" value="aceito" ng-model="pageSignin.signup.user_terms_accepted" required>
155 - Já li os 155 + Já li e concordo com os
156 <button type="button" class="btn btn-link" style="padding:0 0 4px 0;" data-toggle="modal" data-target="#modalTermosDeUso">Termos de Uso</button> 156 <button type="button" class="btn btn-link" style="padding:0 0 4px 0;" data-toggle="modal" data-target="#modalTermosDeUso">Termos de Uso</button>
157 - e concordo com os mesmos*  
158 </label> 157 </label>
159 </div> 158 </div>
160 </input> 159 </input>
src/app/pages/inicio/inicio.html
@@ -135,7 +135,7 @@ @@ -135,7 +135,7 @@
135 <header class="header"> 135 <header class="header">
136 <h2>Programas</h2> 136 <h2>Programas</h2>
137 <button type="button" class="btn btn-link" ng-click="pageInicio.showAllPrograms($event)"> 137 <button type="button" class="btn btn-link" ng-click="pageInicio.showAllPrograms($event)">
138 - <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> Ver todos os {{::pageInicio.programs.length}} programas 138 + <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> Ver todos os programas
139 </button> 139 </button>
140 </header> 140 </header>
141 </div> 141 </div>
src/app/pages/programas/programa.controller.js
@@ -6,13 +6,14 @@ @@ -6,13 +6,14 @@
6 .controller('ProgramaPageController', ProgramaPageController); 6 .controller('ProgramaPageController', ProgramaPageController);
7 7
8 /** @ngInject */ 8 /** @ngInject */
9 - function ProgramaPageController(DialogaService, PATH, $state, $location, $scope, $rootScope, $element, $timeout, $log) { 9 + function ProgramaPageController(DialogaService, PATH, VOTE_OPTIONS, $state, $location, $scope, $rootScope, $element, $timeout, $log) {
10 $log.debug('ProgramaPageController'); 10 $log.debug('ProgramaPageController');
11 11
12 var vm = this; 12 var vm = this;
13 13
14 vm.DialogaService = DialogaService; 14 vm.DialogaService = DialogaService;
15 vm.PATH = PATH; 15 vm.PATH = PATH;
  16 + vm.VOTE_OPTIONS = VOTE_OPTIONS;
16 vm.$state = $state; 17 vm.$state = $state;
17 vm.$location = $location; 18 vm.$location = $location;
18 vm.$scope = $scope; 19 vm.$scope = $scope;
@@ -31,7 +32,11 @@ @@ -31,7 +32,11 @@
31 32
32 vm.article = null; 33 vm.article = null;
33 vm.category = null; 34 vm.category = null;
  35 + vm.loading = null;
  36 + vm.loadingTopProposals = null;
  37 + vm.loadingProposalBox = null;
34 vm.sendProposalRedirectURI = null; 38 vm.sendProposalRedirectURI = null;
  39 + // vm.voteProposalRedirectURI = null;
35 vm.search = vm.$location.search(); 40 vm.search = vm.$location.search();
36 41
37 vm.error = false; 42 vm.error = false;
@@ -45,7 +50,7 @@ @@ -45,7 +50,7 @@
45 // Get program by slug 50 // Get program by slug
46 var slug = vm.$state.params.slug; 51 var slug = vm.$state.params.slug;
47 52
48 - if(!slug){ 53 + if (!slug) {
49 vm.$log.error('slug not defined.'); 54 vm.$log.error('slug not defined.');
50 vm.$log.info('Rollback to home page.'); 55 vm.$log.info('Rollback to home page.');
51 vm.$state.go('inicio', {}, {location: true}); 56 vm.$state.go('inicio', {}, {location: true});
@@ -55,6 +60,7 @@ @@ -55,6 +60,7 @@
55 vm.article = article; 60 vm.article = article;
56 vm.category = vm.article.categories[0]; 61 vm.category = vm.article.categories[0];
57 vm.sendProposalRedirectURI = 'state=programa&task=send-proposal&slug=' + slug; 62 vm.sendProposalRedirectURI = 'state=programa&task=send-proposal&slug=' + slug;
  63 + // vm.voteProposalRedirectURI = 'state=programa&task=vote-proposal&slug=' + slug;
58 64
59 // update the breadcrumb 65 // update the breadcrumb
60 vm.$rootScope.contentTitle = vm.article.title; 66 vm.$rootScope.contentTitle = vm.article.title;
@@ -67,43 +73,23 @@ @@ -67,43 +73,23 @@
67 }; 73 };
68 } 74 }
69 75
70 - vm.DialogaService.getProposalsByTopicId(vm.article.id, {}, function(data){ 76 + vm.loadingTopProposals = true;
  77 + vm.DialogaService.getProposalsByTopicId(vm.article.id, {}, function(data) {
71 vm.proposals = data.articles; 78 vm.proposals = data.articles;
72 vm.proposalsTopRated = vm.proposals.slice(0, 3); 79 vm.proposalsTopRated = vm.proposals.slice(0, 3);
73 - }, function (error) { 80 + vm.loadingTopProposals = false;
  81 + }, function(error) {
74 vm.$log.error(error); 82 vm.$log.error(error);
  83 + vm.loadingTopProposals = false;
75 }); 84 });
76 85
77 - if(vm.search.proposal_id){  
78 - var proposalUrlId = vm.search.proposal_id;  
79 - vm.DialogaService.getProposalById(proposalUrlId, {  
80 - 'limit': '1'  
81 - }, _handleSuccessGetProposal, _handleErrorGetProposal);  
82 -  
83 - }else{  
84 - // get random proposal  
85 - vm.DialogaService.getProposalsByTopicId(vm.article.id, {  
86 - 'order': 'random()',  
87 - 'limit': '1'  
88 - }, _handleSuccessGetProposal, _handleErrorGetProposal);  
89 - }  
90 -  
91 - function _handleSuccessGetProposal(data){  
92 - if(data && data.articles){  
93 - vm.randomProposal = data.articles[0];  
94 - }  
95 86
96 - // scroll to focused proposal  
97 - if(vm.search.proposal_id){  
98 - vm.$timeout(function(){  
99 - var target = angular.element('.focused-proposal');  
100 - angular.element('body').animate({scrollTop: target.offset().top}, 'fast');  
101 - }, 300);  
102 - }  
103 - }  
104 -  
105 - function _handleErrorGetProposal(error){  
106 - vm.$log.error(error); 87 + vm.loadingProposalBox = true;
  88 + if (vm.search.proposal_id) {
  89 + vm.loadProposalById(vm.search.proposal_id);
  90 + }else {
  91 + // random proposal
  92 + vm.loadRandomProposal();
107 } 93 }
108 94
109 vm.loading = false; 95 vm.loading = false;
@@ -111,9 +97,6 @@ @@ -111,9 +97,6 @@
111 vm.$log.error(error); 97 vm.$log.error(error);
112 vm.error = error; 98 vm.error = error;
113 vm.loading = false; 99 vm.loading = false;
114 -  
115 - // vm.$log.info('Rollback to home page.');  
116 - // vm.$state.go('inicio', {}, {location: true});  
117 }); 100 });
118 }; 101 };
119 102
@@ -125,21 +108,117 @@ @@ -125,21 +108,117 @@
125 }); 108 });
126 109
127 vm.$scope.$on('cadastro-proposa:startSendProposal', function(event, proposal) { 110 vm.$scope.$on('cadastro-proposa:startSendProposal', function(event, proposal) {
128 - // vm.$log.debug('proposal', proposal);  
129 vm.creatingProposal = true; 111 vm.creatingProposal = true;
130 - vm.DialogaService.createProposal(proposal, vm.article.id, function (response){ 112 + vm.DialogaService.createProposal(proposal, vm.article.id, function(response) {
131 vm.$log.debug('response', response); 113 vm.$log.debug('response', response);
132 vm.creatingProposal = false; 114 vm.creatingProposal = false;
133 - }, function (error) { 115 + }, function(error) {
134 vm.$log.error(error); 116 vm.$log.error(error);
135 vm.creatingProposal = false; 117 vm.creatingProposal = false;
136 }); 118 });
137 }); 119 });
138 120
139 vm.$scope.$on('proposal-box:vote', function(event, params) { 121 vm.$scope.$on('proposal-box:vote', function(event, params) {
  122 + // vm.$log.debug('event', event);
  123 + // vm.$log.debug('params', params);
  124 + var proposal_id = params.proposal_id;
  125 + var OPTION = params.OPTION;
  126 +
  127 + switch (OPTION){
  128 + case vm.VOTE_OPTIONS.UP:
  129 + case vm.VOTE_OPTIONS.DOWN:
  130 + case vm.VOTE_OPTIONS.SKIP:
  131 + vm.vote(proposal_id, OPTION);
  132 + break;
  133 + default:
  134 + vm.$log.error('Vote option not handled:', OPTION);
  135 + break;
  136 + }
  137 + });
  138 + };
  139 +
  140 + ProgramaPageController.prototype.loadProposalById = function(proposal_id) {
  141 + var vm = this;
  142 +
  143 + vm.DialogaService.getProposalById(proposal_id, {
  144 + 'limit': '1'
  145 + }, vm._handleSuccessOnGetProposal.bind(vm), vm._handleErrorOnGetProposal.bind(vm));
  146 + };
  147 +
  148 + ProgramaPageController.prototype.loadRandomProposal = function() {
  149 + var vm = this;
  150 +
  151 + vm.DialogaService.getProposalsByTopicId(vm.article.id, {
  152 + 'order': 'random()',
  153 + 'limit': '1'
  154 + }, vm._handleSuccessOnGetProposal.bind(vm), vm._handleErrorOnGetProposal.bind(vm));
  155 + };
  156 +
  157 + ProgramaPageController.prototype._handleSuccessOnGetProposal = function(data) {
  158 + var vm = this;
  159 +
  160 + if (data && data.articles) {
  161 + var MAX = data.articles.length;
  162 + vm.randomProposal = data.articles[Math.floor(Math.random() * MAX)];
  163 + vm.loadingProposalBox = false;
  164 + vm.$scope.$broadcast('proposal-box:proposal-loaded', { success: true});
  165 + }
  166 +
  167 + // scroll to focused proposal
  168 + if (vm.search.proposal_id) {
  169 + vm.$timeout(function() {
  170 + var target = angular.element('.focused-proposal');
  171 + if (target && target.length > 0) {
  172 + angular.element('body').animate({scrollTop: target.offset().top}, 'fast');
  173 + }
  174 + }, 300);
  175 + }
  176 + };
  177 +
  178 + ProgramaPageController.prototype._handleErrorOnGetProposal = function(error) {
  179 + var vm = this;
  180 + vm.$log.error(error);
  181 + vm.$scope.$broadcast('proposal-box:proposal-loaded', { error: true});
  182 + };
  183 +
  184 + ProgramaPageController.prototype.voteSkip = function() {
  185 + var vm = this;
  186 + vm.loadRandomProposal();
  187 + };
  188 +
  189 + ProgramaPageController.prototype.vote = function(proposal_id, value) {
  190 + var vm = this;
  191 +
  192 + if (value === vm.VOTE_OPTIONS.SKIP) {
  193 + vm.voteSkip();
  194 + return;
  195 + }
  196 +
  197 + if (!vm.$rootScope.currentUser) {
  198 + // vm.$state.go('entrar', {
  199 + // redirect_uri: vm.sendProposalRedirectURI,
  200 + // message: 'Você precisa estar logado para votar em uma proposta.'
  201 + // }, {
  202 + // location: true
  203 + // });
  204 + return;
  205 + }
  206 +
  207 + vm.DialogaService.voteProposal(proposal_id, {
  208 + value: value
  209 + }, function(response) {
  210 + vm.$log.debug('response', response);
  211 +
  212 + response.success = true;
  213 + vm.$scope.$broadcast('proposal-box:vote-response', response);
  214 + }, function(error) {
  215 + vm.$log.error('error', error);
140 216
  217 + error.error = true;
  218 + vm.$scope.$broadcast('proposal-box:vote-response', error);
141 }); 219 });
142 }; 220 };
  221 + ProgramaPageController.prototype.voteHasBeenComputed = function() {};
143 222
144 ProgramaPageController.prototype.showProposalsList = function() { 223 ProgramaPageController.prototype.showProposalsList = function() {
145 var vm = this; 224 var vm = this;
src/app/pages/programas/programa.html
@@ -23,9 +23,11 @@ @@ -23,9 +23,11 @@
23 <div class="container"> 23 <div class="container">
24 <div class="row"> 24 <div class="row">
25 <article class="program-preview"> 25 <article class="program-preview">
  26 + <!-- Preview > Titulo -->
26 <div class="col-md-12"> 27 <div class="col-md-12">
27 <h1 class="program-preview--title color-theme-fg">{{::pagePrograma.article.title}}</h1> 28 <h1 class="program-preview--title color-theme-fg">{{::pagePrograma.article.title}}</h1>
28 </div> 29 </div>
  30 + <!-- Preview > coluna da esquerda -->
29 <div class="col-md-8"> 31 <div class="col-md-8">
30 <div class="program-preview--box contraste-box"> 32 <div class="program-preview--box contraste-box">
31 <div class="program-preview--banner" ng-style="{'background-image':'url( {{::pagePrograma.banner.src}} )'}"></div> 33 <div class="program-preview--banner" ng-style="{'background-image':'url( {{::pagePrograma.banner.src}} )'}"></div>
@@ -55,24 +57,52 @@ @@ -55,24 +57,52 @@
55 </div> 57 </div>
56 </div> 58 </div>
57 </div> 59 </div>
  60 + <!-- Preview > coluna da direita -->
58 <div class="col-md-4"> 61 <div class="col-md-4">
59 <div class="row"> 62 <div class="row">
60 - <div class="col-xs-12" ng-if="pagePrograma.proposalsTopRated && pagePrograma.proposalsTopRated.length > 0">  
61 - <h3 class="color-theme-fg">Propostas mais votadas</h3>  
62 - <proposal-carousel proposals="pagePrograma.proposalsTopRated"></proposal-carousel>  
63 - </div>  
64 - <div class="col-xs-12" ng-if="pagePrograma.randomProposal" ng-class="{'focused-proposal': !!pagePrograma.search.proposal_id}">  
65 - <h3 class="color-theme-fg">Propostas nesse programa</h3>  
66 - <proposal-box proposal="pagePrograma.randomProposal" topic="pagePrograma.article" category="pagePrograma.category" can-vote="true" focus="{{pagePrograma.search.proposal_id}}" ></proposal-box> 63 +
  64 + <!-- Top Proposals -->
  65 + <div>
  66 + <!-- Loading Top Proposals -->
  67 + <div ng-if="pagePrograma.loadingTopProposals">
  68 + <div class="alert alert-info" role="alert">
  69 + Carregando propostas mais votadas...
  70 + </div>
  71 + </div>
  72 +
  73 + <!-- Top Proposals > Carousel -->
  74 + <div class="col-xs-12" ng-if="!pagePrograma.loadingTopProposals && pagePrograma.proposalsTopRated && pagePrograma.proposalsTopRated.length > 0">
  75 + <h3 class="color-theme-fg">Propostas mais votadas</h3>
  76 + <proposal-carousel proposals="pagePrograma.proposalsTopRated"></proposal-carousel>
  77 + </div>
67 </div> 78 </div>
68 - <div class="col-xs-12" ng-if="!pagePrograma.randomProposal && !(pagePrograma.proposalsTopRated && pagePrograma.proposalsTopRated.length > 0)">  
69 - <h3>Programas sem propostas</h3>  
70 - <p>  
71 - Este programa ainda não possui nenhuma proposta.  
72 - <div class="button--themed">  
73 - <button type="button" class="btn btn-block" ng-click="pagePrograma.showProposalForm()">Faça uma proposta</button> 79 +
  80 + <!-- Proposal Box -->
  81 + <div>
  82 + <div class="col-xs-12" ng-if="!pagePrograma.loadingProposalBox && pagePrograma.randomProposal" ng-class="{'focused-proposal': !!pagePrograma.search.proposal_id}">
  83 + <h3 class="color-theme-fg">Propostas nesse programa</h3>
  84 + <proposal-box proposal="pagePrograma.randomProposal" topic="pagePrograma.article" category="pagePrograma.category" can-vote="true" focus="{{pagePrograma.search.proposal_id}}" ></proposal-box>
  85 + </div>
  86 +
  87 + <!-- Loading Proposal Box -->
  88 + <div ng-if="pagePrograma.loadingProposalBox">
  89 + <div class="alert alert-info" role="alert">
  90 + Carregando propostas nesse programa...
74 </div> 91 </div>
75 - </p> 92 + </div>
  93 + </div>
  94 +
  95 + <!-- No Proposals? okay! -->
  96 + <div ng-if="!pagePrograma.loadingTopProposals && !pagePrograma.loadingProposalBox">
  97 + <div class="col-xs-12" ng-if="!pagePrograma.randomProposal && !(pagePrograma.proposalsTopRated && pagePrograma.proposalsTopRated.length > 0)">
  98 + <h3>Programas sem propostas</h3>
  99 + <p>
  100 + Este programa ainda não possui nenhuma proposta.
  101 + <div class="button--themed">
  102 + <button type="button" class="btn btn-block" ng-click="pagePrograma.showProposalForm()">Faça uma proposta</button>
  103 + </div>
  104 + </p>
  105 + </div>
76 </div> 106 </div>
77 </div> 107 </div>
78 </div> 108 </div>