feat: add AutoRefresh component for automatic data refreshing on pages
Build Images and Deploy / Update-PROD-Stack (push) Failing after 33s
Build Images and Deploy / Update-PROD-Stack (push) Failing after 33s
This commit is contained in:
@@ -6,6 +6,7 @@ import { formatCurrency, formatPnl, pnlColor } from '@/lib/utils'
|
||||
import { formatDistanceToNow } from 'date-fns'
|
||||
import Link from 'next/link'
|
||||
import { Building2, TrendingUp, TrendingDown } from 'lucide-react'
|
||||
import { AutoRefresh } from '@/components/AutoRefresh'
|
||||
import { calcFundNav } from '@/lib/pricing'
|
||||
import InvestPanel from './InvestPanel'
|
||||
import { PriceChart } from '@/components/PriceChart'
|
||||
@@ -88,6 +89,7 @@ export default async function FundPage({ params }: { params: { slug: string } })
|
||||
|
||||
return (
|
||||
<div className="max-w-4xl mx-auto space-y-8">
|
||||
<AutoRefresh intervalMs={30_000} />
|
||||
{/* Header */}
|
||||
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
|
||||
<div>
|
||||
|
||||
@@ -9,6 +9,7 @@ import { ResearchPanel } from './ResearchPanel'
|
||||
import { Hash, Clock, Link as LinkIcon, AlertTriangle } from 'lucide-react'
|
||||
import { formatDistanceToNow } from 'date-fns'
|
||||
import Link from 'next/link'
|
||||
import { AutoRefresh } from '@/components/AutoRefresh'
|
||||
|
||||
const ZOMBIE_ZERO_COUNT = parseInt(process.env.ZOMBIE_ZERO_COUNT ?? '1000', 10)
|
||||
const PRICE_UPDATE_INTERVAL_MINUTES = parseInt(process.env.PRICE_UPDATE_INTERVAL_MINUTES ?? '60', 10)
|
||||
@@ -126,7 +127,8 @@ export default async function HashtagPage({ params, searchParams }: Props) {
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
{/* Header */}
|
||||
<AutoRefresh intervalMs={30_000} />
|
||||
{/* Header */}}
|
||||
<div className="flex flex-col sm:flex-row sm:items-end justify-between gap-4">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold">#{hashtag.displayTag}</h1>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { formatCurrency } from '@/lib/utils'
|
||||
import { calcFundNav } from '@/lib/pricing'
|
||||
import Link from 'next/link'
|
||||
import { Trophy, TrendingUp, TrendingDown, Building2, Users } from 'lucide-react'
|
||||
import { AutoRefresh } from '@/components/AutoRefresh'
|
||||
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
@@ -119,6 +120,7 @@ export default async function LeaderboardPage({
|
||||
|
||||
return (
|
||||
<div className="max-w-3xl mx-auto space-y-6">
|
||||
<AutoRefresh intervalMs={30_000} />
|
||||
<div className="flex items-center gap-3">
|
||||
<Trophy className="h-7 w-7 text-amber-400" />
|
||||
<div>
|
||||
|
||||
+2
-1
@@ -6,6 +6,7 @@ import { TrendingUp, Users, Hash, AlertTriangle } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { formatPnl, pnlColor } from '@/lib/utils'
|
||||
import { formatDistanceToNow } from 'date-fns'
|
||||
import { AutoRefresh } from '@/components/AutoRefresh'
|
||||
|
||||
const ZOMBIE_ZERO_COUNT = parseInt(process.env.ZOMBIE_ZERO_COUNT ?? '1000', 10)
|
||||
const PRICE_UPDATE_INTERVAL_MINUTES = parseInt(process.env.PRICE_UPDATE_INTERVAL_MINUTES ?? '60', 10)
|
||||
@@ -93,7 +94,7 @@ export default async function HomePage() {
|
||||
|
||||
return (
|
||||
<div className="space-y-10">
|
||||
{/* Hero */}
|
||||
<AutoRefresh intervalMs={30_000} />}
|
||||
<div className="text-center py-8">
|
||||
<h1 className="text-4xl font-bold tracking-tight mb-3">
|
||||
The{' '}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { redirect } from 'next/navigation'
|
||||
import { formatCurrency, formatNumber, formatPnl, pnlColor } from '@/lib/utils'
|
||||
import Link from 'next/link'
|
||||
import { Coins, ChevronUp, ChevronDown, ChevronsUpDown } from 'lucide-react'
|
||||
import { AutoRefresh } from '@/components/AutoRefresh'
|
||||
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
@@ -130,6 +131,7 @@ export default async function PositionsPage({
|
||||
|
||||
return (
|
||||
<div className="max-w-4xl mx-auto space-y-6">
|
||||
<AutoRefresh intervalMs={30_000} />
|
||||
<div className="flex items-center gap-3">
|
||||
<Coins className="h-6 w-6 text-indigo-400" />
|
||||
<h1 className="text-2xl font-bold">Open Positions</h1>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { prisma } from '@/lib/prisma'
|
||||
import { formatCurrency, pnlColor } from '@/lib/utils'
|
||||
import Link from 'next/link'
|
||||
import { ArrowUp, ArrowDown, ArrowUpDown, BarChart2, Building2 } from 'lucide-react'
|
||||
import { AutoRefresh } from '@/components/AutoRefresh'
|
||||
import { formatDistanceToNow } from 'date-fns'
|
||||
import { calcFundNav } from '@/lib/pricing'
|
||||
|
||||
@@ -197,7 +198,8 @@ export default async function StocksPage({ searchParams }: PageProps) {
|
||||
|
||||
return (
|
||||
<div className="max-w-5xl mx-auto space-y-6">
|
||||
{/* Header */}
|
||||
<AutoRefresh intervalMs={30_000} />
|
||||
{/* Header */}}
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<BarChart2 className="h-6 w-6 text-indigo-400" />
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
'use client'
|
||||
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
/**
|
||||
* Silently refreshes all server-component data on the current page by calling
|
||||
* router.refresh() on an interval and whenever the tab regains focus.
|
||||
*
|
||||
* Drop this anywhere inside a server-component page — it renders nothing.
|
||||
*/
|
||||
export function AutoRefresh({ intervalMs = 30_000 }: { intervalMs?: number }) {
|
||||
const router = useRouter()
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(() => router.refresh(), intervalMs)
|
||||
|
||||
const onFocus = () => router.refresh()
|
||||
document.addEventListener('visibilitychange', onFocus)
|
||||
|
||||
return () => {
|
||||
clearInterval(id)
|
||||
document.removeEventListener('visibilitychange', onFocus)
|
||||
}
|
||||
}, [router, intervalMs])
|
||||
|
||||
return null
|
||||
}
|
||||
Reference in New Issue
Block a user