36 lines
1.4 KiB
TypeScript
36 lines
1.4 KiB
TypeScript
'use client'
|
|
|
|
import { useEffect, useState } from 'react'
|
|
|
|
export function RealtimeClock() {
|
|
const [date, setDate] = useState<Date | null>(null) // Start null to avoid hydration mismatch
|
|
|
|
useEffect(() => {
|
|
setDate(new Date()) // Set initial date on client
|
|
const timer = setInterval(() => {
|
|
setDate(new Date())
|
|
}, 1000)
|
|
return () => clearInterval(timer)
|
|
}, [])
|
|
|
|
if (!date) {
|
|
// Render a placeholder or nothing during SSR/initial mount to prevent flicker
|
|
return (
|
|
<div className="text-right">
|
|
<div className="text-3xl font-bold opacity-0">00:00:00 <span className="text-sm font-normal text-gray-500">WIB</span></div>
|
|
<div className="text-xs text-gray-400 font-bold tracking-widest opacity-0">LOADING...</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const formattedTime = date.toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit', second: '2-digit' }).replace(/\./g, ':')
|
|
const formattedDate = date.toLocaleDateString('id-ID', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' }).toUpperCase()
|
|
|
|
return (
|
|
<div className="text-right">
|
|
<div className="text-3xl font-bold">{formattedTime} <span className="text-sm font-normal text-gray-500">WIB</span></div>
|
|
<div className="text-xs text-gray-400 font-bold tracking-widest">{formattedDate}</div>
|
|
</div>
|
|
)
|
|
}
|