Skip to content

Instantly share code, notes, and snippets.

@matheusTA
Last active March 10, 2024 21:41
Show Gist options
  • Save matheusTA/e076492765aa78040b4973088a96eb39 to your computer and use it in GitHub Desktop.
Save matheusTA/e076492765aa78040b4973088a96eb39 to your computer and use it in GitHub Desktop.
useCountdown, it`s a hook to block buttons from being clicked for a certain period of time
import { addMilliseconds, differenceInMilliseconds } from 'date-fns'
import { useEffect, useState } from 'react'
interface RetryItem {
id: string
dateToEnable: Date
}
interface UseCountdownProps {
storageKey: string
timer?: number
}
const TIMER_DEFAULT = 1000 * 60 * 10 // 10 minute
export function useCountdown({
storageKey,
timer = TIMER_DEFAULT,
}: UseCountdownProps) {
const [retryItem, setRetryItem] = useState<RetryItem | null>(() => {
const savedItems = localStorage.getItem(storageKey)
if (savedItems) {
return JSON.parse(savedItems) as RetryItem
}
return null
})
function startCountdown(id: string) {
const dateToEnable = addMilliseconds(new Date(), timer)
setRetryItem({ id, dateToEnable })
}
function isDisable(id: string) {
return retryItem?.id === id
}
useEffect(() => {
if (retryItem) {
const currentDate = new Date()
const dateToEnable = new Date(retryItem.dateToEnable)
const difference = differenceInMilliseconds(dateToEnable, currentDate)
if (difference <= 0) {
setRetryItem(null)
}
if (difference > 0) {
setTimeout(() => {
setRetryItem(null)
}, difference)
}
}
}, [retryItem, storageKey])
useEffect(() => {
if (retryItem) {
localStorage.setItem(storageKey, JSON.stringify(retryItem))
} else {
localStorage.removeItem(storageKey)
}
}, [retryItem, storageKey])
return {
startCountdown,
isDisable,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment