diff --git a/frontend/src/api/api.ts b/frontend/src/api/api.ts index c642a4a..1a81e78 100644 --- a/frontend/src/api/api.ts +++ b/frontend/src/api/api.ts @@ -1,32 +1,15 @@ -import axios, { AxiosInstance } from "axios"; - -export interface Part { - description: string; - owner: string; - images: Image[]; - part_id: string; - part_name: string; -} - -export interface Bom { - part_id: string; - quantity: number; -} +import { AxiosInstance } from "axios"; +import { Collection } from "types/model"; export interface Image { filename: string; s3_url: string; } -export interface Robot { - robot_id: string; - name: string; +export interface CollectionCreateFragment { + title: string; description: string; - owner: string; - bom: Bom[]; - images: Image[]; } - export class api { public api: AxiosInstance; @@ -50,131 +33,22 @@ export class api { return { s3_url: "", filename: "" }; } } - public async getUserById(userId: string | undefined): Promise { - const response = await this.api.get(`/users/${userId}`); - return response.data.email; + public async createCollection( + data: CollectionCreateFragment, + ): Promise { + const response = await this.api.post("/create_collection", data); + return response.data; } - public async getRobots(): Promise { - try { - const response = await this.api.get("/robots/"); - return response.data; - } catch (error) { - if (axios.isAxiosError(error)) { - console.error("Error fetching robots:", error.response?.data); - throw new Error( - error.response?.data?.detail || "Error fetching robots", - ); - } else { - console.error("Unexpected error:", error); - throw new Error("Unexpected error"); - } - } + public async getCollection(id: string): Promise { + const response = await this.api.get(`/get_collection?id=${id}`); + return response.data; } - public async getYourRobots(): Promise { - try { - const response = await this.api.get("/robots/your/"); - return response.data; - } catch (error) { - if (axios.isAxiosError(error)) { - console.error("Error fetching robots:", error.response?.data); - throw new Error( - error.response?.data?.detail || "Error fetching robots", - ); - } else { - console.error("Unexpected error:", error); - throw new Error("Unexpected error"); - } - } - } - public async getRobotById(robotId: string | undefined): Promise { - try { - const response = await this.api.get(`/robots/${robotId}`); - return response.data; - } catch (error) { - if (axios.isAxiosError(error)) { - console.error("Error fetching robot:", error.response?.data); - throw new Error(error.response?.data?.detail || "Error fetching robot"); - } else { - console.error("Unexpected error:", error); - throw new Error("Unexpected error"); - } - } + public async editCollection(data: Collection): Promise { + await this.api.post(`/edit_collection`, data); + return null; } - public async getPartById(partId: string | undefined): Promise { - try { - const response = await this.api.get(`/parts/${partId}`); - return response.data; - } catch (error) { - if (axios.isAxiosError(error)) { - console.error("Error fetching robot:", error.response?.data); - throw new Error(error.response?.data?.detail || "Error fetching robot"); - } else { - console.error("Unexpected error:", error); - throw new Error("Unexpected error"); - } - } - } - public async addRobot(robot: Robot): Promise { - const s = robot.name; - try { - await this.api.post("/robots/add/", robot); - } catch (error) { - if (axios.isAxiosError(error)) { - console.error("Error adding robot:", error.response?.data); - throw new Error( - error.response?.data?.detail || "Error adding robot " + s, - ); - } else { - console.error("Unexpected error:", error); - throw new Error("Unexpected error"); - } - } - } - public async getParts(): Promise { - try { - const response = await this.api.get("/parts/"); - return response.data; - } catch (error) { - if (axios.isAxiosError(error)) { - console.error("Error fetching parts:", error.response?.data); - throw new Error(error.response?.data?.detail || "Error fetching parts"); - } else { - console.error("Unexpected error:", error); - throw new Error("Unexpected error"); - } - } - } - public async getYourParts(): Promise { - try { - const response = await this.api.get("/parts/your/"); - return response.data; - } catch (error) { - if (axios.isAxiosError(error)) { - console.error("Error fetching parts:", error.response?.data); - throw new Error(error.response?.data?.detail || "Error fetching parts"); - } else { - console.error("Unexpected error:", error); - throw new Error("Unexpected error"); - } - } - } - public async addPart(part: Part): Promise { - const s = part.part_name; - try { - await this.api.post("/parts/add/", part); - } catch (error) { - if (axios.isAxiosError(error)) { - console.error( - "Error adding part:" + part.part_name, - error.response?.data, - ); - throw new Error( - error.response?.data?.detail || "Error adding part " + s, - ); - } else { - console.error("Unexpected error:", error); - throw new Error("Unexpected error"); - } - } + public async getAllCollections(): Promise | null> { + const response = await this.api.get(`/get_collections`); + return response.data; } } diff --git a/frontend/src/components/card.tsx b/frontend/src/components/card.tsx index ebd9781..71116af 100644 --- a/frontend/src/components/card.tsx +++ b/frontend/src/components/card.tsx @@ -14,7 +14,7 @@ const CardItem: React.FC = (collectionProps) => { }; return ( -
+

{title}

diff --git a/frontend/src/pages/Collection.tsx b/frontend/src/pages/Collection.tsx index cb36780..f859894 100644 --- a/frontend/src/pages/Collection.tsx +++ b/frontend/src/pages/Collection.tsx @@ -1,10 +1,13 @@ +import { api } from "api/api"; +import axios, { AxiosInstance } from "axios"; import ImageComponent from "components/image"; +import { useAuth } from "contexts/AuthContext"; +import { useLoading } from "contexts/LoadingContext"; import React, { useEffect, useState } from "react"; import { Col, Row } from "react-bootstrap"; import { ArrowLeft } from "react-bootstrap-icons"; import { useLocation, useNavigate, useParams } from "react-router-dom"; -import { Image } from "types/model"; - +import { Collection, Image } from "types/model"; // Truncated mock data const images: Array = [ @@ -48,17 +51,34 @@ const CollectionPage: React.FC = () => { const [description, setDescription] = useState(""); const [currentImageIndex, setCurrentImageIndex] = useState(0); const [currentImage, setCurrentImage] = useState(null); + const [collection, setCollection] = useState(null); + const { auth, is_auth } = useAuth(); + const { startLoading, stopLoading } = useLoading(); + const apiClient: AxiosInstance = axios.create({ + baseURL: process.env.REACT_APP_BACKEND_URL, // Base URL for all requests + timeout: 10000, // Request timeout (in milliseconds) + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${auth?.token}`, // Add any default headers you need + }, + }); + const API = new api(apiClient); // Helper to check if it's an edit action const isEditAction = location.search.includes("Action=edit"); // Simulate fetching data for the edit page (mocking API call) useEffect(() => { - if (id && isEditAction) { - setTitle("Sample Collection Title"); - setDescription("Sample collection description"); + if (id && is_auth) { + startLoading(); + const asyncfunction = async () => { + const collection = await API.getCollection(id); + setCollection(collection); + stopLoading(); + }; + asyncfunction(); } - }, [id, isEditAction]); + }, [id, is_auth]); // Get translated images const translatedImages = images.filter((img) => img.is_translated); @@ -69,6 +89,14 @@ const CollectionPage: React.FC = () => { } }, [currentImageIndex, translatedImages]); + const handleCreate = async (e: React.FormEvent) => { + e.preventDefault(); + startLoading(); + const collection = await API.createCollection({ title, description }); + if (collection != null) + navigate(`/collection/${collection.id}?Action=edit`); + stopLoading(); + }; // Navigate between images const handleNext = () => { if (currentImageIndex < translatedImages.length - 1) { @@ -87,6 +115,17 @@ const CollectionPage: React.FC = () => { navigate("/collections"); }; + const handleSave = (e: React.FormEvent) => { + e.preventDefault(); + if (collection) { + const asyncfunction = async () => { + startLoading(); + await API.editCollection(collection); + stopLoading(); + }; + asyncfunction(); + } + }; // Custom Return Button (fixed top-left with border) const ReturnButton = () => (