Skip to content

Commit 2a52149

Browse files
committed
Dashboard template
1 parent ac15cbc commit 2a52149

File tree

10 files changed

+465
-390
lines changed

10 files changed

+465
-390
lines changed
Lines changed: 46 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
body {
22
font-family: "Segoe UI", Tahoma, sans-serif !important;
33
color: #262626;
4-
background-color: rgb(255, 255, 255);
4+
background-color: #eee;
5+
margin: 0;
56
}
67

78
.container {
@@ -257,57 +258,51 @@ label{
257258
position: absolute;
258259
}
259260

260-
261-
/* Tabs */
262-
.tabs {
263-
position: relative;
264-
min-height: 500px;
265-
clear: both;
266-
margin: 25px 0;
267-
}
268-
.tab {
269-
float: left;
270-
clear: both;
271-
width: 286px;
272-
}
273-
.tab > label {
274-
padding: 10px;
275-
margin-left: -1px;
261+
.settings-tabs {
262+
}
263+
.settings-tab {
264+
clear: both;
265+
width: 286px;
266+
}
267+
.settings-tab label[name="tabName"] {
268+
background: #eee;
269+
padding: 5px 0 5px 35px;
276270
font-size: 16px;
277271
vertical-align: middle;
278-
position: relative;
279-
width: 100px;
280-
height: 30px;
272+
width: 250px;
273+
height: 40px;
281274
display: table-cell;
282275
cursor: pointer;
283-
}
284-
.tab [type=radio]:not(:checked) ~ label:hover{
285-
background-color: #e4e4e4;
286-
border-radius: 10px;
287-
}
288-
.tab [type=radio] {
289-
display: none;
290-
}
291-
.content {
292-
position: absolute;
293-
top: 0;
294-
left: 140px;
295-
background: white;
296-
right: 0;
297-
bottom: 0;
298-
padding: 10px 20px;
299-
}
300-
.content {
301-
opacity: 0;
302-
transition: all 0.6s ease;
303-
}
304-
[type=radio]:checked ~ label {
305-
background: white;
306-
border-bottom: 2px solid #6ebf5d;
307-
z-index: 2;
308-
}
309-
[type=radio]:checked ~ label ~ .content {
310-
opacity: 1;
311-
transform: translateX(0);
312-
z-index: 1;
313-
}
276+
}
277+
.settings-tab [type=radio] {
278+
display: none;
279+
}
280+
.settings-content {
281+
position: absolute;
282+
top: 0;
283+
left: 286px;
284+
background: white;
285+
right: 0;
286+
bottom: 0;
287+
padding: 50px;
288+
border-left: 1px solid #ccc;
289+
}
290+
.settings-content span {
291+
animation: 0.5s ease-out 0s 1 slideInFromTop;
292+
}
293+
[type=radio]:checked ~ label {
294+
background: white;
295+
border-bottom: 2px solid #8bc34a;
296+
z-index: 2;
297+
}
298+
[type=radio]:checked ~ label ~ .settings-content {
299+
z-index: 1;
300+
}
301+
.settings-item {
302+
margin-bottom: 30px;
303+
}
304+
.url-list img {
305+
vertical-align: middle;
306+
margin-right: 10px;
307+
cursor: pointer;
308+
}

src/components/About.vue

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<template>
2+
<div class="about">
3+
<label class="about-label"
4+
>GitHub:
5+
<a href="https://github.com/Stigmatoz/web-activity-time-tracker" target="_blank"
6+
>github.com/Stigmatoz/web-activity-time-tracker</a
7+
></label
8+
>
9+
<label class="about-label"
10+
>If you have feedback or would like to report an issue, you can do so on the
11+
<a href="https://github.com/Stigmatoz/web-activity-time-tracker/issues" target="_blank"
12+
>GitHub issues page</a
13+
></label
14+
>
15+
<label class="about-label"
16+
>If experiencing problems, having questions or suggestions, please fill out
17+
<a
18+
href="https://chrome.google.com/webstore/detail/web-activity-time-tracker/hhfnghjdeddcfegfekjeihfmbjenlomm/support"
19+
target="_blank"
20+
>support form</a
21+
>.</label
22+
>
23+
<label class="about-label"
24+
>Do you enjoy using Web Activity Time Tracker?
25+
<a
26+
href="https://chrome.google.com/webstore/detail/web-activity-time-tracker/hhfnghjdeddcfegfekjeihfmbjenlomm/reviews"
27+
target="_blank"
28+
>Leave a review!</a
29+
></label
30+
>
31+
</div>
32+
</template>
33+
34+
<script lang="ts">
35+
export default {
36+
name: 'About',
37+
};
38+
</script>
39+
40+
<style scoped>
41+
.about .about-label {
42+
font-size: 14px;
43+
margin-bottom: 30px;
44+
display: block;
45+
}
46+
</style>

src/components/GeneralSettings.vue

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
<template>
2+
<div class="settings-item">
3+
<label class="setting-header">
4+
<input
5+
type="checkbox"
6+
class="filled-in"
7+
id="viewTimeInBadge"
8+
v-model="viewTimeInBadge"
9+
@change="onChange(StorageParams.VIEW_TIME_IN_BADGE, $event.target.checked)"
10+
/>
11+
<span>Display time tracker in icon</span>
12+
<p class="description">
13+
You can see current spent time in short format in the icon of extension
14+
</p>
15+
</label>
16+
</div>
17+
<div class="settings-item">
18+
<label class="setting-header">
19+
<input
20+
type="checkbox"
21+
class="filled-in"
22+
id="blockDeferral"
23+
v-model="allowDeferringBlock"
24+
@change="onChange(StorageParams.BLOCK_DEFERRAL, $event.target.checked)"
25+
/>
26+
<span>Allow deferring block for 5 minutes</span>
27+
<p class="description">
28+
After the site is blocked, you can postpone the blocking for 5 minutes
29+
</p>
30+
</label>
31+
</div>
32+
<div class="settings-item">
33+
<label class="setting-header">
34+
<input
35+
type="checkbox"
36+
class="filled-in"
37+
id="darkMode"
38+
v-model="darkMode"
39+
@change="onChange(StorageParams.DARK_MODE, $event.target.checked)"
40+
/>
41+
<span>Dark mode</span>
42+
<p class="description">Dark theme</p>
43+
</label>
44+
</div>
45+
<div class="settings-item">
46+
<label class="setting-header d-inline-block"
47+
>Stop tracking if there is no activity during:
48+
</label>
49+
<div class="d-inline-block ml-10">
50+
<select
51+
class="option"
52+
v-model="intervalInactivity"
53+
@change="onChange(StorageParams.INTERVAL_INACTIVITY, $event.target.value)"
54+
>
55+
<option :value="InactivityInterval.Seconds_30">30 seconds</option>
56+
<option :value="InactivityInterval.Seconds_45">45 seconds</option>
57+
<option :value="InactivityInterval.Min_1">1 min</option>
58+
<option :value="InactivityInterval.Min_2">2 min</option>
59+
<option :value="InactivityInterval.Min_5">5 mins</option>
60+
<option :value="InactivityInterval.Min_10">10 mins</option>
61+
<option :value="InactivityInterval.Min_20">20 mins</option>
62+
<option :value="InactivityInterval.Min_30">30 mins</option>
63+
</select>
64+
</div>
65+
<p class="description">These are any actions with the mouse or keyboard</p>
66+
</div>
67+
<div class="settings-item">
68+
<label class="setting-header d-inline-block">Exporting your web activity data to CSV </label>
69+
<p class="description">You can export your web activity for any date range</p>
70+
<div class="export-block">
71+
<VueDatePicker
72+
range
73+
:enable-time-picker="false"
74+
class="date-picker"
75+
v-model="selectedDate"
76+
:preset-ranges="presetRanges"
77+
@update:model-value="handleDate"
78+
>
79+
<template #yearly="{ label, range, presetDateRange }">
80+
<span @click="presetDateRange(range)">{{ label }}</span>
81+
</template>
82+
</VueDatePicker>
83+
<input type="button" value="Export to CSV" @click="exportToCsv()" />
84+
</div>
85+
</div>
86+
</template>
87+
88+
<script lang="ts">
89+
export default {
90+
name: 'GeneralSettings',
91+
};
92+
</script>
93+
94+
<script lang="ts" setup>
95+
import { onMounted, ref } from 'vue';
96+
import { injecStorage } from '../storage/inject-storage';
97+
import { useNotification } from '@kyvg/vue3-notification';
98+
import {
99+
BLOCK_DEFERRAL_DEFAULT,
100+
DARK_MODE_DEFAULT,
101+
INTERVAL_INACTIVITY_DEFAULT,
102+
StorageParams,
103+
VIEW_TIME_IN_BADGE_DEFAULT,
104+
InactivityInterval,
105+
} from '../storage/storage-params';
106+
import { ranges, ThisWeekRange } from '../utils/date';
107+
import { useImportToCsv } from '../compositions/toCsv';
108+
import { FileType, useFile } from '../compositions/loadFile';
109+
110+
const settingsStorage = injecStorage();
111+
const notification = useNotification();
112+
113+
const viewTimeInBadge = ref<boolean>();
114+
const intervalInactivity = ref<InactivityInterval>();
115+
const allowDeferringBlock = ref<boolean>();
116+
const darkMode = ref<boolean>();
117+
const selectedDate = ref<Date[]>();
118+
119+
const presetRanges = ranges();
120+
121+
onMounted(async () => {
122+
viewTimeInBadge.value = await settingsStorage.getValue(
123+
StorageParams.VIEW_TIME_IN_BADGE,
124+
VIEW_TIME_IN_BADGE_DEFAULT,
125+
);
126+
intervalInactivity.value = await settingsStorage.getValue(
127+
StorageParams.INTERVAL_INACTIVITY,
128+
INTERVAL_INACTIVITY_DEFAULT,
129+
);
130+
darkMode.value = await settingsStorage.getValue(StorageParams.DARK_MODE, DARK_MODE_DEFAULT);
131+
allowDeferringBlock.value = await settingsStorage.getValue(
132+
StorageParams.BLOCK_DEFERRAL,
133+
BLOCK_DEFERRAL_DEFAULT,
134+
);
135+
selectedDate.value = ThisWeekRange;
136+
});
137+
138+
async function onChange(storageParam: StorageParams, value: any) {
139+
await save(storageParam, value);
140+
}
141+
142+
async function save(storageParam: StorageParams, value: any) {
143+
if (value != undefined) await settingsStorage.saveValue(storageParam, value);
144+
}
145+
146+
async function handleDate(modelData: Date[]) {
147+
selectedDate.value = modelData;
148+
}
149+
150+
async function exportToCsv() {
151+
const dateFrom = selectedDate.value?.[0] as Date;
152+
const dateTo = selectedDate.value?.[1] as Date;
153+
if (dateFrom == undefined || dateTo == undefined) {
154+
notification.notify({
155+
title: 'No time period selected',
156+
type: 'warn',
157+
});
158+
} else {
159+
const csv = await useImportToCsv(dateFrom, dateTo);
160+
useFile(
161+
csv,
162+
FileType.CSV,
163+
`websites_${dateFrom.toLocaleDateString()}-${dateTo.toLocaleDateString()}.csv`,
164+
);
165+
}
166+
}
167+
</script>
168+
169+
<style scoped>
170+
.export-block {
171+
display: flex;
172+
justify-content: start;
173+
}
174+
175+
.export-block .date-picker {
176+
width: 250px;
177+
margin-right: 15px;
178+
}
179+
</style>

0 commit comments

Comments
 (0)