Auto-refresh jury dashboard every 30s for live round updates
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m40s
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m40s
Add AutoRefresh client component that calls router.refresh() on an interval. Pauses when tab is hidden and refreshes immediately when tab becomes visible again. Jury dashboard now reflects round activations within seconds. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import { Suspense } from 'react'
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { auth } from '@/lib/auth'
|
import { auth } from '@/lib/auth'
|
||||||
import { prisma } from '@/lib/prisma'
|
import { prisma } from '@/lib/prisma'
|
||||||
|
import { AutoRefresh } from '@/components/shared/auto-refresh'
|
||||||
|
|
||||||
export const metadata: Metadata = { title: 'Jury Dashboard' }
|
export const metadata: Metadata = { title: 'Jury Dashboard' }
|
||||||
export const dynamic = 'force-dynamic'
|
export const dynamic = 'force-dynamic'
|
||||||
@@ -744,6 +745,9 @@ export default async function JuryDashboardPage() {
|
|||||||
<Suspense fallback={<DashboardSkeleton />}>
|
<Suspense fallback={<DashboardSkeleton />}>
|
||||||
<JuryDashboardContent />
|
<JuryDashboardContent />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|
||||||
|
{/* Auto-refresh every 30s so voting round changes appear promptly */}
|
||||||
|
<AutoRefresh intervalMs={30_000} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
42
src/components/shared/auto-refresh.tsx
Normal file
42
src/components/shared/auto-refresh.tsx
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
import { useRouter } from 'next/navigation'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invisible client component that periodically calls router.refresh()
|
||||||
|
* to re-fetch server component data without a full page reload.
|
||||||
|
* Pauses when the tab is hidden to avoid unnecessary requests.
|
||||||
|
*/
|
||||||
|
export function AutoRefresh({ intervalMs = 30_000 }: { intervalMs?: number }) {
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let timer: ReturnType<typeof setInterval>
|
||||||
|
|
||||||
|
function start() {
|
||||||
|
timer = setInterval(() => {
|
||||||
|
router.refresh()
|
||||||
|
}, intervalMs)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleVisibility() {
|
||||||
|
clearInterval(timer)
|
||||||
|
if (document.visibilityState === 'visible') {
|
||||||
|
// Refresh immediately when tab becomes visible again
|
||||||
|
router.refresh()
|
||||||
|
start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start()
|
||||||
|
document.addEventListener('visibilitychange', handleVisibility)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearInterval(timer)
|
||||||
|
document.removeEventListener('visibilitychange', handleVisibility)
|
||||||
|
}
|
||||||
|
}, [router, intervalMs])
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user