From e8fa9bd7bba125a339f11876eb5ea99d0cd301b6 Mon Sep 17 00:00:00 2001 From: HombreLaser Date: Thu, 25 May 2023 19:11:31 -0600 Subject: Añade historial de órdenes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/clients/actions.ts | 13 +++++ src/clients/loaders.ts | 40 ++++++++++++--- src/components/forms/login_form.tsx | 3 +- src/components/order_table.tsx | 56 +++++++++++++++++++++ src/components/product_cart.tsx | 2 +- src/components/user_account_dropdown_menu.tsx | 2 +- src/main.tsx | 11 +++- src/models/card.ts | 8 +++ src/models/order.ts | 6 +++ src/routes/account/cart.tsx | 72 +++++++++++++++++++++++---- src/routes/account/orders.tsx | 14 ++++++ 11 files changed, 205 insertions(+), 22 deletions(-) create mode 100644 src/components/order_table.tsx create mode 100644 src/models/card.ts create mode 100644 src/models/order.ts create mode 100644 src/routes/account/orders.tsx diff --git a/src/clients/actions.ts b/src/clients/actions.ts index bd99519..447d054 100644 --- a/src/clients/actions.ts +++ b/src/clients/actions.ts @@ -111,4 +111,17 @@ export async function deleteFromCart({ request }) { } return req.status; +} + +export async function placeOrder({ request }) { + const client = new ApiClient(); + const form = await request.formData(); + + try { + const response = await client.post('/orders', form, client.authorizationHeaders()); + + return redirect('/products'); + } catch(error) { + return redirect('/account/cart') + } } \ No newline at end of file diff --git a/src/clients/loaders.ts b/src/clients/loaders.ts index 9f5a131..a114e8d 100644 --- a/src/clients/loaders.ts +++ b/src/clients/loaders.ts @@ -1,7 +1,9 @@ import { redirect } from "react-router-dom"; import { ApiClient } from "./api_client"; import { Product, mapProduct } from "../models/product"; +import { Card } from "../models/card"; import Token from "../lib/token"; +import Order from "../models/order"; export async function loader({ request }) { const client = new ApiClient(); @@ -12,22 +14,29 @@ export async function loader({ request }) { } export async function cartLoader() { - const data = new Array(); + const product_data = new Array(); + const cards_data = new Array(); const token = new Token(); const client = new ApiClient(); - const request = await client.authenticatedGet("/account/cart"); + const product_request = await client.authenticatedGet("/account/cart"); + const cards_request = await client.authenticatedGet("/account/cards"); - if(request.response) { + if(product_request.response || cards_request.response) { token.logout(); return redirect("/products") } - request.data.data.attributes.products.data.map(response_data => { - data.push(mapProduct(response_data)); + product_request.data.data.attributes.products.data.map(response_data => { + product_data.push(mapProduct(response_data)); }); - return data; + cards_request.data.data.map(data => { + cards_data.push(data.attributes); + }); + + + return [product_data, cards_data]; } export async function addressLoader({ params }) { @@ -71,4 +80,23 @@ export async function productLoader({ params }) { const response = await client.getProduct(params.productId); return [response[0], response[1]]; +} + +export async function ordersLoader() { + const client = new ApiClient(); + const response = await client.authenticatedGet('/orders'); + const orders = new Array + + try { + response.data.data.map(order => { + delete order.attributes.products; + order.attributes['id'] = order.id; + orders.push(order.attributes) + }); + + return orders; + } catch(error) { + + return redirect('/products'); + } } \ No newline at end of file diff --git a/src/components/forms/login_form.tsx b/src/components/forms/login_form.tsx index 44c3da5..b1a2296 100644 --- a/src/components/forms/login_form.tsx +++ b/src/components/forms/login_form.tsx @@ -7,9 +7,8 @@ import "../stylesheets/shared.css" export function LoginForm() { const [error_message, setErrorMessage] = useState(''); - // const [modal, setModal] = useState(new Modal()); - // Error rendering useEffecT + // Error rendering useEffect useEffect(() => { document.getElementById("errorMessage").innerHTML = error_message; }, [error_message]); diff --git a/src/components/order_table.tsx b/src/components/order_table.tsx new file mode 100644 index 0000000..207b3e4 --- /dev/null +++ b/src/components/order_table.tsx @@ -0,0 +1,56 @@ +import Order from "../models/order"; +import "./stylesheets/shared.css"; + +function getRows(orders: Array) { + const rows = orders.map(order => ( + + + {order.id} + + + {order.public_id} + + + {order.created_at.toLocaleString().split('T')[0]} + + + {order.total} + + + )); + + return rows; +} + +export default function OrderTable({ orders }) { + const rows = getRows(orders); + + return( +
+

+ Historial de órdenes +

+ + + + + + + + + + + {rows} + +
+ Número de orden + + Identificador + + Fecha + + Total +
+
+ ); +} \ No newline at end of file diff --git a/src/components/product_cart.tsx b/src/components/product_cart.tsx index 4e78d1a..14710d1 100644 --- a/src/components/product_cart.tsx +++ b/src/components/product_cart.tsx @@ -3,7 +3,7 @@ import "./stylesheets/product_listing.css"; export default function ProductCart({ product }) { return ( -
+
diff --git a/src/components/user_account_dropdown_menu.tsx b/src/components/user_account_dropdown_menu.tsx index b70aa4e..495f3c8 100644 --- a/src/components/user_account_dropdown_menu.tsx +++ b/src/components/user_account_dropdown_menu.tsx @@ -10,7 +10,7 @@ export default function UserAccountDropdownMenu() {
  • - Historial de pedidos + Historial de órdenes
  • diff --git a/src/main.tsx b/src/main.tsx index 147d913..8f9c586 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -6,11 +6,12 @@ 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 Orders from "./routes/account/orders"; import { EditAccount } from './routes/account/edit'; import { Edit as EditAddress } from "./routes/account/addresses/edit"; -import { create, editAccount, authenticatedEdit, addToCart, deleteFromCart } from './clients/actions'; +import { create, editAccount, authenticatedEdit, addToCart, deleteFromCart, placeOrder } from './clients/actions'; import Layout from "./components/layout"; -import { accountLoader, loader, productLoader, addressLoader, cardLoader, cartLoader } from "./clients/loaders"; +import { accountLoader, loader, productLoader, addressLoader, cardLoader, cartLoader, ordersLoader } from "./clients/loaders"; import './index.css'; import { Create as CreateAddress } from './routes/account/addresses/create'; import { Edit as EditCard } from './routes/account/cards/edit'; @@ -72,6 +73,12 @@ const routes = [ loader: cartLoader, action: deleteFromCart }, + { + path: "/account/orders", + element: , + loader: ordersLoader, + action: placeOrder + }, { path: '/', element: diff --git a/src/models/card.ts b/src/models/card.ts new file mode 100644 index 0000000..b143580 --- /dev/null +++ b/src/models/card.ts @@ -0,0 +1,8 @@ +export interface Card { + id: number; + number: number; + expiration_year: string; + expiration_month: number; + expiration_day: number; + security_code: number; +} \ No newline at end of file diff --git a/src/models/order.ts b/src/models/order.ts new file mode 100644 index 0000000..c2a4190 --- /dev/null +++ b/src/models/order.ts @@ -0,0 +1,6 @@ +export default interface Order { + id: number; + created_at: Date; + public_id: string; + total: number; +} \ No newline at end of file diff --git a/src/routes/account/cart.tsx b/src/routes/account/cart.tsx index a98cf20..cc81756 100644 --- a/src/routes/account/cart.tsx +++ b/src/routes/account/cart.tsx @@ -1,25 +1,60 @@ -import { useLoaderData } from "react-router-dom"; -import { cartLoader } from "../../clients/loaders"; +import { Form, useLoaderData } from "react-router-dom"; import ProductCart from "../../components/product_cart"; import { Product } from "../../models/product"; import MainContentLayout from "../../components/main_content_layout"; import { CartXFill } from "react-bootstrap-icons"; +import { Card } from "../../models/card"; +import "../../components/stylesheets/shared.css" -export default function Cart() { - let products; - const data = useLoaderData() as Array; +function getOrderForm(cards: Array) { + if(cards.length > 0) { + const options = cards.map(card => + + ); - if(data.length > 0) { - products = data.map(product => + return( +
    +
    +

    + Completar pago +

    +
    +
    +
    + +
    +
    + +
    +
    +
    + ); + } + else { +
    + + No tiene ningún método de pago configurado. + +
    + } +} + +function getProducts(product_data: Array) { + if(product_data.length > 0) { + return (product_data.map(product =>
    - ); + )); } else { - products = ( + return (
    @@ -30,11 +65,28 @@ export default function Cart() {
    ); } +} + +export default function Cart() { + const product_data = useLoaderData()[0] as Array; + const cards_data = useLoaderData()[1] as Array; + let order_form; + const products = getProducts(product_data); + + if(product_data.length > 0) + order_form = getOrderForm(cards_data); + else + order_form = null; return( <> - {products} +
    +
    + {products} +
    + {order_form} +
    ); diff --git a/src/routes/account/orders.tsx b/src/routes/account/orders.tsx new file mode 100644 index 0000000..1e655d1 --- /dev/null +++ b/src/routes/account/orders.tsx @@ -0,0 +1,14 @@ +import { useLoaderData } from "react-router-dom"; +import MainContentLayout from "../../components/main_content_layout"; +import OrderTable from "../../components/order_table"; + + +export default function Orders() { + const orders = useLoaderData(); + + return( + + + + ); +} \ No newline at end of file -- cgit v1.2.3