Added clock stuff

This commit is contained in:
Dobie Wollert
2014-09-14 06:43:04 -04:00
parent ca587764cd
commit b949f6ff90
12 changed files with 384 additions and 4 deletions

172
public/clock/app.js Normal file
View File

@ -0,0 +1,172 @@
clock = {};
angular.module('clock', ['ngResource'])
.factory("Clock", function($resource) {
return $resource('/api/clock');
})
.constant('geolocation_msgs', {
'errors.location.unsupportedBrowser':'Browser does not support location services',
'errors.location.permissionDenied':'You have rejected access to your location',
'errors.location.positionUnavailable':'Unable to determine your location',
'errors.location.timeout':'Service timeout has been reached'
})
.factory('geolocation', ['$q','$rootScope','$window','geolocation_msgs',function ($q,$rootScope,$window,geolocation_msgs) {
return {
getLocation: function (opts) {
var deferred = $q.defer();
if ($window.navigator && $window.navigator.geolocation) {
$window.navigator.geolocation.getCurrentPosition(function(position){
$rootScope.$apply(function(){deferred.resolve(position);});
}, function(error) {
switch (error.code) {
case 1:
$rootScope.$broadcast('error',geolocation_msgs['errors.location.permissionDenied']);
$rootScope.$apply(function() {
deferred.reject(geolocation_msgs['errors.location.permissionDenied']);
});
break;
case 2:
$rootScope.$broadcast('error',geolocation_msgs['errors.location.positionUnavailable']);
$rootScope.$apply(function() {
deferred.reject(geolocation_msgs['errors.location.positionUnavailable']);
});
break;
case 3:
$rootScope.$broadcast('error',geolocation_msgs['errors.location.timeout']);
$rootScope.$apply(function() {
deferred.reject(geolocation_msgs['errors.location.timeout']);
});
break;
}
}, opts);
}
else
{
$rootScope.$broadcast('error',geolocation_msgs['errors.location.unsupportedBrowser']);
$rootScope.$apply(function(){deferred.reject(geolocation_msgs['errors.location.unsupportedBrowser']);});
}
return deferred.promise;
}
};
}])
.directive('gmap', function($parse) {
return {
template: '<img alt="Google Map">',
replace: true,
restrict: 'E',
controller: 'GMapController',
scope: true,
link: function postLink(scope, element, attrs, ctrl) {
var el = element[0];
var sizeBits = attrs.size.split('x');
el.width = parseInt(sizeBits[0], 10);
el.height = parseInt(sizeBits[1], 10);
scope.$watch(attrs.markers, function(value) {
el.src = ctrl.buildSourceString(attrs, value);
});
}
}
})
.controller('GMapController', function() {
var BASE_URL = '//maps.googleapis.com/maps/api/staticmap?';
var STYLE_ATTRIBUTES = ['color', 'label', 'size'];
function makeMarkerStrings(markers) {
return markers.map(function(marker) {
var str = Object.keys(marker).map(function(key) {
if (STYLE_ATTRIBUTES.indexOf(key) > -1) {
return key + ':' + marker[key] + '|';
}
}).join('');
return str + marker.coords.join(',');
});
}
this.buildSourceString = function(attrs, markers) {
var markerStrings;
if (markers) {
if (!angular.isArray(markers)) {
markers = [markers];
}
markerStrings = makeMarkerStrings(markers);
}
var params = Object.keys(attrs).map(function(attr) {
if (attr === 'markers' && markerStrings) {
return Object.keys(markerStrings).map(function(key) {
return 'markers=' + encodeURIComponent(markerStrings[key]);
}).join('&');
}
if (attr[0] !== '$' && attr !== 'alt') {
return encodeURIComponent(attr) + '=' + encodeURIComponent(attrs[attr]);
}
});
return BASE_URL + params.reduce(function(a, b) {
if (!a) {
return b;
}
if (b !== undefined) {
return a + '&' + b;
}
return a;
}, '');
};
});
clock.PageCtrl = function($scope, $rootScope, geolocation, Clock) {
function save(action) {
Clock.save({
action: action,
lat: $scope.coords.latitude,
long: $scope.coords.longitude
}, function(success) {
$scope.success = 'Request was successful.';
}, function(error) {
$scope.error = 'Unable to complete request, Try again later';
});
}
$scope.working = true;
$scope.clockIn = function() {
save('in');
};
$scope.clockOut = function() {
save('out');
};
$rootScope.$on('error', function(event, msg) {
$scope.working = false;
console.log("ERROR");
console.log(msg);
$scope.error = msg;
});
geolocation.getLocation().then(function(data) {
$scope.working = false;
$scope.coords = data.coords;
console.log('Got location Data');
console.log(data);
$scope.markers = [{
color: 'blue',
coords: [data.coords.latitude, data.coords.longitude]
}];
});
}

44
public/css/clock.css Normal file
View File

@ -0,0 +1,44 @@
html, body {
}
.loading {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
text-align: center;
height:100px;
width:200px;
}
.btn {
width: 100%;
margin-bottom: 5px;
display: block;
}
.mapOuter {
width: 100%;
overflow: hidden;
position: absolute;
left: 0;
}
.mapInner {
width: 100%;
height: auto;
}
.error {
padding: 5px 10px;
color: white;
background: #ba6d6d;
}
.success {
padding: 5px 10px;
color: white;
background: #6ebb72;
}

View File

@ -78,6 +78,10 @@ angular.module('biomed', ['biomed.filters', 'biomed.services', 'biomed.directive
controller: biomed.UsersIndexCtrl,
reloadOnSearch: false
})
.when('/admin/users/:id', {
templateUrl: '/partials/users/clock.html',
controller: biomed.UserClockCtrl
})
.otherwise({
redirectTo: '/schedule'
});

View File

@ -172,6 +172,15 @@ biomed.UsersIndexCtrl = function($scope, $filter, $routeParams, $location, Users
};
};
biomed.UserClockCtrl = function($scope, $routeParams, Users) {
Users.index({userid: $routeParams.id}, function(result) {
console.log(result);
$scope.tech = result[0];
});
$scope.clocks = Users.clocks($routeParams);
};
biomed.ClientIndexCtrl = function($scope, $filter, $routeParams, Clients, LocationBinder) {
$scope.loading = true;

View File

@ -32,6 +32,7 @@ angular.module('biomed.services', [])
details: { method: 'GET', params: { cmd: 'details' }, isArray: true },
create: { method: 'POST', params: {} },
update: { method: 'POST', params: { id: 0 } },
clocks: { method: 'GET', params: { id: 0, cmd: 'clocks' }, isArray: true }
});
})
.factory("Schedule", function($resource) {

View File

@ -0,0 +1,31 @@
<ul class="breadcrumb">
<li><a href="/users"><i class="icon-briefcase"></i> Admin</a><li>
</ul>
<header>
<h1>{{tech.name.first}} {{tech.name.last}}</h1>
</header>
<div class="row-fluid">
<div class="span12">
<table class="biomed-table" threshold="300">
<thead>
<tr>
<th>Action</th>
<th>Date</th>
<th>Location</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-show="loading"><td colspan="11" class="table-loading"><i class="loader"></i></td></tr>
<tr ng-hide="loading || clocks.length"><td colspan="11" class="table-message">There is no information to display.</td></tr>
<tr ng-hide="loading" ng-repeat="clock in clocks">
<td>{{clock.action}}</td>
<td>{{clock.dt | date:'medium'}}</td>
<td>{{clock.lat}},{{clock.long}}</td>
<td><a href="https://www.google.com.au/maps/preview/?q={{clock.lat}},{{clock.long}}" target="_blank">View in Google Maps</a></td>
</tr>
</tbody>
</table>
</div>
</div>

View File

@ -41,7 +41,7 @@
<tr ng-show="loading"><td colspan="11" class="table-loading"><i class="loader"></i></td></tr>
<tr ng-hide="loading || users.length"><td colspan="11" class="table-message">There is no information to display.</td></tr>
<tr ng-hide="loading" ng-repeat="user in users">
<td class="name">{{user.name.first}} {{user.name.last}} <span class="new" ng-show="isNew(user)">NEW</span></td>
<td class="name"><a href="/admin/users/{{user._id}}">{{user.name.first}} {{user.name.last}}</a> <span class="new" ng-show="isNew(user)">NEW</span></td>
<td class="email"><a href="mailto:{{user.email}}">{{user.email | email}}</a></td>
<td class="group-start {{ checkGroup(user, 'all') }}"><a ng-click="toggleGroup(user, 'all')"><i ng-class="{ 'icon-ok': checkGroup(user, 'all'), 'icon-remove': !checkGroup(user, 'all')}"></i></a></td>