From 06f09944fc73ea61c40a68bf30ee47dcc51764b5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 17:33:19 +0000 Subject: [PATCH 1/4] Initial plan From f391cc4378724242f2f334269aa2fdd96f80f824 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 17:37:44 +0000 Subject: [PATCH 2/4] Add comprehensive documentation to frontend/src/App.jsx Co-authored-by: ofirncommit <198444229+ofirncommit@users.noreply.github.com> --- frontend/src/App.jsx | 73 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index e48473c..1cbde46 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,11 +1,28 @@ +/** + * @file App.jsx + * @description Main application component for the Superhero Comparison app. + * Provides functionality to view superheroes in a table, select them for comparison, + * and display a detailed comparison of their power statistics. + */ + import React, { useEffect, useState } from 'react'; import './App.css'; +/** + * Main application component that manages superhero data and comparison functionality. + * + * @component + * @returns {JSX.Element} The main application interface with table view or comparison view + */ function App() { + // State for storing all superheroes fetched from the API const [superheroes, setSuperheroes] = useState([]); + // State for tracking which heroes are selected for comparison (max 2) const [selectedHeroes, setSelectedHeroes] = useState([]); + // State for managing which view to display: 'table' for hero list or 'comparison' for head-to-head const [currentView, setCurrentView] = useState('table'); // 'table' or 'comparison' + // Fetch superheroes data from the API when component mounts useEffect(() => { fetch('/api/superheroes') .then((response) => response.json()) @@ -13,41 +30,76 @@ function App() { .catch((error) => console.error('Error fetching superheroes:', error)); }, []); + /** + * Handles the selection and deselection of heroes for comparison. + * Implements a maximum selection of 2 heroes with automatic replacement logic. + * + * @param {Object} hero - The hero object to select or deselect + * @param {number} hero.id - Unique identifier for the hero + * @param {string} hero.name - Name of the hero + */ const handleHeroSelection = (hero) => { setSelectedHeroes(prev => { if (prev.find(h => h.id === hero.id)) { - // Remove if already selected + // Remove hero if already selected (toggle off) return prev.filter(h => h.id !== hero.id); } else if (prev.length < 2) { - // Add if less than 2 selected + // Add hero if less than 2 are currently selected return [...prev, hero]; } else { - // Replace first selection if 2 already selected + // Replace the oldest selection (first in array) when 2 are already selected return [prev[1], hero]; } }); }; + /** + * Checks if a hero is currently selected for comparison. + * + * @param {number} 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. + * Triggered when the user clicks the "Compare Heroes" button. + */ const handleCompare = () => { if (selectedHeroes.length === 2) { setCurrentView('comparison'); } }; + /** + * Returns to the table view and clears the hero selections. + * Triggered when the user clicks the "Back to Heroes Table" button. + */ const handleBackToTable = () => { setCurrentView('table'); setSelectedHeroes([]); }; + /** + * Calculates the winner between two heroes by comparing their power statistics. + * Each stat category (intelligence, strength, speed, etc.) is scored individually, + * and the hero with more winning categories is declared the overall winner. + * + * @param {Object} hero1 - The first hero to compare + * @param {Object} hero2 - The second hero to compare + * @returns {Object} Object containing the winner (or null for tie) and the score string + * @returns {Object|null} result.winner - The winning hero object, or null if tied + * @returns {string} result.score - Score string in format "X-Y" + */ const calculateWinner = (hero1, hero2) => { + // All stat categories used for comparison const stats = ['intelligence', 'strength', 'speed', 'durability', 'power', 'combat']; let hero1Score = 0; let hero2Score = 0; + // Compare each stat category and award points stats.forEach(stat => { if (hero1.powerstats[stat] > hero2.powerstats[stat]) { hero1Score++; @@ -56,6 +108,7 @@ function App() { } }); + // Determine overall winner based on total points won if (hero1Score > hero2Score) { return { winner: hero1, score: `${hero1Score}-${hero2Score}` }; } else if (hero2Score > hero1Score) { @@ -65,11 +118,18 @@ function App() { } }; + /** + * Renders the comparison view showing two heroes side-by-side with their stats + * and determining a winner based on stat comparisons. + * + * @returns {JSX.Element|null} The comparison view JSX or null if not exactly 2 heroes selected + */ const renderComparison = () => { if (selectedHeroes.length !== 2) return null; const [hero1, hero2] = selectedHeroes; const result = calculateWinner(hero1, hero2); + // All stat categories to display in comparison const stats = ['intelligence', 'strength', 'speed', 'durability', 'power', 'combat']; return ( @@ -99,6 +159,7 @@ function App() { {stats.map(stat => { const stat1 = hero1.powerstats[stat]; const stat2 = hero2.powerstats[stat]; + // Determine which hero wins this particular stat, or if it's a tie const winner = stat1 > stat2 ? 'hero1' : stat1 < stat2 ? 'hero2' : 'tie'; return ( @@ -135,6 +196,12 @@ function App() { ); }; + /** + * Renders the main table view displaying all superheroes with selection checkboxes + * and stats. Includes controls for comparing selected heroes. + * + * @returns {JSX.Element} The table view JSX with hero data and selection controls + */ const renderTable = () => (