diff options
Diffstat (limited to 'frontend/src/components/Sidebar.tsx')
| -rw-r--r-- | frontend/src/components/Sidebar.tsx | 234 |
1 files changed, 26 insertions, 208 deletions
diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 2e66865..8bd795b 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -1,116 +1,27 @@ -import { - useState, - type ChangeEvent, - type Dispatch, - type SetStateAction, -} from "react"; -import "../styles/Button.css"; -import "../styles/Sidebar.css"; -import type { ErrorResponse } from "../types/error"; -import type { CreateRobotResponse, Robot } from "../types/robot"; - -type ExpandedRobotsState = Record<number, boolean>; +import { useState, type Dispatch, type SetStateAction } from "react"; +import API_URL from "../config"; +import "../styles/button.css"; +import "../styles/sidebar.css"; +import type { Robot } from "../types/robot"; +import AddRobotForm from "./AddRobotForm"; +import RobotList from "./RobotList"; +import SimulationActions from "./SimulationActions"; type Props = { - activeSimulation: boolean; errorMessage: string; - setErrorMessage: Dispatch<SetStateAction<string>>; - token: string | null; robots: Robot[]; - onStartAllRobots: () => Promise<void>; - onStopAllRobots: () => Promise<void>; + token: string | null; + setErrorMessage: Dispatch<SetStateAction<string>>; }; -const API_URL = import.meta.env.VITE_API_URL; - -function Sidebar({ - activeSimulation, - errorMessage, - setErrorMessage, - token, - robots, - onStartAllRobots, - onStopAllRobots, -}: Props) { - const [expandedRobots, setExpandedRobots] = useState<ExpandedRobotsState>( - {} - ); +function Sidebar({ errorMessage, robots, token, setErrorMessage }: Props) { const [isAddingRobot, setIsAddingRobot] = useState(false); - const [newRobotName, setNewRobotName] = useState(""); - const [isSubmitting, setIsSubmitting] = useState(false); - - function toggleRobotHistory(robotId: number) { - setExpandedRobots((prev) => ({ - ...prev, - [robotId]: !prev[robotId], - })); - } function handleAddClick() { setIsAddingRobot(true); - setNewRobotName(""); setErrorMessage(""); } - function handleCancel() { - setIsAddingRobot(false); - setNewRobotName(""); - setErrorMessage(""); - } - - async function handleSubmit() { - if (!newRobotName.trim()) { - setErrorMessage("Please enter a name for the robot."); - return; - } - - setIsSubmitting(true); - setErrorMessage(""); - - try { - const response = await fetch(`${API_URL}/robots`, { - method: "POST", - headers: { - Authorization: `Bearer ${token}`, - "Content-Type": "application/json", - }, - body: JSON.stringify({ name: newRobotName.trim() }), - }); - - if (!response.ok) { - const errorData: ErrorResponse = await response.json(); - throw new Error( - errorData.message || - `Error creating the new robot: ${response.status}` - ); - } - - const data: CreateRobotResponse = await response.json(); - console.log("Robot created successfully: ", data); - - // Reset form and close input field - setNewRobotName(""); - setIsAddingRobot(false); - } catch (error) { - console.error("Error creating the new robot:", error); - - if (error instanceof Error) { - setErrorMessage(error.message); - } else { - setErrorMessage("Error creating the new robot."); - } - } finally { - setIsSubmitting(false); - } - } - - function handleInputChange(event: ChangeEvent<HTMLInputElement>) { - setNewRobotName(event.target.value); - if (errorMessage) { - setErrorMessage(""); - } - } - return ( <div className="sidebar"> <div className="sidebar-robots-header"> @@ -120,124 +31,31 @@ function Sidebar({ onClick={handleAddClick} disabled={isAddingRobot} > - + Neu + + Add </button> </div> - {isAddingRobot && ( - <div className="add-robot-form"> - <input - type="text" - placeholder="Robot name..." - value={newRobotName} - onChange={handleInputChange} - disabled={isSubmitting} - autoFocus - /> - <div className="add-robot-actions"> - <button - className="btn btn-start" - onClick={handleSubmit} - disabled={isSubmitting} - > - {isSubmitting ? "Creating..." : "Create"} - </button> - <button - className="btn btn-stop" - onClick={handleCancel} - disabled={isSubmitting} - > - Cancel - </button> - </div> - </div> + {isAddingRobot && ( + <AddRobotForm + apiUrl={API_URL} + errorMessage={errorMessage} + token={token} + setErrorMessage={setErrorMessage} + setIsAddingRobot={setIsAddingRobot} + /> )} {errorMessage && ( <div className="error-message">{errorMessage}</div> )} - <div className="simulation-actions"> - <button - className="btn btn-start" - onClick={onStartAllRobots} - disabled={activeSimulation} - > - Start simulation - </button> - - <button - className="btn btn-stop" - onClick={onStopAllRobots} - disabled={!activeSimulation} - > - Stop simulation - </button> - </div> - - <ul className="sidebar-robot-list"> - {robots.map((robot) => { - const isExpanded = expandedRobots[robot.id]; - - return ( - <li key={robot.id}> - <p className="robot-name">{robot.name}</p> - - <p> - Status:{" "} - <span - className={`robot-status-${robot.status}`} - > - {robot.status} - </span> - </p> - - <p className="robot-coordinates-label">Position:</p> - <ul className="robot-coordinates"> - <li>Lat: {robot.lat}</li> - <li>Lon: {robot.lon}</li> - </ul> - - <button - className="btn btn-robot-history-toggle" - onClick={() => toggleRobotHistory(robot.id)} - aria-expanded={isExpanded} - > - Position history - <span - className={`arrow ${ - isExpanded ? "open" : "" - }`} - > - ▾ - </span> - </button> + <SimulationActions + apiUrl={API_URL} + token={token} + setErrorMessage={setErrorMessage} + /> - <div - className={`robot-history ${ - isExpanded ? "expanded" : "" - }`} - > - <ul> - {robot.robot_positions?.length ? ( - robot.robot_positions.map( - (pos, index) => ( - <li key={index}> - {`Lat: ${pos.lat}, Lon: ${pos.lon}`} - </li> - ) - ) - ) : ( - <li className="robot-history-empty"> - No previous positions. - </li> - )} - </ul> - </div> - </li> - ); - })} - </ul> + <RobotList robots={robots} /> </div> ); } |
