Skip to content

Instantly share code, notes, and snippets.

@DanThiffault
Created December 11, 2013 08:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DanThiffault/7906955 to your computer and use it in GitHub Desktop.
Save DanThiffault/7906955 to your computer and use it in GitHub Desktop.
::-webkit-inner-spin-button { display: none; }
::-webkit-datetime-edit {}
.datePicker {
position: relative;
margin-bottom: 15px;
}
.ul.calendar-header {
display: none;
}
@media (min-width:768px) {
.ul.calendar-header {
display: table;
}
.calendar-table ul.calendar-header > li {
height: 1em;
}
.sidebar {
min-height: 1000px;
}
}
.apply-reimbursement {
/*color: blue; */
}
.request .amount.rejected {
background-color: #d9534f;
}
<!DOCTYPE html>
<html ng-app="expense">
<head>
<meta name="description" content="Work 365 Expense" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular.min.js"></script>
<script src="https://s3-eu-west-1.amazonaws.com/iotap-demos/libraries/ui-bootstrap-tpls-0.7.0.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.1/underscore-min.js"></script>
<link href="http://therandomtests.in/iotap/css/bootstrap.css" rel="stylesheet" type="text/css" />
<meta charset=utf-8 />
<title>Work 365 Expense</title>
</head>
<body ng-controller="CalendarController">
<div class="wrapper container">
<div class="sidebar">
<div class="profile">
<img style="width: 100%" src="{{currentUser.pictureUrl}}" />
<span class="profile-name">{{currentUser.name}}</span>
</div>
<div class="leave-remaining">
<small>Per Diem</small>
<h3>&#8377; 2000</h3>
<div class="double">
<div>
<small>{{unapprovedExpenses}} unapproved expenses</small>
</div>
</div>
<div style="margin-top:15px">
<a class="apply-reimbursement">
<span class="glyphicon glyphicon-plus-sign" ng-click="toggleReimbursementForm()"></span>
<span ng-click="toggleReimbursementForm()">Apply for reimbursement</span>
</a>
</div>
</div>
</div>
<div class="content col-md-9">
<div class="header">
<input type="month" ng-model="monthString" class="pull-right datePicker"/>
</div>
<div class="table clearfix">
<div class="calendar-table">
<ul class="calendar-header">
<li>Sunday</li>
<li>Monday</li>
<li>Tuesday</li>
<li>Wednesday</li>
<li>Thursday</li>
<li>Friday</li>
<li>Saturday</li>
</ul>
<ul ng-repeat="w in weeks">
<li ng-repeat="d in w" ng-class="dateClass(d)" ng-click="selectDay($event,d)">
<div class="date">{{d | date:'dd MMM'}}</div>
<div class="request" ng-repeat="(status, expenses) in d.personal">
<span class="amount" ng-class="expenseStatusCount(status,expenses)">{{expenses.length}}</span>
<span class="type">{{status}}</span>
</div>
<div class="request" ng-repeat="(status, expenses) in d.staff">
<span class="amount" ng-class="expenseStatusCount(status,expenses)">{{expenses.length}}</span>
<span class="type">{{status}}</span>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="date-detail" ng-show="selectedDay">
<!--
<div class="date">
<small>sat-wed</small>
<h4>21-25 Dec</h4>
<h3>Project deadline for <em>Eastbound &amp; Down</em></h3>
</div>
-->
<div ng-repeat="(status, expenses) in selectedDay.personal">
<div class="person" ng-repeat="expense in expenses">
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-default" ng-click="toggleCommentArea(expense)"><span class="glyphicon glyphicon-comment"></span></button>
</div>
<h4>{{employees[expense.user].name}} <small>{{status}}</small></h4>
<h6>{{expense.title}}: &#8377; {{expense.amount}}</h6>
<p ng-repeat="c in expense.comments"><q>{{c.comment}}</q> - {{c.name}}</p>
<div ng-show="expense.showComment">
<textarea ng-model="newComment.comment" placeholder="Enter your comment" style="width: 100%; margin-top: 10px; border: solid 1px #CCC; padding: 10px"></textarea><br/>
<button ng-click="addNewComment(expense, newComment)" class="btn btn-primary" style="margin-top: 10px">Add Comment</button>
</div>
<hr/>
</div>
</div>
<div ng-repeat="(status, expenses) in selectedDay.staff">
<div class="person" ng-repeat="expense in expenses">
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-default" ng-click="toggleCommentArea(expense)"><span class="glyphicon glyphicon-comment"></span></button>
<button type="button" class="btn btn-default" ng-show="{{status=='Pending'}}" ng-click="setStatus(expense,'Rejected')"><span class="glyphicon glyphicon-remove"></span></button>
<button type="button" class="btn btn-default" ng-show="{{status=='Pending'}}" ng-click="setStatus(expense,'Approved')"><span class="glyphicon glyphicon-ok"></span></button>
</div>
<h4>{{employees[expense.user].name}} <small>{{status}}</small></h4>
<h6>{{expense.title}}: &#8377; {{expense.amount}}</h6>
<p ng-repeat="c in expense.comments"><q>{{c.comment}}</q> - {{c.name}}</p>
<div ng-show="expense.showComment">
<textarea ng-model="newComment.comment" placeholder="Enter your comment" style="width: 100%; margin-top: 10px; border: solid 1px #CCC; padding: 10px"></textarea><br/>
<button ng-click="addNewComment(expense, newComment)" class="btn btn-primary" style="margin-top: 10px">Add Comment</button>
</div>
<hr/>
</div>
</div>
</div>
<div class="date-detail" ng-show="showReimbursementForm" >
<header><h4>Apply for a reimbursement</h4><hr/></header>
<form role="form">
<div class="form-group">
<label for="reimbursementReason">Reason for reimbursement</label>
<input type="text" class="form-control" id="reimbursementReason" placeholder="Enter description" ng-model="reimbursement.reason">
</div>
<div class="form-group">
<label for="reimbursementAmount">Amount for reimbursement</label>
<input type="number" class="form-control" id="reimbursementAmount" placeholder="Enter amount (INR)" ng-model="reimbursement.amount">
</div>
<div class="form-group">
<label for="reimbursementDate">Date occurred</label>
<input type="date" class="form-control" id="reimbursementDate" ng-model="reimbursement.date">
</div>
<div class="form-group">
<label for="reimbursementAttachment">Attach a reciept</label>
<input type="file" id="reimbursementAttachment" ng-model="reimbursement.file">
<!--<p class="help-block">Example block-level help text here.</p>-->
</div>
<button class="btn btn-primary" ng-click="applyReimbursement(reimbursement)">Submit</button>
</form>
</div>
<div id="footer">
<a href="#aimee" ng-click="login(0)">Login Aimee</a> |
<a href="#joanne" ng-click="login(1)">Login Joanne</a> |
<a href="#joanne" ng-click="resetTestData()">Reset test data</a>
</div>
</body>
</html>
var ang = angular.module('expense',['ui.bootstrap']);
ang.controller('CalendarController',['$scope', function($scope) {
$scope.calendarStart = new Date();
$scope.dates = [];
$scope.weeks = [];
$scope.selectedDay=null;
$scope.showReimbursementForm = false;
$scope.currentUser = null;
$scope.unapprovedExpenses = 0;
if(sessionStorage.expenses===undefined)
sessionStorage.expenses = JSON.stringify('[]');
$scope.expenses = JSON.parse(sessionStorage.expenses);
$scope.dateClass = function(date) {
return sameMonth($scope.calendarStart, date) ? '' : 'past';
};
$scope.addNewComment = function(expense, newComment) {
expense.comments.push({name: $scope.currentUser.name, comment: newComment.comment});
expense.showComment = false;
newComment.comment = "";
};
$scope.selectDay = function($event,day) {
if($scope.selectedDay==day || day.empty) {
$scope.selectedDay = null;
} else {
$scope.selectedDay = day;
}
};
$scope.toggleCommentArea = function(expense) {
expense.showComment = !expense.showComment;
};
$scope.toggleReimbursementForm = function() {
$scope.showReimbursementForm = !$scope.showReimbursementForm;
};
$scope.applyReimbursement = function(reimbursement) {
var _date = new Date(reimbursement.date);
$scope.expenses.push({ title: reimbursement.reason, amount: reimbursement.amount, comments: [],
status: "Pending", user: $scope.currentUser.id, incurred: _date.getTime() });
$scope.showReimbursementForm = false;
saveExpenses();
};
// setup calendar with a month starting on Sunday
$scope.$watch('calendarStart', function(date) {
// Ensure there is a real date
if (date === undefined || date === null)
return;
// Start on Sunday
var cDay = new Date(date);
cDay.setDate(date.getDate() - date.getDay());
var dates = [];
var sM = date.getMonth();
var sY = date.getYear();
// Loop through month
while(sameMonth(cDay,date) || cDay < date) {
dates.push(new Date(cDay));
cDay.setDate(cDay.getDate() + 1);
}
// Add on until saturday
while(cDay.getDay() !== 0) {
dates.push(new Date(cDay));
cDay.setDate(cDay.getDate() + 1);
}
$scope.dates = dates;
$scope.weeks = createWeeks(dates);
});
$scope.expenseStatusCount = function(status, expenses) {
if(status === "Approved") {
return "approved";
} else if (status === "Rejected") {
return "rejected";
} else {
return "requested";
}
};
$scope.setStatus = function(expense, status) {
expense.status = status;
saveExpenses();
};
function sameMonth(date1, date2) {
return date1.getMonth() == date2.getMonth() &&
date1.getYear() == date2.getYear();
}
function createWeeks(dates) {
var cweek = [];
var weeks = [];
for(var i in dates) {
if(dates[i].getDay() === 0) {
cWeek = [];
weeks.push(cWeek);
}
cWeek.push(dates[i]);
}
return weeks;
}
/********************************************
BEGIN: Handle month picker
********************************************/
$scope.$watch('calendarStart', function (date) {
if(date !== undefined && date !== null) {
$scope.monthString = date.getFullYear() + '-' + pad(date.getMonth() + 1,2);
}
});
$scope.$watch('monthString', function (monthString) {
if(monthString !== undefined) {
$scope.calendarStart = new Date(monthString + "-01");
}
});
function pad(n, width, z) {
z = z || '0';
n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}
/********************************************
END: Handle month picker
********************************************/
/********************************************
BEGIN: Test Data
********************************************/
var aimee = {
name: "Aimee Mann",
pictureUrl: "http://lorempixel.com/400/400/people/9/",
id: 0,
manages: []
};
var joanne = {
name: "Joanne Farr",
pictureUrl: "http://lorempixel.com/400/400/people/1/",
id: 1,
manages: [0]
};
$scope.currentUser = aimee;
$scope.employees = [aimee, joanne];
$scope.$watch('dates', updateDateDetails, true);
$scope.$watch('expenses', updateDateDetails, true);
function updateDateDetails() {
if($scope.dates == [] || $scope.expenses == [])
return;
var personal = _.chain($scope.expenses)
.where({user: $scope.currentUser.id})
.groupBy('incurred')
.value();
var staff = _.chain($scope.expenses)
.filter(function (expense) {
return _.contains($scope.currentUser.manages, expense.user)
;})
.groupBy('incurred')
.value();
for(var i in $scope.dates) {
var thisDate = $scope.dates[i];
var thisTime = thisDate.getTime();
var empty = true;
if(personal[thisTime] !== undefined) {
empty = false;
thisDate.personal = _.groupBy(personal[thisTime], 'status');
} else {
thisDate.personal = {};
}
if(staff[thisTime] !== undefined) {
empty = false;
thisDate.staff = _.groupBy(staff[thisTime], 'status');
} else {
thisDate.staff = {};
}
thisDate.travel = [];
thisDate.empty = empty;
}
// set un approved personal
$scope.unapprovedExpenses = _.chain($scope.expenses)
.where({user: $scope.currentUser.id, status: "Pending"})
.value().length;
}
var sampleTime = (new Date("12/1/2013 UTC")).getTime();
$scope.login = function(id) {
$scope.currentUser = $scope.employees[id];
updateDateDetails();
};
$scope.resetTestData = function() {
$scope.expenses = [tE(), tE({status: "Approved", user: 1, title: "Travel to client"})];
saveExpenses();
};
function saveExpenses() {
sessionStorage.expenses = JSON.stringify($scope.expenses);
}
function tE(params) {
return _.extend({ title: "Client Lunch", amount: "1500", comments: [], status: "Pending", user: 0, incurred: sampleTime },params || {});
}
/********************************************
END: Test Data
********************************************/
}]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment