Loto / src /components /GameViewer.tsx
Raí Santos
oi
4c1e4ec
import React, { useState, useEffect } from 'react';
import { ChevronLeft, ChevronRight, SkipBack, SkipForward, Play, Pause, Info } from 'lucide-react';
import { LotomaniaGame } from '../types';
import LotomaniaGrid from './LotomaniaGrid';
interface GameViewerProps {
games: LotomaniaGame[];
currentGameId: number;
onGameChange: (gameId: number) => void;
}
const GameViewer: React.FC<GameViewerProps> = ({
games,
currentGameId,
onGameChange
}) => {
const [isAutoPlay, setIsAutoPlay] = useState(false);
const [autoPlaySpeed, setAutoPlaySpeed] = useState(1000); // ms
const currentGame = games.find(game => game.id === currentGameId);
const currentIndex = games.findIndex(game => game.id === currentGameId);
// Auto-play functionality
useEffect(() => {
if (!isAutoPlay) return;
const interval = setInterval(() => {
if (currentIndex < games.length - 1) {
onGameChange(games[currentIndex + 1].id);
} else {
setIsAutoPlay(false);
}
}, autoPlaySpeed);
return () => clearInterval(interval);
}, [isAutoPlay, currentIndex, games, onGameChange, autoPlaySpeed]);
const goToFirstGame = () => {
if (games.length > 0) {
onGameChange(games[0].id);
}
};
const goToLastGame = () => {
if (games.length > 0) {
onGameChange(games[games.length - 1].id);
}
};
const goToPreviousGame = () => {
if (currentIndex > 0) {
onGameChange(games[currentIndex - 1].id);
}
};
const goToNextGame = () => {
if (currentIndex < games.length - 1) {
onGameChange(games[currentIndex + 1].id);
}
};
const jumpToGame = (gameId: number) => {
onGameChange(gameId);
};
if (!currentGame) {
return (
<div className="flex items-center justify-center h-64">
<div className="text-center">
<div className="text-gray-500 mb-2">Jogo não encontrado</div>
<button onClick={goToFirstGame} className="btn-primary">
Ir para o primeiro jogo
</button>
</div>
</div>
);
}
return (
<div className="space-y-6">
{/* Header com informações do jogo */}
<div className="bg-gradient-to-r from-blue-600 to-blue-700 p-6 rounded-xl text-white">
<div className="flex items-center justify-between">
<div>
<h2 className="text-2xl font-bold mb-1">
Jogo #{currentGame.id}
</h2>
<p className="text-blue-100">
Fase {currentGame.phase} • Ciclo {currentGame.cycle} •
{currentIndex + 1} de {games.length} jogos
</p>
</div>
<div className="text-right">
<div className="text-3xl font-bold">
{Math.round(((currentIndex + 1) / games.length) * 100)}%
</div>
<div className="text-blue-100 text-sm">Concluído</div>
</div>
</div>
</div>
{/* Controles de Navegação */}
<div className="bg-white p-6 rounded-xl shadow-lg border border-gray-200">
<div className="flex items-center justify-center space-x-4 mb-6">
{/* Controles principais */}
<button
onClick={goToFirstGame}
disabled={currentIndex === 0}
className="p-2 rounded-lg bg-gray-100 text-gray-700 hover:bg-gray-200 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200"
title="Primeiro jogo"
>
<SkipBack className="w-5 h-5" />
</button>
<button
onClick={goToPreviousGame}
disabled={currentIndex === 0}
className="p-2 rounded-lg bg-gray-100 text-gray-700 hover:bg-gray-200 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200"
title="Jogo anterior"
>
<ChevronLeft className="w-5 h-5" />
</button>
<button
onClick={() => setIsAutoPlay(!isAutoPlay)}
className={`p-3 rounded-lg transition-all duration-200 ${
isAutoPlay
? 'bg-red-100 text-red-700 hover:bg-red-200'
: 'bg-green-100 text-green-700 hover:bg-green-200'
}`}
title={isAutoPlay ? 'Pausar reprodução' : 'Reprodução automática'}
>
{isAutoPlay ? <Pause className="w-5 h-5" /> : <Play className="w-5 h-5" />}
</button>
<button
onClick={goToNextGame}
disabled={currentIndex === games.length - 1}
className="p-2 rounded-lg bg-gray-100 text-gray-700 hover:bg-gray-200 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200"
title="Próximo jogo"
>
<ChevronRight className="w-5 h-5" />
</button>
<button
onClick={goToLastGame}
disabled={currentIndex === games.length - 1}
className="p-2 rounded-lg bg-gray-100 text-gray-700 hover:bg-gray-200 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200"
title="Último jogo"
>
<SkipForward className="w-5 h-5" />
</button>
</div>
{/* Barra de progresso */}
<div className="mb-6">
<div className="flex justify-between text-sm text-gray-600 mb-2">
<span>Progresso dos Jogos</span>
<span>{currentIndex + 1} / {games.length}</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-3 cursor-pointer">
<div
className="bg-blue-600 h-3 rounded-full transition-all duration-300"
style={{ width: `${((currentIndex + 1) / games.length) * 100}%` }}
/>
</div>
</div>
{/* Input para saltar para jogo específico */}
<div className="flex items-center space-x-4">
<label className="text-sm font-medium text-gray-700">Ir para o jogo:</label>
<input
type="number"
min="1"
max={games.length}
value={currentGame.id}
onChange={(e) => {
const gameId = parseInt(e.target.value);
if (gameId >= 1 && gameId <= games.length) {
jumpToGame(gameId);
}
}}
className="w-20 px-3 py-1 border border-gray-300 rounded-md text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
{/* Velocidade do auto-play */}
<div className="flex items-center space-x-2 ml-8">
<label className="text-sm font-medium text-gray-700">Velocidade:</label>
<select
value={autoPlaySpeed}
onChange={(e) => setAutoPlaySpeed(parseInt(e.target.value))}
className="px-2 py-1 border border-gray-300 rounded-md text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value={3000}>Lenta (3s)</option>
<option value={1000}>Normal (1s)</option>
<option value={500}>Rápida (0.5s)</option>
<option value={200}>Muito Rápida (0.2s)</option>
</select>
</div>
</div>
</div>
{/* Grid do jogo atual */}
<div className="bg-white rounded-xl shadow-lg border border-gray-200 p-6">
<LotomaniaGrid
markedColumns={currentGame.markedColumns}
showNumbers={false}
size="md"
className="bg-transparent"
/>
</div>
{/* Informações detalhadas do jogo */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<div className="card">
<div className="flex items-center space-x-2 mb-4">
<Info className="w-5 h-5 text-blue-600" />
<h3 className="text-lg font-semibold text-gray-800">Informações do Jogo</h3>
</div>
<div className="space-y-3">
<div className="flex justify-between">
<span className="text-gray-600">ID do Jogo:</span>
<span className="font-semibold">#{currentGame.id}</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600">Fase:</span>
<span className="font-semibold">{currentGame.phase}</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600">Ciclo:</span>
<span className="font-semibold">{currentGame.cycle}</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600">Posição:</span>
<span className="font-semibold">{currentIndex + 1} / {games.length}</span>
</div>
</div>
</div>
<div className="card">
<h3 className="text-lg font-semibold text-gray-800 mb-4">Colunas Marcadas</h3>
<div className="flex flex-wrap gap-2">
{currentGame.markedColumns.map(col => (
<span
key={col}
className="px-3 py-1 bg-blue-600 text-white rounded-full font-medium text-sm"
>
{col}
</span>
))}
</div>
<p className="text-sm text-gray-600 mt-3">
Total: {currentGame.markedColumns.length * 10} números
</p>
</div>
<div className="card">
<h3 className="text-lg font-semibold text-gray-800 mb-4">Estatísticas</h3>
<div className="space-y-3">
<div className="flex justify-between">
<span className="text-gray-600">Números marcados:</span>
<span className="font-semibold">{currentGame.markedColumns.length * 10}</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600">Cobertura:</span>
<span className="font-semibold">{currentGame.markedColumns.length * 10}%</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600">Progresso:</span>
<span className="font-semibold">
{Math.round(((currentIndex + 1) / games.length) * 100)}%
</span>
</div>
</div>
</div>
</div>
{/* Navegação rápida */}
<div className="card">
<h3 className="text-lg font-semibold text-gray-800 mb-4">Navegação Rápida</h3>
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-3">
{[1, 10, 50, 100, 500, 1000].filter(jump => jump <= games.length).map(jump => (
<button
key={jump}
onClick={() => jumpToGame(jump)}
className={`p-3 rounded-lg text-sm font-medium transition-all duration-200 ${
currentGame.id === jump
? 'bg-blue-600 text-white'
: 'bg-gray-100 text-gray-700 hover:bg-gray-200'
}`}
>
Jogo #{jump}
</button>
))}
</div>
</div>
</div>
);
};
export default GameViewer;