31 lines
1023 B
TypeScript
31 lines
1023 B
TypeScript
'use client'
|
|
import { useEffect, useRef, useCallback, useState } from 'react'
|
|
import { fetchCountdownSync } from '@/lib/api/listings'
|
|
|
|
export function useCountdown() {
|
|
const offsets = useRef<Record<number, number>>({})
|
|
const syncedAt = useRef<number>(Date.now())
|
|
const [, forceRender] = useState(0)
|
|
|
|
useEffect(() => {
|
|
const sync = async () => {
|
|
try {
|
|
const data = await fetchCountdownSync()
|
|
data.forEach(({ id, time_left_mins }) => { offsets.current[id] = time_left_mins })
|
|
syncedAt.current = Date.now()
|
|
} catch {}
|
|
}
|
|
|
|
sync()
|
|
const syncInterval = setInterval(sync, 60_000)
|
|
const tickInterval = setInterval(() => forceRender((n) => n + 1), 1_000)
|
|
return () => { clearInterval(syncInterval); clearInterval(tickInterval) }
|
|
}, [])
|
|
|
|
return useCallback((id: number): number | null => {
|
|
if (!(id in offsets.current)) return null
|
|
const elapsed = (Date.now() - syncedAt.current) / 60_000
|
|
return Math.max(0, offsets.current[id] - elapsed)
|
|
}, [])
|
|
}
|