w-funnel/src/hooks/timer/useTimer.ts
gofnnp 55b81890a3 trial-payment
new pages
2025-10-01 17:33:49 +04:00

72 lines
1.7 KiB
TypeScript

"use client";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { formatSecondsToHHMMSS } from "@/shared/utils/date";
export interface UseTimerOptions {
initialSeconds: number;
persist?: boolean;
storageKey?: string;
}
export function useTimer({
initialSeconds,
persist = false,
storageKey,
}: UseTimerOptions) {
const [seconds, setSeconds] = useState<number>(() => {
if (persist && storageKey) {
const saved = localStorage.getItem(storageKey);
if (saved !== null) {
const parsed = parseInt(saved, 10);
if (!isNaN(parsed)) return parsed;
}
}
return initialSeconds;
});
const intervalRef = useRef<NodeJS.Timeout | null>(null);
useEffect(() => {
if (persist && storageKey) {
localStorage.setItem(storageKey, seconds.toString());
}
}, [seconds, persist, storageKey]);
useEffect(() => {
if (seconds <= 0) return;
intervalRef.current = setInterval(() => {
setSeconds((prev) => {
if (prev <= 1) {
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
return 0;
}
return prev - 1;
});
}, 1000);
return () => {
if (intervalRef.current) clearInterval(intervalRef.current);
};
}, [seconds]);
const reset = useCallback(() => {
setSeconds(initialSeconds);
if (persist && storageKey) {
localStorage.setItem(storageKey, initialSeconds.toString());
}
}, [initialSeconds, persist, storageKey]);
return useMemo(
() => ({
time: formatSecondsToHHMMSS(seconds, { isHours: false }),
seconds,
reset,
isFinished: seconds === 0,
}),
[seconds, reset]
);
}