From: Marius Gavrilescu <marius@ieval.ro>
Date: Fri, 12 Dec 2014 14:55:20 +0000 (+0200)
Subject: Add user tracking
X-Git-Url: http://git.ieval.ro/?a=commitdiff_plain;h=d31924ef2cb534377b73a3e0f9a6612678474afc;p=plack-app-gruntmaster.git

Add user tracking
---

diff --git a/css/custom.css b/css/custom.css
index 429955b..4239ab8 100644
--- a/css/custom.css
+++ b/css/custom.css
@@ -78,4 +78,12 @@ ul.inline li:after {
 
 ul.inline li:last-child:after {
 	content: "";
+}
+
+.tracker-mark.tick {
+	color: green;
+}
+
+.tracker-mark.x{
+	color: red;
 }
\ No newline at end of file
diff --git a/js/80-sidebar.js b/js/80-sidebar.js
new file mode 100644
index 0000000..cf729ec
--- /dev/null
+++ b/js/80-sidebar.js
@@ -0,0 +1,10 @@
+(function(){
+	'use strict';
+
+	$( document ).ready(function() {
+		if(!$('#sidebar').size()) {
+            var content = $('#content');
+            content.wrapInner('<div class="col-md-9">').append('<div id="sidebar" class="col-md-3">').addClass('row');
+        }
+	});
+})();
diff --git a/js/90-tracker.js b/js/90-tracker.js
new file mode 100644
index 0000000..5c71e12
--- /dev/null
+++ b/js/90-tracker.js
@@ -0,0 +1,94 @@
+(function(){
+	'use strict';
+
+	function tick()  { return $('<span class="tick tracker-mark">✔</span>') }
+	function xmark() { return $('<span class="x tracker-mark">✘</span>')    }
+
+	function update_tracker(){
+		var data = localStorage.getItem('tracker_data');
+		var user = localStorage.getItem('tracker_username');
+		if(!data)
+			return;
+		data = JSON.parse(data);
+		var solved = {};
+		var attempted = {};
+		var solvednr = 0;
+		var attemptednr = 0;
+		data.problems.forEach(function(e){
+			if(e.solved){
+				solved[e.problem] = 1;
+				solvednr++;
+			} else {
+				attempted[e.problem] = 1;
+				attemptednr++;
+			}
+		});
+
+		var contests = {};
+		data.contests.forEach(function(e){
+			contests[e.contest] = 1;
+		});
+
+		$('#tracker_userlink').html(data.name);
+		$('#tracker_solved').html(solvednr);
+		$('#tracker_attempted').html(attemptednr);
+		$('#tracker_contests').html(data.contests.length);
+
+		$('.tracker-mark').detach();
+		if(location.pathname == '/pb/')
+			$('table').find('.name').find('a').each(function() {
+				var id = $(this).attr('href').split('?', 2)[0];
+				if(solved[id])
+					$(this).parent().append(tick());
+				else if(attempted[id])
+					$(this).parent().append(xmark());
+			});
+
+		if(location.pathname == '/ct/')
+			$('table').find('.name').find('a').each(function() {
+				var id = $(this).attr('href').substr(4);
+				if(contests[id])
+					$(this).parent().append(tick());
+			});
+
+		if(location.pathname == '/log/')
+			$('table').find('tbody').find('tr').each(function() {
+				if($(this).find('.owner').find('a').attr('href') != "/us/" + user)
+					return;
+				$(this).find('.id').append($(this).find('.r0').size() ? tick() : xmark());
+			});
+	}
+
+	function start_tracking(user){
+		localStorage.setItem('tracker_username', user);
+		$('#tracker_userlink').attr('href', '/us/' + user).html(user);
+		$('#tracker_tracking').removeClass('hidden');
+		$('#tracker_form').addClass('hidden');
+		update_tracker();
+		var xhr = new XMLHttpRequest();
+		xhr.open('GET', '/us/' + user);
+		xhr.setRequestHeader('Accept', 'application/json');
+		xhr.onload = function () {
+			localStorage.setItem('tracker_data', this.responseText);
+			update_tracker();
+		};
+		xhr.send();
+	}
+
+	function stop_tracking(){
+		$('.tracker-mark').detach();
+		localStorage.removeItem('tracker_username');
+		localStorage.removeItem('tracker_data');
+		$('#tracker_tracking').addClass('hidden');
+		$('#tracker_form').removeClass('hidden');
+	}
+
+	$( document ).ready(function(){
+		$('#tracker').detach().prependTo($('#sidebar')).removeClass('hidden');
+		$('#tracker_button').on('click', function() { start_tracking($('#tracker_username').val()) });
+		$('#tracker_stop').on('click', stop_tracking);
+
+		if(localStorage.getItem('tracker_username'))
+			start_tracking(localStorage.getItem('tracker_username'));
+	});
+})();
diff --git a/tmpl/skel.en b/tmpl/skel.en
index 1e20c87..4d1e73e 100644
--- a/tmpl/skel.en
+++ b/tmpl/skel.en
@@ -37,6 +37,27 @@
 
 <div id="content">Content goes here</div>
 
+<div id="tracker">
+<h1>Track user</h1>
+<div id="tracker_form">
+<div class="form-group">
+<label for="tracker_username">Username</label>
+<input type="text" id="tracker_username" class="form-control">
+</div>
+<button id="tracker_button" class="btn">Start tracking</button>
+</div>
+
+<div id="tracker_tracking" class="hidden">
+Tracking <a href="#" id="tracker_userlink"></a>.<br>
+<a href="#" id="tracker_stop">Stop tracking</a>
+<dl class="dl-horizontal">
+<dt>Solved</dt>    <dd id="tracker_solved">?</dd>
+<dt>Attempted</dt> <dd id="tracker_attempted">?</dd>
+<dt>Contests</dt>  <dd id="tracker_contests">?</dd>
+</dl>
+</div>
+</div>
+
 <footer>
 Dilmom: Why don't you call your product the Gruntmaster 6000?<br>
 Dilbert: What kind of product do you see when you imagine a Gruntmaster 6000?<br>