criação do website
This commit is contained in:
116
src/pages/LiveGames.tsx
Normal file
116
src/pages/LiveGames.tsx
Normal file
@@ -0,0 +1,116 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { ref, onValue } from 'firebase/database';
|
||||
import { db } from '../lib/firebase';
|
||||
import type { Match } from '../types/database';
|
||||
import { Loader2, Zap, Timer } from 'lucide-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
const LiveGames = () => {
|
||||
const [liveMatches, setLiveMatches] = useState<(Match & { escalao: string, jornadaId: string })[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const jornadasRef = ref(db, 'jornadas');
|
||||
|
||||
const unsubscribe = onValue(jornadasRef, (snapshot) => {
|
||||
const data = snapshot.val();
|
||||
const allLive: (Match & { escalao: string, jornadaId: string })[] = [];
|
||||
|
||||
if (data) {
|
||||
Object.entries(data).forEach(([escalao, jornadas]: [string, any]) => {
|
||||
if (!Array.isArray(jornadas)) return;
|
||||
|
||||
jornadas.forEach((jornadaData, jornadaIdx) => {
|
||||
if (!jornadaData) return;
|
||||
|
||||
Object.entries(jornadaData).forEach(([matchId, match]: [string, any]) => {
|
||||
if (match.isLive) {
|
||||
allLive.push({
|
||||
id: matchId,
|
||||
...match,
|
||||
escalao,
|
||||
jornadaId: jornadaIdx.toString()
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setLiveMatches(allLive);
|
||||
setLoading(false);
|
||||
});
|
||||
|
||||
return () => unsubscribe();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-4xl uppercase flex items-center gap-3">
|
||||
<Zap className="text-brand-primary animate-pulse" size={32} fill="currentColor" />
|
||||
Jogos em Direto
|
||||
</h1>
|
||||
<p className="text-text-secondary mt-1">Jogos a decorrer neste momento.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
<div className="flex flex-col items-center justify-center h-64 text-brand-primary">
|
||||
<Loader2 className="animate-spin mb-4" size={48} />
|
||||
<p className="text-text-secondary font-medium">A procurar jogos em direto...</p>
|
||||
</div>
|
||||
) : liveMatches.length === 0 ? (
|
||||
<div className="p-20 text-center text-text-muted bg-bg-surface rounded-2xl border border-dashed border-border">
|
||||
<div className="w-20 h-20 bg-bg-elevated rounded-full flex items-center justify-center mx-auto mb-6 opacity-20">
|
||||
<Timer size={40} />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-text-primary mb-2">Sem jogos em direto</h3>
|
||||
<p className="max-w-md mx-auto">Não existem jogos marcados como "Em Direto" neste momento. Vai às Jornadas para iniciar um acompanhamento em tempo real.</p>
|
||||
<Link to="/games" className="btn btn-primary mt-8 inline-block">IR PARA JORNADAS</Link>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{liveMatches.map((match) => (
|
||||
<Link
|
||||
key={match.id}
|
||||
to={`/games/live-editor/${match.escalao}/${match.jornadaId}/${match.id}`}
|
||||
className="card group hover:border-brand-primary transition-all overflow-hidden"
|
||||
>
|
||||
<div className="bg-brand-primary/10 p-3 flex justify-between items-center px-6">
|
||||
<span className="text-[10px] font-black uppercase tracking-[0.2em] text-brand-primary">
|
||||
{match.escalao} - Jornada {match.jornadaId}
|
||||
</span>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 bg-brand-primary rounded-full animate-ping"></div>
|
||||
<span className="text-[10px] font-bold text-brand-primary uppercase">Direto</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="p-8 flex items-center justify-between gap-4">
|
||||
<div className="flex-1 flex flex-col items-center gap-3 text-center">
|
||||
<img src={match.home_logo} className="w-12 h-12 object-contain" alt="" />
|
||||
<span className="text-xs font-bold uppercase">{match.home_nome}</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="text-4xl font-display font-black">{match.home_golos}</span>
|
||||
<span className="text-xl text-text-muted">:</span>
|
||||
<span className="text-4xl font-display font-black">{match.away_golos}</span>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 flex flex-col items-center gap-3 text-center">
|
||||
<img src={match.away_logo} className="w-12 h-12 object-contain" alt="" />
|
||||
<span className="text-xs font-bold uppercase">{match.away_nome}</span>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LiveGames;
|
||||
Reference in New Issue
Block a user