feat: replace text loading messages with PageSpinner component
Add a shared PageSpinner (spinning ring + optional label) and use it in all pages that previously showed a plain text loading message: home, stats, player, team, and tournament pages. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+2
-3
@@ -3,6 +3,7 @@ import { useQuery, gql } from '@/lib/graphql/hooks'
|
||||
import Link from 'next/link'
|
||||
import { TeamFlag } from '@/components/team-flag'
|
||||
import { LiveBadge } from '@/components/live-badge'
|
||||
import { PageSpinner } from '@/components/page-spinner'
|
||||
import { MatchCard } from '@/components/match-card'
|
||||
|
||||
const HOME_QUERY = gql`
|
||||
@@ -231,9 +232,7 @@ export function HomeClient() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{loading && !data && (
|
||||
<div className="py-16 text-center text-green-muted text-sm">Loading live World Cup data…</div>
|
||||
)}
|
||||
{loading && !data && <PageSpinner />}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ import { use, useEffect } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { TeamFlag } from '@/components/team-flag'
|
||||
import { MatchCard } from '@/components/match-card'
|
||||
import { PageSpinner } from '@/components/page-spinner'
|
||||
|
||||
const PLAYER_QUERY = gql`
|
||||
query Player($name: String!) {
|
||||
@@ -46,7 +47,7 @@ export function PlayerClient({ params }: { params: Promise<{ name: string }> })
|
||||
`)
|
||||
|
||||
if (loading && !data) {
|
||||
return <div className="max-w-[1200px] mx-auto px-7 py-10 text-green-muted">Loading player…</div>
|
||||
return <PageSpinner />
|
||||
}
|
||||
|
||||
if (!player) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { useQuery, gql } from '@/lib/graphql/hooks'
|
||||
import Link from 'next/link'
|
||||
import { TeamFlag } from '@/components/team-flag'
|
||||
import { PageSpinner } from '@/components/page-spinner'
|
||||
import {
|
||||
ChartBarIcon, StarIcon, TrophyIcon, ClockIcon, BoltIcon,
|
||||
FireIcon, SparklesIcon, ArrowPathIcon, GlobeEuropeAfricaIcon, TableCellsIcon,
|
||||
@@ -92,9 +93,7 @@ export function StatsClient() {
|
||||
<div className="max-w-[1200px] mx-auto px-7 py-10 pb-16">
|
||||
<h1 className="font-['Bebas_Neue'] text-[52px] tracking-[0.04em] text-green leading-none mb-10">Historical Statistics</h1>
|
||||
|
||||
{loading && !data && (
|
||||
<div className="text-green-muted text-sm py-16 text-center">Loading statistics…</div>
|
||||
)}
|
||||
{loading && !data && <PageSpinner />}
|
||||
|
||||
{/* ── Goals per tournament bar chart ── */}
|
||||
{tournaments.length > 0 && (
|
||||
|
||||
@@ -4,6 +4,7 @@ import { use, useEffect } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { TeamFlag } from '@/components/team-flag'
|
||||
import { TrophyIcon } from '@heroicons/react/24/outline'
|
||||
import { PageSpinner } from '@/components/page-spinner'
|
||||
|
||||
const TEAM_QUERY = gql`
|
||||
query Team($slug: String!) {
|
||||
@@ -76,7 +77,7 @@ export function TeamClient({ params }: { params: Promise<{ slug: string }> }) {
|
||||
const years = Object.keys(matchesByYear).map(Number).sort((a, b) => b - a)
|
||||
|
||||
if (loading && !teamData) {
|
||||
return <div className="max-w-[1200px] mx-auto px-7 py-10 text-green-muted">Loading team…</div>
|
||||
return <PageSpinner />
|
||||
}
|
||||
|
||||
if (!team) {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useQuery, gql } from '@/lib/graphql/hooks'
|
||||
import { use, useEffect } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { TeamFlag } from '@/components/team-flag'
|
||||
import { PageSpinner } from '@/components/page-spinner'
|
||||
import { MatchCard } from '@/components/match-card'
|
||||
import { LiveBadge } from '@/components/live-badge'
|
||||
|
||||
@@ -114,12 +115,7 @@ export function TournamentClient({ params }: { params: Promise<{ year: string }>
|
||||
const maxScorer = Math.max(...(t?.topScorers?.map((s: { goals: number }) => s.goals) ?? [1]), 1)
|
||||
|
||||
if (loading && !data) {
|
||||
return (
|
||||
<div className="max-w-[1200px] mx-auto px-7 py-10">
|
||||
<div className="h-24 w-48 rounded-xl animate-pulse mb-6 bg-card" />
|
||||
<div className="text-green-muted text-sm">Loading {year} World Cup…</div>
|
||||
</div>
|
||||
)
|
||||
return <PageSpinner label={`${year} World Cup`} />
|
||||
}
|
||||
|
||||
if (!t) return <div className="max-w-[1200px] mx-auto px-7 py-10 text-green-muted">Tournament {year} not found.</div>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
export function PageSpinner({ label }: { label?: string }) {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center gap-4 py-24 text-green-muted">
|
||||
<div className="w-8 h-8 rounded-full border-2 border-green/20 border-t-green animate-spin" />
|
||||
{label && <span className="text-sm tracking-wide">{label}</span>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user