@@ -7,6 +7,7 @@ import { FC, useEffect, useState } from 'react'
77import { CryptoBubbles } from './crypto-bubbles'
88import { CryptoDataTable } from './crypto-table/crypto-table'
99import { columns } from './crypto-table/columns'
10+ import { Progress } from '@/components/ui/progress'
1011
1112export type RealtimeCryptoWrapperProps = {
1213 initialCryptos : CryptoData [ ]
@@ -18,9 +19,11 @@ export const RealtimeCryptoWrapper: FC<RealtimeCryptoWrapperProps> = ({
1819 top,
1920} ) => {
2021 const [ cryptos , setCryptos ] = useState < CryptoData [ ] > ( initialCryptos )
22+ const [ lastUpdatedAt , setLastUpdatedAt ] = useState ( Date . now ( ) )
2123
2224 useEffect ( ( ) => {
2325 const interval = setInterval ( async ( ) => {
26+ setLastUpdatedAt ( Date . now ( ) )
2427 getCryptoData ( top ) . then ( setCryptos )
2528 } , REFRESH_INTERVAL )
2629
@@ -29,6 +32,10 @@ export const RealtimeCryptoWrapper: FC<RealtimeCryptoWrapperProps> = ({
2932
3033 return (
3134 < >
35+ < UpdateProgress
36+ lastUpdatedAt = { lastUpdatedAt }
37+ updateInterval = { REFRESH_INTERVAL }
38+ />
3239 < CryptoBubbles
3340 cryptos = { cryptos }
3441 className = "h-[calc(100dvh-56px)] bg-slate-900"
@@ -39,3 +46,26 @@ export const RealtimeCryptoWrapper: FC<RealtimeCryptoWrapperProps> = ({
3946 </ >
4047 )
4148}
49+
50+ const UpdateProgress : FC < { lastUpdatedAt : number ; updateInterval : number } > = ( {
51+ lastUpdatedAt,
52+ updateInterval,
53+ } ) => {
54+ const [ progress , setProgress ] = useState ( 0 )
55+
56+ useEffect ( ( ) => {
57+ const interval = setInterval ( ( ) => {
58+ const elapsed = Date . now ( ) - lastUpdatedAt
59+ setProgress ( ( elapsed / updateInterval ) * 100 )
60+ } , 200 )
61+
62+ return ( ) => clearInterval ( interval )
63+ } , [ lastUpdatedAt , updateInterval ] )
64+
65+ return (
66+ < Progress
67+ value = { progress }
68+ className = "h-1 rounded-none [&>.indicator]:duration-200"
69+ />
70+ )
71+ }
0 commit comments