Commit 5f15306a6ccdc3a274bf48fdf3186bc8031c3616

Authored by Rachel Lee

Merge

Showing 24 changed files 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:
... ... @@ -10,7 +10,7 @@
10 10 'flashy.UserService',
11 11 'flashy.FlashcardDirective',
12 12 'flashy.ResetPasswordController',
13   - 'flashy.VerifyEmailController',
  13 + 'flashy.VerifyEmailController',
14 14 'ngCookies']).
15 15 config(['$stateProvider', '$urlRouterProvider', '$httpProvider',
16 16 '$locationProvider',
... ... @@ -21,6 +21,14 @@
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  
... ... @@ -28,36 +36,43 @@
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 48 controller: 'RootController'
39 49 }).
40 50 state('feed', {
41   - url: '/feed',
  51 + resolve: auth_resolve,
  52 + url: '/feed/{sectionId}',
42 53 templateUrl: 'templates/feed.html',
43 54 controller: 'FeedController'
44 55 }).
45 56 state('addclass', {
  57 + resolve: auth_resolve,
46 58 url: '/addclass',
47 59 templateUrl: 'templates/addclass.html',
48 60 controller: 'ClassAddController'
49 61 }).
50 62 state('deck', {
  63 + resolve: auth_resolve,
51 64 url: '/deck',
52 65 templateUrl: 'templates/deck.html',
53 66 controller: 'DeckController'
54 67 }).
55 68 state('study', {
  69 + resolve: auth_resolve,
56 70 url: '/study',
57 71 templateUrl: 'templates/study.html',
58 72 controller: 'StudyController'
59 73 }).
60 74 state('flashcard', {
  75 + resolve: auth_resolve,
61 76 url: '/flashcard',
62 77 templateUrl: 'templates/flashcard.html',
63 78 controller: 'FlashcardController'
... ... @@ -67,15 +82,32 @@
67 82 templateUrl: 'templates/requestpasswordreset.html',
68 83 controller: 'RequestResetController'
69 84 }).
70   - state('resetpassword', {
71   - url: '/resetpassword/{uid}/{token}',
72   - templateUrl: 'templates/resetpassword.html',
73   - controller: 'ResetPasswordController'
74   - }).
75   - state('verifyemail', {
76   - url: '/verifyemail/{key}',
77   - templateUrl: 'templates/verifyemail.html',
78   - controller: 'VerifyEmailController'
79   - });
80   - }]);
  85 + state('resetpassword', {
  86 + url: '/resetpassword/{uid}/{token}',
  87 + templateUrl: 'templates/resetpassword.html',
  88 + controller: 'ResetPasswordController'
  89 + }).
  90 + state('verifyemail', {
  91 + resolve: auth_resolve,
  92 + url: '/verifyemail/{key}',
  93 + templateUrl: 'templates/verifyemail.html',
  94 + controller: 'VerifyEmailController'
  95 + });
  96 + }]).run(['$rootScope', '$state', '$stateParams', '$location', 'UserService',
  97 + function($rootScope, $state, $stateParams, $location, UserService) {
  98 + $rootScope.$on('$stateChangeStart', function(event, toState, toStateParams) {
  99 + if (UserService.isLoggedIn()) return console.log('no login required; going straight to ' + toState.name);
  100 + if (toState.name == 'login') return console.log('we are going to login anyway; just let it happen :)');
  101 + if (!UserService.isUserResolved()) return console.log('user not yet resolved; hold off');
  102 + $rootScope.returnToState = toState;
  103 + $rootScope.returnToStateParams = toStateParams;
  104 + console.log('going to ' + toState.name + ' after login');
  105 + $state.go('login');
  106 + });
  107 + $rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) {
  108 + console.log('failed to change state: ' + error);
  109 + $state.go('login');
  110 + });
  111 + }
  112 + ]);
... ... @@ -27,15 +27,39 @@
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 +
39 63 /* Flashcard directive css */
40 64 .card {
41 65 word-wrap: break-word;
... ... @@ -107,6 +131,7 @@
107 131 transition: all 0.2s cubic-bezier(0,0,0.6,1) 0s;
108 132 width: 50%;
109 133 }
  134 +
110 135 .left-box:hover {
111 136 background-color: rgba(15,0,155,0.7);
112 137 }
113 138  
... ... @@ -130,9 +155,10 @@
130 155 }
131 156  
132 157 .container {
133   - position: relative;
  158 + margin-left: 250px;
  159 + /*position: relative;
134 160 width: 600px;
135   - height: 80px;
  161 + height: 80px;*/
136 162 }
137 163  
138 164 .modal.bottom-sheet {
139 165  
140 166  
141 167  
142 168  
143 169  
144 170  
145 171  
146 172  
147 173  
148 174  
149 175  
... ... @@ -143,57 +169,65 @@
143 169  
144 170 /* label color */
145 171 .input-field label {
146   - color: #673ab7;
  172 + color: #673ab7;
147 173 }
148 174  
149 175 /* label focus color */
150 176 .input-field input[type]:focus + label {
151   - color: #b388ff;
  177 + color: #b388ff;
152 178 }
153 179  
154 180 /* label underline focus color */
155 181 .input-field input[type]:focus {
156   - border-bottom: 1px solid #b388ff;
157   - box-shadow: 0 1px 0 0 #b388ff;
  182 + border-bottom: 1px solid #b388ff;
  183 + box-shadow: 0 1px 0 0 #b388ff;
158 184 }
159 185  
160 186 /* valid color */
161 187 .input-field input[type].valid {
162   - border-bottom: 1px solid #673ab7;
163   - box-shadow: 0 1px 0 0 #673ab7;
  188 + border-bottom: 1px solid #673ab7;
  189 + box-shadow: 0 1px 0 0 #673ab7;
164 190 }
165 191  
166 192 /* invalid color */
167 193 .input-field input[type].invalid {
168   - border-bottom: 1px solid #673ab7;
169   - box-shadow: 0 1px 0 0 #673ab7;
  194 + border-bottom: 1px solid #673ab7;
  195 + box-shadow: 0 1px 0 0 #673ab7;
170 196 }
171 197  
172 198 /* icon prefix focus color */
173 199 .input-field .prefix.active {
174   - color: #b388ff;
  200 + color: #b388ff;
175 201 }
176 202  
177 203 /* label focus color */
178 204 .input-field textarea[type]:focus + label {
179   - color: #b388ff;
  205 + color: #b388ff;
180 206 }
181 207  
182 208 /* label underline focus color */
183 209 .input-field textarea[type]:focus {
184   - border-bottom: 1px solid #b388ff;
185   - box-shadow: 0 1px 0 0 #b388ff;
  210 + border-bottom: 1px solid #b388ff;
  211 + box-shadow: 0 1px 0 0 #b388ff;
186 212 }
187 213  
188 214 body {
189   - background-color: #3e1944;
  215 + background-color: #3e1944;
190 216 }
191 217  
192 218 .btn {
193   - background-color: #673ab7;
  219 + background-color: #673ab7;
194 220 }
195 221  
  222 +.btn:hover {
  223 + background-color: #7c4dff;
  224 +}
  225 +
196 226 .btn-floating {
197   - background-color: #673ab7;
  227 + background-color: #673ab7;
  228 +}
  229 +
  230 +.btn-floating:hover {
  231 + background-color: #7c4dff;
198 232 }
gjslint.conf View file @ 5f15306
1   ---summary
  1 +--max_line_length=140
... ... @@ -2,25 +2,44 @@
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 id="nav" class="side-nav fixed">
15   - <li class="bold"><a ui-sref="login">Login</a></li>
  16 +<ul id="slide-out" ng-show="isLoggedIn" 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 ng-repeat="section in sections">
  26 + <li ui-sref="feed({{section.id}})">{{section.short_name}} </li>
  27 + </ul>
  28 + </li>
16 29 <li class="bold"><a ui-sref="addclass">Add Class</a></li>
  30 + <li class="bold"><a ui-sref="feed">Feed</a></li>
  31 + <li class="bold"><a ui-sref="deck">Deck</a></li>
  32 + <li class="bold"><a ui-sref="logout">Logout</a></li>
17 33 </ul>
  34 +
  35 +
18 36 <div class="container" ui-view></div>
19 37 <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script>
20 38 <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.14/angular-ui-router.js"></script>
21 39 <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-cookies.js"></script>
22 40 <script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
23 41 <script type="text/javascript" src="scripts/materialize.min.js"></script>
  42 +<script type="text/javascript" src="scripts/jquery.collapsible.js"></script>
24 43 <script src="https://ajax.googleapis.com/ajax/libs/angular_material/0.9.0/angular-material.min.js"></script>
25 44 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.min.js"></script>
26 45 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-aria.min.js"></script>
27 46  
... ... @@ -36,7 +55,9 @@
36 55 <script src="scripts/RequestResetController.js"></script>
37 56 <script src="scripts/ClassAddController.js"></script>
38 57 <script src="scripts/StudyController.js"></script>
  58 +<script src="scripts/ResetPasswordController.js"></script>
39 59 <script src="scripts/VerifyEmailController.js"></script>
  60 +<!--<script src="scripts/SidebarController.js"></script>-->
40 61  
41 62 <!-- Services -->
42 63 <script src="scripts/UserService.js"></script>
... ... @@ -46,10 +67,7 @@
46 67  
47 68 <!-- Other -->
48 69 <!--<script src="scripts/StudyController.js"></script>-->
49   -<script src="scripts/UserService.js"></script>
50   -<script src="scripts/ResetPasswordController.js"></script>
51   -<script src="//ghiden.github.io/angucomplete-alt/js/libs/angucomplete-alt.js"></script>
52   -<!--<script src="scripts/bootstrap.js"></script>-->
  70 +
53 71  
54 72 </body>
55 73 </html>
materialize/sass/components/_variables.scss View file @ 5f15306
1 1 /*** Colors ***/
2   -$primary-color: color("grey", "lighten-2") !default;
  2 +$primary-color: #3e1944 !default;
3 3 $primary-color-light: lighten($primary-color, 15%) !default;
4 4 $primary-color-dark: darken($primary-color, 15%) !default;
5 5  
scripts/ClassAddController.js View file @ 5f15306
1   -angular.module('flashy.ClassAddController', ['ui.router', 'angucomplete-alt', 'ngMaterial']).
  1 +angular.module('flashy.ClassAddController', ['ui.router', 'ngMaterial']).
2 2  
3 3 controller('ClassAddController', ['$scope', '$state', '$http', function($scope, $state, $http) {
4 4  
... ... @@ -13,6 +13,16 @@
13 13 };
14 14  
15 15 $scope.searchText = '';
  16 + $scope.submit = function() {
  17 + $http.post('/api/sections/' + $scope.selectedItem.id + '/enroll/').
  18 + success(function(data) {
  19 + $scope.sections.push($scope.selectedItem);
  20 + $state.go('feed', {sectionId: $scope.selectedItem.id});
  21 + }).
  22 + error(function(data, status, header, config) {
  23 + console.log(data);
  24 + });
  25 + };
16 26  
17 27 /*$scope.trySearch = function() {
18 28 $http.get('/api/sections/search', [$scope.searchText]).
scripts/DeckController.js View file @ 5f15306
... ... @@ -16,8 +16,8 @@
16 16  
17 17  
18 18 // reorganize cards in array based on time
19   - $scope.filter = function (card) {
20   -
  19 + $scope.filter = function(card) {
  20 +
21 21 // get index of card
22 22 var index = $scope.cards.indexOf(card);
23 23  
24 24  
25 25  
26 26  
27 27  
28 28  
29 29  
... ... @@ -38,25 +38,33 @@
38 38 };
39 39  
40 40  
41   - $scope.editCard = function (card) {
  41 + $scope.editCard = function(card) {
42 42  
  43 + var index = $scope.cards.indexOf(card);
  44 +
43 45 $('.modal-trigger').leanModal({
44 46 dismissible: true, // Modal can be dismissed by clicking outside of the modal
45 47 opacity: .5, // Opacity of modal background
46 48 in_duration: 300, // Transition in duration
47 49 out_duration: 200, // Transition out duration
  50 + ready: function() {
  51 +
  52 +
  53 + $scope.editableContent = $scope.cards[index].content;
  54 + }, // Callback for Modal open
  55 + complete: function() {
  56 +
  57 + $scope.cards[index].content = $scope.editableContent;
  58 +
  59 + } // Callback for Modal close
48 60 }
49 61 );
50 62  
51 63  
52   - // get index of card
53   - var index = $scope.cards.indexOf(card);
54 64  
55   - $scope.editedContent = $scope.cards[index].content;
56 65  
57   - $scope.cards[index].content = $scope.editedContent;
  66 + //alert($scope.cards[index].content);
58 67  
59   -
60 68 // post flashcard edits
61 69 /*$http.post('/api/flashcards/', { 'text': $scope.editedContent }).
62 70 success(function (data) {
... ... @@ -67,7 +75,7 @@
67 75 });
68 76  
69 77 */
70   - }
  78 + };
71 79  
72 80  
73 81  
scripts/FeedController.js View file @ 5f15306
1 1 angular.module('flashy.FeedController', ['ui.router']).
2 2  
3   - controller('FeedController', ['$scope', '$state', '$http', function($scope, $state, $http) {
  3 + controller('FeedController', ['$scope', '$stateParams', '$state', '$http', function($scope, $stateParams, $state, $http) {
4 4 console.log('Hello from feed');
5   -
  5 + sectionId = $stateParams.sectionId;
6 6 $scope.cards = [];
7 7  
  8 + $scope.cards[0] = {'id': 1, 'title': 'title1', 'content': 'abc'};
  9 + $scope.cards[1] = {'id': 2, 'title': 'title2', 'content': 'xyz'};
  10 + $scope.cards[2] = {'id': 2, 'title': 'title3', 'content': 'qwe'};
8 11  
9   - $scope.cards[0] = { 'id': 1, 'title': 'title1', 'content': 'abc' };
10   - $scope.cards[1] = { 'id': 2, 'title': 'title2', 'content': 'xyz' };
11   - $scope.cards[2] = { 'id': 2, 'title': 'title3', 'content': 'qwe' };
  12 + $http.get('/api/sections/' + sectionId + '/flashcards/').
  13 + success(function(data) {
  14 + for (var i = 0; i < data.length; i++) {
  15 + cards.push({'title': data[i].title, 'content': data[i].content});
  16 + }
  17 + }).
  18 + error(function(err) {
  19 + console.log('no');
  20 + });
12 21  
13   - $http.get("/api/sections/{pk}/flashcards").
14   - success(function(data) {
15   - for (var i = 0; i < data.length; i++) {
16   - cards.push({ 'title': data[i].title, 'content': data[i].content });
17   - }
18   - }).
19   - error(function(err) {
20   - console.log('no');
21   - });
22   -
23 22 $scope.viewDeck = function() {
24 23 $state.go('deck');
25 24 console.log('go to deck');
26 25  
27 26  
... ... @@ -38,30 +37,31 @@
38 37  
39 38 // attempt to make card :(
40 39 $http.post('/api/flashcards/', {'text': $scope.text, 'pushed': pushed, 'mask': []}).
41   - success(function(data) {
42   - console.log('No way, really?');
43   - }).
44   - error(function(error) {
45   - console.log('haha, n00b');
46   - });
  40 + success(function(data) {
  41 + console.log('No way, really?');
  42 + }).
  43 + error(function(error) {
  44 + console.log('haha, n00b');
  45 + });
47 46  
48 47 $scope.text = '';
49 48 };
50 49  
51   - $scope.flashcard = 'hi i am a flashcard. I need to be really long and awesome I ain\'t know how long I am right now. Is it good enough now?????????? Howz about now???';
  50 + $scope.flashcard = 'hi i am a flashcard. I need to be really long and awesome I ain\'t ' +
  51 + 'know how long I am right now. Is it good enough now?????????? Howz about now???';
52 52 $scope.text = '';
53   -
54   - $(document).ready(function(){
55   - // the "href" attribute of .modal-trigger must specify the modal ID that wants to be triggered
56   - $('.modal-trigger').leanModal({
57   - dismissible: true, // Modal can be dismissed by clicking outside of the modal
58   - opacity: 0, // Opacity of modal background
59   - in_duration: 300, // Transition in duration
60   - out_duration: 200, // Transition out duration
61   - /*ready: function() { alert('Ready'); }, // Callback for Modal open
62   - complete: function() { alert('Closed'); } // Callback for Modal close*/
63   - }
64   - );
  53 +
  54 + $(document).ready(function() {
  55 + // the "href" attribute of .modal-trigger must specify the modal ID that wants to be triggered
  56 + $('.modal-trigger').leanModal({
  57 + dismissible: true, // Modal can be dismissed by clicking outside of the modal
  58 + opacity: 0, // Opacity of modal background
  59 + in_duration: 300, // Transition in duration
  60 + out_duration: 200, // Transition out duration
  61 + /*ready: function() { alert('Ready'); }, // Callback for Modal open
  62 + complete: function() { alert('Closed'); } // Callback for Modal close*/
  63 + }
  64 + );
65 65 });
66 66  
67 67 }]);
scripts/LoginController.js View file @ 5f15306
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 we're logged in, there's nothing to do here
  7 + if (UserService.isLoggedIn()) $state.go('addclass');
6 8 $scope.uniqueError = false;
7 9 $scope.loginError = false;
8 10 $scope.login = function(email, password) {
9   - $http.post('/api/login', JSON.stringify({
  11 + $http.post('/api/login/', JSON.stringify({
10 12 'email': email,
11 13 'password': password
12 14 })).
13 15 success(function(data) {
14   - UserService.getUserData();
15   - $state.go('feed');
  16 + UserService.setUserData(data);
  17 + if (angular.isDefined($scope.returnToState))
  18 + $state.go($scope.returnToState.name, $scope.returnToStateParams);
  19 + else $state.go('addclass');
16 20 console.log(data);
17 21 }).
18 22 error(function(data, status, header, config) {
19 23  
... ... @@ -23,12 +27,12 @@
23 27 });
24 28 };
25 29 $scope.signUp = function(email, password) {
26   - $http.post('/api/register', JSON.stringify({
  30 + $http.post('/api/register/', JSON.stringify({
27 31 'email': email,
28 32 'password': password
29 33 })).
30 34 success(function(data) {
31   - $state.go('feed');
  35 + $state.go($rootScope.returnToState);
32 36 console.log(data);
33 37 }).
34 38 error(function(data, status, headers, config) {
... ... @@ -48,9 +52,9 @@
48 52 $scope.triggerPasswordReset = function() {
49 53 $state.go('requestpasswordreset');
50 54 };
51   - $(document).ready(function(){
52   - $('ul.tabs').tabs();
53   - });
  55 + $(document).ready(function() {
  56 + $('ul.tabs').tabs();
  57 + });
54 58 }
55 59 ]);
scripts/LogoutController.js View file @ 5f15306
1 1 angular.module('flashy.LogoutController', ['ui.router']).
2   - controller('LogoutController', ['$scope', '$state', '$timeout',
3   - function($scope, $state, $timeout) {
4   - $timeout(function($state) {
5   - $state.go('home');
6   - }, 1000);
  2 + controller('LogoutController', ['$scope', '$state', '$http', '$timeout', 'UserService',
  3 + function($scope, $state, $http, $timeout, UserService) {
  4 + $http.post('/api/logout/').success(function() {
  5 + UserService.logout();
  6 + $timeout(function() {
  7 + $state.go('login');
  8 + }, 1000);
  9 + }).error(function() {
  10 + console.log('Problem logging out');
  11 + });
7 12 }
8 13 ]);
scripts/RequestResetController.js View file @ 5f15306
... ... @@ -6,20 +6,20 @@
6 6 $scope.success = false;
7 7 $scope.error = false;
8 8 $scope.resetPass = function(email) {
9   - $http.post('/api/request_password_reset', JSON.stringify({
  9 + $http.post('/api/request_password_reset/', JSON.stringify({
10 10 'email': email
11 11 }))
12 12 .success(function(data) {
13 13 $scope.success = true;
14 14 //$state.go('requestresetsuccess');
15   - console.log("SUCCESS");
  15 + console.log('SUCCESS');
16 16 console.log(data);
17 17 })
18 18 .error(function(data, status, header, config) {
19 19 if (data.email) {
20 20 $scope.error = true;
21 21 }
22   - console.log("ERROR");
  22 + console.log('ERROR');
23 23 console.log(data);
24 24 });
25 25 };
scripts/ResetPasswordController.js View file @ 5f15306
... ... @@ -4,8 +4,8 @@
4 4 function($scope, $state, $http, $timeout) {
5 5 'use strict';
6 6 var url = document.location.href.split('/');
7   - var token = url[url.length-1];
8   - var uid = url[url.length-2];
  7 + var token = url[url.length - 1];
  8 + var uid = url[url.length - 2];
9 9 $scope.error = false;
10 10 $scope.success = false;
11 11 $scope.mismatch = false;
12 12  
13 13  
14 14  
15 15  
... ... @@ -13,19 +13,19 @@
13 13 /*if(token == 'resetpassword') {
14 14 $state.go('login');
15 15 }*/
16   - console.log("RESETTING");
  16 + console.log('RESETTING');
17 17 $scope.confirmResetPass = function() {
18   - if($scope.newPassword.length < 8) {
  18 + if ($scope.newPassword.length < 8) {
19 19 $scope.unacceptable = true;
20 20 return;
21 21 }
22   - if($scope.newPassword != $scope.confirmPassword) {
  22 + if ($scope.newPassword != $scope.confirmPassword) {
23 23 $scope.mismatch = true;
24 24 $scope.confirmPassword.$setPristine();
25   - console.log("mismatch");
  25 + console.log('mismatch');
26 26 return;
27 27 }
28   - $http.post('/api/reset_password', JSON.stringify({
  28 + $http.post('/api/reset_password/', JSON.stringify({
29 29 'uid': uid,
30 30 'token': token,
31 31 'new_password': $scope.newPassword
scripts/RootController.js View file @ 5f15306
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 + //UserService.getUserData();
  5 + //$('#top').collapsible('accordion');
4 6 if (UserService.isLoggedIn()) $state.go('login');
5 7 else $state.go('addclass');
  8 + $rootScope.isLoggedIn = false;
  9 + console.log(UserService._user);
  10 + UserService.getUserData().then(function(data) {
  11 + console.log(data);
  12 + $rootScope.user = data;
  13 + });
6 14 }]);
scripts/UserService.js View file @ 5f15306
1 1 angular.module('flashy.UserService', ['ui.router']).
2   - service('UserService', function($http, $q) {
3   - var _user = null;
4   - this.getUserData = function() {
  2 + service('UserService', function($rootScope, $http, $q) {
  3 + var _user = undefined;
  4 + $rootScope.sections = [];
  5 + this.getUserData = function(refresh) {
5 6 var deferred = $q.defer();
6   - $http.get('/api/user/me').success(function(data) {
  7 + if (angular.isDefined(_user)) {
  8 + console.log('user is already defined: ' + _user);
  9 + if (!_user) {
  10 + console.log('rejecting deferred');
  11 + deferred.reject(_user);
  12 + } else {
  13 + $rootScope.isLoggedIn = true;
  14 + $rootScope.sections = _user.sections;
  15 + deferred.resolve(_user);
  16 + }
  17 + return deferred.promise;
  18 + }
  19 + $http.get('/api/me/').success(function(data) {
  20 + console.log('user is logged in!');
  21 + _user = data;
  22 + $rootScope.isLoggedIn = true;
  23 + $rootScope.sections = _user.sections;
7 24 deferred.resolve(data);
8   - }).error(function() {
  25 + }).error(function(data) {
  26 + console.log('not logged in yet: ' + data.detail);
9 27 deferred.reject('error getting own data');
10   - console.log(deferred);
  28 + _user = false;
11 29 });
12   - _user = deferred.promise;
13   - return _user;
  30 + return deferred.promise;
14 31 };
  32 + this.setUserData = function(data) {
  33 + _user = data;
  34 + };
  35 + this.isUserResolved = function() {
  36 + return angular.isDefined(_user);
  37 + };
  38 + this.logout = function() {
  39 + $rootScope.isLoggedIn = false;
  40 + _user = undefined;
  41 + };
15 42 this.isLoggedIn = function() {
16   - return !_user;
  43 + rv = this.isUserResolved() && _user;
  44 + console.log('is user logged in? ' + rv);
  45 + return rv;
17 46 };
18 47 });
scripts/VerifyEmailController.js View file @ 5f15306
... ... @@ -3,27 +3,27 @@
3 3 .controller('VerifyEmailController', ['$scope', '$state', '$http', '$timeout',
4 4 function($scope, $state, $http, $timeout) {
5 5 'use strict';
6   - var url = document.location.href.split('/');
7   - var key = url[url.length-1];
  6 + var url = document.location.href.split('/');
  7 + var key = url[url.length - 1];
8 8 $scope.success = false;
9 9 $scope.error = false;
10   -
11   - $http.patch('/api/me', JSON.stringify({
12   - 'confirmation_key': key
13   - }))
14   - .success(function(data) {
15   - $scope.success = true;
16   - console.log("SUCCESS");
17   - console.log(data);
18   - $timeout(function($state) {
19   - $state.go('feed');
20   - }, 2000);
21   - })
22   - .error(function(data, status, header, config) {
23   - $scope.error = true;
24   - console.log("ERROR");
25   - console.log(data);
26   - });
  10 +
  11 + $http.patch('/api/me/', JSON.stringify({
  12 + 'confirmation_key': key
  13 + }))
  14 + .success(function(data) {
  15 + $scope.success = true;
  16 + console.log('SUCCESS');
  17 + console.log(data);
  18 + $timeout(function($state) {
  19 + $state.go('feed');
  20 + }, 2000);
  21 + })
  22 + .error(function(data, status, header, config) {
  23 + $scope.error = true;
  24 + console.log('ERROR');
  25 + console.log(data);
  26 + });
27 27 }
28 28 ]);
scripts/jquery.collapsible.js View file @ 5f15306
  1 +/*!
  2 +* Collapsible.js 1.0.0
  3 +* https://github.com/jordnkr/collapsible
  4 +*
  5 +* Copyright 2013, Jordan Ruedy
  6 +* This content is released under the MIT license
  7 +* http://opensource.org/licenses/MIT
  8 +*/
  9 +
  10 +(function($, undefined) {
  11 + $.fn.collapsible = function(effect, options) {
  12 +
  13 + var defaults = {
  14 + accordionUpSpeed: 400,
  15 + accordionDownSpeed: 400,
  16 + collapseSpeed: 400,
  17 + contentOpen: 0,
  18 + arrowRclass: 'arrow-r',
  19 + arrowDclass: 'arrow-d',
  20 + animate: true
  21 + };
  22 +
  23 + if (typeof effect === "object") {
  24 + var settings = $.extend(defaults, effect);
  25 + } else {
  26 + var settings = $.extend(defaults, options);
  27 + }
  28 +
  29 + return this.each(function() {
  30 + if (settings.animate === false) {
  31 + settings.accordionUpSpeed = 0;
  32 + settings.accordionDownSpeed = 0;
  33 + settings.collapseSpeed = 0;
  34 + }
  35 +
  36 + var $thisEven = $(this).children(':even');
  37 + var $thisOdd = $(this).children(':odd');
  38 + var accord = 'accordion-active';
  39 +
  40 + switch (effect) {
  41 + case 'accordion-open':
  42 + /* FALLTHROUGH */
  43 + case 'accordion':
  44 + if (effect === 'accordion-open') {
  45 + $($thisEven[settings.contentOpen]).children(':first-child').toggleClass(settings.arrowRclass + ' ' + settings.arrowDclass);
  46 + $($thisOdd[settings.contentOpen]).show().addClass(accord);
  47 + }
  48 + $($thisEven).click(function() {
  49 + if ($(this).next().attr('class') === accord) {
  50 + $(this).next().slideUp(settings.accordionUpSpeed).removeClass(accord);
  51 + $(this).children(':first-child').toggleClass(settings.arrowRclass + ' ' + settings.arrowDclass);
  52 + } else {
  53 + $($thisEven).children().removeClass(settings.arrowDclass).addClass(settings.arrowRclass);
  54 + $($thisOdd).slideUp(settings.accordionUpSpeed).removeClass(accord);
  55 + $(this).next().slideDown(settings.accordionDownSpeed).addClass(accord);
  56 + $(this).children(':first-child').toggleClass(settings.arrowRclass + ' ' + settings.arrowDclass);
  57 + }
  58 + });
  59 + break;
  60 + case 'default-open':
  61 + /* FALLTHROUGH */
  62 + default:
  63 + if (effect === 'default-open') {
  64 + $($thisEven[settings.contentOpen]).children(':first-child').toggleClass(settings.arrowRclass + ' ' + settings.arrowDclass);
  65 + $($thisOdd[settings.contentOpen]).show();
  66 + }
  67 + $($thisEven).click(function() {
  68 + $(this).children(':first-child').toggleClass(settings.arrowRclass + ' ' + settings.arrowDclass);
  69 + $(this).next().slideToggle(settings.collapseSpeed);
  70 + });
  71 + break;
  72 + }
  73 + });
  74 + };
  75 +})(jQuery);
1 1 //http://docs.casperjs.org/en/latest/modules/casper.html#captureselector
  2 +//Run with: casperjs --ssl-protocol=tlsv1 ss_test.js
2 3  
  4 +var casper = require('casper').create({
  5 + viewportSize: {width: 800, height: 600}
  6 +});
3 7  
4   -var casper = require('casper').create();
5   -
6   -casper.start('https://flashy.cards/app/login', function() {
7   - this.captureSelector('test.png', 'ul#nav.side-nav.fixed');
  8 +casper.start().zoom(.9).thenOpen('https://flashy.cards/app/login', function() {
  9 + this.captureSelector('test2.png','.ng-scope' );
8 10 });
9 11  
10 12 casper.run();
styles/materialize.css View file @ 5f15306
... ... @@ -2067,7 +2067,7 @@
2067 2067 .pagination li.active a {
2068 2068 color: #fff; }
2069 2069 .pagination li.active {
2070   - background-color: #e0e0e0; }
  2070 + background-color: #3e1944; }
2071 2071 .pagination li.disabled a {
2072 2072 color: #999; }
2073 2073 .pagination li i {
... ... @@ -2163,7 +2163,7 @@
2163 2163 footer.page-footer {
2164 2164 margin-top: 20px;
2165 2165 padding-top: 20px;
2166   - background-color: #e0e0e0; }
  2166 + background-color: #3e1944; }
2167 2167 footer.page-footer .footer-copyright {
2168 2168 overflow: hidden;
2169 2169 height: 50px;
... ... @@ -5052,7 +5052,7 @@
5052 5052  
5053 5053 nav {
5054 5054 color: #fff;
5055   - background-color: #e0e0e0;
  5055 + background-color: #3e1944;
5056 5056 width: 100%;
5057 5057 height: 56px;
5058 5058 line-height: 56px; }
... ... @@ -5566,7 +5566,7 @@
5566 5566 letter-spacing: 0.8px;
5567 5567 width: 15%; }
5568 5568 .tabs .tab a {
5569   - color: #e0e0e0;
  5569 + color: #3e1944;
5570 5570 display: block;
5571 5571 width: 100%;
5572 5572 height: 100%;
5573 5573  
... ... @@ -5576,12 +5576,12 @@
5576 5576 -ms-transition: color 0.28s ease;
5577 5577 transition: color 0.28s ease; }
5578 5578 .tabs .tab a:hover {
5579   - color: white; }
  5579 + color: #82348f; }
5580 5580 .tabs .indicator {
5581 5581 position: absolute;
5582 5582 bottom: 0;
5583 5583 height: 2px;
5584   - background-color: white;
  5584 + background-color: #712e7c;
5585 5585 will-change: left, right; }
5586 5586  
5587 5587 .tabs .tab {
... ... @@ -6855,7 +6855,7 @@
6855 6855 }
6856 6856  
6857 6857 .side-nav .collapsible-body li.active, .side-nav.fixed .collapsible-body li.active {
6858   - background-color: #e0e0e0; }
  6858 + background-color: #3e1944; }
6859 6859 .side-nav .collapsible-body li.active a, .side-nav.fixed .collapsible-body li.active a {
6860 6860 color: #fff; }
6861 6861  
templates/addclass.html View file @ 5f15306
... ... @@ -4,25 +4,35 @@
4 4 <md-content layout-padding="" layout="column" style="overflow:hidden">
5 5  
6 6 <form ng-submit="$event.preventDefault()">
7   - <div layout="column">
  7 + <div layout="row">
8 8 <md-autocomplete flex=""
9 9 md-autofocus="true"
10 10 md-selected-item="selectedItem"
11 11 md-search-text="searchText"
12 12 md-items="item in trySearch(searchText)"
13 13 md-item-text="item.short_name"
  14 + md-selected-item-change="selectObject(event)"
  15 + md-autoselect="true"
14 16 >
15 17 <md-item-template>
16 18 <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>
  19 + <div>{{item.short_name}}: {{item.course_title}}
  20 + ({{item.instructor}})
  21 + </div>
  22 + <div style="margin-left:auto;text-align:right;padding-left:30px">
  23 + {{item.lecture_times}}
  24 + </div>
19 25 </div>
20 26 </md-item-template>
21 27 <md-not-found>
22 28 No classes match "{{searchText}}".
23 29 </md-not-found>
24 30 </md-autocomplete>
  31 + <button class="btn waves-effect waves-light" type="submit" name="add" ng-click="submit()">Add
  32 + <i class="mdi-content-add right"></i>
  33 + </button>
25 34 </div>
  35 +
26 36 </form>
27 37 </md-content>
28 38 </div>
templates/deck.html View file @ 5f15306
... ... @@ -14,7 +14,6 @@
14 14  
15 15 <div class="card-action">
16 16  
17   - <!--<button type="button" class="waves-effect waves-light btn" ng-click="removeCard()">Remove</button>-->
18 17 <i class="small mdi-action-delete" ng-click="removeCard(card)"></i>
19 18  
20 19 <a class="modal-trigger" href="#editModal"><i class="small mdi-editor-border-color modal-trigger" ng-click="editCard(card)"></i></a>
... ... @@ -27,7 +26,7 @@
27 26 <div class="row">
28 27 <div class="input-field col s6">
29 28 <i class="mdi-editor-mode-edit prefix"></i>
30   - <textarea id="icon_prefix2" class="materialize-textarea">{{editedContent}}</textarea>
  29 + <textarea id="icon_prefix2" class="materialize-textarea" ng-model="$parent.editableContent">{{card.content}}</textarea>
31 30 <label for="icon_prefix2"></label>
32 31 </div>
33 32 </div>
... ... @@ -39,8 +38,6 @@
39 38  
40 39 <div class="modal-footer">
41 40 <a href="#!" class="modal-action modal-close waves-effect waves-green btn-flat">Done</a>
42   - <a href="#!" class="modal-action modal-close waves-effect waves-green btn-flat">Cancel</a>
43   -
44 41 </div>
45 42 </div>
46 43  
templates/feed.html View file @ 5f15306
1 1 <body>
2 2 <div class="col s12">
3 3 <div class="row">
4   - <a class="waves-effect waves-light btn" ng-click="viewDeck()" style="top: 15px">View Deck</a>
  4 + <a class="btn" ng-click="viewDeck()" style="margin-top: 15px">View Deck</a>
5 5 </div>
6 6  
7 7 <!--cards-->
8 8 <div class="row">
9 9 <div ng-repeat="card in cards">
10   - <div class="col s6">
  10 + <div class="col s4">
11 11 <div class="card" ng-click="pullCard(card)">
12 12 <div class="card-content">
13 13 <span> {{card.content}} </span>
... ... @@ -46,7 +46,7 @@
46 46 </form>
47 47 </div>
48 48 <div class="modal-footer">
49   - <button class="btn waves-effect waves-light purple modal-close" type="submit" ng-click="pushCard()">Submit
  49 + <button class="btn modal-close" type="submit" ng-click="pushCard()">Submit
50 50 <i class="mdi-content-send right"></i>
51 51 </button>
52 52 </div>
templates/login.html View file @ 5f15306
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>
templates/study.html View file @ 5f15306
1   -<div class="container">
2   - Hello<br>
3   - 1. Get card from server.<br>
4   - 2. Show card<br>
5   - 3. Inputs<br>
6   - 4. Compare answers<br>
7   - 5. User decides for correct/incorrect<br>
8   - <div ng-repeat="card in samples">
9   - <flashcard flashcard-content="card.desc"></flashcard>
10   - </div>
  1 +Hello<br>
  2 +1. Get card from server.<br>
  3 +2. Show card<br>
  4 +3. Inputs<br>
  5 +4. Compare answers<br>
  6 +5. User decides for correct/incorrect<br>
  7 +<div ng-repeat="card in samples">
  8 + <flashcard flashcard-content="card.desc"></flashcard>
11 9 </div>