// App.tsx
import { useState, useCallback, useRef } from 'react';
import { Zap, Shield, Eye, Star, Brain } from 'lucide-react';
import Header from './components/Header';
import HybridSearch from './components/HybridSearch';
import SearchResults from './components/SearchResults';
import PokemonAnalysis from './components/PokemonAnalysis';
import { useGSAPAnimations } from './hooks/useGSAPAnimations';
import type { PokemonData, RecommendationData } from './types/pokemon';
interface BattleQueryResult {
pokemon: PokemonData[];
recommendations: RecommendationData[];
summary?: string;
intent?: string;
}
const PokeBattleStrategist = () => {
const [selectedPokemon, setSelectedPokemon] = useState<PokemonData | null>(null);
const [battleResults, setBattleResults] = useState<BattleQueryResult | null>(null);
const [activeView, setActiveView] = useState<'search' | 'analysis' | 'team'>('search');
const [isTransitioning, setIsTransitioning] = useState(false);
const searchResultsRef = useRef<HTMLDivElement>(null);
const analysisRef = useRef<HTMLDivElement>(null);
const teamBuilderRef = useRef<HTMLDivElement>(null);
const { animatePokemonSelection } = useGSAPAnimations();
const handleNaturalLanguageResults = useCallback((results: BattleQueryResult) => {
setBattleResults(results);
setSelectedPokemon(null); // Clear previously selected Pokemon on new search
// Start with search results view by default for new searches
if (results.pokemon.length > 0) {
setActiveView('search');
}
}, []);
const handlePokemonSelect = useCallback((pokemon: PokemonData, sourceImageRef?: HTMLImageElement) => {
setIsTransitioning(true);
setSelectedPokemon(pokemon);
// If we have a source image, animate the transition
if (sourceImageRef && analysisRef.current) {
animatePokemonSelection(sourceImageRef, analysisRef.current, {
duration: 0.8,
onComplete: () => {
setActiveView('analysis');
setIsTransitioning(false);
}
});
} else {
// Fallback for when no source image is available
setTimeout(() => {
setActiveView('analysis');
setIsTransitioning(false);
}, 100);
}
}, [animatePokemonSelection]);
const handleViewChange = useCallback((newView: 'search' | 'analysis' | 'team') => {
if (newView === activeView || isTransitioning) return;
setIsTransitioning(true);
// Simple fade transition without complex positioning
setTimeout(() => {
setActiveView(newView);
setIsTransitioning(false);
}, 300);
}, [activeView, isTransitioning]);
return (
<div className="min-h-screen text-white pb-16">
<div className="container mx-auto px-4 py-8">
<Header />
{/* Hybrid Search Interface */}
<HybridSearch
onResultsReceived={handleNaturalLanguageResults}
onPokemonSelect={handlePokemonSelect}
/>
{/* View Tabs */}
{battleResults && (
<div className="flex space-x-4 mb-6 mt-6">
<button
onClick={() => handleViewChange('search')}
disabled={isTransitioning}
className={`px-4 py-2 rounded-lg transition-all transform-gpu will-change-transform ${
activeView === 'search'
? 'bg-purple-600 text-white scale-105'
: 'bg-white/10 hover:bg-white/20 hover:scale-105'
} ${isTransitioning ? 'opacity-50 cursor-not-allowed' : ''}`}
>
Search Results
</button>
<button
onClick={() => handleViewChange('analysis')}
disabled={isTransitioning}
className={`px-4 py-2 rounded-lg transition-all transform-gpu will-change-transform ${
activeView === 'analysis'
? 'bg-purple-600 text-white scale-105'
: 'bg-white/10 hover:bg-white/20 hover:scale-105'
} ${isTransitioning ? 'opacity-50 cursor-not-allowed' : ''}`}
>
Battle Analysis
</button>
<button
onClick={() => handleViewChange('team')}
disabled={isTransitioning}
className={`px-4 py-2 rounded-lg transition-all transform-gpu will-change-transform ${
activeView === 'team'
? 'bg-purple-600 text-white scale-105'
: 'bg-white/10 hover:bg-white/20 hover:scale-105'
} ${isTransitioning ? 'opacity-50 cursor-not-allowed' : ''}`}
>
Team Builder (Coming Soon)
</button>
</div>
)}
{/* Dynamic Content Based on Active View */}
<div className="relative w-full">
{isTransitioning && (
<div className="w-full flex items-center justify-center py-16">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-white"></div>
</div>
)}
{battleResults && activeView === 'search' && !isTransitioning && (
<div ref={searchResultsRef} className="w-full animate-fadeIn mt-8">
<SearchResults
results={battleResults.pokemon}
onPokemonSelect={handlePokemonSelect}
/>
</div>
)}
{battleResults && activeView === 'analysis' && !isTransitioning && (
<div ref={analysisRef} className="w-full animate-fadeIn mt-8">
{selectedPokemon ? (
<PokemonAnalysis pokemon={selectedPokemon} />
) : (
<div className="bg-white/10 backdrop-blur-lg rounded-2xl p-8 border border-white/20">
<h2 className="text-2xl font-bold mb-4">Battle Analysis</h2>
<p className="text-gray-300 mb-4">
To see detailed battle analysis for a specific Pokemon, please select one from the Search Results tab.
</p>
<p className="text-gray-400 text-sm">
For strategic counter recommendations, try queries like "What counters Charizard?" or "Best walls against Dragon types".
</p>
</div>
)}
</div>
)}
{battleResults && activeView === 'team' && !isTransitioning && (
<div ref={teamBuilderRef} className="w-full animate-fadeIn">
<div className="bg-white/10 backdrop-blur-lg rounded-2xl p-8 border border-white/20">
<h2 className="text-3xl font-bold mb-6">Team Builder (Coming Soon)</h2>
<p className="text-gray-300">
AI-powered team composition based on your requirements.
</p>
</div>
</div>
)}
</div>
{/* Feature Showcase */}
<div className="text-center mt-12">
<h2 className="text-3xl font-bold mb-8">Powered by Advanced AI & Algolia MCP</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-6">
<div className="bg-white/5 p-6 rounded-xl">
<Brain className="mx-auto mb-4 text-purple-400" size={48} />
<h3 className="font-bold mb-2">Natural Language AI</h3>
<p className="text-sm text-gray-300">Understands complex battle queries</p>
</div>
<div className="bg-white/5 p-6 rounded-xl">
<Zap className="mx-auto mb-4 text-yellow-400" size={48} />
<h3 className="font-bold mb-2">Multi-Index Search</h3>
<p className="text-sm text-gray-300">Searches Pokemon, moves, abilities simultaneously</p>
</div>
<div className="bg-white/5 p-6 rounded-xl">
<Eye className="mx-auto mb-4 text-blue-400" size={48} />
<h3 className="font-bold mb-2">Competitive Analysis</h3>
<p className="text-sm text-gray-300">Usage stats and tier-based recommendations</p>
</div>
<div className="bg-white/5 p-6 rounded-xl">
<Shield className="mx-auto mb-4 text-green-400" size={48} />
<h3 className="font-bold mb-2">Type Intelligence</h3>
<p className="text-sm text-gray-300">Advanced type effectiveness calculations</p>
</div>
<div className="bg-white/5 p-6 rounded-xl">
<Star className="mx-auto mb-4 text-orange-400" size={48} />
<h3 className="font-bold mb-2">MCP Integration</h3>
<p className="text-sm text-gray-300">Claude Desktop for intelligent responses</p>
</div>
</div>
</div>
</div>
</div>
);
};
export default PokeBattleStrategist;