mhz-helpers 1.3.26 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/composables/useAuth.d.ts +14 -0
- package/dist/composables/useAuth.js +36 -0
- package/dist/composables/useCalendar.d.ts +15 -0
- package/dist/composables/useCalendar.js +22 -0
- package/dist/composables/useDarkMode.d.ts +9 -0
- package/dist/composables/useDarkMode.js +28 -0
- package/dist/composables/useInfiniteScroll.d.ts +12 -0
- package/dist/composables/useInfiniteScroll.js +22 -0
- package/dist/composables/usePage.d.ts +35 -0
- package/dist/composables/usePage.js +96 -0
- package/dist/composables/usePageLock.d.ts +4 -0
- package/dist/composables/usePageLock.js +28 -0
- package/dist/composables/usePagination.d.ts +14 -0
- package/dist/composables/usePagination.js +20 -0
- package/dist/composables/usePwa.d.ts +13 -0
- package/dist/composables/usePwa.js +41 -0
- package/dist/composables/useRouteId.d.ts +8 -0
- package/dist/composables/useRouteId.js +13 -0
- package/dist/composables/useTimer.d.ts +11 -0
- package/dist/composables/useTimer.js +38 -0
- package/dist/composables/useValidate.d.ts +19 -0
- package/dist/composables/useValidate.js +62 -0
- package/dist/helpers/api.d.ts +10 -0
- package/dist/helpers/api.js +19 -0
- package/dist/helpers/clone.d.ts +4 -0
- package/dist/helpers/clone.js +44 -0
- package/dist/helpers/date.d.ts +25 -0
- package/dist/helpers/date.js +76 -0
- package/dist/helpers/id.d.ts +7 -0
- package/dist/helpers/id.js +17 -0
- package/dist/helpers/link.d.ts +4 -0
- package/dist/helpers/link.js +8 -0
- package/dist/helpers/locale.d.ts +6 -0
- package/dist/helpers/locale.js +7 -0
- package/dist/helpers/numbers.d.ts +5 -0
- package/dist/helpers/numbers.js +12 -0
- package/dist/helpers/password.d.ts +4 -0
- package/dist/helpers/password.js +10 -0
- package/dist/helpers/query.d.ts +9 -0
- package/dist/helpers/query.js +30 -0
- package/dist/helpers/scroll.d.ts +4 -0
- package/dist/helpers/scroll.js +7 -0
- package/dist/helpers/string.d.ts +4 -0
- package/dist/helpers/string.js +12 -0
- package/dist/helpers/test.d.ts +9 -0
- package/dist/helpers/test.js +45 -0
- package/dist/index.d.ts +25 -23
- package/dist/index.js +25 -23
- package/dist/locales/index.js +26 -0
- package/dist/locales/types.d.ts +4 -1
- package/package.json +15 -17
- package/dist/api/index.d.ts +0 -5
- package/dist/api/index.js +0 -1832
- package/dist/clone/index.d.ts +0 -1
- package/dist/clone/index.js +0 -45
- package/dist/date/index.d.ts +0 -22
- package/dist/date/index.js +0 -62
- package/dist/id/index.d.ts +0 -4
- package/dist/id/index.js +0 -10
- package/dist/index-BpwdWGUI.js +0 -25
- package/dist/link/index.d.ts +0 -1
- package/dist/link/index.js +0 -6
- package/dist/locale/index.d.ts +0 -2
- package/dist/locale/index.js +0 -7
- package/dist/locales/index.d.ts +0 -22
- package/dist/numbers/index.d.ts +0 -2
- package/dist/numbers/index.js +0 -10
- package/dist/password/index.d.ts +0 -1
- package/dist/password/index.js +0 -10
- package/dist/query/index.d.ts +0 -7
- package/dist/query/index.js +0 -2996
- package/dist/scroll/index.d.ts +0 -1
- package/dist/scroll/index.js +0 -6
- package/dist/string/index.d.ts +0 -1
- package/dist/string/index.js +0 -9
- package/dist/test/index.d.ts +0 -5
- package/dist/test/index.js +0 -39
- package/dist/useAuth/index.d.ts +0 -9
- package/dist/useAuth/index.js +0 -35
- package/dist/useCalendar/index.d.ts +0 -10
- package/dist/useCalendar/index.js +0 -11
- package/dist/useDarkMode/index.d.ts +0 -4
- package/dist/useDarkMode/index.js +0 -20
- package/dist/useInfiniteScroll/index.d.ts +0 -7
- package/dist/useInfiniteScroll/index.js +0 -14
- package/dist/usePage/index.d.ts +0 -30
- package/dist/usePage/index.js +0 -67
- package/dist/usePageLock/index.d.ts +0 -1
- package/dist/usePageLock/index.js +0 -21
- package/dist/usePagination/index.d.ts +0 -9
- package/dist/usePagination/index.js +0 -11
- package/dist/usePwa/index.d.ts +0 -8
- package/dist/usePwa/index.js +0 -27
- package/dist/useRouteId/index.d.ts +0 -3
- package/dist/useRouteId/index.js +0 -9
- package/dist/useTimer/index.d.ts +0 -6
- package/dist/useTimer/index.js +0 -19
- package/dist/useValidate/index.d.ts +0 -15
- package/dist/useValidate/index.js +0 -843
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as vue from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/composables/useAuth.d.ts
|
|
4
|
+
declare const isAuth: Readonly<vue.Ref<boolean, boolean>>;
|
|
5
|
+
declare function setAuth(auth: boolean): void;
|
|
6
|
+
declare function logout(url: string, deleteAuthHeader: () => void, tokenName: string): void;
|
|
7
|
+
declare function getCookieToken(tokenName: string): string | undefined;
|
|
8
|
+
declare function setCookieToken(token: string, tokenName: string): void;
|
|
9
|
+
declare function deleteCookieToken(tokenName: string): void;
|
|
10
|
+
declare function useAuth(): {
|
|
11
|
+
auth: (token: string, setAuthHeader: (token: string) => void, tokenName: string) => void;
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { deleteCookieToken, getCookieToken, isAuth, logout, setAuth, setCookieToken, useAuth };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getOneYearFromNow } from "../helpers/date.js";
|
|
2
|
+
import { readonly, shallowRef } from "vue";
|
|
3
|
+
|
|
4
|
+
//#region src/composables/useAuth.ts
|
|
5
|
+
const isAuthLocal = shallowRef(false);
|
|
6
|
+
const isAuth = readonly(isAuthLocal);
|
|
7
|
+
function setAuth(auth) {
|
|
8
|
+
isAuthLocal.value = auth;
|
|
9
|
+
}
|
|
10
|
+
function logout(url, deleteAuthHeader, tokenName) {
|
|
11
|
+
deleteCookieToken(tokenName);
|
|
12
|
+
deleteAuthHeader();
|
|
13
|
+
globalThis.location.href = url;
|
|
14
|
+
}
|
|
15
|
+
function getCookieToken(tokenName) {
|
|
16
|
+
if (!document.cookie) return;
|
|
17
|
+
const { [tokenName]: token } = Object.fromEntries(document.cookie.split("; ").map((v) => v.split("=")));
|
|
18
|
+
return token;
|
|
19
|
+
}
|
|
20
|
+
function setCookieToken(token, tokenName) {
|
|
21
|
+
document.cookie = `${tokenName}=${token};Secure;SameSite=strict;expires=${getOneYearFromNow()}`;
|
|
22
|
+
}
|
|
23
|
+
function deleteCookieToken(tokenName) {
|
|
24
|
+
document.cookie = `${tokenName}=;expires=${(/* @__PURE__ */ new Date(0)).toUTCString()}`;
|
|
25
|
+
}
|
|
26
|
+
function useAuth() {
|
|
27
|
+
function auth(token, setAuthHeader, tokenName) {
|
|
28
|
+
setCookieToken(token, tokenName);
|
|
29
|
+
setAuthHeader(token);
|
|
30
|
+
setAuth(true);
|
|
31
|
+
}
|
|
32
|
+
return { auth };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
export { deleteCookieToken, getCookieToken, isAuth, logout, setAuth, setCookieToken, useAuth };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as vue from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/composables/useCalendar.d.ts
|
|
4
|
+
interface ICalendarDates {
|
|
5
|
+
dateFrom: Date;
|
|
6
|
+
dateTo: Date;
|
|
7
|
+
}
|
|
8
|
+
declare function useCalendar(): {
|
|
9
|
+
dateFrom: vue.ShallowRef<Date | undefined, Date | undefined>;
|
|
10
|
+
dateTo: vue.ShallowRef<Date | undefined, Date | undefined>;
|
|
11
|
+
isDatesReady: vue.ShallowRef<boolean, boolean>;
|
|
12
|
+
updateDates: (dates: ICalendarDates) => void;
|
|
13
|
+
};
|
|
14
|
+
//#endregion
|
|
15
|
+
export { ICalendarDates, useCalendar };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { shallowRef } from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/composables/useCalendar.ts
|
|
4
|
+
function useCalendar() {
|
|
5
|
+
const dateFrom = shallowRef();
|
|
6
|
+
const dateTo = shallowRef();
|
|
7
|
+
const isDatesReady = shallowRef(false);
|
|
8
|
+
function updateDates(dates) {
|
|
9
|
+
dateFrom.value = dates.dateFrom;
|
|
10
|
+
dateTo.value = dates.dateTo;
|
|
11
|
+
isDatesReady.value = true;
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
dateFrom,
|
|
15
|
+
dateTo,
|
|
16
|
+
isDatesReady,
|
|
17
|
+
updateDates
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { useCalendar };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { onBeforeMount, readonly, shallowRef } from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/composables/useDarkMode.ts
|
|
4
|
+
function useDarkMode() {
|
|
5
|
+
const isDarkModeState = shallowRef(false);
|
|
6
|
+
const isDarkMode = readonly(isDarkModeState);
|
|
7
|
+
onBeforeMount(() => {
|
|
8
|
+
const isLocalStorageValue = localStorage.getItem("dark");
|
|
9
|
+
if (isLocalStorageValue === null) localStorage.setItem("dark", "false");
|
|
10
|
+
else {
|
|
11
|
+
const isDarkModeEnabled = isLocalStorageValue === "true";
|
|
12
|
+
isDarkModeState.value = isDarkModeEnabled;
|
|
13
|
+
if (isDarkModeEnabled) document.body?.classList.add("dark");
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
function toggleDarkMode() {
|
|
17
|
+
isDarkModeState.value = !isDarkModeState.value;
|
|
18
|
+
document.body?.classList.toggle("dark", isDarkModeState.value);
|
|
19
|
+
localStorage.setItem("dark", String(isDarkModeState.value));
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
isDarkMode,
|
|
23
|
+
toggleDarkMode
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
export { useDarkMode };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as vue from "vue";
|
|
2
|
+
import { Ref } from "vue";
|
|
3
|
+
|
|
4
|
+
//#region src/composables/useInfiniteScroll.d.ts
|
|
5
|
+
declare function useInfiniteScroll<T>(): {
|
|
6
|
+
page: vue.ShallowRef<number, number>;
|
|
7
|
+
allData: Ref<T[], T[]>;
|
|
8
|
+
addData: (data: T[]) => void;
|
|
9
|
+
handleScroll: (isLoading: boolean, pageToSet: number) => void;
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
export { useInfiniteScroll };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ref, shallowRef } from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/composables/useInfiniteScroll.ts
|
|
4
|
+
function useInfiniteScroll() {
|
|
5
|
+
const page = shallowRef(1);
|
|
6
|
+
const allData = ref([]);
|
|
7
|
+
function addData(data) {
|
|
8
|
+
allData.value = [...allData.value, ...data];
|
|
9
|
+
}
|
|
10
|
+
function handleScroll(isLoading, pageToSet) {
|
|
11
|
+
if (!isLoading) page.value = pageToSet > 0 ? pageToSet : 1;
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
page,
|
|
15
|
+
allData,
|
|
16
|
+
addData,
|
|
17
|
+
handleScroll
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { useInfiniteScroll };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as vue from "vue";
|
|
2
|
+
import { Ref } from "vue";
|
|
3
|
+
|
|
4
|
+
//#region src/composables/usePage.d.ts
|
|
5
|
+
interface ISortOption {
|
|
6
|
+
value?: string;
|
|
7
|
+
isAsc: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface IPageQuery {
|
|
10
|
+
page: number;
|
|
11
|
+
sort: ISortOption;
|
|
12
|
+
filter: object;
|
|
13
|
+
}
|
|
14
|
+
interface IPageParams {
|
|
15
|
+
page: number;
|
|
16
|
+
}
|
|
17
|
+
interface IPageSortParams extends IPageParams {
|
|
18
|
+
dir: string;
|
|
19
|
+
sort?: string;
|
|
20
|
+
initiator?: string;
|
|
21
|
+
}
|
|
22
|
+
declare function convertParams(params: Ref<IPageQuery | number>, initiator?: string): IPageSortParams | IPageParams;
|
|
23
|
+
declare function usePage(filter?: object): {
|
|
24
|
+
query: Ref<IPageQuery, IPageQuery>;
|
|
25
|
+
resetQuery: (sortValue: string | ISortOption) => void;
|
|
26
|
+
setQueryPage: (pageToSet: number) => void;
|
|
27
|
+
setQueryFilter: (filterToSet?: object) => void;
|
|
28
|
+
};
|
|
29
|
+
declare function usePageNumber(): {
|
|
30
|
+
page: vue.ShallowRef<number, number>;
|
|
31
|
+
resetPage: () => void;
|
|
32
|
+
setPage: (pageToSet: number) => void;
|
|
33
|
+
};
|
|
34
|
+
//#endregion
|
|
35
|
+
export { IPageParams, IPageQuery, IPageSortParams, ISortOption, convertParams, usePage, usePageNumber };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { ref, shallowRef, watch } from "vue";
|
|
2
|
+
import { useRoute, useRouter } from "vue-router";
|
|
3
|
+
|
|
4
|
+
//#region src/composables/usePage.ts
|
|
5
|
+
function convertParams(params, initiator) {
|
|
6
|
+
if (typeof params.value === "number") return { page: params.value };
|
|
7
|
+
const { page, sort, filter } = params.value;
|
|
8
|
+
return {
|
|
9
|
+
page: page > 0 ? page : 1,
|
|
10
|
+
dir: sort.isAsc === false ? "desc" : "asc",
|
|
11
|
+
sort: sort.value,
|
|
12
|
+
initiator,
|
|
13
|
+
...filter
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function usePage(filter) {
|
|
17
|
+
const router = useRouter();
|
|
18
|
+
const route = useRoute();
|
|
19
|
+
const query = ref({
|
|
20
|
+
page: route.query.page && Number(route.query.page > 0) ? Number(route.query.page) : 1,
|
|
21
|
+
sort: {
|
|
22
|
+
value: route.query.sort?.toString(),
|
|
23
|
+
isAsc: route.query.dir !== "desc"
|
|
24
|
+
},
|
|
25
|
+
filter: { ...filter }
|
|
26
|
+
});
|
|
27
|
+
function resetQuery(sortValue) {
|
|
28
|
+
query.value = typeof sortValue === "string" ? {
|
|
29
|
+
page: 1,
|
|
30
|
+
sort: {
|
|
31
|
+
value: sortValue,
|
|
32
|
+
isAsc: true
|
|
33
|
+
},
|
|
34
|
+
filter: {}
|
|
35
|
+
} : {
|
|
36
|
+
...query.value,
|
|
37
|
+
page: 1,
|
|
38
|
+
sort: sortValue
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function setQueryPage(pageToSet) {
|
|
42
|
+
query.value.page = pageToSet > 0 ? pageToSet : 1;
|
|
43
|
+
}
|
|
44
|
+
function setQueryFilter(filterToSet) {
|
|
45
|
+
query.value = {
|
|
46
|
+
page: 1,
|
|
47
|
+
sort: query.value.sort,
|
|
48
|
+
filter: { ...filterToSet }
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
watch(() => [
|
|
52
|
+
query.value.page,
|
|
53
|
+
query.value.sort.value,
|
|
54
|
+
query.value.sort.isAsc
|
|
55
|
+
], () => {
|
|
56
|
+
router.push({
|
|
57
|
+
path: route.path,
|
|
58
|
+
query: {
|
|
59
|
+
page: query.value.page,
|
|
60
|
+
sort: query.value.sort.value,
|
|
61
|
+
dir: query.value.sort.isAsc ? "asc" : "desc"
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
return {
|
|
66
|
+
query,
|
|
67
|
+
resetQuery,
|
|
68
|
+
setQueryPage,
|
|
69
|
+
setQueryFilter
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function usePageNumber() {
|
|
73
|
+
const router = useRouter();
|
|
74
|
+
const route = useRoute();
|
|
75
|
+
const page = shallowRef(Number(route.query.page || 1));
|
|
76
|
+
function resetPage() {
|
|
77
|
+
page.value = 1;
|
|
78
|
+
}
|
|
79
|
+
function setPage(pageToSet) {
|
|
80
|
+
page.value = pageToSet;
|
|
81
|
+
}
|
|
82
|
+
watch(() => page.value, () => {
|
|
83
|
+
router.push({
|
|
84
|
+
path: route.path,
|
|
85
|
+
query: { page: page.value }
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
return {
|
|
89
|
+
page,
|
|
90
|
+
resetPage,
|
|
91
|
+
setPage
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
//#endregion
|
|
96
|
+
export { convertParams, usePage, usePageNumber };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { onBeforeUnmount, onMounted, ref } from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/composables/usePageLock.ts
|
|
4
|
+
function usePageLock() {
|
|
5
|
+
const pageLock = ref();
|
|
6
|
+
async function lockPage() {
|
|
7
|
+
pageLock.value = await navigator.wakeLock?.request();
|
|
8
|
+
}
|
|
9
|
+
function releasePage() {
|
|
10
|
+
pageLock.value?.release();
|
|
11
|
+
pageLock.value = void 0;
|
|
12
|
+
}
|
|
13
|
+
async function updatePageVisibility() {
|
|
14
|
+
if (document.visibilityState === "visible") await lockPage();
|
|
15
|
+
else releasePage();
|
|
16
|
+
}
|
|
17
|
+
onMounted(async () => {
|
|
18
|
+
await lockPage();
|
|
19
|
+
document.addEventListener("visibilitychange", updatePageVisibility);
|
|
20
|
+
});
|
|
21
|
+
onBeforeUnmount(() => {
|
|
22
|
+
releasePage();
|
|
23
|
+
document.removeEventListener("visibilitychange", updatePageVisibility);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
export { usePageLock };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as vue from "vue";
|
|
2
|
+
import { Ref } from "vue";
|
|
3
|
+
|
|
4
|
+
//#region src/composables/usePagination.d.ts
|
|
5
|
+
declare function usePagination<T>(dataRaw: Ref<{
|
|
6
|
+
data: T[];
|
|
7
|
+
total: number;
|
|
8
|
+
} | undefined>): {
|
|
9
|
+
data: vue.ComputedRef<T[]>;
|
|
10
|
+
total: vue.ComputedRef<number>;
|
|
11
|
+
setPaginationPage: (pageToSet: number, page: number) => number;
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { usePagination };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { computed } from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/composables/usePagination.ts
|
|
4
|
+
function usePagination(dataRaw) {
|
|
5
|
+
const data = computed(() => dataRaw.value?.data || []);
|
|
6
|
+
const total = computed(() => dataRaw.value?.total || 0);
|
|
7
|
+
function setPaginationPage(pageToSet, page) {
|
|
8
|
+
if (!total.value) return page;
|
|
9
|
+
if (pageToSet < 1 || pageToSet > total.value) return page;
|
|
10
|
+
return pageToSet;
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
data,
|
|
14
|
+
total,
|
|
15
|
+
setPaginationPage
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
export { usePagination };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as vue from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/composables/usePwa.d.ts
|
|
4
|
+
interface IPromptEvent extends Event {
|
|
5
|
+
prompt: () => Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
declare function usePwa(): {
|
|
8
|
+
installPWA: () => Promise<void>;
|
|
9
|
+
isShowInstallPWA: vue.ShallowRef<boolean, boolean>;
|
|
10
|
+
isPWACanBeInstalled: vue.ShallowRef<boolean, boolean>;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { IPromptEvent, usePwa };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { onBeforeUnmount, onMounted, ref, shallowRef } from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/composables/usePwa.ts
|
|
4
|
+
function usePwa() {
|
|
5
|
+
const isShowInstallPWA = shallowRef(false);
|
|
6
|
+
const isPWACanBeInstalled = shallowRef(false);
|
|
7
|
+
const installPWAPrompt = ref();
|
|
8
|
+
async function installPWA() {
|
|
9
|
+
if (installPWAPrompt.value) {
|
|
10
|
+
await installPWAPrompt.value.prompt();
|
|
11
|
+
setTimeout(() => {
|
|
12
|
+
isShowInstallPWA.value = false;
|
|
13
|
+
installPWAPrompt.value = void 0;
|
|
14
|
+
}, 100);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function isInstallPromptEvent(e) {
|
|
18
|
+
return !!e && "prompt" in e;
|
|
19
|
+
}
|
|
20
|
+
function installHandler(event) {
|
|
21
|
+
if (isInstallPromptEvent(event)) {
|
|
22
|
+
isPWACanBeInstalled.value = true;
|
|
23
|
+
isShowInstallPWA.value = true;
|
|
24
|
+
installPWAPrompt.value = event;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
onMounted(() => {
|
|
28
|
+
globalThis.addEventListener("beforeinstallprompt", installHandler);
|
|
29
|
+
});
|
|
30
|
+
onBeforeUnmount(() => {
|
|
31
|
+
globalThis.removeEventListener("beforeinstallprompt", installHandler);
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
installPWA,
|
|
35
|
+
isShowInstallPWA,
|
|
36
|
+
isPWACanBeInstalled
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
//#endregion
|
|
41
|
+
export { usePwa };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { computed } from "vue";
|
|
2
|
+
import { useRoute } from "vue-router";
|
|
3
|
+
|
|
4
|
+
//#region src/composables/useRouteId.ts
|
|
5
|
+
function useRouteId(title, isQuery) {
|
|
6
|
+
const route = useRoute();
|
|
7
|
+
return { id: computed(() => {
|
|
8
|
+
return (isQuery ? route.query[title]?.toString() : route.params[title]?.toString()) || "";
|
|
9
|
+
}) };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
//#endregion
|
|
13
|
+
export { useRouteId };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as vue from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/composables/useTimer.d.ts
|
|
4
|
+
declare function useTimer(): {
|
|
5
|
+
timer: vue.ComputedRef<string>;
|
|
6
|
+
duration: vue.ComputedRef<number>;
|
|
7
|
+
startTimer: () => void;
|
|
8
|
+
stopTimer: () => void;
|
|
9
|
+
};
|
|
10
|
+
//#endregion
|
|
11
|
+
export { useTimer };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { addZero } from "../helpers/date.js";
|
|
2
|
+
import { computed, shallowRef } from "vue";
|
|
3
|
+
|
|
4
|
+
//#region src/composables/useTimer.ts
|
|
5
|
+
function useTimer() {
|
|
6
|
+
const secondsRaw = shallowRef(0);
|
|
7
|
+
const minutesRaw = shallowRef(0);
|
|
8
|
+
const timer = computed(() => `${addZero(minutesRaw.value)}:${addZero(secondsRaw.value)}`);
|
|
9
|
+
const duration = computed(() => minutesRaw.value * 60 + secondsRaw.value);
|
|
10
|
+
let interval = null;
|
|
11
|
+
function updateTime() {
|
|
12
|
+
secondsRaw.value++;
|
|
13
|
+
if (secondsRaw.value === 60) {
|
|
14
|
+
minutesRaw.value++;
|
|
15
|
+
secondsRaw.value = 0;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function startTimer() {
|
|
19
|
+
if (!interval) interval = setInterval(updateTime, 1e3);
|
|
20
|
+
}
|
|
21
|
+
function stopTimer() {
|
|
22
|
+
if (interval) {
|
|
23
|
+
clearInterval(interval);
|
|
24
|
+
interval = null;
|
|
25
|
+
}
|
|
26
|
+
secondsRaw.value = 0;
|
|
27
|
+
minutesRaw.value = 0;
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
timer,
|
|
31
|
+
duration,
|
|
32
|
+
startTimer,
|
|
33
|
+
stopTimer
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
export { useTimer };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { TLocale } from "../locales/types.js";
|
|
2
|
+
import * as vue from "vue";
|
|
3
|
+
import { Ref } from "vue";
|
|
4
|
+
import * as async_validator0 from "async-validator";
|
|
5
|
+
import { RuleItem } from "async-validator";
|
|
6
|
+
|
|
7
|
+
//#region src/composables/useValidate.d.ts
|
|
8
|
+
declare function useValidate<T>(formData: Ref<T>, rules: Partial<{ [fieldName in keyof T]: (RuleItem | ((locale: TLocale) => RuleItem))[] }>, locale?: TLocale): {
|
|
9
|
+
error: (field: string) => string | undefined;
|
|
10
|
+
errors: vue.ComputedRef<Record<string, async_validator0.ValidateError[]> | undefined>;
|
|
11
|
+
isValid: () => boolean;
|
|
12
|
+
};
|
|
13
|
+
declare function required(locale?: TLocale): RuleItem;
|
|
14
|
+
declare function email(locale?: TLocale): RuleItem;
|
|
15
|
+
declare function letters(locale?: TLocale): RuleItem;
|
|
16
|
+
declare function min(value: number, locale?: TLocale): RuleItem;
|
|
17
|
+
declare function max(value: number, locale?: TLocale): RuleItem;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { email, letters, max, min, required, useValidate };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { MESSAGES } from "../locales/index.js";
|
|
2
|
+
import { computed, shallowRef } from "vue";
|
|
3
|
+
import { useAsyncValidator } from "@vueuse/integrations/useAsyncValidator";
|
|
4
|
+
|
|
5
|
+
//#region src/composables/useValidate.ts
|
|
6
|
+
function useValidate(formData, rules, locale = "ru") {
|
|
7
|
+
const { errorFields, isFinished, pass } = useAsyncValidator(formData, computed(() => {
|
|
8
|
+
return Object.entries(rules).reduce((acc, [key, ruleArray]) => {
|
|
9
|
+
acc[key] = Array.isArray(ruleArray) ? ruleArray.map((rule) => typeof rule === "function" ? rule(locale) : rule) : [];
|
|
10
|
+
return acc;
|
|
11
|
+
}, {});
|
|
12
|
+
}), { validateOption: { suppressWarning: true } });
|
|
13
|
+
const tries = shallowRef(0);
|
|
14
|
+
function isValid() {
|
|
15
|
+
tries.value++;
|
|
16
|
+
return pass.value && isFinished.value;
|
|
17
|
+
}
|
|
18
|
+
const errors = computed(() => tries.value ? errorFields.value : void 0);
|
|
19
|
+
function error(field) {
|
|
20
|
+
return errors.value?.[field]?.[0]?.message;
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
error,
|
|
24
|
+
errors,
|
|
25
|
+
isValid
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function required(locale = "ru") {
|
|
29
|
+
return {
|
|
30
|
+
required: true,
|
|
31
|
+
whitespace: true,
|
|
32
|
+
message: MESSAGES[locale].fieldIsRequired
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function email(locale = "ru") {
|
|
36
|
+
return {
|
|
37
|
+
type: "email",
|
|
38
|
+
message: MESSAGES[locale].enterCorrectEmail
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function letters(locale = "ru") {
|
|
42
|
+
return {
|
|
43
|
+
validator: (_rule, value) => /^[a-zA-Zа-яА-ЯёЁ\s-]+$/.test(value) || value.length === 0,
|
|
44
|
+
type: "string",
|
|
45
|
+
message: MESSAGES[locale].onlyLetters
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function min(value, locale = "ru") {
|
|
49
|
+
return {
|
|
50
|
+
min: value,
|
|
51
|
+
message: `${MESSAGES[locale].minSymbols}: ${value}`
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function max(value, locale = "ru") {
|
|
55
|
+
return {
|
|
56
|
+
max: value,
|
|
57
|
+
message: `${MESSAGES[locale].maxSymbols}: ${value}`
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
//#endregion
|
|
62
|
+
export { email, letters, max, min, required, useValidate };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as axios$1 from "axios";
|
|
2
|
+
|
|
3
|
+
//#region src/helpers/api.d.ts
|
|
4
|
+
declare const api: axios$1.AxiosStatic;
|
|
5
|
+
declare function setBaseURL(url: string): void;
|
|
6
|
+
declare function setAuthHeader(token: string): void;
|
|
7
|
+
declare function deleteAuthHeader(): void;
|
|
8
|
+
declare function handleError(error: unknown): string;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { api, deleteAuthHeader, handleError, setAuthHeader, setBaseURL };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
|
|
3
|
+
//#region src/helpers/api.ts
|
|
4
|
+
const api = axios;
|
|
5
|
+
function setBaseURL(url) {
|
|
6
|
+
api.defaults.baseURL = url;
|
|
7
|
+
}
|
|
8
|
+
function setAuthHeader(token) {
|
|
9
|
+
api.defaults.headers.common["Authorization"] = `Bearer ${token}`;
|
|
10
|
+
}
|
|
11
|
+
function deleteAuthHeader() {
|
|
12
|
+
api.defaults.headers.common["Authorization"] = void 0;
|
|
13
|
+
}
|
|
14
|
+
function handleError(error) {
|
|
15
|
+
return api.isAxiosError(error) ? error.response?.data.message : "Ошибка";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
export { api, deleteAuthHeader, handleError, setAuthHeader, setBaseURL };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { toRaw } from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/helpers/clone.ts
|
|
4
|
+
function deepClone(obj) {
|
|
5
|
+
if (obj === null) return obj;
|
|
6
|
+
if (typeof obj !== "object") return obj;
|
|
7
|
+
if (obj instanceof Date) return new Date(obj);
|
|
8
|
+
if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags);
|
|
9
|
+
if (Array.isArray(obj)) return obj.map((item) => deepClone(item));
|
|
10
|
+
if (obj instanceof Set) {
|
|
11
|
+
const clonedSet = /* @__PURE__ */ new Set();
|
|
12
|
+
obj.forEach((value) => {
|
|
13
|
+
clonedSet.add(deepClone(value));
|
|
14
|
+
});
|
|
15
|
+
return clonedSet;
|
|
16
|
+
}
|
|
17
|
+
if (obj instanceof Map) {
|
|
18
|
+
const clonedMap = /* @__PURE__ */ new Map();
|
|
19
|
+
obj.forEach((value, key) => {
|
|
20
|
+
clonedMap.set(deepClone(key), deepClone(value));
|
|
21
|
+
});
|
|
22
|
+
return clonedMap;
|
|
23
|
+
}
|
|
24
|
+
if (typeof obj === "object") {
|
|
25
|
+
const cloned = {};
|
|
26
|
+
Object.getOwnPropertySymbols(obj).forEach((symbol) => {
|
|
27
|
+
if (Object.getOwnPropertyDescriptor(obj, symbol)?.enumerable) Object.defineProperty(cloned, symbol, {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
configurable: true,
|
|
30
|
+
writable: true,
|
|
31
|
+
value: deepClone(obj[symbol])
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
for (const key in obj) if (Object.hasOwn(obj, key)) cloned[key] = deepClone(obj[key]);
|
|
35
|
+
return cloned;
|
|
36
|
+
}
|
|
37
|
+
return obj;
|
|
38
|
+
}
|
|
39
|
+
function clone(obj) {
|
|
40
|
+
return deepClone(toRaw(obj));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { clone };
|