From c7e493ce3d2855e61787d86714625bc7fc51f9bd Mon Sep 17 00:00:00 2001 From: HombreLaser Date: Wed, 26 Apr 2023 21:37:38 -0600 Subject: Añade vista de producto individual MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/clients/api_client.ts | 19 ++++++++-- src/clients/loader.ts | 9 ----- src/clients/loaders.ts | 16 +++++++++ src/components/product_listing.tsx | 71 ++++++++++++++++++++------------------ src/components/review.tsx | 30 ++++++++++++++++ src/main.tsx | 12 +++++-- src/routes/products/product.tsx | 37 ++++++++++++++++++++ src/routes/products/products.tsx | 4 +-- 8 files changed, 148 insertions(+), 50 deletions(-) delete mode 100644 src/clients/loader.ts create mode 100644 src/clients/loaders.ts create mode 100644 src/components/review.tsx create mode 100644 src/routes/products/product.tsx diff --git a/src/clients/api_client.ts b/src/clients/api_client.ts index a7b5e0d..0e96c36 100644 --- a/src/clients/api_client.ts +++ b/src/clients/api_client.ts @@ -5,13 +5,28 @@ export class ApiClient { async get(path: string) { const request_url = `${ this.url }${ path }`; + const response = await this.makeRequest(request_url); + return response; + } + + async getProduct(id: string) { + const request_url = `${ this.url }/products/${ id }`; + const [product_response, product_reviews] = await Promise.all([ + this.makeRequest(request_url), + this.makeRequest(`${ request_url }/reviews`) + ]); + + return [product_response, product_reviews]; + } + + private async makeRequest(request_url: string) { try { const response = await axios.get(request_url); - return response; + return response } catch(error) { - return error.response; + return error; } } } \ No newline at end of file diff --git a/src/clients/loader.ts b/src/clients/loader.ts deleted file mode 100644 index c529806..0000000 --- a/src/clients/loader.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ApiClient } from "./api_client"; - -export default async function productLoader({ request }) { - const client = new ApiClient(); - const url = new URL(request.url) - const response = await client.get(url.pathname); - - return response.data; -} \ No newline at end of file diff --git a/src/clients/loaders.ts b/src/clients/loaders.ts new file mode 100644 index 0000000..43c1581 --- /dev/null +++ b/src/clients/loaders.ts @@ -0,0 +1,16 @@ +import { ApiClient } from "./api_client"; + +export async function loader({ request }) { + const client = new ApiClient(); + const url = new URL(request.url) + const response = await client.get(url.pathname); + + return response; +} + +export async function productLoader({ params }) { + const client = new ApiClient(); + const response = await client.getProduct(params.productId); + + return [response[0], response[1]]; +} \ No newline at end of file diff --git a/src/components/product_listing.tsx b/src/components/product_listing.tsx index 497bd19..d9c5488 100644 --- a/src/components/product_listing.tsx +++ b/src/components/product_listing.tsx @@ -1,5 +1,5 @@ import { Collapse, Ripple, initTE} from "tw-elements"; -initTE({Collapse, Ripple}); +import { Link } from "react-router-dom"; import "./stylesheets/shared.css" import "./stylesheets/product_listing.css" @@ -7,60 +7,63 @@ export default function ProductListing({ product }) { const collapseMenu = `collapse${product.id}` const collapseTarget = `#${collapseMenu}` const categories = product.attributes.categories.map(category => -
  • {category}
  • ); return ( -
    +
    - + - - + + - - + + - - + + - - + + +
    {product.attributes.name} + + {product.attributes.name} + +
    Precio al por menor{product.attributes.unitary_price} $Precio al por menor{product.attributes.unitary_price} $
    Precio al por mayor{product.attributes.bulk_price} $Precio al por mayor{product.attributes.bulk_price} $
    Proveedor{product.attributes.company.name}Disponibles{product.attributes.available_quantity}
    -
    - -
    -
    -
      -
    • {categories}
    • -
    -
    -
    -
    -
    Proveedor{product.attributes.company.name}
    +
    + +
    +
    +
      + {categories} +
    +
    +
    +
    ); diff --git a/src/components/review.tsx b/src/components/review.tsx new file mode 100644 index 0000000..e3f34df --- /dev/null +++ b/src/components/review.tsx @@ -0,0 +1,30 @@ +import { PersonCircle, StarFill } from "react-bootstrap-icons"; + +export default function Review({ review }) { + const rating = [...Array(review.attributes.rating)].map((value: undefined, index: number) => + + ); + + return( + <> +
    +
    +
    + {review.attributes.author_name} +
    +
    + +
    +
    + {rating} +
    +
    +
    +
    + {review.attributes.review} +
    +
    +
    + + ); +} \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx index 7d0af9a..45f5fd6 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -2,16 +2,22 @@ import React from 'react' import ReactDOM from 'react-dom/client' import { createBrowserRouter, Navigate, RouterProvider } from 'react-router-dom' import Products from "./routes/products/products"; +import Product from "./routes/products/product"; import Layout from "./components/layout"; -import productLoader from "./clients/loader"; -import './index.css' +import { loader, productLoader } from "./clients/loaders"; +import './index.css'; const routes = [ { path: '/products', - loader: productLoader, + loader: loader, element: }, + { + path: "products/:productId", + loader: productLoader, + element: + }, { path: '/', element: diff --git a/src/routes/products/product.tsx b/src/routes/products/product.tsx new file mode 100644 index 0000000..1eecbcf --- /dev/null +++ b/src/routes/products/product.tsx @@ -0,0 +1,37 @@ +import { useLoaderData } from "react-router-dom"; +import { CartPlusFill } from "react-bootstrap-icons" +import ProductListing from "../../components/product_listing"; +import MainContentLayout from "../../components/main_content_layout"; +import Review from "../../components/review"; +import "../../components/stylesheets/shared.css" + +export default function Product() { + const response = useLoaderData(); + const product = response[0].data; + const reviews = response[1].data.data.map(review => +
  • + +
  • + ); + + return ( + <> + + +
    +
    + +
    +
    +
    +
      + {reviews} +
    +
    +
    + + ); +} \ No newline at end of file diff --git a/src/routes/products/products.tsx b/src/routes/products/products.tsx index c7f3a3a..ea06c15 100644 --- a/src/routes/products/products.tsx +++ b/src/routes/products/products.tsx @@ -1,11 +1,11 @@ -import { useLoaderData } from "react-router-dom"; +import { Link, useLoaderData } from "react-router-dom"; import ProductListing from "../../components/product_listing"; import SearchBar from "../../components/search_bar"; import MainContentLayout from "../../components/main_content_layout"; export default function Products() { const products = useLoaderData().data; - const productList = products.map(product => + const productList = products.data.map(product =>
  • -- cgit v1.2.3