From d947e3118a06e768dd508c6e5bca1f29246937cd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 12:20:44 +0000 Subject: [PATCH 1/6] Initial plan From 0637f80b0c89db3a917451ffea708a369af2857f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 12:24:58 +0000 Subject: [PATCH 2/6] Add comprehensive documentation to frontend/src/App.jsx Co-authored-by: ofirncommit <198444229+ofirncommit@users.noreply.github.com> --- frontend/src/App.jsx | 113 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 4 deletions(-) diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index e48473c..aa39447 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,11 +1,39 @@ +/** + * Superhero Comparison Application + * + * This application allows users to view a list of superheroes, select two heroes, + * and compare their stats (intelligence, strength, speed, durability, power, combat) + * to determine a winner. The app provides two main views: + * - Table view: Displays all superheroes with their stats and allows selection + * - Comparison view: Shows a head-to-head comparison of two selected heroes + * + * @module App + */ + import React, { useEffect, useState } from 'react'; import './App.css'; +/** + * Main App component that manages the superhero comparison application. + * + * This component handles: + * - Fetching superhero data from the API + * - Managing hero selection (up to 2 heroes) + * - Switching between table and comparison views + * - Calculating and displaying comparison results + * + * @component + * @returns {JSX.Element} The rendered application + */ function App() { + // State for storing the list of all superheroes fetched from API const [superheroes, setSuperheroes] = useState([]); + // State for tracking up to 2 selected heroes for comparison const [selectedHeroes, setSelectedHeroes] = useState([]); - const [currentView, setCurrentView] = useState('table'); // 'table' or 'comparison' + // State for managing current view: 'table' for hero list, 'comparison' for hero comparison + const [currentView, setCurrentView] = useState('table'); + // Fetch superhero data from the API when component mounts useEffect(() => { fetch('/api/superheroes') .then((response) => response.json()) @@ -13,58 +41,119 @@ function App() { .catch((error) => console.error('Error fetching superheroes:', error)); }, []); + /** + * Handles hero selection/deselection with a maximum of 2 heroes. + * + * Behavior: + * - If hero is already selected, it will be removed from selection + * - If less than 2 heroes are selected, the new hero will be added + * - If 2 heroes are already selected, the first hero will be replaced with the new one + * + * @param {Object} hero - The superhero object to select/deselect + * @param {number} hero.id - The unique identifier 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 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 selected return [...prev, hero]; } else { - // Replace first selection if 2 already selected + // Replace the first hero if 2 are already selected (FIFO behavior) return [prev[1], hero]; } }); }; + /** + * Checks if a hero is currently selected. + * + * @param {number} heroId - The unique identifier 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. + * This function is called when the user clicks the "Compare Heroes" button. + */ const handleCompare = () => { if (selectedHeroes.length === 2) { setCurrentView('comparison'); } }; + /** + * Returns to the table view and clears the selected heroes. + * This function is called when the user clicks the "Back to Heroes Table" button. + */ const handleBackToTable = () => { setCurrentView('table'); setSelectedHeroes([]); }; + /** + * Calculates the winner between two heroes based on their power stats. + * + * Compares six stats (intelligence, strength, speed, durability, power, combat) and + * awards a point to the hero with the higher value in each category. The hero with + * more points wins. + * + * @param {Object} hero1 - The first hero to compare + * @param {Object} hero1.powerstats - The power statistics object + * @param {number} hero1.powerstats.intelligence - Intelligence stat + * @param {number} hero1.powerstats.strength - Strength stat + * @param {number} hero1.powerstats.speed - Speed stat + * @param {number} hero1.powerstats.durability - Durability stat + * @param {number} hero1.powerstats.power - Power stat + * @param {number} hero1.powerstats.combat - Combat stat + * @param {Object} hero2 - The second hero to compare + * @param {Object} hero2.powerstats - The power statistics object (same structure as hero1) + * @returns {Object} The comparison result + * @returns {Object|null} returns.winner - The winning hero object, or null if it's a tie + * @returns {string} returns.score - The final score in format "X-Y" where X is winner's score + */ const calculateWinner = (hero1, hero2) => { const stats = ['intelligence', 'strength', 'speed', 'durability', 'power', 'combat']; let hero1Score = 0; let hero2Score = 0; + // Compare each stat and award points to the hero with higher value stats.forEach(stat => { if (hero1.powerstats[stat] > hero2.powerstats[stat]) { hero1Score++; } else if (hero2.powerstats[stat] > hero1.powerstats[stat]) { hero2Score++; } + // No points awarded if stats are equal }); + // Determine the winner based on total points if (hero1Score > hero2Score) { return { winner: hero1, score: `${hero1Score}-${hero2Score}` }; } else if (hero2Score > hero1Score) { return { winner: hero2, score: `${hero2Score}-${hero1Score}` }; } else { + // It's a tie if scores are equal return { winner: null, score: `${hero1Score}-${hero2Score}` }; } }; + /** + * Renders the comparison view showing two heroes side-by-side with their stats. + * + * Displays: + * - Hero cards with images and names + * - Detailed stat-by-stat comparison + * - Winner announcement or tie message + * - Back button to return to the table view + * + * @returns {JSX.Element|null} The comparison view JSX, or null if not exactly 2 heroes are selected + */ const renderComparison = () => { if (selectedHeroes.length !== 2) return null; @@ -79,6 +168,7 @@ function App() {

Superhero Comparison

+ {/* Hero cards section with images */}
{hero1.name} @@ -95,10 +185,12 @@ function App() {
+ {/* Stat-by-stat comparison table */}
{stats.map(stat => { const stat1 = hero1.powerstats[stat]; const stat2 = hero2.powerstats[stat]; + // Determine which hero wins this stat (or if it's a tie) const winner = stat1 > stat2 ? 'hero1' : stat1 < stat2 ? 'hero2' : 'tie'; return ( @@ -117,6 +209,7 @@ function App() { })}
+ {/* Final result section */}

Final Result

{result.winner ? ( @@ -135,6 +228,18 @@ function App() { ); }; + /** + * Renders the table view showing all superheroes with their stats. + * + * Displays: + * - Selection status and count + * - List of currently selected heroes + * - Compare button (enabled when exactly 2 heroes are selected) + * - Table with all heroes and their stats + * - Checkboxes for hero selection + * + * @returns {JSX.Element} The table view JSX + */ const renderTable = () => (

Superheroes

From d7984dcf8696aaae86d9e3506f80da267389e9bb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 12:25:58 +0000 Subject: [PATCH 3/6] Improve JSDoc documentation for calculateWinner function Co-authored-by: ofirncommit <198444229+ofirncommit@users.noreply.github.com> --- frontend/src/App.jsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index aa39447..80010cd 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -112,7 +112,13 @@ function App() { * @param {number} hero1.powerstats.power - Power stat * @param {number} hero1.powerstats.combat - Combat stat * @param {Object} hero2 - The second hero to compare - * @param {Object} hero2.powerstats - The power statistics object (same structure as hero1) + * @param {Object} hero2.powerstats - The power statistics object + * @param {number} hero2.powerstats.intelligence - Intelligence stat + * @param {number} hero2.powerstats.strength - Strength stat + * @param {number} hero2.powerstats.speed - Speed stat + * @param {number} hero2.powerstats.durability - Durability stat + * @param {number} hero2.powerstats.power - Power stat + * @param {number} hero2.powerstats.combat - Combat stat * @returns {Object} The comparison result * @returns {Object|null} returns.winner - The winning hero object, or null if it's a tie * @returns {string} returns.score - The final score in format "X-Y" where X is winner's score From 96b692d875a5133c53700a1b0cb6090da1943f41 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 12:26:57 +0000 Subject: [PATCH 4/6] Fix return documentation format for calculateWinner Co-authored-by: ofirncommit <198444229+ofirncommit@users.noreply.github.com> --- frontend/src/App.jsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 80010cd..b6024e3 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -119,9 +119,7 @@ function App() { * @param {number} hero2.powerstats.durability - Durability stat * @param {number} hero2.powerstats.power - Power stat * @param {number} hero2.powerstats.combat - Combat stat - * @returns {Object} The comparison result - * @returns {Object|null} returns.winner - The winning hero object, or null if it's a tie - * @returns {string} returns.score - The final score in format "X-Y" where X is winner's score + * @returns {{winner: Object|null, score: string}} The comparison result with winner (the winning hero object, or null if tie) and score (in format "winnerScore-loserScore", or "score1-score2" if tie) */ const calculateWinner = (hero1, hero2) => { const stats = ['intelligence', 'strength', 'speed', 'durability', 'power', 'combat']; From 33e98b1c6b5a59733ae84a9de599596635edfac2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 12:27:48 +0000 Subject: [PATCH 5/6] Clarify score format in calculateWinner documentation Co-authored-by: ofirncommit <198444229+ofirncommit@users.noreply.github.com> --- frontend/src/App.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index b6024e3..db086b1 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -119,7 +119,7 @@ function App() { * @param {number} hero2.powerstats.durability - Durability stat * @param {number} hero2.powerstats.power - Power stat * @param {number} hero2.powerstats.combat - Combat stat - * @returns {{winner: Object|null, score: string}} The comparison result with winner (the winning hero object, or null if tie) and score (in format "winnerScore-loserScore", or "score1-score2" if tie) + * @returns {{winner: Object|null, score: string}} The comparison result with winner (the winning hero object, or null if tie) and score (in format "hero1Score-hero2Score", always showing hero1's score first) */ const calculateWinner = (hero1, hero2) => { const stats = ['intelligence', 'strength', 'speed', 'durability', 'power', 'combat']; From df81df336477f67f598a383ae9f60a26cd5da9ce Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 12:28:48 +0000 Subject: [PATCH 6/6] Correct score format documentation to match implementation Co-authored-by: ofirncommit <198444229+ofirncommit@users.noreply.github.com> --- frontend/src/App.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index db086b1..66e8d2d 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -119,7 +119,7 @@ function App() { * @param {number} hero2.powerstats.durability - Durability stat * @param {number} hero2.powerstats.power - Power stat * @param {number} hero2.powerstats.combat - Combat stat - * @returns {{winner: Object|null, score: string}} The comparison result with winner (the winning hero object, or null if tie) and score (in format "hero1Score-hero2Score", always showing hero1's score first) + * @returns {{winner: Object|null, score: string}} The comparison result with winner (the winning hero object, or null if tie) and score (in format "winnerScore-loserScore" when there's a winner, or "hero1Score-hero2Score" when tied) */ const calculateWinner = (hero1, hero2) => { const stats = ['intelligence', 'strength', 'speed', 'durability', 'power', 'combat'];