forked from FlowwStar/FlowStar
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcountdown-timer.tsx
More file actions
42 lines (36 loc) · 1.15 KB
/
Copy pathcountdown-timer.tsx
File metadata and controls
42 lines (36 loc) · 1.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
'use client'
import { useEffect, useState } from 'react'
import { cn } from '@/lib/utils'
import { useNow } from '@/hooks/use-now'
import { formatTimeRemaining } from '@/lib/stream-utils'
interface CountdownTimerProps {
/** Target UNIX timestamp (seconds). */
target: bigint
className?: string
endedLabel?: string
/** Callback when a significant state change occurs (e.g., timer expires). */
onStateChange?: (state: 'expired' | 'active') => void
}
/** Live "2d 4h 13m" countdown to a target timestamp. */
export function CountdownTimer({
target,
className,
endedLabel = 'Ended',
onStateChange,
}: CountdownTimerProps) {
const now = useNow(1000)
const ended = Number(target) <= now
const [lastState, setLastState] = useState<'expired' | 'active'>(ended ? 'expired' : 'active')
useEffect(() => {
const newState = ended ? 'expired' : 'active'
if (newState !== lastState) {
setLastState(newState)
onStateChange?.(newState)
}
}, [ended, lastState, onStateChange])
return (
<span className={cn('font-mono tabular-nums', className)}>
{ended ? endedLabel : formatTimeRemaining(target, now)}
</span>
)
}