From ed39b9f9ab618b5e3ed99054ad9af735230dfa3f Mon Sep 17 00:00:00 2001 From: Viktor Riabkov Date: Fri, 2 Feb 2024 17:38:41 +0200 Subject: [PATCH 1/7] Create useTimer hook --- src/shared/utils/useTimer.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/shared/utils/useTimer.ts diff --git a/src/shared/utils/useTimer.ts b/src/shared/utils/useTimer.ts new file mode 100644 index 000000000..d5a8f9fc8 --- /dev/null +++ b/src/shared/utils/useTimer.ts @@ -0,0 +1,29 @@ +import { useCallback, useRef } from "react" + +type SetTimerProps = { + callback: () => void + delay: number +} + +export const useTimer = () => { + const timerRef = useRef(undefined) + + // this resets the timer if it exists. + const resetTimer = useCallback(() => { + if (timerRef) window.clearTimeout(timerRef.current) + }, [timerRef]) + + const setTimer = useCallback( + (props: SetTimerProps) => { + timerRef.current = window.setTimeout(() => { + // clears any pending timer. + resetTimer() + + props.callback() + }, props.delay) + }, + [resetTimer], + ) + + return { setTimer, resetTimer } +} From b02ef08bbcef95abb150005e33784e8446242dac Mon Sep 17 00:00:00 2001 From: Viktor Riabkov Date: Fri, 2 Feb 2024 17:41:18 +0200 Subject: [PATCH 2/7] Create matchPatchs method --- src/shared/utils/index.ts | 2 ++ src/shared/utils/matchPaths.ts | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/shared/utils/matchPaths.ts diff --git a/src/shared/utils/index.ts b/src/shared/utils/index.ts index 15f5f6968..82d738379 100644 --- a/src/shared/utils/index.ts +++ b/src/shared/utils/index.ts @@ -13,3 +13,5 @@ export * from "./helpers" export * from "./eventEmitter" export * from "./dictionary.map" export * from "./mixpanel" +export * from "./useTimer" +export * from "./matchPaths" diff --git a/src/shared/utils/matchPaths.ts b/src/shared/utils/matchPaths.ts new file mode 100644 index 000000000..ebbede444 --- /dev/null +++ b/src/shared/utils/matchPaths.ts @@ -0,0 +1,22 @@ +import { matchPath } from "react-router-dom" + +type Params = { + end?: boolean + caseSensitive?: boolean +} + +export const matchPaths = ( + patterns: string[], + pathname: string, + params: Params = { end: false, caseSensitive: false }, +) => { + return patterns.map(path => + matchPath( + { + path, + ...params, + }, + pathname, + ), + ) +} From de899c4a2390497e4892ddb24433b9ceac4dd632 Mon Sep 17 00:00:00 2001 From: Viktor Riabkov Date: Fri, 2 Feb 2024 17:43:32 +0200 Subject: [PATCH 3/7] Refactor InactivityTracker component --- .../ProtectedRoute/InactivityTracker.tsx | 35 +++++++------------ 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/src/widgets/ProtectedRoute/InactivityTracker.tsx b/src/widgets/ProtectedRoute/InactivityTracker.tsx index d55aa9fe9..cf5164485 100644 --- a/src/widgets/ProtectedRoute/InactivityTracker.tsx +++ b/src/widgets/ProtectedRoute/InactivityTracker.tsx @@ -1,6 +1,7 @@ -import { PropsWithChildren, useCallback, useEffect, useRef } from "react" +import { PropsWithChildren, useCallback, useEffect } from "react" import { useLogout } from "~/features/Logout" +import { useTimer } from "~/shared/utils" export type InactivityTrackerProps = PropsWithChildren @@ -11,33 +12,23 @@ const ONE_MIN = 60 * ONE_SEC const LOGOUT_TIME_LIMIT = 15 * ONE_MIN // 15 min export const InactivityTracker = ({ children }: InactivityTrackerProps) => { - const timerRef = useRef(undefined) const { logout } = useLogout() + const { resetTimer, setTimer } = useTimer() - // this resets the timer if it exists. - const resetTimer = useCallback(() => { - if (timerRef) window.clearTimeout(timerRef.current) - }, [timerRef]) - - const logoutTimer = useCallback(() => { - timerRef.current = window.setTimeout(() => { - // clears any pending timer. - resetTimer() - - // Listener clean up. Removes the existing event listener from the window - Object.values(events).forEach(item => { - window.removeEventListener(item, resetTimer) - }) + const onLogoutTimerExpire = useCallback(() => { + // Listener clean up. Removes the existing event listener from the window + Object.values(events).forEach(item => { + window.removeEventListener(item, resetTimer) + }) - // logs out user - logout() - }, LOGOUT_TIME_LIMIT) - }, [resetTimer, logout]) + // logs out user + logout() + }, [logout, resetTimer]) const onActivityEventHandler = useCallback(() => { resetTimer() - logoutTimer() - }, [resetTimer, logoutTimer]) + setTimer({ delay: LOGOUT_TIME_LIMIT, callback: onLogoutTimerExpire }) + }, [resetTimer, setTimer, onLogoutTimerExpire]) useEffect(() => { Object.values(events).forEach(item => { From 9fec3a4e8eda5cc4f255ed392461aad657230e2d Mon Sep 17 00:00:00 2001 From: Viktor Riabkov Date: Fri, 2 Feb 2024 17:46:28 +0200 Subject: [PATCH 4/7] Update getUserEvents api server type --- src/shared/api/services/events.service.ts | 9 +++++++-- src/shared/api/types/applet.ts | 5 +++++ src/shared/api/types/events.ts | 3 ++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/shared/api/services/events.service.ts b/src/shared/api/services/events.service.ts index b0ff788df..891f1f256 100644 --- a/src/shared/api/services/events.service.ts +++ b/src/shared/api/services/events.service.ts @@ -1,5 +1,10 @@ import axiosService from "./axios" -import { GetEventsByAppletIdPayload, GetEventsByPublicAppletKey, SuccessEventsByAppletIdResponse } from "../types" +import { + GetEventsByAppletIdPayload, + GetEventsByPublicAppletKey, + SuccessAllUserEventsResponse, + SuccessEventsByAppletIdResponse, +} from "../types" function eventService() { return { @@ -7,7 +12,7 @@ function eventService() { return axiosService.get(`/users/me/events/${payload.appletId}`) }, getUserEvents() { - return axiosService.get("/users/me/events") + return axiosService.get("/users/me/events") }, getEventsByPublicAppletKey(payload: GetEventsByPublicAppletKey) { return axiosService.get(`/public/applets/${payload.publicAppletKey}/events`) diff --git a/src/shared/api/types/applet.ts b/src/shared/api/types/applet.ts index 1f500078c..46b91aab4 100644 --- a/src/shared/api/types/applet.ts +++ b/src/shared/api/types/applet.ts @@ -125,6 +125,11 @@ export type AppletEventsResponse = { events: ScheduleEventDto[] } +export type AllUserEventsDTO = { + appletId: string + events: ScheduleEventDto[] +} + export type AppletEncryptionDTO = { accountId: string base: string // Contains number[] diff --git a/src/shared/api/types/events.ts b/src/shared/api/types/events.ts index a473bb5af..f69f788b8 100644 --- a/src/shared/api/types/events.ts +++ b/src/shared/api/types/events.ts @@ -1,4 +1,4 @@ -import { AppletEventsResponse } from "./applet" +import { AllUserEventsDTO, AppletEventsResponse } from "./applet" import { BaseSuccessResponse } from "./base" import { HourMinute } from "../../utils" @@ -14,6 +14,7 @@ export type GetEventsByPublicAppletKey = { } export type SuccessEventsByAppletIdResponse = BaseSuccessResponse +export type SuccessAllUserEventsResponse = BaseSuccessResponse export type EventsByAppletIdResponseDTO = { appletId: string From 2f15c9b37ecc2b9824d0669cddc703590f178107 Mon Sep 17 00:00:00 2001 From: Viktor Riabkov Date: Fri, 2 Feb 2024 17:48:04 +0200 Subject: [PATCH 5/7] Create method to get data from progressId --- src/abstract/lib/getProgressId.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/abstract/lib/getProgressId.ts b/src/abstract/lib/getProgressId.ts index 4aa85495a..3f97067a5 100644 --- a/src/abstract/lib/getProgressId.ts +++ b/src/abstract/lib/getProgressId.ts @@ -1,3 +1,9 @@ export const getProgressId = (entityId: string, eventId: string): string => { return `${entityId}/${eventId}` } + +export const getDataFromProgressId = (progressId: string): { entityId: string; eventId: string } => { + const [entityId, eventId] = progressId.split("/") + + return { entityId, eventId } +} From 5e5f36ae3d2a3033b80a884b58c9e37ac3255213 Mon Sep 17 00:00:00 2001 From: Viktor Riabkov Date: Fri, 2 Feb 2024 17:50:04 +0200 Subject: [PATCH 6/7] Create useUserEventsMutation --- src/entities/event/api/index.ts | 1 + src/entities/event/api/useUserEventsMutation.ts | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 src/entities/event/api/useUserEventsMutation.ts diff --git a/src/entities/event/api/index.ts b/src/entities/event/api/index.ts index 347cf2b5a..d266e622e 100644 --- a/src/entities/event/api/index.ts +++ b/src/entities/event/api/index.ts @@ -1 +1,2 @@ export * from "./useEventsByAppletIdQuery" +export * from "./useUserEventsMutation" diff --git a/src/entities/event/api/useUserEventsMutation.ts b/src/entities/event/api/useUserEventsMutation.ts new file mode 100644 index 000000000..94fdd9591 --- /dev/null +++ b/src/entities/event/api/useUserEventsMutation.ts @@ -0,0 +1,7 @@ +import { MutationOptions, eventsService, useBaseMutation } from "~/shared/api" + +type Options = MutationOptions + +export const useUserEventsMutation = (options?: Options) => { + return useBaseMutation(["getUserEvents"], eventsService.getUserEvents, { ...options }) +} From 2617d3da0b5d831ff8c5d27873b6a7abd121d8d0 Mon Sep 17 00:00:00 2001 From: Viktor Riabkov Date: Fri, 2 Feb 2024 17:57:21 +0200 Subject: [PATCH 7/7] Added mousemove event to track inactivity --- src/widgets/ProtectedRoute/InactivityTracker.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/ProtectedRoute/InactivityTracker.tsx b/src/widgets/ProtectedRoute/InactivityTracker.tsx index cf5164485..1494249c2 100644 --- a/src/widgets/ProtectedRoute/InactivityTracker.tsx +++ b/src/widgets/ProtectedRoute/InactivityTracker.tsx @@ -5,7 +5,7 @@ import { useTimer } from "~/shared/utils" export type InactivityTrackerProps = PropsWithChildren -const events = ["load", "click", "scroll", "keypress"] +const events = ["load", "click", "scroll", "keypress", "mousemove"] const ONE_SEC = 1000 const ONE_MIN = 60 * ONE_SEC