timer in timesheet
diff --git a/erpnext/projects/doctype/timesheet/timesheet.css b/erpnext/projects/doctype/timesheet/timesheet.css
new file mode 100644
index 0000000..9cce5f4
--- /dev/null
+++ b/erpnext/projects/doctype/timesheet/timesheet.css
@@ -0,0 +1,122 @@
+@import 'https://fonts.googleapis.com/css?family=Open+Sans:300,600,800';
+/*html,
+body {
+  background-color: #000;
+  color: #fff;
+  height: 100%;
+  width: 100%;
+  margin: 0;
+  box-sizing: border-box;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  -o-user-select: none;
+  user-select: none;
+  -webkit-tap-highlight-color: transparent;
+}*/
+
+.stopwatch {
+  height: 50%;
+  width: 100%;
+  display: inline-flex;
+  transition: all .5s ease;
+  -moz-transition: all .5s ease;
+  -ms-transition: all .5s ease;
+  -webkit-transition: all .5s ease;
+  -o-transition: all .5s ease;
+}
+
+.stopwatch span {
+  display: table-cell;
+  width: 33%;
+  font-size: 5em;
+  font-family: 'Open Sans', sans serif;
+  text-align: center;
+  vertical-align: middle;
+  transition: all .5s ease;
+  -moz-transition: all .5s ease;
+  -ms-transition: all .5s ease;
+  -webkit-transition: all .5s ease;
+  -o-transition: all .5s ease;
+}
+
+.stopwatch .hours {
+  font-weight: 800;
+}
+
+.stopwatch .minutes {
+  font-weight: 600;
+}
+
+.stopwatch .seconds {
+  font-weight: 300;
+}
+
+.stopcontrols {
+  height: 50%;
+  width: 100%;
+  display: table;
+  transition: all .5s ease;
+  -moz-transition: all .5s ease;
+  -ms-transition: all .5s ease;
+  -webkit-transition: all .5s ease;
+  -o-transition: all .5s ease;
+}
+
+.stopcontrols div {
+  display: table-cell;
+  width: 50%;
+  text-align: center;
+  vertical-align: middle;
+  cursor: pointer;
+}
+
+.playpause {
+  border-right: 1px dashed #fff;
+  border-bottom: 1px dashed #fff;
+}
+
+.playpause .play {
+  display: inline-block;
+  border-top: 28px solid transparent;
+  border-left: 37px solid #000;
+  border-bottom: 28px solid transparent;
+}
+
+.playpause .pause {
+  border-right: 5px solid #000;
+  border-left: 5px solid #000;
+  padding: 20px 10px;
+}
+
+.stop {
+  border-bottom: 1px dashed #fff;
+}
+
+.stop span {
+  display: inline-block;
+  background-color: #e74c3c;
+  width: 45px;
+  height: 45px;
+}
+
+@media screen and (max-width: 500px) {
+  .stopwatch span {
+    font-size: 6em;
+  }
+}
+
+@media screen and (max-width: 390px) {
+  .stopwatch {
+    height: 75%;
+    display: block;
+  }
+  .stopcontrols {
+    height: 25%;
+  }
+  .stopwatch span {
+    width: 100%;
+    height: 33%;
+    display: block;
+  }
+}
diff --git a/erpnext/projects/doctype/timesheet/timesheet.html b/erpnext/projects/doctype/timesheet/timesheet.html
new file mode 100644
index 0000000..3414fc1
--- /dev/null
+++ b/erpnext/projects/doctype/timesheet/timesheet.html
@@ -0,0 +1,13 @@
+<div class="stopcontrols">
+  <div class="playpause">
+    <span class="play"></span>
+  </div>
+  <div class="stop">
+    <span></span>
+  </div>
+</div>
+<div class="stopwatch">
+  <span class="hours">00</span>
+  <span class="minutes">00</span>
+  <span class="seconds">00</span>
+</div>
\ No newline at end of file
diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js
index 99ee2a2..ed8bbb6 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.js
+++ b/erpnext/projects/doctype/timesheet/timesheet.js
@@ -50,12 +50,127 @@
 			}
 		}
 
+		if (frm.doc.total_hours) {
+			frm.add_custom_button(__('Start Timer'), function() {
+				frm.trigger("timer")
+			}).addClass("btn-primary");
+		}
+
 		if(frm.doc.per_billed > 0) {
 			frm.fields_dict["time_logs"].grid.toggle_enable("billing_hours", false);
 			frm.fields_dict["time_logs"].grid.toggle_enable("billable", false);
 		}
 	},
 
+	timer: function(frm) {
+		let dialog = new frappe.ui.Dialog({
+			title: __("Timer"),
+			fields: [
+				{"fieldtype": "Select", "label": __("Activity"),
+					"fieldname": "activity",
+					"options": frm.doc.time_logs.map(d => d.activity_type),
+					"reqd": 1 },
+				{"fieldtype": "Select", "label": __("Project"),
+					"fieldname": "project",
+					"options": frm.doc.time_logs.map(d => d.project)},
+				{"fieldtype": "Select", "label": __("Hours"),
+					"fieldname": "hours",
+					"options": frm.doc.time_logs.map(d => d.hours)}
+			]
+		});
+
+		dialog.wrapper.append(frappe.render_template("timesheet"));
+		frm.trigger("control_timer");
+		dialog.show();
+	},
+
+	control_timer: function() {
+		var interval = null;
+		var currentIncrement = 0;
+		var isPaused = false;
+		var initialised = false;
+		var clicked = false;
+		var paused_time = 0;
+
+		$(".playpause").click(function(e) {
+			if (clicked) {
+				e.preventDefault();
+				return false;
+			}
+
+			if (!initialised) {
+				initialised = true;
+				isPaused = false;
+				$(".playpause span").removeClass();
+				$(".playpause span").addClass("pause");
+				initialiseTimer();
+			}
+			else {
+				$(".playpause span").removeClass();
+				if (isPaused) {
+					isPaused = false;
+					$(".playpause span").addClass("pause");
+				}
+				else {
+					isPaused = true;
+					$(".playpause span").addClass("play");
+					paused_time = currentIncrement;
+				}
+			}
+		});
+
+		$(".stop").click(function() {
+			reset();
+		});
+
+		function initialiseTimer() {
+			interval = setInterval(function() {
+				if (isPaused) return;
+				var current = setCurrentIncrement();
+				updateStopwatch(current);
+			}, 1000);
+		}
+
+		function updateStopwatch(increment) {
+			var hours = Math.floor(increment / 3600);
+			var minutes = Math.floor((increment - (hours * 3600)) / 60);
+			var seconds = increment - (hours * 3600) - (minutes * 60);
+			// if(!$('modal-open:visible')){
+			// 	reset();
+			// }
+			if (!$('.modal-dialog').is(':visible')) {
+				reset();
+			}
+			if(hours > 99)
+			reset();
+			if(cur_dialog && cur_dialog.get_value('hours') == hours) {
+				isPaused = true;
+				initialised = false;
+				frappe.msgprint(__("Timer exceeded the given hours"));
+			}
+			$(".hours").text(hours < 10 ? ("0" + hours.toString()) : hours.toString());
+			$(".minutes").text(minutes < 10 ? ("0" + minutes.toString()) : minutes.toString());
+			$(".seconds").text(seconds < 10 ? ("0" + seconds.toString()) : seconds.toString());
+		}
+
+		function setCurrentIncrement() {
+			currentIncrement += 1;
+			return currentIncrement;
+		}
+
+		function reset() {
+			currentIncrement = 0;
+			isPaused = true;
+			initialised = false;
+			clearInterval(interval);
+			$(".hours").text("00");
+			$(".minutes").text("00");
+			$(".seconds").text("00");
+			$(".playpause span").removeClass();
+			$(".playpause span").addClass("play");
+		}
+	},
+
 	make_invoice: function(frm) {
 		let dialog = new frappe.ui.Dialog({
 			title: __("Select Item (optional)"),