diff --git a/frontend/src/hooks/api.tsx b/frontend/src/hooks/api.tsx index c322fd64..5b45bf69 100644 --- a/frontend/src/hooks/api.tsx +++ b/frontend/src/hooks/api.tsx @@ -97,6 +97,22 @@ export class api { } } } + public async currentUser(): Promise<string> { + try { + const response = await this.api.get("/robots/user/"); + return response.data; + } catch (error) { + if (axios.isAxiosError(error)) { + console.error("Error fetching current user:", error.response?.data); + throw new Error( + error.response?.data?.detail || "Error fetching current user", + ); + } else { + console.error("Unexpected error:", error); + throw new Error("Unexpected error"); + } + } + } public async addRobot(robot: Robot): Promise<void> { const s = robot.name; try { @@ -113,6 +129,22 @@ export class api { } } } + public async deleteRobot(id: string | undefined): Promise<void> { + const s = id + try { + await this.api.delete(`robots/delete/${id}/`); + } catch (error) { + if (axios.isAxiosError(error)) { + console.error("Error deleting robot:", error.response?.data); + throw new Error( + error.response?.data?.detail || "Error deleting robot " + s, + ); + } else { + console.error("Unexpected error:", error); + throw new Error("Unexpected error"); + } + } + } public async editRobot(robot: Robot): Promise<void> { const s = robot.name; try { diff --git a/frontend/src/pages/EditRobotForm.tsx b/frontend/src/pages/EditRobotForm.tsx index 6e2cf739..cdec5bec 100644 --- a/frontend/src/pages/EditRobotForm.tsx +++ b/frontend/src/pages/EditRobotForm.tsx @@ -57,7 +57,7 @@ const EditRobotForm: React.FC = () => { newImages[index][name as keyof Image] = value; setImages(newImages); }; - + const navigate = useNavigate(); const handleAddImage = () => { setImages([...robot_images, { url: "", caption: "" }]); }; @@ -107,7 +107,8 @@ const EditRobotForm: React.FC = () => { }; try { await auth_api.editRobot(newFormData); - setMessage(`Robot added successfully.`); + setMessage(`Robot edited successfully.`); + navigate(`/robots/your/`); } catch (error) { setMessage("Error adding robot "); } diff --git a/frontend/src/pages/RobotDetails.tsx b/frontend/src/pages/RobotDetails.tsx index 6cfbe7b9..91eceeee 100644 --- a/frontend/src/pages/RobotDetails.tsx +++ b/frontend/src/pages/RobotDetails.tsx @@ -30,6 +30,7 @@ interface ExtendedBom { const RobotDetails = () => { const auth = useAuthentication(); const auth_api = new api(auth.api); + const [userId, setUserId] = useState<string | null>(null); const { id } = useParams(); const [show, setShow] = useState(false); const [ownerEmail, setOwnerEmail] = useState<string | null>(null); @@ -37,10 +38,14 @@ const RobotDetails = () => { const [parts, setParts] = useState<ExtendedBom[]>([]); const [imageIndex, setImageIndex] = useState(0); const [error, setError] = useState<string | null>(null); + const [showDelete, setShowDelete] = useState(false); const handleClose = () => setShow(false); const handleShow = () => setShow(true); + const handleShowDelete = () => setShowDelete(true); + const handleCloseDelete = () => setShowDelete(false); + useEffect(() => { const fetchRobot = async () => { try { @@ -67,6 +72,14 @@ const RobotDetails = () => { fetchRobot(); }, [id]); + useEffect(() => { + const fetchUserId = async () => { + const user_id = await auth_api.currentUser(); + setUserId(user_id); + }; + fetchUserId(); + }, []); + const navigate = useNavigate(); useEffect(() => { @@ -95,7 +108,7 @@ const RobotDetails = () => { <Breadcrumb.Item onClick={() => navigate("/robots/")}> Robots </Breadcrumb.Item> - <Breadcrumb.Item active>{name}</Breadcrumb.Item> + <Breadcrumb.Item active>{name} </Breadcrumb.Item> </Breadcrumb> <Row className="mt-3"> @@ -198,7 +211,6 @@ const RobotDetails = () => { </Col> )} </Row> - <Modal show={show} onHide={handleClose} @@ -209,7 +221,7 @@ const RobotDetails = () => { > <Modal.Header closeButton> <Modal.Title> - {images[imageIndex].caption} ({imageIndex + 1} of {images.length}) + {images[imageIndex].caption} ({imageIndex + 1} of {images.length} {userId}) </Modal.Title> </Modal.Header> <Modal.Body> @@ -242,6 +254,81 @@ const RobotDetails = () => { </ButtonGroup> </Modal.Footer> </Modal> + <> + {robot.owner === (userId) && ( + <> + <Row> + <Col md={3} sm={12}> + <Button + variant="success" + size="lg" + style={{ + backgroundColor: "light-green", + borderColor: "black", + padding: "10px", + width: "100%", + }} + onClick={() => { + navigate(`/edit-robot/${id}/`); + }} + > + Edit Robot + </Button> + </Col> + <Col md={3} sm={12}> + <Button + variant="danger" + size="lg" + style={{ + backgroundColor: "light-green", + borderColor: "black", + padding: "10px", + width: "100%", + }} + onClick={() => { + handleShowDelete(); + }} + > + Delete Robot + </Button> + </Col> + </Row> + <Modal + show={showDelete} + onHide={handleCloseDelete} + fullscreen="md-down" + centered + size="lg" + scrollable + > + <Modal.Header closeButton> + <Modal.Title> + Are you sure you want to delete this robot? :{"("} + </Modal.Title> + </Modal.Header> + <Modal.Footer className = "d-flex justify-content-start"> + <Button + variant="danger" + onClick={async () => { + await auth_api.deleteRobot(id); + navigate(`/robots/`); + }} + > + Delete Robot + </Button> + <Button + variant="outline-secondary" + onClick={() => { + handleCloseDelete(); + }} + > + Cancel + </Button> + </Modal.Footer> + </Modal> + </> + )} + </> </> ); }; diff --git a/frontend/src/pages/RobotForm.tsx b/frontend/src/pages/RobotForm.tsx index 1deaf800..550f2571 100644 --- a/frontend/src/pages/RobotForm.tsx +++ b/frontend/src/pages/RobotForm.tsx @@ -2,6 +2,7 @@ import { api, Bom, Image, Part, Robot } from "hooks/api"; import { useAuthentication } from "hooks/auth"; import React, { ChangeEvent, FormEvent, useEffect, useState } from "react"; import { Button, Col, Form, Row } from "react-bootstrap"; +import { Link, useNavigate, useParams } from "react-router-dom"; const RobotForm: React.FC = () => { const auth = useAuthentication(); @@ -55,7 +56,7 @@ const RobotForm: React.FC = () => { const newBom = robot_bom.filter((_, i) => i !== index); setBom(newBom); }; - + const navigate = useNavigate(); const handleSubmit = async (event: FormEvent<HTMLFormElement>) => { event.preventDefault(); if (robot_images.length === 0) { @@ -73,6 +74,7 @@ const RobotForm: React.FC = () => { try { await auth_api.addRobot(newFormData); setMessage(`Robot added successfully.`); + navigate(`/robots/your/`); } catch (error) { setMessage("Error adding robot "); } diff --git a/store/app/routers/robot.py b/store/app/routers/robot.py index 4982a000..84db110f 100644 --- a/store/app/routers/robot.py +++ b/store/app/routers/robot.py @@ -12,7 +12,6 @@ robots_router = APIRouter() - logger = logging.getLogger(__name__) @@ -41,6 +40,14 @@ async def get_robot(robot_id: str, crud: Annotated[Crud, Depends(Crud.get)]) -> return await crud.get_robot(robot_id) +@robots_router.get("/user/") +async def current_user( + crud: Annotated[Crud, Depends(Crud.get)], data: Annotated[ApiKeyData, Depends(get_api_key)] +) -> str | None: + user_id = await crud.get_user_id_from_api_key(data.api_key) + return str(user_id) + + @robots_router.post("/add/") async def add_robot( robot: Robot, @@ -56,7 +63,7 @@ async def add_robot( return True -@robots_router.delete("/delete/{robot_id}") +@robots_router.delete("/delete/{robot_id}/") async def delete_robot( robot_id: str, data: Annotated[ApiKeyData, Depends(get_api_key)], @@ -66,7 +73,7 @@ async def delete_robot( if robot is None: raise HTTPException(status_code=404, detail="Robot not found") user_id = await crud.get_user_id_from_api_key(data.api_key) - if robot.owner != user_id: + if str(robot.owner) != str(user_id): raise HTTPException(status_code=403, detail="You do not own this robot") await crud.delete_robot(robot_id) return True