Commit 25f31ee2a67bf170078c248b7645854b7c387da6

Authored by Melody
1 parent e91de4c040

Add more to settings

Showing 2 changed files with 119 additions and 63 deletions Inline Diff

scripts/SettingsController.js View file @ 25f31ee
angular.module('flashy.SettingsController', ['ui.router']). 1 1 angular.module('flashy.SettingsController', ['ui.router']).
2 2
controller('SettingsController', function($scope, $http) { 3 3 controller('SettingsController', function($rootScope, $resource, $scope, $state, $http, UserService) {
$scope.error = false; 4 4 $scope.error = false;
$scope.success = false; 5 5 $scope.success = false;
$scope.mismatch = false; 6 6 $scope.mismatch = false;
$scope.unacceptable = false; 7 7 $scope.unacceptable = false;
8 8
$scope.changePassword = function(oldPassword, newPassword, confirmedNewPassword) { 9 9 $scope.changePassword = function(oldPassword, newPassword, confirmedNewPassword) {
console.log('in change password'); 10 10 console.log('in change password');
11
12 $http.patch('/api/me/', {
13 'old_password': oldPassword,
14 'new_password': newPassword
15 }).
16 success(function(data) {
11 17
$http.patch('/api/me/', { 12 18 console.log('password successfully changes');
'old_password': oldPassword, 13 19
'new_password': newPassword 14 20 }).
}). 15 21 error(function(data) {
success(function(data) { 16 22 console.log('not changed');
17 23 });
console.log('password successfully changes'); 18
19
}). 20
error(function(data) { 21
console.log('not changed'); 22
}); 23
24 24
25 25
}; 26 26 };
27
28 $rootScope.SectionResource = $resource('/api/sections/:sectionId/');
29 $rootScope.currentSection = {};
30 $rootScope.UserService = UserService;
31
32 $scope.dropClass = function(section) {
33 $http.post('/api/sections/' + section.id + '/drop/').
34 success(function(data) {
35 console.log(section.short_name + ' dropped');
36
37 Materialize.toast('Dropped', 3000, 'rounded');
38 }).
39 error(function(err) {
40 console.log('no drop for you');
41 });
42 };
27 43
28 44
29 45
console.log('checking to see if chrome'); 30 46 console.log('checking to see if chrome');
if (!chrome) { 31 47 if (true/*!chrome*/) {
return; 32 48 return;
} 33 49 }
console.log('chrome'); 34 50 console.log('chrome');
35 51
console.log('executing things outside of module'); 36 52 console.log('executing things outside of module');
var PUSH_SERVER_URL = '/api/subscribe/'; 37 53 var PUSH_SERVER_URL = '/api/subscribe/';
var UNPUSH_SERVER_URL = '/api/unsubscribe/'; 38 54 var UNPUSH_SERVER_URL = '/api/unsubscribe/';
39 55
function onPushSubscription(pushSubscription) { 40 56 function onPushSubscription(pushSubscription) {
console.log('pushSubscription = ', pushSubscription.endpoint); 41 57 console.log('pushSubscription = ', pushSubscription.endpoint);
// Here we would normally send the endpoint 42 58 // Here we would normally send the endpoint
// and subscription ID to our server. 43 59 // and subscription ID to our server.
// In this demo we just use send these values to 44 60 // In this demo we just use send these values to
// our server via XHR which sends a push message. 45 61 // our server via XHR which sends a push message.
46 62
var endpoint = pushSubscription.endpoint; 47 63 var endpoint = pushSubscription.endpoint;
var subscriptionId = pushSubscription.subscriptionId; 48 64 var subscriptionId = pushSubscription.subscriptionId;
49 65
console.log('registration_id: ', subscriptionId); 50 66 console.log('registration_id: ', subscriptionId);
$http.post(PUSH_SERVER_URL, {'registration_id': subscriptionId}); 51 67 $http.post(PUSH_SERVER_URL, {'registration_id': subscriptionId});
} 52 68 }
53 69
function removeSubscription(pushSubscription) { 54 70 function removeSubscription(pushSubscription) {
console.log('removing subscription'); 55 71 console.log('removing subscription');
console.log('pushSubscription endpoint = ', pushSubscription.endpoint); 56 72 console.log('pushSubscription endpoint = ', pushSubscription.endpoint);
57 73
var subscriptionId = pushSubscription.subscriptionId; 58 74 var subscriptionId = pushSubscription.subscriptionId;
59 75
console.log('registration_id: ', subscriptionId); 60 76 console.log('registration_id: ', subscriptionId);
$http.post(UNPUSH_SERVER_URL, {'registration_id': subscriptionId}); 61 77 $http.post(UNPUSH_SERVER_URL, {'registration_id': subscriptionId});
} 62 78 }
63 79
function subscribeDevice() { 64 80 function subscribeDevice() {
// We need the service worker registration to access the push manager 65 81 // We need the service worker registration to access the push manager
navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { 66 82 navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
serviceWorkerRegistration.pushManager.subscribe() 67 83 serviceWorkerRegistration.pushManager.subscribe()
.then(onPushSubscription) 68 84 .then(onPushSubscription)
.catch(function(e) { 69 85 .catch(function(e) {
console.log('Error in subscribing'); 70 86 console.log('Error in subscribing');
// Check for a permission prompt issue 71 87 // Check for a permission prompt issue
if ('permissions' in navigator) { 72 88 if ('permissions' in navigator) {
navigator.permissions.query({name: 'push', userVisibleOnly: true}) 73 89 navigator.permissions.query({name: 'push', userVisibleOnly: true})
.then(function(permissionStatus) { 74 90 .then(function(permissionStatus) {
console.log('subscribe() Error: Push permission status = ', 75 91 console.log('subscribe() Error: Push permission status = ',
permissionStatus); 76 92 permissionStatus);
if (permissionStatus.status === 'denied') { 77 93 if (permissionStatus.status === 'denied') {
pushSwitch.checked = false; 78 94 pushSwitch.checked = false;
pushSwitch.disabled = true; 79 95 pushSwitch.disabled = true;
// The user blocked the permission prompt 80 96 // The user blocked the permission prompt
console.log('Ooops Notifications are Blocked', 81 97 console.log('Ooops Notifications are Blocked',
'Unfortunately you just permanently blocked notifications. ' + 82 98 'Unfortunately you just permanently blocked notifications. ' +
'Please unblock / allow them to switch on push ' + 83 99 'Please unblock / allow them to switch on push ' +
'notifications.'); 84 100 'notifications.');
} else { 85 101 } else {
pushSwitch.checked = false; 86 102 pushSwitch.checked = false;
console.log('Ooops Push Couldn\'t Register', 87 103 console.log('Ooops Push Couldn\'t Register',
'<p>When we tried to ' + 88 104 '<p>When we tried to ' +
'get the subscription ID for GCM, something went wrong,' + 89 105 'get the subscription ID for GCM, something went wrong,' +
' not sure why.</p>' + 90 106 ' not sure why.</p>' +
'<p>Have you defined "gcm_sender_id" and ' + 91 107 '<p>Have you defined "gcm_sender_id" and ' +
'"gcm_user_visible_only" in the manifest?</p>' + 92 108 '"gcm_user_visible_only" in the manifest?</p>' +
'<p>Error message: ' + 93 109 '<p>Error message: ' +
e.message + 94 110 e.message +
'</p>'); 95 111 '</p>');
} 96 112 }
}).catch(function(err) { 97 113 }).catch(function(err) {
pushSwitch.checked = false; 98 114 pushSwitch.checked = false;
console.log('Ooops Push Couldn\'t Register', 99 115 console.log('Ooops Push Couldn\'t Register',
'<p>When we tried to ' + 100 116 '<p>When we tried to ' +
'get the subscription ID for GCM, something went wrong, not ' + 101 117 'get the subscription ID for GCM, something went wrong, not ' +
'sure why.</p>' + 102 118 'sure why.</p>' +
'<p>Have you defined "gcm_sender_id" and ' + 103 119 '<p>Have you defined "gcm_sender_id" and ' +
'"gcm_user_visible_only" in the manifest?</p>' + 104 120 '"gcm_user_visible_only" in the manifest?</p>' +
'<p>Error message: ' + 105 121 '<p>Error message: ' +
err.message + 106 122 err.message +
'</p>'); 107 123 '</p>');
}); 108 124 });
} else { 109 125 } else {
// Use notification permission to do something 110 126 // Use notification permission to do something
if (Notification.permission === 'denied') { 111 127 if (Notification.permission === 'denied') {
pushSwitch.disabled = true; 112 128 pushSwitch.disabled = true;
pushSwitch.checked = false; 113 129 pushSwitch.checked = false;
console.log('Ooops Notifications are Blocked', 114 130 console.log('Ooops Notifications are Blocked',
'Unfortunately you just permanently blocked notifications. ' + 115 131 'Unfortunately you just permanently blocked notifications. ' +
'Please unblock / allow them to switch on push notifications.'); 116 132 'Please unblock / allow them to switch on push notifications.');
} else { 117 133 } else {
pushSwitch.checked = false; 118 134 pushSwitch.checked = false;
console.log('Ooops Push Couldn\'t Register', 119 135 console.log('Ooops Push Couldn\'t Register',
'<p>When we tried to ' + 120 136 '<p>When we tried to ' +
'get the subscription ID for GCM, something went wrong, not ' + 121 137 'get the subscription ID for GCM, something went wrong, not ' +
'sure why.</p>' + 122 138 'sure why.</p>' +
'<p>Have you defined "gcm_sender_id" and ' + 123 139 '<p>Have you defined "gcm_sender_id" and ' +
'"gcm_user_visible_only" in the manifest?</p>' + 124 140 '"gcm_user_visible_only" in the manifest?</p>' +
'<p>Error message: ' + 125 141 '<p>Error message: ' +
e.message + 126 142 e.message +
'</p>'); 127 143 '</p>');
} 128 144 }
} 129 145 }
}); 130 146 });
}); 131 147 });
} 132 148 }
133 149
function unsubscribeDevice() { 134 150 function unsubscribeDevice() {
navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { 135 151 navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
serviceWorkerRegistration.pushManager.getSubscription().then( 136 152 serviceWorkerRegistration.pushManager.getSubscription().then(
function(pushSubscription) { 137 153 function(pushSubscription) {
// Check we have everything we need to unsubscribe 138 154 // Check we have everything we need to unsubscribe
if (!pushSubscription) { 139 155 if (!pushSubscription) {
pushSwitch.checked = false; 140 156 pushSwitch.checked = false;
return; 141 157 return;
} 142 158 }
143 159
// TODO: Remove the device details from the server 144 160 // TODO: Remove the device details from the server
// i.e. the pushSubscription.subscriptionId and 145 161 // i.e. the pushSubscription.subscriptionId and
// pushSubscription.endpoint 146 162 // pushSubscription.endpoint
var subscriptionId = pushSubscription.subscriptionId; 147 163 var subscriptionId = pushSubscription.subscriptionId;
148 164
pushSubscription.unsubscribe().then(function(successful) { 149 165 pushSubscription.unsubscribe().then(function(successful) {
console.log('Unsubscribed from push: ', successful); 150 166 console.log('Unsubscribed from push: ', successful);
151 167
if (!successful) { 152 168 if (!successful) {
// The unsubscribe was unsuccessful, but we can 153 169 // The unsubscribe was unsuccessful, but we can
// remove the subscriptionId from our server 154 170 // remove the subscriptionId from our server
// and notifications will stop 155 171 // and notifications will stop
// This just may be in a bad state when the user returns 156 172 // This just may be in a bad state when the user returns
pushSwitch.checked = true; 157 173 pushSwitch.checked = true;
removeSubscription(pushSubscription); 158 174 removeSubscription(pushSubscription);
console.error('We were unable to unregister from push, but we removed'+ 159 175 console.error('We were unable to unregister from push, but we removed'+
'registration id from the server'); 160 176 'registration id from the server');
} 161 177 }
162 178
}).catch(function(e) { 163 179 }).catch(function(e) {
console.log('Unsubscribtion error: ', e); 164 180 console.log('Unsubscribtion error: ', e);
}); 165 181 });
}.bind(this)).catch(function(e) { 166 182 }.bind(this)).catch(function(e) {
console.error('Error thrown while revoking push notifications. ' + 167 183 console.error('Error thrown while revoking push notifications. ' +
'Most likely because push was never registered', e); 168 184 'Most likely because push was never registered', e);
}); 169 185 });
}); 170 186 });
} 171 187 }
172 188
function permissionStatusChange(permissionStatus) { 173 189 function permissionStatusChange(permissionStatus) {
console.log('permissionStatusChange = ', permissionStatus); 174 190 console.log('permissionStatusChange = ', permissionStatus);
// If the notification permission is denied, it's a permanent block 175 191 // If the notification permission is denied, it's a permanent block
switch (permissionStatus.status) { 176 192 switch (permissionStatus.status) {
case 'denied': 177 193 case 'denied':
pushSwitch.disabled = true; 178 194 pushSwitch.disabled = true;
console.log('Ooops Push has been Blocked', 179 195 console.log('Ooops Push has been Blocked',
'Unfortunately the user permanently blocked push. Please unblock / ' + 180 196 'Unfortunately the user permanently blocked push. Please unblock / ' +
'allow them to switch on push notifications.'); 181 197 'allow them to switch on push notifications.');
break; 182 198 break;
case 'granted': 183 199 case 'granted':
// Set the state of the push switch 184 200 // Set the state of the push switch
console.log('case granted'); 185 201 console.log('case granted');
break; 186 202 break;
case 'prompt': 187 203 case 'prompt':
pushSwitch.checked = false; 188 204 pushSwitch.checked = false;
console.log('case prompt'); 189 205 console.log('case prompt');
break; 190 206 break;
} 191 207 }
} 192 208 }
193 209
function setUpPushPermission() { 194 210 function setUpPushPermission() {
navigator.permissions.query({name: 'push', userVisibleOnly: true}) 195 211 navigator.permissions.query({name: 'push', userVisibleOnly: true})
.then(function(permissionStatus) { 196 212 .then(function(permissionStatus) {
// Set the initial state 197 213 // Set the initial state
permissionStatusChange(permissionStatus); 198 214 permissionStatusChange(permissionStatus);
199 215
// Handle Permission State Changes 200 216 // Handle Permission State Changes
permissionStatus.onchange = function() { 201 217 permissionStatus.onchange = function() {
permissionStatusChange(this); 202 218 permissionStatusChange(this);
}; 203 219 };
204 220
// Check if push is supported and what the current state is 205 221 // Check if push is supported and what the current state is
navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { 206 222 navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
// Let's see if we have a subscription already 207 223 // Let's see if we have a subscription already
serviceWorkerRegistration.pushManager.getSubscription() 208 224 serviceWorkerRegistration.pushManager.getSubscription()
.then(function(subscription) { 209 225 .then(function(subscription) {
if (!subscription) { 210 226 if (!subscription) {
// NOOP 211 227 // NOOP
return; 212 228 return;
} 213 229 }
214 230
console.log('update current state.'); 215 231 console.log('update current state.');
// Update the current state with the 216 232 // Update the current state with the
// subscriptionid and endpoint 217 233 // subscriptionid and endpoint
onPushSubscription(subscription); 218 234 onPushSubscription(subscription);
}) 219 235 })
.catch(function(e) { 220 236 .catch(function(e) {
console.log('An error occured while calling getSubscription()', e); 221 237 console.log('An error occured while calling getSubscription()', e);
}); 222 238 });
}); 223 239 });
}).catch(function(err) { 224 240 }).catch(function(err) {
console.log('Ooops Unable to check the permission', 225 241 console.log('Ooops Unable to check the permission',
'Unfortunately the permission for push notifications couldn\'t be ' + 226 242 'Unfortunately the permission for push notifications couldn\'t be ' +
'checked. Are you on Chrome 43+?'); 227 243 'checked. Are you on Chrome 43+?');
}); 228 244 });
} 229 245 }
230 246
function setUpNotificationPermission() { 231 247 function setUpNotificationPermission() {
console.log('setting notification setting'); 232 248 console.log('setting notification setting');
233 249
if (Notification.permission === 'default') { 234 250 if (Notification.permission === 'default') {
console.log('notification permissions === default'); 235 251 console.log('notification permissions === default');
return; 236 252 return;
} 237 253 }
238 254
// Check if push is supported and what the current state is 239 255 // Check if push is supported and what the current state is
navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { 240 256 navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
// Let's see if we have a subscription already 241 257 // Let's see if we have a subscription already
serviceWorkerRegistration.pushManager.getSubscription() 242 258 serviceWorkerRegistration.pushManager.getSubscription()
.then(function(subscription) { 243 259 .then(function(subscription) {
if (!subscription) { 244 260 if (!subscription) {
// NOOP 245 261 // NOOP
console.log('not subscription'); 246 262 console.log('not subscription');
return; 247 263 return;
} 248 264 }
249 265
// Update the current state with the 250 266 // Update the current state with the
// subscriptionid and endpoint 251 267 // subscriptionid and endpoint
console.log('onpushsubscription should be entered'); 252 268 console.log('onpushsubscription should be entered');
onPushSubscription(subscription); 253 269 onPushSubscription(subscription);
}) 254 270 })
.catch(function(e) { 255 271 .catch(function(e) {
console.log('An error occured while calling getSubscription()', e); 256 272 console.log('An error occured while calling getSubscription()', e);
}); 257 273 });
}); 258 274 });
} 259 275 }
260 276
// Once the service worker is registered set the initial state 261 277 // Once the service worker is registered set the initial state
function initialiseState() { 262 278 function initialiseState() {
// Check if notifications are supported 263 279 // Check if notifications are supported
if (!('showNotification' in ServiceWorkerRegistration.prototype)) { 264 280 if (!('showNotification' in ServiceWorkerRegistration.prototype)) {
console.warn('Notifications aren\'t supported.'); 265 281 console.warn('Notifications aren\'t supported.');
return; 266 282 return;
} 267 283 }
// Check the current Notification permission. 268 284 // Check the current Notification permission.
// If its denied, it's a permanent block until the 269 285 // If its denied, it's a permanent block until the
// user changes the permission 270 286 // user changes the permission
else if (Notification.permission === 'denied') { 271 287 else if (Notification.permission === 'denied') {
console.log('Ooops Notifications are Blocked', 272 288 console.log('Ooops Notifications are Blocked',
'Unfortunately notifications are permanently blocked. Please unblock / ' + 273 289 'Unfortunately notifications are permanently blocked. Please unblock / ' +
'allow them to switch on push notifications.'); 274 290 'allow them to switch on push notifications.');
return; 275 291 return;
} 276 292 }
// Check if push messaging is supported 277 293 // Check if push messaging is supported
else if (!('PushManager' in window)) { 278 294 else if (!('PushManager' in window)) {
console.warn('Push messaging isn\'t supported.'); 279 295 console.warn('Push messaging isn\'t supported.');
return; 280 296 return;
} 281 297 }
282 298
pushSwitch.disabled = false; 283 299 pushSwitch.disabled = false;
// Is the Permissions API supported 284 300 // Is the Permissions API supported
if ('permissions' in navigator) { 285 301 if ('permissions' in navigator) {
console.log('setting push permissions'); 286 302 console.log('setting push permissions');
setUpPushPermission(); 287 303 setUpPushPermission();
return; 288 304 return;
} else { 289 305 } else {
console.log('setting notification permissions'); 290 306 console.log('setting notification permissions');
setUpNotificationPermission(); 291 307 setUpNotificationPermission();
} 292 308 }
} 293 309 }
294 310
var enablePushSwitch = $('.js-checkbox'); 295 311 var enablePushSwitch = $('.js-checkbox');
var pushSwitch = document.getElementById("notifbox"); 296 312 var pushSwitch = document.getElementById("notifbox");
pushSwitch.disabled = true; 297 313 pushSwitch.disabled = true;
298 314
enablePushSwitch.change(function(e) { 299 315 enablePushSwitch.change(function(e) {
console.log('checkbox changed'); 300 316 console.log('checkbox changed');
if (e.target.checked) { 301 317 if (e.target.checked) {
console.log('subscribing device'); 302 318 console.log('subscribing device');
subscribeDevice(); 303 319 subscribeDevice();
templates/settings.html View file @ 25f31ee
<div class="card" id="resetPasswordForm"> 1 1 <div class="row">
2 <div class="col s6 offset-s3">
3 <div class="card-panel" id="dropClassForm">
4 <h2>Notification Settings</h2>
5 <!--
6 class="js-checkbox" name="notifbox" value="toggle notifs"> -->
7 <form action="#">
8 <input type="checkbox" id = "notifbox" class="js-checkbox" />
9 <label for="notifbox">Enable notifications</label>
10 </form>
11 </div>
12 </div>
13 </div>
2 14
<!-- 3 15 <div class="row">
class="js-checkbox" name="notifbox" value="toggle notifs"> --> 4 16 <div class="col s6 offset-s3">
<form action="#"> 5 17 <div class="card-panel" id="resetPasswordForm">
<input type="checkbox" id = "notifbox" class="js-checkbox" /> 6
<label for="notifbox">Check this to enable notifications</label> 7
</form> 8
9 18
<h2>Change Password</h2> 10 19 <h2>Change Password</h2>
11 20
<div class="row"> 12 21 <form name="ChangePasswordForm">
<form class="col s12" name="ChangePasswordForm"> 13
14 22
<div class="row"> 15 23 <div class="row">
<div class="input-field col s12"> 16 24 <div class="input-field col s12">
<input id="password" required type="password" name="oldpw" ng-model="oldPassword" class="validate"> 17 25 <input id="password" required type="password" name="oldpw" ng-model="oldPassword" class="validate">
<label for="password">Old Password</label> 18 26 <label for="password">Old Password</label>
27 </div>
</div> 19 28 </div>
</div> 20
21 29
<div role="alert"> 22 30 <div role="alert">
<span class="error" ng-show="ChangePasswordForm.oldpw.$error.required"> 23 31 <span class="error" ng-show="ChangePasswordForm.oldpw.$error.required">
Required!</span> 24 32 Required!</span>
</div> 25 33 </div>
26 34
27 35
<div class="row"> 28 36 <div class="row">
<div class="input-field col s12"> 29 37 <div class="input-field col s12">
<input id="password" required ng-minlength=8 type="password" name="newpw" ng-model="newPassword" class="validate"> 30 38 <input id="password" required ng-minlength=8 type="password" name="newpw" ng-model="newPassword" class="validate">
<label for="password">New Password</label> 31 39 <label for="password">New Password</label>
40 </div>
</div> 32 41 </div>
</div> 33 42
34 43 <div role="alert">
<div role="alert"> 35 44 <span class="error" ng-show="ChangePasswordForm.newpw.$error.minlength">
<span class="error" ng-show="ChangePasswordForm.newpw.$error.minlength"> 36 45 New password must be at least 8 characters. </span>
New password must be at least 8 characters. </span> 37 46 </div>
</div> 38
39 47
<div class="row"> 40 48 <div class="row">
<div class="input-field col s12"> 41 49 <div class="input-field col s12">
<input id="password" required ng-minlength=8 compare-to="newpw" type="password" name="confirmpw" ng-model="confirmedNewPassword" class="validate"> 42 50 <input id="password" required ng-minlength=8 compare-to="newpw" type="password" name="confirmpw" ng-model="confirmedNewPassword" class="validate">
<label for="password">Confirm New Password</label> 43 51 <label for="password">Confirm New Password</label>
52 </div>
</div> 44 53 </div>
</div> 45 54
46 55 <div role="alert">
<div role="alert"> 47 56 <span class="error" ng-show="ChangePasswordForm.confirm.$error.minlength">
<span class="error" ng-show="ChangePasswordForm.confirm.$error.minlength"> 48 57 Must be the same as the new password. </span>
Must be the same as the new password. </span> 49 58 </div>
</div> 50
51 59
52 60
</form> 53 61 </form>
<a class="waves-effect waves-light btn" id="resetPWButton" 54 62 <a class="waves-effect waves-light btn" id="resetPWButton"
ng-click="changePassword(oldPassword, newPassword, confirmedNewPassword)">Change Password</a> 55 63 ng-click="changePassword(oldPassword, newPassword, confirmedNewPassword)">Change Password</a>
64 </div>
65 </div>
66 </div>
67
68 <div class="row">
69 <div class="col s6 offset-s3">
70 <div class="card-panel" id="dropClassForm">
71
72 <h2>Enrolled Classes</h2>
73 <div class="row" style="padding: 0px 25px">
74 <table class="hoverable responsive-table">
75 <thead>
76 <tr>
77 <th data-field="id">Class</th>
78 <th data-field="drop">Drop?</th>
79 </tr>
80 </thead>
81
82 <tbody>
83 <tr ng-repeat="section in UserService.getUserData().sections">
84 <td>
85 <span>{{section.short_name}}</span>
86 <p>{{section.long_name}}</p>
87 </td>
88 <td><a href="" ng-click="dropClass(section)"><i class="mdi-content-clear small"></i></a></td>
89 </tr>
90 </tbody>
91 </table>
92 </div>
93 </div>
94 </div>
95 </div>
56 96