Skip to content

Commit 8a320eb

Browse files
committed
Merge pull request silverbux#17 from silverbux/user-profile
User Profile
2 parents ff16dbc + 27c1e83 commit 8a320eb

File tree

10 files changed

+303
-1
lines changed

10 files changed

+303
-1
lines changed

angular/app/components/nav-header/nav-header.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ <h3>
243243
<!-- Menu Footer-->
244244
<li class="user-footer">
245245
<div class="pull-left">
246-
<a href="#" class="btn btn-default btn-flat">Profile</a>
246+
<a ui-sref="app.profile" class="btn btn-default btn-flat">Profile</a>
247247
</div>
248248
<div class="pull-right">
249249
<a ui-sref="app.logout" class="btn btn-default btn-flat">Sign out</a>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
function passwordVerifyClass () {
2+
return {
3+
require: "ngModel",
4+
scope: {
5+
passwordVerify: '='
6+
},
7+
link: function(scope, element, attrs, ctrl) {
8+
scope.$watch(function() {
9+
var combined;
10+
11+
if (scope.passwordVerify || ctrl.$viewValue) {
12+
combined = scope.passwordVerify + '_' + ctrl.$viewValue;
13+
}
14+
15+
return combined;
16+
}, function(value) {
17+
if (value) {
18+
ctrl.$parsers.unshift(function(viewValue) {
19+
var origin = scope.passwordVerify;
20+
21+
if (origin !== viewValue) {
22+
ctrl.$setValidity("passwordVerify", false);
23+
return undefined;
24+
} else {
25+
ctrl.$setValidity("passwordVerify", true);
26+
return viewValue;
27+
}
28+
});
29+
}
30+
});
31+
}
32+
}
33+
}
34+
35+
export const PasswordVerifyClassComponent = passwordVerifyClass
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<section class="content-header">
2+
<h1>Users <small>Module description here</small></h1>
3+
<ol class="breadcrumb">
4+
<li><a ui-sref="app.landing"><i class="fa fa-dashboard"></i> Home</a></li>
5+
<li><a ui-sref="app.userlist">User Lists</a></li>
6+
<li class="active">Edit User</li>
7+
</ol>
8+
</section>
9+
<section class="content">
10+
<div class="row">
11+
<div class="col-sm-12 col-md-7">
12+
<div class="box box-primary">
13+
<div class="box-header with-border">
14+
<h3 class="box-title">Profile</h3>
15+
</div>
16+
<form class="form-horizontal" name="userForm" ng-submit="vm.save(userForm.$valid, userForm)" novalidate>
17+
<div class="box-body">
18+
<div ng-if="vm.alerts" class="alert alert-{{alert.type}}" ng-repeat="alert in vm.alerts">
19+
<h4>{{alert.title}}</h4>
20+
<p ng-bind-html="alert.msg | trustHtml"></p>
21+
</div>
22+
<div class="form-group" ng-class="{ 'has-error': userForm.name.$invalid && ( vm.formSubmitted || userForm.name.$touched) }">
23+
<label for="inputEmail3" class="col-sm-3 control-label">Name</label>
24+
<div class="col-sm-9">
25+
<input type="text" class="form-control" ng-model="vm.userdata.data.name" name="name" placeholder="Name" required>
26+
<p ng-show="userForm.name.$error.required && ( vm.formSubmitted || userForm.name.$touched)" class="help-block">Name is required.</p>
27+
<p ng-show="userForm.name.customError" class="help-block">{{userForm.name.customError}}</p>
28+
</div>
29+
</div>
30+
<div class="form-group" ng-class="{ 'has-error': userForm.email.$invalid && ( vm.formSubmitted || userForm.email.$touched) }">
31+
<label for="inputEmail3" class="col-sm-3 control-label">Email</label>
32+
<div class="col-sm-9">
33+
<input type="email" class="form-control" ng-model="vm.userdata.data.email" name="email" placeholder="Email" required>
34+
<p ng-show="userForm.email.$error.required && ( vm.formSubmitted || userForm.email.$touched)" class="help-block">Email is required.</p>
35+
<p ng-show="userForm.email.$error.email && ( vm.formSubmitted || userForm.email.$touched)" class="help-block">This is not a valid email.</p>
36+
<p ng-show="userForm.email.customError" class="help-block">{{userForm.email.customError}}</p>
37+
</div>
38+
</div>
39+
<div class="page-header">
40+
<h4>Update Password <small>( Optional )</small></h4>
41+
</div>
42+
<div class="form-group" ng-class="{ 'has-error': userForm.current_password.$invalid && ( vm.formSubmitted || userForm.current_password.$touched) }">
43+
<label for="inputEmail3" class="col-sm-3 control-label">Current Password</label>
44+
<div class="col-sm-9">
45+
<input type="password" class="form-control" placeholder="Password" name="current_password"
46+
ng-model="vm.userdata.data.current_password"
47+
ng-minlength="8"
48+
ng-maxlength="50"
49+
ng-required="vm.userdata.data.new_password">
50+
<p ng-show="userForm.current_password.$error.required && ( vm.formSubmitted || userForm.current_password.$touched)" class="help-block">Password is required.</p>
51+
<p ng-show="userForm.current_password.$error.maxlength" class="help-block">Password is too long.</p>
52+
<p ng-show="userForm.current_password.$invalid &&
53+
userForm.current_password.$error.minlength &&
54+
userForm.current_password.$touched"
55+
class="help-block">Password is too short, Please enter more than 8 characters.</p>
56+
57+
<p ng-show="userForm.current_password.$invalid && (vm.formSubmitted || vm.errors.current_password)" class="help-block">{{vm.errors.current_password}}</p>
58+
<p ng-show="userForm.current_password.customError" class="help-block">{{userForm.current_password.customError}}</p>
59+
</div>
60+
</div>
61+
<div class="form-group" ng-class="{ 'has-error': userForm.new_password.$invalid && ( vm.formSubmitted || userForm.new_password.$touched) }">
62+
<label for="inputEmail3" class="col-sm-3 control-label">New Password</label>
63+
<div class="col-sm-9">
64+
<input type="password" class="form-control" placeholder="Password" name="new_password"
65+
ng-model="vm.userdata.data.new_password"
66+
ng-minlength="8"
67+
ng-maxlength="50"
68+
ng-required="vm.userdata.data.current_password">
69+
<p ng-show="userForm.new_password.$error.required && ( vm.formSubmitted || userForm.new_password.$touched)" class="help-block">New Password is required.</p>
70+
<p ng-show="userForm.new_password.$error.maxlength" class="help-block">Password is too long.</p>
71+
<p ng-show="userForm.new_password.$invalid &&
72+
userForm.new_password.$error.minlength &&
73+
userForm.new_password.$touched"
74+
class="help-block">Password is too short, Please enter more than 8 characters.</p>
75+
<p ng-show="userForm.new_password.$invalid && (vm.formSubmitted || vm.errors.new_password)" class="help-block">{{vm.errors.new_password}}</p>
76+
<p ng-show="userForm.new_password.customError" class="help-block">{{userForm.new_password.customError}}</p>
77+
</div>
78+
</div>
79+
<div class="form-group" ng-class="{ 'has-error': userForm.new_password_confirmation.$invalid && ( vm.formSubmitted || userForm.new_password_confirmation.$touched) }">
80+
<label for="inputEmail3" class="col-sm-3 control-label">Confirm Password</label>
81+
<div class="col-sm-9">
82+
<input type="password" class="form-control" placeholder="Password" name="new_password_confirmation"
83+
ng-model="vm.userdata.data.new_password_confirmation"
84+
ng-minlength="8"
85+
ng-maxlength="50"
86+
ng-required="vm.userdata.data.current_password"
87+
password-verify="vm.userdata.data.new_password">
88+
<p ng-show="userForm.new_password_confirmation.$error.required &&
89+
( vm.formSubmitted || userForm.new_password_confirmation.$touched)" class="help-block">Confirm Password is required.</p>
90+
<p ng-show="userForm.new_password_confirmation.$error.maxlength" class="help-block">Password is too long.</p>
91+
<p ng-show="userForm.new_password_confirmation.$invalid &&
92+
userForm.new_password_confirmation.$error.minlength &&
93+
userForm.new_password_confirmation.$touched"
94+
class="help-block">Password is too short, Please enter more than 8 characters.</p>
95+
<p ng-show="userForm.new_password_confirmation.$invalid && (vm.formSubmitted || vm.errors.new_password_confirmation)" class="help-block">{{vm.errors.new_password_confirmation}}</p>
96+
<p ng-show="userForm.new_password_confirmation.$error.passwordVerify && (vm.formSubmitted || userForm.new_password_confirmation.$touched)" class="help-block">Password Mismatch</p>
97+
<p ng-show="userForm.new_password_confirmation.customError" class="help-block">{{userForm.new_password.customError}}</p>
98+
</div>
99+
</div>
100+
</div>
101+
<div class="box-footer">
102+
<a ui-sref="app.userlist" class="btn btn-default"><i class="fa fa-angle-double-left"></i> Back</a>
103+
<button type="submit" class="btn btn-primary pull-right">Update</button>
104+
</div>
105+
</form>
106+
</div>
107+
</div>
108+
</div>
109+
</section>
110+
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
class UserProfileController{
2+
constructor($stateParams, $state, API){
3+
'ngInject';
4+
5+
this.$state = $state
6+
this.formSubmitted = false
7+
this.alerts = []
8+
this.userRolesSelected = []
9+
10+
if ($stateParams.alerts) {
11+
this.alerts.push($stateParams.alerts)
12+
}
13+
14+
let UserData = API.service('me', API.all('users'))
15+
UserData.one().get()
16+
.then((response) => {
17+
this.userdata = API.copy(response)
18+
this.userdata.data.current_password = ''
19+
this.userdata.data.new_password = ''
20+
this.userdata.data.new_password_confirmation = ''
21+
})
22+
}
23+
24+
save (isValid, userForm) {
25+
if (isValid) {
26+
let $state = this.$state
27+
28+
this.userdata.put()
29+
.then(() => {
30+
let alert = { type: 'success', 'title': 'Success!', msg: 'Profile has been updated.' }
31+
$state.go($state.current, { alerts: alert})
32+
}, (response) => {
33+
let formErrors = []
34+
35+
if(angular.isDefined(response.data.errors.message)) {
36+
formErrors = response.data.errors.message[0];
37+
} else {
38+
formErrors = response.data.errors;
39+
}
40+
41+
angular.forEach(formErrors, function(value, key) {
42+
let varkey = key.replace("data.", "")
43+
userForm[varkey].$invalid = true;
44+
userForm[varkey].customError = value[0];
45+
});
46+
47+
this.formSubmitted = true;
48+
})
49+
} else {
50+
this.formSubmitted = true;
51+
}
52+
}
53+
54+
$onInit(){
55+
}
56+
}
57+
58+
export const UserProfileComponent = {
59+
templateUrl: './views/app/components/user-profile/user-profile.component.html',
60+
controller: UserProfileController,
61+
controllerAs: 'vm',
62+
bindings: {}
63+
}
64+
65+

angular/app/components/user-profile/user-profile.less

Whitespace-only changes.

angular/config/routes.config.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ export function RoutesConfig ($stateProvider, $urlRouterProvider) {
5252
}
5353
}
5454
})
55+
.state('app.profile', {
56+
url: '/profile',
57+
data: {
58+
auth: true
59+
},
60+
views: {
61+
'main@app': {
62+
template: '<userProfile></userProfile>'
63+
}
64+
},
65+
params: {
66+
alerts: null
67+
}
68+
})
5569
.state('app.userlist', {
5670
url: '/user-lists',
5771
data: {

angular/index.components.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { UserProfileComponent } from './app/components/user-profile/user-profile.component';
12
import { UserVerificationComponent } from './app/components/user-verification/user-verification.component'
23
import { ComingSoonComponent } from './app/components/coming-soon/coming-soon.component'
34
import { UserEditComponent } from './app/components/user-edit/user-edit.component'
@@ -16,6 +17,7 @@ import { LoginFormComponent } from './app/components/login-form/login-form.compo
1617
import { RegisterFormComponent } from './app/components/register-form/register-form.component'
1718

1819
angular.module('app.components')
20+
.component('userprofile', UserProfileComponent)
1921
.component('userVerification', UserVerificationComponent)
2022
.component('comingsoon', ComingSoonComponent)
2123
.component('useredit', UserEditComponent)

angular/index.directives.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { RouteBodyClassComponent } from './app/components/route-bodyclass/route-bodyclass.component'
2+
import { PasswordVerifyClassComponent } from './app/components/password-verify/password-verify.component'
23

34
angular.module('app.components')
45
.directive('routeBodyclass', RouteBodyClassComponent)
6+
.directive('passwordVerify', PasswordVerifyClassComponent)

app/Http/Controllers/UserController.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,72 @@
88
use Bican\Roles\Models\Role;
99
use Bican\Roles\Models\Permission;
1010
use Input;
11+
use Auth;
12+
use Hash;
13+
use Validator;
1114

1215
class UserController extends Controller
1316
{
17+
public function getMe()
18+
{
19+
$user = Auth::user();
20+
21+
return response()->success($user);
22+
}
23+
24+
public function putMe(Request $request)
25+
{
26+
$user = Auth::user();
27+
28+
$this->validate($request, [
29+
'data.name' => 'required|min:3',
30+
'data.email' => 'required|email|unique:users,email,'.$user->id
31+
]);
32+
33+
$userForm = app('request')
34+
->only(
35+
'data.current_password',
36+
'data.new_password',
37+
'data.new_password_confirmation',
38+
'data.name',
39+
'data.email'
40+
);
41+
42+
$userForm = $userForm['data'];
43+
$user->name = $userForm['name'];
44+
$user->email = $userForm['email'];
45+
46+
if ($request->has('data.current_password')) {
47+
Validator::extend('hashmatch', function ($attribute, $value, $parameters) {
48+
return Hash::check($value, Auth::user()->password);
49+
});
50+
51+
$rules = [
52+
'data.current_password' => 'required|hashmatch:data.current_password',
53+
'data.new_password' => 'required|min:8|confirmed',
54+
'data.new_password_confirmation' => 'required|min:8',
55+
];
56+
57+
$payload = app('request')->only('data.current_password', 'data.new_password', 'data.new_password_confirmation');
58+
59+
$messages = array(
60+
'hashmatch' => 'Invalid Password',
61+
);
62+
63+
$validator = app('validator')->make($payload, $rules, $messages);
64+
65+
if ($validator->fails()) {
66+
return response()->error($validator->errors());
67+
} else {
68+
$user->password = Hash::make($userForm['new_password']);
69+
}
70+
}
71+
72+
$user->save();
73+
74+
return response()->success('success');
75+
}
76+
1477
/**
1578
* Get all users
1679
*
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
ngDescribe({
2+
name: 'Test user-profile component',
3+
modules: 'app',
4+
element: '<user-profile></user-profile>',
5+
tests: function (deps) {
6+
7+
it('basic test', () => {
8+
//
9+
});
10+
}
11+
});

0 commit comments

Comments
 (0)