Skip to content

Commit

Permalink
TS Server
Browse files Browse the repository at this point in the history
  • Loading branch information
ChachoPacho committed Oct 15, 2021
1 parent 2380684 commit 813d612
Show file tree
Hide file tree
Showing 28 changed files with 548 additions and 0 deletions.
25 changes: 25 additions & 0 deletions app/server/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const express = require('express');
const ejs = require('ejs');
var morgan = require('morgan');

const ROUTES = require('./routes');
const { PUBLIC_DIR } = require('./config');

const app = express();

// ["Primeros auxilios", "Diabetes", "Óptica", "Pediculosis", "Pédicos", "Suplementos Dietarios", "Suplementos Nutricionales", "Suplementos Deportivos", "Protección y Recuperación", "Fitness"];

// settings
app.set('view engine', 'ejs');
app.listen(4444);

// middlewares
app.use(morgan('dev'));
app.use(express.urlencoded({extended: true}));
app.use(express.json());

// static
app.use(express.static(PUBLIC_DIR));

// routes
app.use(ROUTES);
43 changes: 43 additions & 0 deletions app/server/classes/API.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import Product from "../interfaces/Product";

const fs = require("fs");

const { DATABASE_DIR } = require("../config");

const DATABASE_TABLE_PRODUCT: string = DATABASE_DIR + "/products.json";
const PRODUCTS: Product[] = JSON.parse(
fs.readFileSync(DATABASE_TABLE_PRODUCT, "utf8")
);

export default class API {
public static getProduct(id: number): Product {
return PRODUCTS.find((product: any) => product.id === id);
}

public static getProducts(
search: string = "",
min: number = null,
max: number = null
): Product[] {
const SEARCH_REGEX: RegExp = new RegExp(search);
return PRODUCTS.filter(
(product: Product) =>
SEARCH_REGEX.test(product.title.toLowerCase()) &&
API.inRange(product.price, min, max)
);
}

public static getProductsByIds(IDList: string[] = []): Product[] {
return PRODUCTS.filter((product: Product) =>
IDList.includes(String(product.id))
);
}

private static inRange(
elem: number,
min: number = null,
max: number = null
): boolean {
return (min ? elem >= min : true) && (max ? elem <= max : true);
}
}
38 changes: 38 additions & 0 deletions app/server/classes/ProductsAPI.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Product from "../interfaces/Product";

import API from "./API";

export default class ProductsAPI extends API {
private params: any = {};
private body: any = {};

constructor(req: any) {
super();
this.params = req.params;
this.body = req.body;
}

public getProducts(): {
products: Product[];
maxPage: number;
page: number;
} {
const { page, min, max } = this.params;
const { search } = this.body;
const products: Product[] = API.getProducts(search, min, max);

const maxPage: number = Math.ceil(products.length / 10);
const currentPage: number = +page || 1;
const firstProductIndex: number = (currentPage - 1) * 10;

return {
products: products.slice(firstProductIndex, firstProductIndex + 10),
maxPage,
page: currentPage,
};
}

public getProductsById(): Product[] {
return API.getProductsByIds(this.body.IDList);
}
}
24 changes: 24 additions & 0 deletions app/server/components/FavoritesEntryComponent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Product from "../interfaces/Product";

export default function FavoritesEntryComponent(
{
price,
id,
title,
body
}: Product
): string {
return /* html */ `
<tr>
<td class="conceptTable">
<a class="product-image" href="?htmlFileName=product&id=${id}">
${title}
</a>
</td>
<td class="text-center"></td>
<td class="text-center">${body}</td>
<td class="text-center">$${price}</td>
<td class="text-center">F</td>
</tr>
`;
}
13 changes: 13 additions & 0 deletions app/server/components/FavoritesTableComponent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Product from "../interfaces/Product";

import { htmlString } from "../../client/types/html";

import FavoritesEntryComponent from "./FavoritesEntryComponent";

export default function FavoritesTableComponent(
products: Product[]
): htmlString {
return products
.map((product: Product): string => FavoritesEntryComponent(product))
.join("");
}
55 changes: 55 additions & 0 deletions app/server/components/PaginatorComponent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
export default function PaginatorComponenet(
page: number,
maxPage: number,
): string {
let left = page - 1;
let center = page;
let right = page + 1;

if (page === 1) {
++left;
++center;
++right;
} else if (page === maxPage) {
--left;
--center;
--right;
}

return `
${exteriorPaginator(1, maxPage, "<<", page > 2)}
${midPaginator(left, maxPage, page)}
${midPaginator(center, maxPage, page)}
${midPaginator(right, maxPage, page)}
${exteriorPaginator(maxPage, maxPage, ">>", page < (maxPage - 1))}
`;
}

function midPaginator(
redirectPage: number,
maxPage: number,
currentPage: number
): string {
return redirectPage > 0 && redirectPage <= maxPage
? `
<a class="js-paginator ${redirectPage === currentPage ? "active" : ""}" data-page="${redirectPage}">
${redirectPage}
</a>
`
: "";
}

function exteriorPaginator(
redirectPage: number,
maxPage: number,
content: string,
condition: boolean
): string {
return condition && maxPage > 3
? `
<a class="js-paginator" data-page="${redirectPage}">
${content}
</a>
`
: "";
}
10 changes: 10 additions & 0 deletions app/server/components/ProductSpecComponent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default function ProductSpecComponent(
specTitle: string,
specBody: string
): string {
return /* html */ `
<div class="productSpecs">
<span class="product-spec">${specTitle}: </span> ${specBody}
</div>
`;
}
11 changes: 11 additions & 0 deletions app/server/components/ProductSpecsComponent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { htmlString } from "../types/html";

import ProductSpecComponent from "./ProductSpecComponent";

export default function ProductSpecsComponent(caracts: {
[index: string]: string;
}): htmlString {
return Object.entries(caracts)
.map(([key, value]): string => ProductSpecComponent(key, value))
.join("");
}
31 changes: 31 additions & 0 deletions app/server/components/ProductsCardComponent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Product from "../interfaces/Product";

export default function ProductsCardComponent(
{
image,
id,
price,
title
}: Product,
isFavorite: boolean
): string {
return /* html */ `
<div class="product-card">
<div class="product-image">
<div style="position:relative;">
<a href="/product/${id}">
<img src="${image}">
</a>
<div class="favorites-icon ${isFavorite ? "selected" : ""}" data-id="${id}">
&#9733;
</div>
</div>
</div>
<div class="product-info">
<h5><a href="/product/${id}">${title}</a></h5>
<h6>$${price}</h6>
</div>
<a class="shopButton shopButton-products" data-id="${id}">Comprar</a>
</div>
`;
}
12 changes: 12 additions & 0 deletions app/server/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const path = require('path');

const ROOT_PATH = [__dirname, '..', '..'];

const ROOT = path.join(...ROOT_PATH);
const PUBLIC_DIR = path.join(...ROOT_PATH, 'public');
const DATABASE_DIR = path.join(...ROOT_PATH, 'database');

export {
PUBLIC_DIR,
DATABASE_DIR
}
6 changes: 6 additions & 0 deletions app/server/interfaces/BasicProduct.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default interface BasicProduct {
id: number;
price: number;
stock: number;
title: string;
}
6 changes: 6 additions & 0 deletions app/server/interfaces/CartProduct.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import BasicProduct from "./BasicProduct";

export default interface CartProduct extends BasicProduct {
units: number,
total: number,
}
7 changes: 7 additions & 0 deletions app/server/interfaces/CartStructure.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// import { cartStructureProducts } from "../types/cart";

// export default interface CartStructure {
// products: cartStructureProducts,
// quantityProducts: number,
// total: number
// }
10 changes: 10 additions & 0 deletions app/server/interfaces/Product.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import BasicProduct from "./BasicProduct";

export default interface Product extends BasicProduct {
body: string;
image: string;
category: string;
caracts: {
[index: string]: string
};
}
8 changes: 8 additions & 0 deletions app/server/interfaces/SearchURLParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// import { htmlFileName } from "../types/search";

// export default interface SearchURLParams {
// htmlFileName: htmlFileName,
// page: string,
// id: string,
// search: string
// }
37 changes: 37 additions & 0 deletions app/server/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import ProductsAPI from "./classes/ProductsAPI";

const { Router } = require("express");
const router = Router();

// CONTROLLERS
const productsController = require("./routes/products.controller");
const productController = require("./routes/product.controller");
const indexController = require("./routes/index.controller");
const cartController = require("./routes/cart.controller");

router.get("/", indexController);
router.get("/products/:page", productsController);
router.get("/products", productsController);
router.get("/product/:id", productController);
router.get("/cart", cartController);

// POST
router.post("/products/ids", (req: any, res: any) => {
const response = new ProductsAPI(req).getProductsById()
res.json(response);
});
router.post("/products/:page", (req: any, res: any) => {
const response = new ProductsAPI(req).getProducts()
res.json(response);
});
router.post("/products", (req: any, res: any) => {
const response = new ProductsAPI(req).getProducts()
res.json(response);
});


router.use((req: any, res: any) => {
res.status(404).render("404");
});

module.exports = router;
3 changes: 3 additions & 0 deletions app/server/routes/cart.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = function indexController(req: any, res: any) {
res.render('cart');
}
3 changes: 3 additions & 0 deletions app/server/routes/index.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = function indexController(req: any, res: any) {
res.render('index');
}
15 changes: 15 additions & 0 deletions app/server/routes/product.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Product from "../interfaces/Product";

import API from "../classes/API";

import ProductSpecsComponent from "../components/ProductSpecsComponent";

module.exports = function productController(req: any, res: any) {
const product: Product = API.getProduct(+req.params.id);

const config: any = product;
config.productSpecs = ProductSpecsComponent(product.caracts);
config.isFavorite = true;

res.render("product", config);
};
Loading

0 comments on commit 813d612

Please sign in to comment.