Commit 0b8a1b605091fce8e0b524431179435250387650

Authored by Andrew Buss
1 parent f05ccab307

still trying to fix login

Showing 12 changed files with 226 additions and 164 deletions Side-by-side Diff

1 1 styles/materialize.css: .PHONY
2 2 sassc materialize/sass/materialize.scss > styles/materialize.css
3 3  
  4 +fixjsstyle:
  5 + fixjsstyle --flagfile gjslint.conf config.js scripts/*{Controller,Directive,Service}.js
  6 +
4 7 .PHONY:
... ... @@ -14,13 +14,21 @@
14 14 'ngCookies']).
15 15 config(['$stateProvider', '$urlRouterProvider', '$httpProvider',
16 16 '$locationProvider',
17   - function ($stateProvider, $urlRouterProvider, $httpProvider, $locationProvider) {
  17 + function($stateProvider, $urlRouterProvider, $httpProvider, $locationProvider) {
18 18 'use strict';
19 19 $httpProvider.defaults.withCredentials = true;
20 20 $httpProvider.defaults.xsrfCookieName = 'csrftoken';
21 21 $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
22 22 $locationProvider.html5Mode(true);
23 23 $urlRouterProvider.otherwise('/home');
  24 + var auth_resolve = {
  25 + authorize: ['$q', 'UserService',
  26 + function($q, UserService) {
  27 + console.log('resolving user before continuing');
  28 + return UserService.getUserData();
  29 + }
  30 + ]
  31 + };
24 32 $stateProvider.
25 33 state('login', {
26 34 url: '/login',
27 35  
28 36  
29 37  
30 38  
31 39  
32 40  
33 41  
34 42  
35 43  
36 44  
37 45  
38 46  
39 47  
... ... @@ -28,78 +36,78 @@
28 36 controller: 'LoginController'
29 37 }).
30 38 state('logout', {
  39 + resolve: auth_resolve,
31 40 url: '/logout',
32 41 templateUrl: 'templates/logout.html',
33 42 controller: 'LogoutController'
34 43 }).
35 44 state('root', {
  45 + resolve: auth_resolve,
36 46 url: '/',
37 47 templateUrl: 'templates/root.html',
38   - controller: 'RootController',
39   - resolve: {
40   - authorize: ['UserService',
41   - function (UserService) {
42   - return UserService.getUserData();
43   - }
44   - ]
45   - }
46   -
  48 + controller: 'RootController'
47 49 }).
48 50 state('feed', {
  51 + resolve: auth_resolve,
49 52 url: '/feed',
50 53 templateUrl: 'templates/feed.html',
51   - controller: 'FeedController',
52   - resolve: {
53   - authorize: ['UserService',
54   - function (UserService) {
55   - return UserService.getUserData();
56   - }
57   - ]
58   - }
  54 + controller: 'FeedController'
59 55 }).
60 56 state('addclass', {
  57 + resolve: auth_resolve,
61 58 url: '/addclass',
62 59 templateUrl: 'templates/addclass.html',
63 60 controller: 'ClassAddController'
64 61 }).
65 62 state('deck', {
  63 + resolve: auth_resolve,
66 64 url: '/deck',
67 65 templateUrl: 'templates/deck.html',
68 66 controller: 'DeckController'
69 67 }).
70 68 state('study', {
  69 + resolve: auth_resolve,
71 70 url: '/study',
72 71 templateUrl: 'templates/study.html',
73 72 controller: 'StudyController'
74 73 }).
75 74 state('flashcard', {
  75 + resolve: auth_resolve,
76 76 url: '/flashcard',
77 77 templateUrl: 'templates/flashcard.html',
78 78 controller: 'FlashcardController'
79 79 }).
80 80 state('requestpasswordreset', {
  81 + resolve: auth_resolve,
81 82 url: '/requestpasswordreset',
82 83 templateUrl: 'templates/requestpasswordreset.html',
83 84 controller: 'RequestResetController'
84 85 }).
85 86 state('resetpassword', {
  87 + resolve: auth_resolve,
86 88 url: '/resetpassword/{uid}/{token}',
87 89 templateUrl: 'templates/resetpassword.html',
88 90 controller: 'ResetPasswordController'
89 91 }).
90 92 state('verifyemail', {
  93 + resolve: auth_resolve,
91 94 url: '/verifyemail/{key}',
92 95 templateUrl: 'templates/verifyemail.html',
93 96 controller: 'VerifyEmailController'
94 97 });
95 98 }]).run(['$rootScope', '$state', '$stateParams', '$location', 'UserService',
96   - function ($rootScope, $state, $stateParams, $location, UserService) {
97   - $rootScope.$on('$stateChangeStart', function (event, toState, toStateParams) {
  99 + function($rootScope, $state, $stateParams, $location, UserService) {
  100 + $rootScope.$on('$stateChangeStart', function(event, toState, toStateParams) {
  101 + if (UserService.isLoggedIn()) return console.log('no login required; going straight to ' + toState.name);
  102 + if (toState.name == 'login') return;
  103 + if (!UserService.isUserResolved()) return;
98 104 $rootScope.returnToState = toState;
99 105 $rootScope.returnToStateParams = toStateParams;
100   - console.log('going to' + toState.name);
101   - console.log(UserService.isLoggedIn());
102   - if (!UserService.isLoggedIn() && toState.name != 'login') $location.path('login');
  106 + console.log('going to ' + toState.name + ' after login');
  107 + $state.go('login');
  108 + });
  109 + $rootScope.$on('$routeChangeError', function() {
  110 + console.log('failed to change routes');
103 111 });
104 112 }
105 113 ]);
... ... @@ -27,70 +27,98 @@
27 27 }
28 28  
29 29 .angucomplete-selected-row {
30   - background-color:#aaaaff;
  30 + background-color: #aaaaff;
31 31 }
32 32  
33   -
34 33 .container .row {
35   - margin-left: 0;
36   - margin-right: 0;
  34 + margin-left: 0;
  35 + margin-right: 0;
37 36 }
38 37  
  38 +ul.side-nav.fixed li {
  39 + /*line-height: 30px;*/
  40 + /*font-weight:700;*/
  41 + font-size:24px;
  42 +}
  43 +
  44 +ul.side-nav.fixed li a {
  45 + /*line-height: 30px;*/
  46 + /*font-weight:700;*/
  47 + font-size:24px;
  48 +}
  49 +
  50 +
  51 +ul.side-nav.fixed li ul li {
  52 + /*line-height: 30px;*/
  53 + /*font-weight:700;*/
  54 + margin-left:20px;
  55 +}
  56 +
  57 +ul.side-nav.fixed li a {
  58 + /*line-height: 30px;*/
  59 + /*font-weight:700;*/
  60 + font-size:24px;
  61 +}
  62 +
  63 +
  64 +#logo-container{
  65 + height:110px;
  66 +}
39 67 /* Flashcard directive css */
40 68 .card.fixed-size {
41   - height: calc(3*5vw);
42   - min-height: calc(3*50px);
43   - min-width: calc(5*50px);
44   - width: calc(5*5vw);
  69 + height: calc(3 * 5vw);
  70 + min-height: calc(3 * 50px);
  71 + min-width: calc(5 * 50px);
  72 + width: calc(5 * 5vw);
45 73 }
46 74  
47 75 .card-overlay {
48   -/* display: none; */
49   - height: calc(3*5vw);
50   - left: 0;
51   - min-height: calc(3*50px);
52   - min-width: calc(5*50px);
53   - position: absolute;
54   - top: 0;
55   - width: calc(5*5vw);
  76 + /* display: none; */
  77 + height: calc(3 * 5vw);
  78 + left: 0;
  79 + min-height: calc(3 * 50px);
  80 + min-width: calc(5 * 50px);
  81 + position: absolute;
  82 + top: 0;
  83 + width: calc(5 * 5vw);
56 84 }
57 85  
58 86 .card-overlay i {
59   - color: #FFF;
  87 + color: #FFF;
60 88 }
61 89  
62 90 .card:hover .card-overlay {
63   - display: block;
  91 + display: block;
64 92 }
65 93  
66 94 .top-box {
67   - background-color: rgba(50,50,90,0.5);
68   - height: 50%;
69   - position: relative;
70   - width: 100%;
  95 + background-color: rgba(50, 50, 90, 0.5);
  96 + height: 50%;
  97 + position: relative;
  98 + width: 100%;
71 99 }
72 100  
73 101 .bottom-box {
74   - height: 50%;
75   - position: relative;
76   - width: 100%;
  102 + height: 50%;
  103 + position: relative;
  104 + width: 100%;
77 105 }
78 106  
79 107 .left-box {
80   - background-color: rgba(90,50,190,0.5);
81   - float: left;
82   - position: relative;
83   - width: 50%;
  108 + background-color: rgba(90, 50, 190, 0.5);
  109 + float: left;
  110 + position: relative;
  111 + width: 50%;
84 112 }
85 113  
86 114 .right-box {
87   - background-color: rgba(190,50,90,0.5);
88   - float: right;
89   - width: 50%;
  115 + background-color: rgba(190, 50, 90, 0.5);
  116 + float: right;
  117 + width: 50%;
90 118 }
91 119  
92 120 .center-me {
93   - margin: 0 auto;
  121 + margin: 0 auto;
94 122 }
95 123  
96 124 .container {
97 125  
98 126  
99 127  
100 128  
101 129  
102 130  
103 131  
104 132  
105 133  
106 134  
107 135  
108 136  
... ... @@ -108,65 +136,65 @@
108 136  
109 137 /* label color */
110 138 .input-field label {
111   - color: #673ab7;
  139 + color: #673ab7;
112 140 }
113 141  
114 142 /* label focus color */
115 143 .input-field input[type]:focus + label {
116   - color: #b388ff;
  144 + color: #b388ff;
117 145 }
118 146  
119 147 /* label underline focus color */
120 148 .input-field input[type]:focus {
121   - border-bottom: 1px solid #b388ff;
122   - box-shadow: 0 1px 0 0 #b388ff;
  149 + border-bottom: 1px solid #b388ff;
  150 + box-shadow: 0 1px 0 0 #b388ff;
123 151 }
124 152  
125 153 /* valid color */
126 154 .input-field input[type].valid {
127   - border-bottom: 1px solid #673ab7;
128   - box-shadow: 0 1px 0 0 #673ab7;
  155 + border-bottom: 1px solid #673ab7;
  156 + box-shadow: 0 1px 0 0 #673ab7;
129 157 }
130 158  
131 159 /* invalid color */
132 160 .input-field input[type].invalid {
133   - border-bottom: 1px solid #673ab7;
134   - box-shadow: 0 1px 0 0 #673ab7;
  161 + border-bottom: 1px solid #673ab7;
  162 + box-shadow: 0 1px 0 0 #673ab7;
135 163 }
136 164  
137 165 /* icon prefix focus color */
138 166 .input-field .prefix.active {
139   - color: #b388ff;
  167 + color: #b388ff;
140 168 }
141 169  
142 170 /* label focus color */
143 171 .input-field textarea[type]:focus + label {
144   - color: #b388ff;
  172 + color: #b388ff;
145 173 }
146 174  
147 175 /* label underline focus color */
148 176 .input-field textarea[type]:focus {
149   - border-bottom: 1px solid #b388ff;
150   - box-shadow: 0 1px 0 0 #b388ff;
  177 + border-bottom: 1px solid #b388ff;
  178 + box-shadow: 0 1px 0 0 #b388ff;
151 179 }
152 180  
153 181 body {
154   - background-color: #3e1944;
  182 + background-color: #3e1944;
155 183 }
156 184  
157 185 .btn {
158   - background-color: #673ab7;
  186 + background-color: #673ab7;
159 187 }
160 188  
161 189 .btn:hover {
162   - background-color: #7c4dff;
  190 + background-color: #7c4dff;
163 191 }
164 192  
165 193 .btn-floating {
166   - background-color: #673ab7;
  194 + background-color: #673ab7;
167 195 }
168 196  
169 197 .btn-floating:hover {
170   - background-color: #7c4dff;
  198 + background-color: #7c4dff;
171 199 }
gjslint.conf View file @ 0b8a1b6
1   ---summary
  1 +--max_line_length=140
... ... @@ -2,38 +2,39 @@
2 2 <html ng-app="flashy">
3 3 <base href="/app/">
4 4 <head>
5   - <link type="text/css" rel="stylesheet" href="styles/materialize.min.css" media="screen,projection"/>
  5 + <link type="text/css" rel="stylesheet" href="styles/materialize.min.css"
  6 + media="screen,projection"/>
6 7 <!--<link rel="stylesheet" href="styles/bootstrap-3.3.4-dist/css/bootstrap.css"/>-->
7   - <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/0.9.0/angular-material.min.css">
  8 + <link rel="stylesheet"
  9 + href="https://ajax.googleapis.com/ajax/libs/angular_material/0.9.0/angular-material.min.css">
8 10  
9 11 <link rel="stylesheet" href="flashy.css"/>
10 12 </head>
11 13  
12 14 <body ng-controller="RootController">
13 15  
14   -<ul ng-show="UserService.isLoggedIn()" id="slide-out" class="side-nav fixed">
15   - <ul class="collapsible collapsible-accordion">
16   - <div class = "top">
17   - <li id = "sidebar">
18   - <a class="collapsible-header waves-effect waves-teal active">
19   - Flashy
20   - </a>
21   -
22   - <div class ="collapsible-body" style="display: block;">
23   - <ul>
24   - <li class="bold"><a ui-sref="login">Login</a></li>
25   - <li class="bold"><a ui-sref="addclass">Add Class</a></li>
26   - <li class="bold"><a ui-sref="feed">Feed</a></li>
27   - <li class="bold"><a ui-sref="deck">Deck</a></li>
28   - <li class="bold"><a ui-sref="logout">Logout</a></li>
29   - </ul>
30   - </div>
31   - </li>
32   -
33   - </div>
34   - </ul>
35   -
  16 +<ul id="slide-out" class="side-nav fixed">
  17 + <li class="logo"><a href="//flashy.cards/" id="logo-container">
  18 + <h1>Flashy</h1>
  19 + </a></li>
  20 + <li class="bold">
  21 + <a>Classes</a>
  22 + <!--<a ui-sref="addclass"><i class="mdi-content-add"></i></a>-->
  23 + </li>
  24 + <li>
  25 + <ul>
  26 + <li ui-sref="feed">WRONG 123</li>
  27 + <li ui-sref="feed/4567">CSE 1337</li>
  28 + <li ui-sref="feed/1242">MATH 20Z</li>
  29 + <li ui-sref="feed/2842">BILD 99</li>
  30 + </ul>
  31 + </li>
  32 + <li class="bold"><a ui-sref="addclass">Add Class</a></li>
  33 + <li class="bold"><a ui-sref="feed">Feed</a></li>
  34 + <li class="bold"><a ui-sref="deck">Deck</a></li>
  35 + <li class="bold"><a ui-sref="logout">Logout</a></li>
36 36 </ul>
  37 +
37 38  
38 39 <div class="container" ui-view></div>
39 40 <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script>
scripts/FlashcardDirective.js View file @ 0b8a1b6
... ... @@ -5,7 +5,7 @@
5 5 templateUrl: '/app/templates/flashcard.html',
6 6 restrict: 'E',
7 7 link: function() {
8   - console.log("HELLO FROM FLASHCARD DIRECTIVE");
  8 + console.log('HELLO FROM FLASHCARD DIRECTIVE');
9 9 }
10 10 };
11 11 });
scripts/LoginController.js View file @ 0b8a1b6
1 1 angular.module('flashy.LoginController', ['ui.router']).
2 2  
3   - controller('LoginController', ['$scope', '$state', '$http', 'UserService',
4   - function($scope, $state, $http, UserService) {
  3 + controller('LoginController', ['$rootScope', '$scope', '$state', '$http', 'UserService',
  4 + function($rootScope, $scope, $state, $http, UserService) {
5 5 'use strict';
6   - if (UserService.isLoggedIn()) state.go('/addclass');
  6 + // If we're logged in, there's nothing to do here
  7 + if (UserService.isLoggedIn()) $state.go('addclass');
7 8 $scope.uniqueError = false;
8 9 $scope.loginError = false;
9 10 $scope.login = function(email, password) {
... ... @@ -13,7 +14,9 @@
13 14 })).
14 15 success(function(data) {
15 16 UserService.setUserData(data);
16   - $state.go('feed');
  17 + if (angular.isDefined($scope.returnToState))
  18 + $state.go($scope.returnToState.name, $scope.returnToStateParams);
  19 + else $state.go('addclass');
17 20 console.log(data);
18 21 }).
19 22 error(function(data, status, header, config) {
... ... @@ -29,7 +32,7 @@
29 32 'password': password
30 33 })).
31 34 success(function(data) {
32   - $state.go('feed');
  35 + $state.go($rootScope.returnToState);
33 36 console.log(data);
34 37 }).
35 38 error(function(data, status, headers, config) {
scripts/LogoutController.js View file @ 0b8a1b6
1 1 angular.module('flashy.LogoutController', ['ui.router']).
2   - controller('LogoutController', ['$scope', '$state', '$http', '$timeout',
3   - function($scope, $state, $http, $timeout) {
  2 + controller('LogoutController', ['$scope', '$state', '$http', '$timeout', 'UserService',
  3 + function($scope, $state, $http, $timeout, UserService) {
4 4 $http.post('/api/logout/').success(function() {
  5 + UserService.logout();
5 6 $timeout(function() {
6 7 $state.go('login');
7 8 }, 1000);
scripts/RootController.js View file @ 0b8a1b6
1 1 angular.module('flashy.RootController', ['ui.router']).
2 2  
3   - controller('RootController', ['$scope', '$state', 'UserService', function($scope, $state, UserService) {
  3 + controller('RootController', ['$rootScope', '$scope', '$state', 'UserService', function($rootScope, $scope, $state, UserService) {
4 4 //UserService.getUserData();
5   - $('#top').collapsible('accordion');
6   - //if (UserService.isLoggedIn()) $state.go('login');
7   - //else $state.go('addclass');
  5 + //$('#top').collapsible('accordion');
  6 + if (UserService.isLoggedIn()) $state.go('login');
  7 + else $state.go('addclass');
8 8 }]);
scripts/UserService.js View file @ 0b8a1b6
1 1 angular.module('flashy.UserService', ['ui.router']).
2   - service('UserService', function ($http, $q) {
  2 + service('UserService', function($rootScope, $http, $q) {
3 3 var _user = undefined;
4   - this.getUserData = function () {
  4 + this.getUserData = function() {
5 5 var deferred = $q.defer();
6 6 if (angular.isDefined(_user)) {
  7 + console.log('user is already defined: ' + _user);
  8 + if (!_user) deferred.reject(_user);
7 9 deferred.resolve(_user);
8 10 return deferred.promise;
9 11 }
10   - $http.get('/api/me/').success(function (data) {
11   - console.log('user is logged in!')
  12 + $http.get('/api/me/').success(function(data) {
  13 + console.log('user is logged in!');
  14 + _user = data;
12 15 deferred.resolve(data);
13   - }).error(function () {
  16 + }).error(function(data) {
14 17 deferred.reject('error getting own data');
15   - console.log(deferred);
  18 + _user = false;
  19 + console.log(data);
16 20 });
17 21 return deferred.promise;
18 22 };
19   - this.setUserData = function(data){
  23 + this.setUserData = function(data) {
20 24 _user = data;
21   - }
22   - this.isLoggedIn = function () {
23   - return !(!angular.isDefined(_user) && !_user);
  25 + };
  26 + this.isUserResolved = function() {
  27 + return angular.isDefined(_user);
  28 + };
  29 + this.logout = function() {
  30 + _user = undefined;
  31 + };
  32 + this.isLoggedIn = function() {
  33 + rv = this.isUserResolved() && _user;
  34 + console.log('is user logged in? ' + rv);
  35 + return rv;
24 36 };
25 37 });
templates/addclass.html View file @ 0b8a1b6
... ... @@ -14,8 +14,12 @@
14 14 >
15 15 <md-item-template>
16 16 <div layout="row">
17   - <div>{{item.short_name}}: {{item.course_title}} ({{item.instructor}})</div>
18   - <div style="margin-left:auto;text-align:right;padding-left:30px">{{item.lecture_times}}</div>
  17 + <div>{{item.short_name}}: {{item.course_title}}
  18 + ({{item.instructor}})
  19 + </div>
  20 + <div style="margin-left:auto;text-align:right;padding-left:30px">
  21 + {{item.lecture_times}}
  22 + </div>
19 23 </div>
20 24 </md-item-template>
21 25 <md-not-found>
templates/login.html View file @ 0b8a1b6
1 1 <div class="row">
2   -<div class="offset-s2 col s8">
  2 + <div class="offset-s2 col s8">
3 3 <ul class="tabs">
4 4 <li class="tab col s6"><a href="#register-tab">Sign Up</a></li>
5 5 <li class="tab col s6"><a class="active" href="#login-tab">Login</a></li>
6 6 </ul>
  7 + </div>
7 8 </div>
8   -</div>
9 9 <div class="row">
10   -<div class="offset-s2 col s8">
11   -<div class="card">
12   - <!--LOGIN TAB-->
13   - <div id="login-tab" class="row col s12">
14   - <div class="card-content">
15   - <div class="check-element animate-show" role="alert" ng-show="loginError">
16   - <span style="color:#8E2323">Invalid username or password!!</span>
  10 + <div class="offset-s2 col s8">
  11 + <div class="card">
  12 + <!--LOGIN TAB-->
  13 + <div id="login-tab" class="row col s12">
  14 + <div class="card-content">
  15 + <div class="check-element animate-show" role="alert" ng-show="loginError">
  16 + <span style="color:#8E2323">Invalid username or password!!</span>
  17 + </div>
  18 + <div class="input-field">
  19 + <input id="email" type="email" name="login" class="validate" ng-model="loginEmail" required/>
  20 + <label for="email">Email</label>
  21 + </div>
  22 + <div class="input-field">
  23 + <input id="password" type="password" name="password" class="validate" ng-model="loginPassword" required/>
  24 + <label for="password">Password</label>
  25 + </div>
17 26 </div>
18   - <div class="input-field">
19   - <input id="email" type="email" class="validate" ng-model="loginEmail" required/>
20   - <label for="email">Email</label>
  27 + <div class="card-action">
  28 + <button class="btn waves-effect waves-light col s12 blue lighten-1" type="submit" name="action"
  29 + ng-click="login(loginEmail, loginPassword)">Login
  30 + </button>
21 31 </div>
22   - <div class="input-field">
23   - <input id="password" type="password" class="validate" ng-model="loginPassword" required/>
24   - <label for="password">Password</label>
25   - </div>
26 32 </div>
27   - <div class="card-action">
28   - <button class="btn waves-effect waves-light col s12 blue lighten-1" type="submit" name="action"
29   - ng-click="login(loginEmail, loginPassword)">Login</button>
30   - </div>
31   - </div>
32   - <!--REGISTER TAB-->
33   - <div id="register-tab" class="row col s12">
34   - <div class="card-content">
35   - <div class="check-element animate-show" role="alert" ng-show="uniqueError">
36   - <span style="color:#8E2323">Invalid username or password!!</span>
  33 + <!--REGISTER TAB-->
  34 + <div id="register-tab" class="row col s12">
  35 + <div class="card-content">
  36 + <div class="check-element animate-show" role="alert" ng-show="uniqueError">
  37 + <span style="color:#8E2323">Invalid username or password!!</span>
  38 + </div>
  39 + <div class="input-field">
  40 + <input id="email" type="email" class="validate" ng-model="loginEmail" required/>
  41 + <label for="email">Email</label>
  42 + </div>
  43 + <div class="input-field">
  44 + <input type="password" class="validate" ng-model="registerPassword" required/>
  45 + <label for="password">Password</label>
  46 + </div>
37 47 </div>
38   - <div class="input-field">
39   - <input id="email" type="email" class="validate" ng-model="loginEmail" required/>
40   - <label for="email">Email</label>
  48 + <div class="card-action">
  49 + <button class="btn waves-effect waves-light col s12 blue lighten-1" type="" name="action"
  50 + ng-click="signUp(loginEmail, registerPassword)">Register
  51 + </button>
41 52 </div>
42   - <div class="input-field">
43   - <input type="password" class="validate" ng-model="registerPassword" required/>
44   - <label for="password">Password</label>
45   - </div>
46 53 </div>
47   - <div class="card-action">
48   - <button class="btn waves-effect waves-light col s12 blue lighten-1" type="" name="action"
49   - ng-click="signUp(loginEmail, registerPassword)">Register</button>
  54 +
  55 + <div class="row offset-s1 col s12">
  56 + <a class="trigger-password-reset" ng-click="triggerPasswordReset()" href="#">Forgot Password?</a>
50 57 </div>
51 58 </div>
52   -
53   - <div class="row offset-s1 col s12">
54   - <a class="trigger-password-reset" ng-click="triggerPasswordReset()" href="#">Forgot Password?</a>
55   - </div>
56   -</div>
57   -</div>
  59 + </div>
58 60 </div>