Skip to content

Commit 3b1ab47

Browse files
committed
Initial commit.
0 parents  commit 3b1ab47

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+10374
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
.idea
3+
dist

app/index.html

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Task timer</title>
6+
7+
<!-- Stylesheets -->
8+
<link rel="stylesheet" type="text/css" href="../node_modules/bulma/css/bulma.css">
9+
<link rel="stylesheet" href="../vendor/font-awesome-4.7.0/css/font-awesome.min.css">
10+
11+
<style>
12+
.notification.is-success {
13+
background-color: #257140;
14+
}
15+
16+
.notification {
17+
padding: 8px 20px;
18+
}
19+
20+
.notification:not(:last-child) {
21+
margin-bottom: 10px;
22+
}
23+
24+
.icon {
25+
height: 20px;
26+
width: 20px;
27+
}
28+
</style>
29+
</head>
30+
<body>
31+
<section class="hero is-primary">
32+
<div class="hero-body">
33+
<div class="container">
34+
<h1 class="title">
35+
Task Timer
36+
</h1>
37+
<h2 class="subtitle">
38+
A simple app to keep track of the time spent on your tasks
39+
</h2>
40+
</div>
41+
</div>
42+
</section>
43+
<div id="app" class="section">
44+
<div class="container">
45+
<p class="control has-addons">
46+
<input type="text"
47+
class="input is-expanded"
48+
placeholder="Task name"
49+
v-model="taskName"
50+
@keyup.enter="newTask">
51+
<button class="button" @click="newTask">New task</button>
52+
</p>
53+
54+
<div class="box" v-if="orderedTasks.length">
55+
<task v-for="task in orderedTasks" :task-id="task.id" :key="task.id"></task>
56+
</div>
57+
58+
<!--<div class="box">-->
59+
<!--<task v-for="task in orderedTasks" :task-id="task.id" :key="task.id"></task>-->
60+
<!--</div>-->
61+
</div>
62+
</div>
63+
64+
<script>
65+
require('./js/app.js');
66+
</script>
67+
</body>
68+
</html>

app/js/app.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
const Vue = require('vue/dist/vue');
2+
const _ = require('lodash');
3+
4+
Vue.filter('pad', require('./filters/pad'));
5+
Vue.filter('seconds', require('./filters/seconds'));
6+
Vue.filter('minutes', require('./filters/minutes'));
7+
Vue.filter('hours', require('./filters/hours'));
8+
9+
new Vue({
10+
el: '#app',
11+
12+
data() {
13+
return require('./store')
14+
},
15+
16+
computed: {
17+
orderedTasks() {
18+
return _.orderBy(this.tasks, 'id', 'desc');
19+
}
20+
},
21+
22+
components: {
23+
task: require('./components/task/task')
24+
},
25+
26+
filters: {
27+
pad: require('./filters/pad')
28+
},
29+
30+
mounted() {
31+
// TODO: Read local file containing tasks
32+
},
33+
34+
methods: {
35+
newTask() {
36+
// Validation
37+
if (this.taskName.length < 3) {
38+
alert('The task name must contain atleast 3 characters');
39+
40+
return;
41+
}
42+
43+
this.tasks.unshift({
44+
id: (this.tasks.length + 1),
45+
name: this.taskName,
46+
completed: false,
47+
48+
timer: {
49+
seconds: 0,
50+
active: true,
51+
instance: null
52+
}
53+
});
54+
55+
this.taskName = '';
56+
}
57+
}
58+
});

app/js/components/task/task.html

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<div class="notification" :class="{ 'is-success' : task.completed }">
2+
<div class="columns is-mobile is-gapless">
3+
<div class="column is-half">
4+
<span>
5+
{{ task.name }}
6+
</span>
7+
</div>
8+
<div class="column">
9+
{{ task.timer.seconds | hours | pad }} :
10+
{{ task.timer.seconds | minutes | pad }} :
11+
{{ task.timer.seconds | seconds | pad }}
12+
13+
14+
15+
<!--<span v-show="task.timer.seconds >= 3600">{{ task.timer.seconds | hours | pad }}h</span>-->
16+
<!--<span v-show="task.timer.seconds >= 60">{{ task.timer.seconds | minutes | pad }}m</span>-->
17+
<!--<span>{{ task.timer.seconds | seconds | pad }}s</span>-->
18+
</div>
19+
<div class="column">
20+
<a @click="startTimer()" v-show="!task.timer.active && !task.completed">
21+
<span class="icon">
22+
<i class="fa fa-play-circle"></i>
23+
</span>
24+
</a>
25+
<a @click="stopTimer()" v-show="task.timer.active && !task.completed">
26+
<span class="icon">
27+
<i class="fa fa-pause-circle"></i>
28+
</span>
29+
</a>
30+
<a @click="completeTask()" v-show="!task.completed">
31+
<span class="icon">
32+
<i class="fa fa-check-circle"></i>
33+
</span>
34+
</a>
35+
</div>
36+
</div>
37+
</div>

app/js/components/task/task.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
const fs = require('fs');
2+
const store = require('../../store');
3+
const _ = require('lodash');
4+
5+
module.exports = {
6+
template: fs.readFileSync(__dirname + '/task.html', 'utf-8'),
7+
8+
props: {
9+
taskId: {
10+
required: true,
11+
type: Number
12+
}
13+
},
14+
15+
data() {
16+
return {
17+
task: null
18+
}
19+
},
20+
21+
computed: {
22+
styleObject() {
23+
if (this.task.completed) {
24+
return {
25+
textDecoration: 'line-through'
26+
};
27+
}
28+
29+
return {};
30+
}
31+
},
32+
33+
created() {
34+
this.task = _.find(store.tasks, { id: this.taskId });
35+
},
36+
37+
mounted() {
38+
if (this.task.timer.active) {
39+
this.startTimer();
40+
}
41+
},
42+
43+
methods: {
44+
startTimer() {
45+
this.task.timer.active = true;
46+
47+
this.task.timer.instance = window.setInterval(() => {
48+
this.task.timer.seconds += 1;
49+
}, 1000);
50+
},
51+
52+
stopTimer() {
53+
this.task.timer.active = false;
54+
55+
window.clearInterval(this.task.timer.instance);
56+
},
57+
58+
completeTask() {
59+
if (this.task.timer.active) {
60+
this.stopTimer();
61+
}
62+
63+
this.task.completed = true;
64+
}
65+
}
66+
}

app/js/filters/hours.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = function (value) {
2+
return Math.floor(value / 3600);
3+
}

app/js/filters/minutes.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = function (value) {
2+
return Math.floor(value / 60) % 60;
3+
}

app/js/filters/pad.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = function (value) {
2+
if (value.toString().length <= 1) {
3+
return '0' + value.toString();
4+
}
5+
6+
return value.toString();
7+
}

app/js/filters/seconds.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = function (value) {
2+
return value % 60;
3+
}

app/js/store.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
module.exports = {
2+
title: 'Simple CSV reader',
3+
4+
// Used for creating tasks
5+
taskName: '',
6+
7+
file: {
8+
path: null
9+
},
10+
11+
tasks: [
12+
// {
13+
// id: 1,
14+
// name: 'First task',
15+
//
16+
// timer: {
17+
// seconds: 25,
18+
// active: false,
19+
// instance: null
20+
// }
21+
// },
22+
// {
23+
// id: 2,
24+
// name: 'Second task',
25+
//
26+
// timer: {
27+
// seconds: 50,
28+
// active: false,
29+
// instance: null
30+
// }
31+
// },
32+
// {
33+
// id: 3,
34+
// name: 'Third task',
35+
//
36+
// timer: {
37+
// seconds: 50,
38+
// active: false,
39+
// instance: null
40+
// }
41+
// },
42+
]
43+
}

0 commit comments

Comments
 (0)