From 21508a3514500f8f38ddaa8bef7a9cd420d76628 Mon Sep 17 00:00:00 2001 From: HombreLaser Date: Mon, 22 May 2023 21:18:20 -0600 Subject: Añade carrito MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/clients/actions.ts | 6 +++-- src/clients/loaders.ts | 21 ++++++++++++++++ src/components/navbar.tsx | 26 +++++++++++++++----- src/components/payment_methods_table.tsx | 8 ++++++- src/components/product_cart.tsx | 28 ++++++++++++++++++++++ src/main.tsx | 18 +++++++++++--- src/models/product.ts | 26 ++++++++++++++++++++ src/routes/account/cards/create.tsx | 18 ++++++++++++++ src/routes/account/cart.tsx | 41 ++++++++++++++++++++++++++++++++ 9 files changed, 180 insertions(+), 12 deletions(-) create mode 100644 src/components/product_cart.tsx create mode 100644 src/models/product.ts create mode 100644 src/routes/account/cards/create.tsx create mode 100644 src/routes/account/cart.tsx (limited to 'src') diff --git a/src/clients/actions.ts b/src/clients/actions.ts index acc5ad3..cee9a85 100644 --- a/src/clients/actions.ts +++ b/src/clients/actions.ts @@ -56,13 +56,15 @@ export async function authenticatedEdit({ request }) { } } -export async function createAddress({ request }) { +export async function create({ request }) { clearSessionStorage(); const client = new ApiClient(); + const paths = new URL(request.url).pathname.split('/'); + const request_path = paths.slice(0, paths.length - 1).join('/'); const form_data = await request.formData(); try{ - await client.post('/account/addresses', form_data, client.authorizationHeaders()); + await client.post(request_path, form_data, client.authorizationHeaders()); return redirect("/account"); } catch(error) { diff --git a/src/clients/loaders.ts b/src/clients/loaders.ts index 7e44f16..9f5a131 100644 --- a/src/clients/loaders.ts +++ b/src/clients/loaders.ts @@ -1,5 +1,7 @@ import { redirect } from "react-router-dom"; import { ApiClient } from "./api_client"; +import { Product, mapProduct } from "../models/product"; +import Token from "../lib/token"; export async function loader({ request }) { const client = new ApiClient(); @@ -9,6 +11,25 @@ export async function loader({ request }) { return response; } +export async function cartLoader() { + const data = new Array(); + const token = new Token(); + const client = new ApiClient(); + const request = await client.authenticatedGet("/account/cart"); + + if(request.response) { + token.logout(); + + return redirect("/products") + } + + request.data.data.attributes.products.data.map(response_data => { + data.push(mapProduct(response_data)); + }); + + return data; +} + export async function addressLoader({ params }) { const client = new ApiClient(); const path = `/account/addresses/${params.addressId}`; diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx index d136e31..4078405 100644 --- a/src/components/navbar.tsx +++ b/src/components/navbar.tsx @@ -2,8 +2,26 @@ import { CartFill } from "react-bootstrap-icons"; import "./stylesheets/navbar.css"; import "./stylesheets/shared.css"; import MainPageDropdownMenu from "./main_page_dropdown_menu"; +import Token from "../lib/token"; export default function Navbar() { + const session = new Token(); + let cart; + + if (session.present()) { + cart = ( + + + + + + ); + } + else { + cart = null; + } + return( <>
@@ -33,12 +51,8 @@ export default function Navbar() { { /* Lado derecho */}
- - - - - + + {cart}
diff --git a/src/components/payment_methods_table.tsx b/src/components/payment_methods_table.tsx index e9ac639..03fe473 100644 --- a/src/components/payment_methods_table.tsx +++ b/src/components/payment_methods_table.tsx @@ -7,10 +7,16 @@ export default function PaymentMethodsTable({ payment_methods }) { ); return( -
+

Métodos de pago

+ diff --git a/src/components/product_cart.tsx b/src/components/product_cart.tsx new file mode 100644 index 0000000..86d2615 --- /dev/null +++ b/src/components/product_cart.tsx @@ -0,0 +1,28 @@ +import "./stylesheets/product_listing.css"; + +export default function ProductCart({ product }) { + return ( +
+
+ +
+
+
+ {product.name} +
+
+ + Precio unitario + + {product.unitary_price} +
+
+ + Precio al por mayor + + {product.bulk_price} +
+
+
+ ); +} \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx index 404cc0f..ebe246a 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -5,14 +5,16 @@ import Products from "./routes/products/products"; import Product from "./routes/products/product"; import Companies from "./routes/companies/companies"; import Account from "./routes/account/account"; +import Cart from "./routes/account/cart"; import { EditAccount } from './routes/account/edit'; import { Edit as EditAddress } from "./routes/account/addresses/edit"; -import { createAddress, editAccount, authenticatedEdit } from './clients/actions'; +import { create, editAccount, authenticatedEdit } from './clients/actions'; import Layout from "./components/layout"; -import { accountLoader, loader, productLoader, addressLoader, cardLoader } from "./clients/loaders"; +import { accountLoader, loader, productLoader, addressLoader, cardLoader, cartLoader } from "./clients/loaders"; import './index.css'; import { Create as CreateAddress } from './routes/account/addresses/create'; import { Edit as EditCard } from './routes/account/cards/edit'; +import { Create as CreateCard } from './routes/account/cards/create'; const routes = [ { @@ -50,7 +52,7 @@ const routes = [ { path: "/account/addresses/new", element: , - action: createAddress + action: create }, { path: "/account/cards/:cardId/edit", @@ -58,6 +60,16 @@ const routes = [ loader: cardLoader, action: authenticatedEdit }, + { + path: "/account/cards/new", + element: , + action: create + }, + { + path: "/account/cart", + element: , + loader: cartLoader + }, { path: '/', element: diff --git a/src/models/product.ts b/src/models/product.ts new file mode 100644 index 0000000..b375537 --- /dev/null +++ b/src/models/product.ts @@ -0,0 +1,26 @@ +export interface Product { + id: number; + name: string; + picture: string; + unitary_price: number; + bulk_price: number; + available_quantity: number; + company_name: string; +} + +export function mapProduct(data: any) { + if(!data) + return null; + + const product: Product = { + id: data.id, + name: data.attributes.name, + picture: data.attributes.picture, + unitary_price: data.attributes.unitary_price, + bulk_price: data.attributes.bulk_price, + available_quantity: data.attributes.available_quantity, + company_name: data.attributes.company.name + }; + + return product; +} \ No newline at end of file diff --git a/src/routes/account/cards/create.tsx b/src/routes/account/cards/create.tsx new file mode 100644 index 0000000..9779ef2 --- /dev/null +++ b/src/routes/account/cards/create.tsx @@ -0,0 +1,18 @@ +import { useActionData } from "react-router-dom"; +import CardForm from "../../../components/forms/card_form"; +import MainContentLayout from "../../../components/main_content_layout"; + +export function Create() { + const errors = useActionData(); + + return ( + +
+

+ Nuevo método de pago +

+ +
+
+ ); +} \ No newline at end of file diff --git a/src/routes/account/cart.tsx b/src/routes/account/cart.tsx new file mode 100644 index 0000000..a98cf20 --- /dev/null +++ b/src/routes/account/cart.tsx @@ -0,0 +1,41 @@ +import { useLoaderData } from "react-router-dom"; +import { cartLoader } from "../../clients/loaders"; +import ProductCart from "../../components/product_cart"; +import { Product } from "../../models/product"; +import MainContentLayout from "../../components/main_content_layout"; +import { CartXFill } from "react-bootstrap-icons"; + +export default function Cart() { + let products; + const data = useLoaderData() as Array; + + if(data.length > 0) { + products = data.map(product => +
    +
  • + +
  • +
+ ); + } + else { + products = ( +
+
+ +
+
+ Su carrito está vacío, añada algunos productos para empezar a comprar. +
+
+ ); + } + + return( + <> + + {products} + + + ); +} \ No newline at end of file -- cgit v1.2.3