diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index e48473c..fa7cf01 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,11 +1,27 @@ +/** + * @file App.jsx + * @description Main application component for the Superhero Comparison App. + * Provides a table view of superheroes with their stats and a comparison view + * to compare two selected superheroes side-by-side with a winner determination. + */ + import React, { useEffect, useState } from 'react'; import './App.css'; +/** + * Main application component that manages superhero data and views. + * Handles fetching superhero data, hero selection, and switching between + * table view and comparison view. + * + * @returns {JSX.Element} The main application UI + */ function App() { - const [superheroes, setSuperheroes] = useState([]); - const [selectedHeroes, setSelectedHeroes] = useState([]); - const [currentView, setCurrentView] = useState('table'); // 'table' or 'comparison' + // State management + const [superheroes, setSuperheroes] = useState([]); // Array of all superhero objects + const [selectedHeroes, setSelectedHeroes] = useState([]); // Array of up to 2 selected heroes for comparison + const [currentView, setCurrentView] = useState('table'); // Current view: 'table' or 'comparison' + // Fetch superhero data from API on component mount useEffect(() => { fetch('/api/superheroes') .then((response) => response.json()) @@ -13,6 +29,13 @@ function App() { .catch((error) => console.error('Error fetching superheroes:', error)); }, []); + /** + * Handles selection/deselection of heroes for comparison. + * Allows up to 2 heroes to be selected. If a third hero is selected, + * it replaces the first selected hero (FIFO behavior). + * + * @param {Object} hero - The superhero object to select or deselect + */ const handleHeroSelection = (hero) => { setSelectedHeroes(prev => { if (prev.find(h => h.id === hero.id)) { @@ -28,34 +51,59 @@ function App() { }); }; + /** + * Checks if a hero is currently selected for comparison. + * + * @param {number|string} heroId - The ID of the hero to check + * @returns {boolean} True if the hero is selected, false otherwise + */ const isHeroSelected = (heroId) => { return selectedHeroes.some(h => h.id === heroId); }; + /** + * Switches to the comparison view if exactly 2 heroes are selected. + * Does nothing if the selection requirement is not met. + */ const handleCompare = () => { if (selectedHeroes.length === 2) { setCurrentView('comparison'); } }; + /** + * Returns to the table view and clears the hero selections. + */ const handleBackToTable = () => { setCurrentView('table'); setSelectedHeroes([]); }; + /** + * Calculates the winner between two heroes by comparing their stats. + * Each stat category (intelligence, strength, speed, durability, power, combat) + * is compared, and the hero with more winning categories wins overall. + * + * @param {Object} hero1 - First superhero object containing name, id, image, and powerstats properties + * @param {Object} hero2 - Second superhero object containing name, id, image, and powerstats properties + * @returns {Object} Object containing winner (hero object or null for tie) and score string + */ const calculateWinner = (hero1, hero2) => { const stats = ['intelligence', 'strength', 'speed', 'durability', 'power', 'combat']; let hero1Score = 0; let hero2Score = 0; + // Compare each stat category and increment the winner's score stats.forEach(stat => { if (hero1.powerstats[stat] > hero2.powerstats[stat]) { hero1Score++; } else if (hero2.powerstats[stat] > hero1.powerstats[stat]) { hero2Score++; } + // Ties in individual stats don't increment either score }); + // Determine overall winner based on category wins if (hero1Score > hero2Score) { return { winner: hero1, score: `${hero1Score}-${hero2Score}` }; } else if (hero2Score > hero1Score) { @@ -65,6 +113,13 @@ function App() { } }; + /** + * Renders the comparison view displaying two heroes side-by-side. + * Shows hero images, stat-by-stat comparison with visual indicators, + * and the final winner determination. + * + * @returns {JSX.Element|null} The comparison view JSX element, or null if exactly 2 heroes are not selected + */ const renderComparison = () => { if (selectedHeroes.length !== 2) return null; @@ -79,6 +134,7 @@ function App() {
Select 2 superheroes to compare ({selectedHeroes.length}/2 selected)
{selectedHeroes.length > 0 && ( @@ -154,6 +220,7 @@ function App() {