import { useState, type Dispatch, type MouseEvent, type SetStateAction, } from "react"; import type { ErrorResponse } from "../types/error"; import type { Robot, SimulationResponse } from "../types/robot"; type ExpandedRobotsState = Record; type Props = { apiUrl: string; robots: Robot[]; token: string | null; setErrorMessage: Dispatch>; }; function RobotList({ apiUrl, robots, token, setErrorMessage }: Props) { const [expandedRobots, setExpandedRobots] = useState( {} ); function toggleRobotHistory(robotId: number) { setExpandedRobots((prev) => ({ ...prev, [robotId]: !prev[robotId], })); } // Move or stop individual robot async function controlSingleRobot( event: MouseEvent, robotId: number, robotStatus: Robot["status"] ) { const isRobotMoving = robotStatus === "moving"; const button = event.currentTarget; button.disabled = true; // prevent spamming try { // Make button clickable again after 1 second setTimeout(() => { button.disabled = false; }, 1000); const response = await fetch( `${apiUrl}/robots/${robotId}/${ isRobotMoving ? "stop" : "move" }`, { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, } ); if (!response.ok) { const errorData: ErrorResponse = await response.json(); throw new Error( errorData.message || `Failed to ${ isRobotMoving ? "stop" : "start" } robot ID ${robotId}.` ); } const data: SimulationResponse = await response.json(); console.log(data.message); } catch (error) { console.error( `Error ${ isRobotMoving ? "stopping" : "starting" } robot ID ${robotId}: `, error ); if (error instanceof Error) { setErrorMessage(error.message); } else { setErrorMessage("An unexpected error occurred."); } } } return (
    {robots?.map((robot) => { const isExpanded = expandedRobots[robot?.id]; return (
  • {robot?.name}

    {/* Move/stop individual robot */} {/* Movement status */}

    Status:{" "} {robot?.status}

    {/* Current position */}

    Position:

    • Lat: {robot?.lat}
    • Lon: {robot?.lon}
    {/* Expand position log */} {/* Position log/history */}
      {robot?.robot_positions?.length ? ( robot?.robot_positions?.map( (pos, index) => (
    • {`Lat: ${pos?.lat}, Lon: ${pos?.lon}`}
    • ) ) ) : (
    • No previous positions.
    • )}
  • ); })}
); } export default RobotList;