Skip to content

Commit 53317f6

Browse files
committed
Use one component for list with time
1 parent 6c88a78 commit 53317f6

File tree

10 files changed

+224
-150
lines changed

10 files changed

+224
-150
lines changed

src/assets/css/dashboard.css

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,4 +305,12 @@ label{
305305
vertical-align: middle;
306306
margin-right: 10px;
307307
cursor: pointer;
308-
}
308+
}
309+
.url-list {
310+
width: 655px !important;
311+
}
312+
313+
.url-list .time-value {
314+
margin-top: 5px;
315+
margin-left: 30px;
316+
}

src/components/Limits.vue

Lines changed: 3 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,7 @@
88
<p class="description">
99
If you set the blocking time to 0 hours 0 minutes, the website will be blocked immediately
1010
</p>
11-
<ul readonly class="url-list">
12-
<li v-for="(limit, i) of limitList" :key="i">
13-
<div>
14-
<img
15-
src="../assets/icons/delete.png"
16-
height="16"
17-
@click="deleteFromLimitList(limit.domain)"
18-
/>
19-
<img
20-
src="../assets/icons/edit.svg"
21-
height="16"
22-
@click="editItemFromLimitList(limit.domain, limit.time)"
23-
/>
24-
{{ limit.domain }}
25-
<p class="time-value">{{ getTimeForLimit(limit.time) }}</p>
26-
</div>
27-
</li>
28-
</ul>
29-
<div class="limits-time-block mt-20">
30-
<input
31-
type="text"
32-
:disabled="isEdit"
33-
class="d-inline-block"
34-
placeholder="Enter website name..."
35-
v-model="newWebsiteForLimitList"
36-
/>
37-
<VueDatePicker v-model="time" time-picker class="date-picker height" />
38-
<input
39-
type="button"
40-
class="d-inline-block small-btn"
41-
:value="!isEdit ? 'Add Website' : 'Save'"
42-
:disabled="newWebsiteForLimitList == null || newWebsiteForLimitList == '' || time == null"
43-
@click="isEdit ? editItem() : addToLimitList()"
44-
/>
45-
</div>
11+
<ListWithTimeComponent :type="ListWithTime.Limits" />
4612
</div>
4713
</template>
4814

@@ -53,90 +19,8 @@ export default {
5319
</script>
5420

5521
<script lang="ts" setup>
56-
import { onMounted, ref } from 'vue';
57-
import { useNotification } from '@kyvg/vue3-notification';
58-
import { injecStorage } from '../storage/inject-storage';
59-
import { StorageParams } from '../storage/storage-params';
60-
import { isDomainEquals } from '../utils/common';
61-
import { extractHostname } from '../compositions/extract-hostname';
62-
import { Restriction } from '../entity/restriction';
63-
import { convertHHMMToSeconds, convertSecondsToHHMM } from '../utils/converter';
64-
import { Time } from '../utils/time';
65-
66-
const notification = useNotification();
67-
68-
const settingsStorage = injecStorage();
69-
70-
const limitList = ref<Restriction[]>();
71-
const time = ref<Time>({
72-
hours: 0,
73-
minutes: 30,
74-
});
75-
const newWebsiteForLimitList = ref<string>();
76-
const isEdit = ref<boolean>();
77-
78-
onMounted(async () => {
79-
limitList.value = Object.values(
80-
await settingsStorage.getValue(StorageParams.RESTRICTION_LIST, []),
81-
);
82-
});
83-
84-
function addToLimitList() {
85-
const existingItem = limitList.value?.find(x =>
86-
isDomainEquals(extractHostname(x.domain), extractHostname(newWebsiteForLimitList.value!)),
87-
);
88-
if (existingItem !== undefined) {
89-
notification.notify({
90-
title: 'You have already added this site',
91-
type: 'error',
92-
});
93-
} else {
94-
const newLimit = new Restriction(
95-
extractHostname(newWebsiteForLimitList.value!),
96-
time.value.hours,
97-
time.value.minutes,
98-
);
99-
limitList.value?.push(newLimit);
100-
save(limitList.value);
101-
newWebsiteForLimitList.value = '';
102-
}
103-
}
104-
105-
function getTimeForLimit(time: number) {
106-
const timeObj = convertSecondsToHHMM(time);
107-
return `${timeObj.hours}:${timeObj.minutes < 10 ? '0' + timeObj.minutes : timeObj.minutes}`;
108-
}
109-
110-
function deleteFromLimitList(url: string) {
111-
limitList.value = limitList.value!.filter(x => x.domain != url);
112-
save(limitList.value);
113-
newWebsiteForLimitList.value = '';
114-
isEdit.value = false;
115-
}
116-
117-
function editItemFromLimitList(url: string, timeForUrl: number) {
118-
isEdit.value = true;
119-
newWebsiteForLimitList.value = url;
120-
const timeObj = convertSecondsToHHMM(timeForUrl);
121-
time.value.hours = timeObj.hours;
122-
time.value.minutes = timeObj.minutes;
123-
}
124-
125-
function editItem() {
126-
const existingItem = limitList.value?.find(x =>
127-
isDomainEquals(extractHostname(x.domain), extractHostname(newWebsiteForLimitList.value!)),
128-
);
129-
if (existingItem != undefined) {
130-
existingItem.time = convertHHMMToSeconds(time.value.hours, time.value.minutes);
131-
save(limitList.value);
132-
newWebsiteForLimitList.value = '';
133-
isEdit.value = false;
134-
}
135-
}
136-
137-
async function save(value: any) {
138-
if (value != undefined) await settingsStorage.saveValue(StorageParams.RESTRICTION_LIST, value);
139-
}
22+
import ListWithTimeComponent from '../components/ListWithTime.vue';
23+
import { ListWithTime } from '../utils/enums';
14024
</script>
14125

14226
<style scoped>
@@ -145,27 +29,4 @@ async function save(value: any) {
14529
margin-bottom: 30px;
14630
display: block;
14731
}
148-
149-
.limits-time-block {
150-
display: flex;
151-
justify-content: start;
152-
}
153-
154-
.limits-time-block .date-picker {
155-
width: 120px;
156-
margin: 0 15px;
157-
}
158-
159-
.height {
160-
height: 36px;
161-
}
162-
163-
.url-list {
164-
width: 655px !important;
165-
}
166-
167-
.url-list .time-value {
168-
margin-top: 5px;
169-
margin-left: 30px;
170-
}
17132
</style>

src/components/ListWithTime.vue

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<template>
2+
<ul readonly class="url-list">
3+
<li v-for="(limit, i) of list" :key="i">
4+
<div>
5+
<img src="../assets/icons/delete.png" height="16" @click="deleteFromList(limit.domain)" />
6+
<img
7+
src="../assets/icons/edit.svg"
8+
height="16"
9+
@click="editItemFromList(limit.domain, limit.time)"
10+
/>
11+
{{ limit.domain }}
12+
<p class="time-value">{{ getTime(limit.time) }}</p>
13+
</div>
14+
</li>
15+
</ul>
16+
<div class="limits-time-block mt-20">
17+
<input
18+
type="text"
19+
:disabled="isEdit"
20+
class="d-inline-block"
21+
placeholder="Enter website name..."
22+
v-model="newWebsiteForList"
23+
/>
24+
<VueDatePicker v-model="time" time-picker class="date-picker height" />
25+
<input
26+
type="button"
27+
class="d-inline-block small-btn"
28+
:value="!isEdit ? 'Add Website' : 'Save'"
29+
:disabled="isDisabledSaving"
30+
@click="isEdit ? editItem() : addToList()"
31+
/>
32+
</div>
33+
</template>
34+
35+
<script lang="ts">
36+
export default {
37+
name: 'ListWithTime',
38+
};
39+
</script>
40+
41+
<script lang="ts" setup>
42+
import { useNotification } from '@kyvg/vue3-notification';
43+
import { injecStorage } from '../storage/inject-storage';
44+
import { Time } from '../utils/time';
45+
import { computed, onMounted, ref } from 'vue';
46+
import { ListWithTime } from '../utils/enums';
47+
import { StorageParams } from '../storage/storage-params';
48+
import { isDomainEquals } from '../utils/common';
49+
import { extractHostname } from '../compositions/extract-hostname';
50+
import { convertHHMMToSeconds, convertSecondsToHHMM } from '../utils/converter';
51+
import { Restriction } from '../entity/restriction';
52+
import { BaseTimeList } from '../entity/baseTimeList';
53+
import { Notifications } from '../entity/notification';
54+
55+
const props = defineProps<{
56+
type: ListWithTime;
57+
}>();
58+
59+
const notification = useNotification();
60+
const settingsStorage = injecStorage();
61+
62+
const list = ref<BaseTimeList[]>();
63+
const isEdit = ref<boolean>();
64+
const time = ref<Time>({
65+
hours: 0,
66+
minutes: 30,
67+
});
68+
const newWebsiteForList = ref<string>();
69+
const storageParam = ref<StorageParams>();
70+
71+
onMounted(async () => {
72+
switch (props.type) {
73+
case ListWithTime.Limits:
74+
list.value = Object.values(
75+
await settingsStorage.getValue(StorageParams.RESTRICTION_LIST, []),
76+
) as Restriction[];
77+
storageParam.value = StorageParams.RESTRICTION_LIST;
78+
break;
79+
case ListWithTime.Notifications:
80+
list.value = Object.values(
81+
await settingsStorage.getValue(StorageParams.NOTIFICATION_LIST, []),
82+
) as Notifications[];
83+
storageParam.value = StorageParams.NOTIFICATION_LIST;
84+
break;
85+
}
86+
});
87+
88+
function addToList() {
89+
const existingItem = list.value?.find(x =>
90+
isDomainEquals(extractHostname(x.domain), extractHostname(newWebsiteForList.value!)),
91+
);
92+
if (existingItem !== undefined) {
93+
notification.notify({
94+
title: 'You have already added this site',
95+
type: 'error',
96+
});
97+
} else {
98+
const newLimit = new Restriction(
99+
extractHostname(newWebsiteForList.value!),
100+
time.value.hours,
101+
time.value.minutes,
102+
);
103+
list.value?.push(newLimit);
104+
save(list.value);
105+
newWebsiteForList.value = '';
106+
}
107+
}
108+
109+
function getTime(time: number) {
110+
const timeObj = convertSecondsToHHMM(time);
111+
return `${timeObj.hours}:${timeObj.minutes < 10 ? '0' + timeObj.minutes : timeObj.minutes}`;
112+
}
113+
114+
const isDisabledSaving = computed(() => {
115+
if (
116+
props.type == ListWithTime.Notifications &&
117+
time.value?.hours == 0 &&
118+
time.value?.minutes == 0
119+
)
120+
return true;
121+
return (
122+
newWebsiteForList.value == '' || newWebsiteForList.value == undefined || time.value == null
123+
);
124+
});
125+
126+
function deleteFromList(url: string) {
127+
list.value = list.value!.filter(x => x.domain != url);
128+
save(list.value);
129+
newWebsiteForList.value = '';
130+
isEdit.value = false;
131+
}
132+
133+
function editItemFromList(url: string, timeForUrl: number) {
134+
isEdit.value = true;
135+
newWebsiteForList.value = url;
136+
const timeObj = convertSecondsToHHMM(timeForUrl);
137+
time.value.hours = timeObj.hours;
138+
time.value.minutes = timeObj.minutes;
139+
}
140+
141+
function editItem() {
142+
const existingItem = list.value?.find(x =>
143+
isDomainEquals(extractHostname(x.domain), extractHostname(newWebsiteForList.value!)),
144+
);
145+
if (existingItem != undefined) {
146+
existingItem.time = convertHHMMToSeconds(time.value.hours, time.value.minutes);
147+
save(list.value);
148+
newWebsiteForList.value = '';
149+
isEdit.value = false;
150+
}
151+
}
152+
153+
async function save(value: any) {
154+
if (value != undefined) await settingsStorage.saveValue(storageParam.value!, value);
155+
}
156+
</script>
157+
158+
<style scoped>
159+
.limits-time-block {
160+
display: flex;
161+
justify-content: start;
162+
}
163+
164+
.limits-time-block .date-picker {
165+
width: 120px;
166+
margin: 0 15px;
167+
}
168+
</style>

src/components/Notifications.vue

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@
2727
class="date-picker d-inline-block"
2828
/>
2929
</div>
30+
<div class="settings-item">
31+
<label class="setting-header">Notifications for websites</label>
32+
<p class="description">
33+
Show notifications every time you spend a certain period of time on the website
34+
</p>
35+
<ListWithTimeComponent :type="ListWithTime.Notifications" />
36+
</div>
3037
</div>
3138
</template>
3239

@@ -44,8 +51,11 @@ import {
4451
DAILY_NOTIFICATION_DEFAULT,
4552
DAILY_SUMMARY_NOTIFICATION_TIME_DEFAULT,
4653
} from '../storage/storage-params';
47-
import { convertHHMMToMilliSeconds, convertMilliSecondsToHHMM } from '../utils/converter';
54+
import { convertHHMMToSeconds, convertSecondsToHHMM } from '../utils/converter';
4855
import { Time } from '../utils/time';
56+
import { rescheduleJobs } from '../jobs/sheduler';
57+
import ListWithTimeComponent from '../components/ListWithTime.vue';
58+
import { ListWithTime } from '../utils/enums';
4959
5060
const settingsStorage = injecStorage();
5161
@@ -64,17 +74,18 @@ onMounted(async () => {
6474
DAILY_SUMMARY_NOTIFICATION_TIME_DEFAULT,
6575
)) as number;
6676
67-
const timeObj = convertMilliSecondsToHHMM(dailyNotificationTime.value);
77+
const timeObj = convertSecondsToHHMM(dailyNotificationTime.value);
6878
notificationTime.value = timeObj;
6979
});
7080
71-
function handleDate(modelData: Time) {
81+
async function handleDate(modelData: Time) {
7282
if (modelData != null) {
7383
notificationTime.value = modelData;
7484
save(
7585
StorageParams.DAILY_SUMMARY_NOTIFICATION_TIME,
76-
convertHHMMToMilliSeconds(notificationTime.value.hours, notificationTime.value.minutes),
86+
convertHHMMToSeconds(notificationTime.value.hours, notificationTime.value.minutes),
7787
);
88+
await rescheduleJobs();
7889
}
7990
}
8091

0 commit comments

Comments
 (0)