Skip to content
This repository was archived by the owner on Mar 4, 2025. It is now read-only.

Commit 7b500a9

Browse files
committedSep 29, 2015
Merge pull request #234 from appirio-tech/feature/settings-styles
Feature/settings styles
2 parents 8381751 + 371e7bf commit 7b500a9

25 files changed

+1340
-443
lines changed
 
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
(function() {
2+
'use strict';
3+
4+
angular.module('tcUIComponents').directive('tcBusyButton', tcBusyButton);
5+
6+
function tcBusyButton() {
7+
return {
8+
restrict: "A",
9+
scope: {
10+
tcBusyMessage: "=",
11+
tcBusyWhen: "="
12+
},
13+
link: function(scope, element, attrs) {
14+
scope.originalContent = element.html();
15+
scope.busyMessage = attrs.tcBusyMessage || "Saving...";
16+
scope.$watch('tcBusyWhen', function(newValue, oldValue) {
17+
if (newValue !== oldValue && newValue === true) {
18+
19+
var busyMessageHtml = String.supplant(
20+
'<i class="fa fa-spinner fa-spin"></i>&nbsp;<span style="text-transform:none;">{busyMessage}</span>',
21+
scope);
22+
element.attr('disabled', true).html('').append(busyMessageHtml);
23+
} else {
24+
element.removeAttr('disabled').html(scope.originalContent);
25+
}
26+
});
27+
}
28+
}
29+
}
30+
})();

‎app/directives/busy-button/busy-button.directive.spec.js

Whitespace-only changes.

‎app/directives/external-account/external-link-data.directive.jade

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
.external-link-list
22
div.external-link-tile(ng-repeat="account in linkedAccounts")
3-
div.logo
4-
i.fa(ng-class="(account|providerData:'className') || 'fa-globe'")
5-
h2 {{account|providerData:"displayName"}}
3+
.top
4+
div.logo
5+
i.fa(ng-class="(account|providerData:'className') || 'fa-globe'")
6+
h2 {{account|providerData:"displayName"}}
67

7-
div(ng-switch="account.provider")
8+
div.bottom(ng-switch="account.provider")
89

910
div(ng-switch-when="github")
1011
.handle {{account.data.handle}}

‎app/directives/skill-tile/skill-tile.directive.jade

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ a(ng-click="enableHide && toggle()")
44
i.colored(ng-show="icon", ng-class="icon")
55
img.default(ng-hide="icon", src="/images/ico-code-c.svg")
66
.name {{skill.tagName}} [{{skill.score}}]
7-
spam(ng-if="skill.hidden") Hidden
7+
span.hidden(ng-if="skill.hidden") (Hidden)
88

‎app/filters/track.filter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
'FRONT_END_FLASH': 'Front-End Flash',
2020
'APPLICATION_FRONT_END_DESIGN': 'Application Front-End Design',
2121
'DESIGN_FIRST_2_FINISH': 'Design First2Finish',
22-
'DEVELOP': 'DEVELOPMENT'
22+
'DEVELOP': 'Development'
2323
};
2424

2525
function capitalized(str) {

‎app/index.jade

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ html
143143
script(src="directives/account/validate-email.directive.js")
144144
script(src="directives/account/validate-register.directive.js")
145145
script(src="directives/badges/badge-tooltip.directive.js")
146+
script(src="directives/busy-button/busy-button.directive.js")
146147
script(src="directives/challenge-tile/challenge-tile.directive.js")
147148
script(src="directives/distribution-graph/distribution-graph.directive.js")
148149
script(src="directives/external-account/external-account.directive.js")

‎app/profile/profile.controller.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@
6161
// externalLinks
6262
vm.externalLinksPromise = ExternalAccountService.getLinkedExternalLinksData(vm.userHandle).then(function(data) {
6363
vm.linkedExternalAccountsData = data.plain();
64+
console.log('EXT')
65+
console.log(vm.linkedExternalAccountsData)
6466
vm.status.externalLinks = CONSTANTS.STATE_READY;
6567
}).catch(function(err) {
6668
vm.status.externalLinks = CONSTANTS.STATE_ERROR;

‎app/settings/account-info/account-info.controller.js

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,31 @@
33

44
angular.module('tc.settings').controller('AccountInfoController', AccountInfoController);
55

6-
AccountInfoController.$inject = ['userData', 'UserService', 'ProfileService', '$log', 'ISO3166'];
6+
AccountInfoController.$inject = ['userData', 'UserService', 'ProfileService', '$log', 'ISO3166', 'toaster'];
77

8-
function AccountInfoController(userData, UserService, ProfileService, $log, ISO3166) {
8+
function AccountInfoController(userData, UserService, ProfileService, $log, ISO3166, toaster) {
99
var vm = this;
1010
vm.saveAccountInfo = saveAccountInfo;
1111
vm.updateCountry = updateCountry;
12+
vm.isSocialRegistrant = false;
13+
vm.formProcessing = {
14+
accountInfoForm: false,
15+
newPasswordForm: false
16+
};
1217

1318
activate();
1419

1520
function activate() {
1621
processData();
17-
vm.userData = userData;
22+
vm.userData = _.clone(userData, true);
23+
UserService.getUserProfile({fields: 'credential'})
24+
.then(function(res) {
25+
vm.isSocialRegistrant = !res.credential.hasPassword;
26+
})
27+
.catch(function(err) {
28+
$log.error("Error fetching user profile. Redirecting to edit profile.");
29+
$state.go('settings.profile');
30+
});
1831

1932
vm.countries = ISO3166.getAllCountryObjects();
2033
vm.countryObj = ISO3166.getCountryObjFromAlpha3(userData.homeCountryCode);
@@ -24,15 +37,45 @@
2437
var countryCode = _.get(angucompleteCountryObj, 'originalObject.alpha3', undefined);
2538

2639
var isValidCountry = _.isUndefined(countryCode) ? false : true;
27-
vm.updateAccountInfo.country.$setValidity('required', isValidCountry);
40+
vm.accountInfoForm.country.$setValidity('required', isValidCountry);
2841
}
2942

3043
function saveAccountInfo() {
31-
ProfileService.updateUserProfile(userData);
44+
vm.formProcessing.accountInfoForm = true;
45+
ProfileService.updateUserProfile(userData)
46+
.then(function(data) {
47+
vm.formProcessing.accountInfoForm = false;
48+
toaster.pop('success', "Success!", "Your account information was updated.");
49+
})
50+
.catch(function() {
51+
vm.formProcessing.accountInfoForm = false;
52+
toaster.pop('error', "Whoops!", "Something went wrong. Please try again later.");
53+
})
3254
}
3355

3456
function processData() {
3557
vm.homeAddress = _.find(userData.addresses, {type: 'HOME'}) || {};
3658
}
59+
60+
function submitNewPassword() {
61+
vm.formProcessing.newPasswordForm = true;
62+
UserService.updatePassword(vm.newPassword, vm.currentPassword)
63+
.then(function() {
64+
vm.formProcessing.newPasswordForm = false;
65+
vm.newPassword = '';
66+
vm.currentPassword = '';
67+
toaster.pop('success', "Success", "Password successfully updated");
68+
vm.newPasswordForm.$setPristine();
69+
vm.currentPasswordFocus = false;
70+
// vm.placeholder = vm.defaultPlaceholder;
71+
// vm.currentPasswordPlaceholder = vm.currentPasswordDefaultPlaceholder;
72+
73+
$log.info('Your password has been updated.');
74+
})
75+
.catch(function(err) {
76+
vm.formProcessing.newPasswordForm = false;
77+
$log.error(err);
78+
});
79+
}
3780
}
3881
})();
Lines changed: 157 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,159 @@
11
.account-info-container
2-
h1.tab-title Account Info
3-
4-
.fields
5-
.field-section
6-
h4.field-title Username
7-
8-
p {{vm.userData.handle}}
9-
10-
.field-section
11-
h4.field-title Email
12-
13-
p {{vm.userData.email}}
14-
15-
.field-section.update-account-info
16-
form(name="vm.updateAccountInfo", role="form", ng-submit="vm.updateAccountInfo.$valid && vm.saveAccountInfo()", novalidate, autocomplete="off")
17-
// Stops Chrome from autofilling and autocompleting (along with autocomplete="off" on the form)
18-
input(autocomplete="false", name="hidden", type="text", style="display:none;")
19-
20-
.address-fields
21-
label *First name (Given name)
22-
input(name="firstname", type="text", value="{{vm.userData.firstName}}", ng-model="vm.userData.firstName", maxlength="64", required)
23-
24-
label *Last name (Surname)
25-
input(name="lastname", type="text", value="{{vm.userData.lastName}}", ng-model="vm.userData.lastName", maxlength="64", required)
26-
27-
label Address
28-
input(name="address", type="text", value="{{vm.homeAddress.streetAddr1}}", ng-model="vm.homeAddress.streetAddr1")
29-
30-
label Address 2 (apartment, suite, etc.)
31-
input(name="address2", type="text", value="{{vm.homeAddress.streetAddr2}}", ng-model="vm.homeAddress.streetAddr2")
32-
33-
label City
34-
input(name="city", type="text", value="{{vm.homeAddress.city}}", ng-model="vm.homeAddress.city")
35-
36-
label State/Province
37-
input(name="state", type="text", value="{{vm.homeAddress.stateCode}}", ng-model="vm.homeAddress.stateCode")
38-
39-
label Zip code/Post code
40-
input(name="zipcode", type="text", value="{{vm.homeAddress.zip}}", ng-model="vm.homeAddress.zip")
41-
42-
label *Country
43-
angucomplete-alt(
44-
input-name="country",
45-
pause="100",
46-
selected-object="vm.updateCountry",
47-
local-data="vm.countries",
48-
initial-value="vm.countryObj",
49-
search-fields="name",
50-
title-field="name",
51-
match-class="angucomplete-highlight",
52-
minlength="1"
2+
.settings-section.credentials
3+
.section-info
4+
h2 credentials
5+
.description Used to log in to your account and cannot be edited. Please contact support@topcoder.com if you need to make changes.
6+
7+
.section-fields
8+
.form-label.username Username
9+
input.form-field(name="username", value="{{vm.userData.handle}}", disabled=true)
10+
11+
.form-label email
12+
input.form-field(name="email", value="{{vm.userData.email}}", disabled=true)
13+
14+
div(ng-hide="vm.isSocialRegistration")
15+
form(name="vm.newPasswordForm", role="form", ng-submit="vm.newPasswordForm.$valid && vm.submitNewPassword()", novalidate)
16+
.form-label Current password
17+
.validation-bar(ng-class="{ 'success-bar': (vm.newPasswordForm.newPassword.$valid) }")
18+
toggle-password.form-field(ng-model="vm.currentPassword")
19+
//- input.form-field(
20+
//- name="currentPassword", type="text",
21+
//- placeholder="First",
22+
//- ng-model="vm.currentPassword",
23+
//- maxlength="64", required,
24+
//- ng-class="{'form-field-focused': hasFocus==true}"
25+
//- )
26+
27+
.form-label New Password
28+
.validation-bar(ng-class="{ 'success-bar': (vm.newPasswordForm.newPassword.$valid) }")
29+
toggle-password-with-tips.form-field(placeholder="Pick a new password")
30+
.tips.password-tips(ng-show="vm.passwordFocus")
31+
h3 Password Tips:
32+
33+
p Your password must have:
34+
35+
p(ng-class="{ 'has-length-between-range': (vm.newPasswordForm.password.$dirty && !vm.newPasswordForm.password.$error.minlength && !vm.newPasswordForm.password.$error.maxlength && !vm.newPasswordForm.password.$error.required) }") At least 8 characters
36+
37+
p(ng-class="{ 'has-letter': (vm.newPasswordForm.password.$dirty && !vm.newPasswordForm.password.$error.hasLetter) }") At least one letter
38+
39+
p(ng-class="{ 'has-symbol-or-number': (vm.newPasswordForm.password.$dirty && !vm.newPasswordForm.password.$error.hasSymbolOrNumber) }") At least one number or symbol
40+
41+
.button-container
42+
button.button-l.save(type="submit", tc-busy-button, tc-busy-when="vm.formProcessing.newPasswordForm", ng-disabled="vm.newPasswordForm.$invalid") Save
43+
44+
45+
div(ng-show="vm.isSocialRegistration")
46+
p You joined Topcoder by using an external account, so we don't have a password for you.
47+
48+
49+
form(name="vm.accountInfoForm", role="form", ng-submit="vm.accountInfoForm.$valid && vm.saveAccountInfo()", novalidate, autocomplete="off")
50+
51+
.settings-section.name
52+
.section-info
53+
h2 Name
54+
.description Required for legal purposes; will be kept private and not shared with anyone.
55+
56+
.section-fields
57+
58+
// Stops Chrome from autofilling and autocompleting (along with autocomplete="off" on the form)
59+
input(autocomplete="false", name="hidden", type="text", style="display:none;")
60+
.form-label.first First name
61+
span(style="text-transform: none;") &nbsp;(Given name)
62+
.validation-bar(ng-class="{ 'error-bar': (vm.accountInfoForm.$dirty && vm.accountInfoForm.firstname.$invalid), 'success-bar': (vm.accountInfoForm.$dirty && vm.accountInfoForm.firstname.$valid)}")
63+
input.form-field(
64+
name="firstname", type="text",
65+
placeholder="First",
66+
ng-model="vm.userData.firstName",
67+
maxlength="64", required,
68+
ng-class="{'form-field-focused': hasFocus==true}"
5369
)
54-
55-
.account-info-error
56-
p.form-error(ng-show="vm.updateAccountInfo.country.$error.required") Please choose a country from the list.
57-
58-
59-
button(type="submit", ng-disabled="vm.updateAccountInfo.$invalid", ng-class="{'enabled-button': vm.updateAccountInfo.$valid}") Save
70+
.form-input-error(ng-show="vm.accountInfoForm.firstname.$invalid")
71+
p(ng-show="vm.accountInfoForm.firstname.$error.required") This is a required field.
72+
73+
.form-label Last name
74+
span(style="text-transform: none;") &nbsp;(Surname)
75+
.validation-bar(ng-class="{ 'error-bar': (vm.accountInfoForm.$dirty && vm.accountInfoForm.lastname.$invalid), 'success-bar': (vm.accountInfoForm.$dirty && vm.accountInfoForm.lastname.$valid)}")
76+
input.form-field(
77+
name="lastname", type="text",
78+
placeholder="Last",
79+
ng-model="vm.userData.lastName",
80+
maxlength="64", required,
81+
ng-class="{'form-field-focused': hasFocus==true}"
82+
)
83+
.form-input-error(ng-show="vm.accountInfoForm.lastname.$invalid")
84+
p(ng-show="vm.accountInfoForm.lastname.$error.required") This is a required field.
85+
86+
87+
.settings-section.address
88+
.section-info
89+
h2 address
90+
.description Required for payments and in case we need to mail you something. Will be kept private and not shared with anyone.
91+
92+
.section-fields
93+
.form-label.address Address
94+
input.form-field(
95+
name="address", type="text",
96+
placeholder="123 Topcoder Ave.",
97+
value="{{vm.homeAddress.streetAddr1}}",
98+
ng-model="vm.homeAddress.streetAddr1",
99+
ng-class="{'form-field-focused': hasFocus==true}"
100+
)
101+
102+
.form-label Address 2
103+
span(style="text-transform: none;") &nbsp;(opt., suite, etc.)
104+
input.form-field(
105+
name="address2",
106+
type="text",
107+
placeholder="Suite 42",
108+
value="{{vm.homeAddress.streetAddr2}}",
109+
ng-model="vm.homeAddress.streetAddr2",
110+
ng-class="{'form-field-focused': hasFocus==true}"
111+
)
112+
113+
.form-label City
114+
input.form-field(
115+
name="city", type="text",
116+
value="{{vm.homeAddress.city}}",
117+
placeholder="Best City in the World",
118+
ng-model="vm.homeAddress.city",
119+
ng-class="{'form-field-focused': hasFocus==true}"
120+
)
121+
122+
.form-label State/Province
123+
input.form-field(
124+
name="state", type="text",
125+
value="{{vm.homeAddress.stateCode}}",
126+
placeholder="California",
127+
ng-model="vm.homeAddress.stateCode",
128+
ng-class="{'form-field-focused': hasFocus==true}"
129+
)
130+
131+
.form-label Zip
132+
input.form-field(
133+
name="zipcode", type="text",
134+
placeholder="Zip"
135+
value="{{vm.homeAddress.zip}}",
136+
ng-model="vm.homeAddress.zip",
137+
ng-class="{'form-field-focused': hasFocus==true}"
138+
)
139+
140+
.form-label Country
141+
angucomplete-alt(
142+
input-name="country",
143+
input-class="form-field",
144+
pause="100",
145+
selected-object="vm.updateCountry",
146+
local-data="vm.countries",
147+
initial-value="vm.countryObj",
148+
search-fields="name",
149+
title-field="name",
150+
match-class="angucomplete-highlight",
151+
minlength="1",
152+
ng-class="{'form-field-focused': hasFocus==true}"
153+
)
154+
.account-info-error(ng-show="vm.accountInfoForm.country.$invalid")
155+
p(ng-show="vm.accountInfoForm.country.$error.required") Please choose a country from the list.
156+
157+
158+
.button-container
159+
button.button-l(type="submit", tc-busy-button, tc-busy-when="vm.formProcessing.accountInfoForm", ng-disabled="vm.accountInfoForm.$invalid", ng-class="{'enabled-button': vm.accountInfoForm.$valid}") Save

0 commit comments

Comments
 (0)
This repository has been archived.