Commit 4c0183630bda780eb58e93cb1f3a1ec7e9d67dcd
1 parent
105102b0
Exists in
master
and in
8 other branches
proposal-box: vote with captch (initial commit)
Showing
5 changed files
with
123 additions
and
30 deletions
Show diff stats
src/app/components/auth/auth.service.js
... | ... | @@ -53,11 +53,7 @@ |
53 | 53 | } |
54 | 54 | |
55 | 55 | function activate (code) { |
56 | - var url = '/api/v1/activate'; | |
57 | - // var data = { | |
58 | - // private_token: API.token, | |
59 | - // activation_code: code | |
60 | - // }; | |
56 | + var url = PATH.host + '/api/v1/activate'; | |
61 | 57 | var encodedData = 'private_token=' + API.token; |
62 | 58 | encodedData += '&activation_code=' + code; |
63 | 59 | |
... | ... | @@ -77,12 +73,7 @@ |
77 | 73 | } |
78 | 74 | |
79 | 75 | function changePassword (code, newPassword, newPasswordConfirmation){ |
80 | - var url = '/api/v1/new_password'; | |
81 | - // var data = { | |
82 | - // code: code, | |
83 | - // password: newPassword, | |
84 | - // password_confirmation: newPasswordConfirmation | |
85 | - // }; | |
76 | + var url = PATH.host + '/api/v1/new_password'; | |
86 | 77 | var encodedData = 'code=' + code; |
87 | 78 | encodedData += '&password=' + newPassword; |
88 | 79 | encodedData += '&password_confirmation=' + newPasswordConfirmation; |
... | ... | @@ -103,7 +94,7 @@ |
103 | 94 | } |
104 | 95 | |
105 | 96 | function forgotPassword (data){ |
106 | - var url = 'http://hom.login.dialoga.gov.br/api/v1/forgot_password'; | |
97 | + var url = PATH.host + '/api/v1/forgot_password'; | |
107 | 98 | var encodedData = ([ |
108 | 99 | 'value=' + data.login, |
109 | 100 | 'captcha_text=' + data.captcha_text, |
... | ... | @@ -129,8 +120,7 @@ |
129 | 120 | } |
130 | 121 | |
131 | 122 | function login (credentials) { |
132 | - var hostProd = 'http://login.dialoga.gov.br'; | |
133 | - var url = hostProd + '/api/v1/login'; | |
123 | + var url = PATH.host + '/api/v1/login'; | |
134 | 124 | var encodedData = 'login=' + credentials.username + '&password=' + credentials.password; |
135 | 125 | |
136 | 126 | return $http |
... | ... | @@ -149,6 +139,13 @@ |
149 | 139 | }); |
150 | 140 | } |
151 | 141 | |
142 | + function loginCaptcha (data) { | |
143 | + var url = PATH.host + '/api/v1/login-captcha'; | |
144 | + var encodedData = angular.element.param(data); | |
145 | + | |
146 | + return $http.post(url, encodedData); | |
147 | + } | |
148 | + | |
152 | 149 | function logout () { |
153 | 150 | |
154 | 151 | Session.destroy(); |
... | ... | @@ -190,6 +187,7 @@ |
190 | 187 | changePassword: changePassword, |
191 | 188 | forgotPassword: forgotPassword, |
192 | 189 | login: login, |
190 | + loginCaptcha: loginCaptcha, | |
193 | 191 | logout: logout, |
194 | 192 | isAuthenticated: isAuthenticated, |
195 | 193 | isAuthorized: isAuthorized | ... | ... |
src/app/components/proposal-box/proposal-box.directive.js
... | ... | @@ -9,15 +9,19 @@ |
9 | 9 | function proposalBox() { |
10 | 10 | |
11 | 11 | /** @ngInject */ |
12 | - function ProposalBoxController($scope, $rootScope, $state, VOTE_STATUS, VOTE_OPTIONS, $log) { | |
12 | + function ProposalBoxController($scope, $rootScope, $state, $timeout, $interval, $window, VOTE_STATUS, VOTE_OPTIONS, AuthService, $log) { | |
13 | 13 | $log.debug('ProposalBoxController'); |
14 | 14 | |
15 | 15 | var vm = this; |
16 | 16 | vm.$scope = $scope; |
17 | 17 | vm.$rootScope = $rootScope; |
18 | 18 | vm.$state = $state; |
19 | + vm.$timeout = $timeout; | |
20 | + vm.$interval = $interval; | |
21 | + vm.$window = $window; | |
19 | 22 | vm.VOTE_STATUS = VOTE_STATUS; |
20 | 23 | vm.VOTE_OPTIONS = VOTE_OPTIONS; |
24 | + vm.AuthService = AuthService; | |
21 | 25 | vm.$log = $log; |
22 | 26 | |
23 | 27 | vm.init(); |
... | ... | @@ -28,11 +32,11 @@ |
28 | 32 | |
29 | 33 | var vm = this; |
30 | 34 | |
31 | - vm.canVote = vm.canVote || false; | |
35 | + vm.showVote = vm.showVote || false; | |
32 | 36 | vm.focus = vm.focus || false; |
33 | 37 | vm.STATE = null; |
34 | 38 | vm.errorOnSkip = false; |
35 | - vm.showAuthMessage = null; | |
39 | + vm.showCaptchaForm = null; | |
36 | 40 | vm.voteProposalRedirectURI = null; |
37 | 41 | |
38 | 42 | var slug = vm.topic.slug; |
... | ... | @@ -68,6 +72,21 @@ |
68 | 72 | |
69 | 73 | vm.message = data.message; |
70 | 74 | }); |
75 | + | |
76 | + // Load captcha | |
77 | + var stop = null; | |
78 | + stop = vm.$interval(function(){ | |
79 | + var $el = angular.element('#serpro_captcha'); | |
80 | + | |
81 | + if ($el && $el.length > 0 ){ | |
82 | + vm.$window.initCaptcha($el[0]); | |
83 | + vm.$interval.cancel(stop); | |
84 | + stop = undefined; | |
85 | + }else{ | |
86 | + vm.$log.debug('captcha element not found.'); | |
87 | + } | |
88 | + | |
89 | + }, 10); | |
71 | 90 | }; |
72 | 91 | |
73 | 92 | ProposalBoxController.prototype.showContent = function (slug) { |
... | ... | @@ -81,18 +100,56 @@ |
81 | 100 | }); |
82 | 101 | }; |
83 | 102 | |
103 | + ProposalBoxController.prototype.canVote = function () { | |
104 | + return false; | |
105 | + }; | |
106 | + | |
107 | + ProposalBoxController.prototype.submitCaptcha = function ($event, captchaForm) { | |
108 | + var vm = this; | |
109 | + | |
110 | + var target = $event.target; | |
111 | + var $target = angular.element(target); | |
112 | + var $captcha = $target.find('[name="txtToken_captcha_serpro_gov_br"]'); | |
113 | + | |
114 | + vm.sendingCaptcha = true; | |
115 | + vm.AuthService.loginCaptcha({ | |
116 | + captcha_text: captchaForm.captcha_text.$modelValue, | |
117 | + txtToken_captcha_serpro_gov_br: $captcha.val() | |
118 | + }).then(function(data) { | |
119 | + // SUCCESS | |
120 | + vm.$log.debug('register success.data', data); | |
121 | + | |
122 | + // get captcha_token | |
123 | + }, function(data) { | |
124 | + // ERROR | |
125 | + vm.$log.debug('register error.data', data); | |
126 | + | |
127 | + vm.sendingCaptchaError = {code: data.status }; | |
128 | + | |
129 | + if(data.status === 404){ | |
130 | + vm.$log.error('The api service is out!?'); | |
131 | + } | |
132 | + | |
133 | + }, function(data){ | |
134 | + // UPDATE | |
135 | + vm.$log.debug('register update.data', data); | |
136 | + }).finally(function(){ | |
137 | + vm.sendingCaptcha = false; | |
138 | + }); | |
139 | + }; | |
140 | + | |
84 | 141 | ProposalBoxController.prototype.vote = function (value) { |
85 | 142 | var vm = this; |
86 | 143 | |
87 | - if(vm.$rootScope.currentUser){ | |
144 | + if(vm.canVote()){ | |
88 | 145 | vm.$scope.$emit('proposal-box:vote', { |
89 | 146 | OPTION: value, |
90 | 147 | proposal_id: vm.proposal.id |
91 | 148 | }); |
92 | 149 | vm.$log.debug('Sending vote', value); |
93 | 150 | }else{ |
94 | - vm.$log.info('Must be logged in...'); | |
95 | - vm.showAuthMessage = true; | |
151 | + vm.$log.debug('You cannot vote.'); | |
152 | + vm.showCaptchaForm = true; | |
96 | 153 | } |
97 | 154 | }; |
98 | 155 | |
... | ... | @@ -135,7 +192,7 @@ |
135 | 192 | proposal: '=', |
136 | 193 | topic: '=', |
137 | 194 | category: '=', |
138 | - canVote: '=', | |
195 | + showVote: '=', | |
139 | 196 | focus: '@' |
140 | 197 | // @ -> Text binding / one-way binding |
141 | 198 | // = -> Direct model binding / two-way binding | ... | ... |
src/app/components/proposal-box/proposal-box.html
... | ... | @@ -65,18 +65,48 @@ |
65 | 65 | </div> |
66 | 66 | </div> |
67 | 67 | </div> |
68 | - <div ng-show="vm.showAuthMessage"> | |
68 | + <div ng-show="vm.showCaptchaForm"> | |
69 | 69 | <div class="proposal-message-panel"> |
70 | 70 | <div class="row"> |
71 | 71 | <div class="row-height"> |
72 | 72 | <div class="col-sm-12 col-height col-middle"> |
73 | 73 | <div class="inside inside-full-height"> |
74 | 74 | <div class="content text-center"> |
75 | - <p>Você precisa estar logado para votar na proposta</p> | |
76 | - <br> | |
77 | - <p> | |
78 | - <a ui-sref="entrar({redirect_uri: vm.voteProposalRedirectURI})">Clique aqui para ir para a página de login</a> | |
79 | - </p> | |
75 | + <div ng-if="vm.sendingCaptcha"> | |
76 | + <p>Enviando captcha...</p> | |
77 | + </div> | |
78 | + <div ng-if="!vm.sendingCaptcha"> | |
79 | + | |
80 | + <div class="row" class="feedback-message" ng-if="vm.sendingCaptchaError"> | |
81 | + <div class="col-sm-12"> | |
82 | + <div class="feedback--title alert alert-danger">Erro!</div> | |
83 | + <div class="feedback--message" ng-if="vm.sendingCaptchaError.code === 404"> | |
84 | + <p> | |
85 | + Houve uma falha. Já estamos trabalhando para resolver o problema. | |
86 | + <br/> Por favor, tente novamente mais tarde | |
87 | + </p> | |
88 | + </div> | |
89 | + </div> | |
90 | + </div> | |
91 | + <div ng-if="!vm.sendingCaptchaError"> | |
92 | + <form name="captchaForm" ng-submit="vm.submitCaptcha($event, captchaForm)"> | |
93 | + <div class="form-group"> | |
94 | + <div id="serpro_captcha" class="captcha"></div> | |
95 | + <div class="captcha">Digite os caracteres acima:</div> | |
96 | + <div class="captcha"> | |
97 | + <input type="text" name="captcha_text" id="captcha_text" aria-label="Escreva os caracteres do captcha aqui" ng-model="vm._captcha_text" ng-minlength="" ng-maxlength="" required> | |
98 | + <validation-messages field="captchaForm.captcha_text"></validation-messages> | |
99 | + </div> | |
100 | + </div> | |
101 | + <div class="form-group"> | |
102 | + <button type="submit" class="btn btn-lg btn-block btn-submit">Enviar</button> | |
103 | + </div> | |
104 | + <div class="form-group"> | |
105 | + <button class="btn btn-link" ng-click="vm.showCaptchaForm = false">Voltar</button> | |
106 | + </div> | |
107 | + </form> | |
108 | + </div> | |
109 | + </div> | |
80 | 110 | </div> |
81 | 111 | </div> |
82 | 112 | </div> |
... | ... | @@ -112,12 +142,12 @@ |
112 | 142 | <div class="proposal-box--content"> |
113 | 143 | <div class="proposal-box--content-inner">{{vm.proposal.abstract}}</div> |
114 | 144 | </div> |
115 | - <div ng-hide="vm.canVote" class="proposal-box--join"> | |
145 | + <div ng-hide="vm.showVote" class="proposal-box--join"> | |
116 | 146 | <button class="btn btn-link color-theme-common-fg" ng-click="vm.showContent(vm.topic.slug)"> |
117 | 147 | Participe |
118 | 148 | </button> |
119 | 149 | </div> |
120 | - <div ng-show="vm.canVote" class="proposal-box--actions text-center"> | |
150 | + <div ng-show="vm.showVote" class="proposal-box--actions text-center"> | |
121 | 151 | <div class="row"> |
122 | 152 | <div class="col-xs-4"> |
123 | 153 | <div class="action vote_for" ng-click="vm.vote(vm.VOTE_OPTIONS.UP)"> | ... | ... |
src/app/components/proposal-box/proposal-box.scss
... | ... | @@ -91,9 +91,15 @@ |
91 | 91 | .content { |
92 | 92 | color: #262626; |
93 | 93 | font-size: 24px; |
94 | + font-size: 2.4rem; | |
94 | 95 | font-weight: bold; |
95 | 96 | line-height: 24px; |
96 | 97 | padding: 10px 30px; |
98 | + | |
99 | + form { | |
100 | + font-size: 18px; | |
101 | + font-size: 1.8rem; | |
102 | + } | |
97 | 103 | } |
98 | 104 | |
99 | 105 | .message-icon { |
... | ... | @@ -108,11 +114,13 @@ |
108 | 114 | |
109 | 115 | &--title { |
110 | 116 | font-size: 22px; |
117 | + font-size: 2.2rem; | |
111 | 118 | font-weight: bold; |
112 | 119 | } |
113 | 120 | |
114 | 121 | &--message { |
115 | 122 | font-size: 14px; |
123 | + font-size: 1.4rem; | |
116 | 124 | font-weight: normal; |
117 | 125 | line-height: 20px; |
118 | 126 | margin-top: 48px; | ... | ... |
src/app/components/proposal-grid/proposal-grid.html
1 | 1 | <div class="proposal-grid row"> |
2 | 2 | <div ng-repeat="proposal in vm.proposals as results"> |
3 | - <proposal-box proposal="proposal" topic="proposal.parent" category="proposal.parent.categories[0]" class="col-xs-12 col-sm-6"></proposal-box> | |
3 | + <proposal-box proposal="proposal" topic="proposal.parent" category="proposal.parent.categories[0]" show-vote="false" class="col-xs-12 col-sm-6"></proposal-box> | |
4 | 4 | <div ng-if="$odd" class="clearfix"></div> |
5 | 5 | </div> |
6 | 6 | <div class="animate-repeat" ng-if="results.length == 0"> | ... | ... |