API refactored

This commit is contained in:
Sergey Yarkov 2019-12-01 23:51:50 +03:00
parent 58a41aa82e
commit ec8ed92e0f
14 changed files with 171 additions and 250 deletions

View File

@ -1,124 +1,100 @@
const ObjectID = require('mongodb').ObjectID;
function indexRoute(req, res, dbo) {
dbo.collection('storeInfo').find().toArray((err, result) => {
if (err) throw err;
const array = Object.keys(result[0].items)
const categories = array.map(cat => {
return cat[0].toUpperCase() + cat.slice(1);
});
dbo.collection('categories').find().toArray((err, result) => {
const categories = result.map(category => category.title[0].toUpperCase() + category.title.slice(1));
res.render('index', {
pageName: 'index',
categories
});
})
});
}
// API
function getItemsRoute(req, res, dbo) {
if (req.query.auth === 'yYNfW8ynVO18L1TW5qIkILM1WtWgrVZz') {
if (req.query.option === 'all' && !req.query.sorting) {
dbo.collection('storeInfo').find().toArray((err, result) => {
if (err) throw err;
res.send(result[0].items);
})
} else if (!req.query.option && req.query.category && req.query.sorting === 'ascending') {
dbo.collection('storeInfo').find().toArray((err, result) => {
if (err) throw err;
const items = result[0].items[req.query.category];
items.sort((a, b) => a.price - b.price) // фильтр по возрастанию по цене
res.send(items);
if (req.query.token === 'yYNfW8ynVO18L1TW5qIkILM1WtWgrVZz') {
if (req.query.items === 'all' && !req.query.category && !req.query.sorting) {
dbo.collection('items').find().toArray((err, result) => {
res.send(result);
});
} else if (!req.query.option && req.query.category && req.query.sorting === 'descending') {
dbo.collection('storeInfo').find().toArray((err, result) => {
if (err) throw err;
const items = result[0].items[req.query.category];
items.sort((a, b) => b.price - a.price) // фильтр по убыванию по цене
res.send(items);
} else if (req.query.items === 'all' && req.query.sorting && !req.query.category) {
if (req.query.sorting === 'ascending') {
dbo.collection('items').find().sort({price: 1}).toArray((err, result) => {
res.send(result);
});
} else if (!req.query.option && req.query.category && req.query.sorting === 'older') {
dbo.collection('storeInfo').find().toArray((err, result) => {
if (err) throw err;
const items = result[0].items[req.query.category];
items.sort((a, b) => new Date(a.date) - new Date(b.date)); // фильтр по возрастанию по дате
res.send(items);
} else if (req.query.sorting === 'descending') {
dbo.collection('items').find().sort({price: -1}).toArray((err, result) => {
res.send(result);
});
} else if (!req.query.option && req.query.category && req.query.sorting === 'newer') {
dbo.collection('storeInfo').find().toArray((err, result) => {
if (err) throw err;
const items = result[0].items[req.query.category];
items.sort((a, b) => new Date(b.date) - new Date(a.date)) // фильтр по убыванию по дате
res.send(items);
} else if (req.query.sorting === 'newer') {
dbo.collection('items').find().sort({date: -1}).toArray((err, result) => {
res.send(result);
});
} else if (req.query.sorting === 'older') {
dbo.collection('items').find().sort({date: 1}).toArray((err, result) => {
res.send(result);
});
} else if (!req.query.option && req.query.category) {
dbo.collection('storeInfo').find().toArray((err, result) => {
if (err) throw err;
const query = result[0].items[req.query.category]
if (query != undefined) {
res.send(query);
} else {
res.send('Товары в этой категории не найдены или такой категории нет')
res.send('Введите параметр по убыванию или возрастанию.');
}
})
} else if (req.query.option && req.query.sorting === 'ascending') {
dbo.collection('storeInfo').find().toArray((err, result) => {
if (err) throw err;
const items = result[0].items;
Object.values(items).forEach(arr => arr.sort((a, b) => a.price - b.price)) // фильтр по возрастанию по цене
res.send(items);
} else if (req.query.items === 'all' && req.query.category && !req.query.sorting) {
dbo.collection('items').find({category: req.query.category}).toArray((err, result) => {
result.length > 0
? res.send(result)
: res.send('Такой категории не существует или там нет товаров.');
});
} else if (req.query.option && req.query.sorting === 'descending') {
dbo.collection('storeInfo').find().toArray((err, result) => {
if (err) throw err;
const items = result[0].items;
Object.values(items).forEach(arr => arr.sort((a, b) => b.price - a.price)) // фильтр по убыванию по цене
res.send(items);
})
} else if (req.query.option && req.query.sorting === 'older') {
dbo.collection('storeInfo').find().toArray((err, result) => {
if (err) throw err;
const items = result[0].items;
Object.values(items).forEach(arr => arr.sort((a, b) => new Date(a.date) - new Date(b.date))) // фильтр по возрастанию пр дате
res.send(items);
} else if (req.query.items === 'all' && req.query.category && req.query.sorting) {
if (req.query.sorting === 'ascending') {
dbo.collection('items').find({category: req.query.category}).sort({price: 1}).toArray((err, result) => {
res.send(result);
});
} else if (req.query.option && req.query.sorting === 'newer') {
dbo.collection('storeInfo').find().toArray((err, result) => {
if (err) throw err;
const items = result[0].items;
Object.values(items).forEach(arr => arr.sort((a, b) => new Date(b.date) - new Date(a.date))) // фильтр по возрастанию пр дате
res.send(items);
} else if (req.query.sorting === 'descending') {
dbo.collection('items').find({category: req.query.category}).sort({price: -1}).toArray((err, result) => {
res.send(result);
});
} else if (req.query.sorting === 'newer') {
dbo.collection('items').find({category: req.query.category}).sort({date: -1}).toArray((err, result) => {
res.send(result);
});
} else if (req.query.sorting === 'older') {
dbo.collection('items').find({category: req.query.category}).sort({date: 1}).toArray((err, result) => {
res.send(result);
});
} else {
res.send('Запрос неверный');
res.send('Введите параметр по убыванию или возрастанию.');
}
} else if (req.query.categories === 'all') {
dbo.collection('categories').find().toArray((err, result) => {
res.send(result);
});
} else if (req.query.category) {
dbo.collection('categories').find({title: req.query.category}).toArray((err, result) => {
res.send(result);
});
} else {
res.send('Запрос неверный.');
}
} else {
res.send('Неверный токен');
res.send('Неверный токен.');
}
}
function onePageItemRoute(req, res, dbo) {
dbo.collection('storeInfo').find().toArray((err, result) => {
if (err) throw err;
const items = result[0].items;
const keys = Object.keys(result[0].items);
let itemFind = false;
keys.forEach(key => {
items[key].forEach(item => {
if (item._id != undefined) {
if (item._id == req.params.id) {
itemFind = true;
dbo.collection('items').find({_id: new ObjectID(req.params.id)}).toArray((err, result) => {
const item = result[0];
dbo.collection('categories').find({title: item.category}).toArray((err, result) => {
const category = result[0];
res.render('product', {
title: item.title,
image: item.image,
image: category.img,
count: item.count,
category: item.category[0].toUpperCase() + item.category.slice(1),
price: item.price,
description: item.description,
date: item.date
});
}
}
date: item.date,
id: item._id
})
});
if (!itemFind) res.send('Error 404');
})
}
@ -146,10 +122,9 @@ function myOrdersRoute(req, res) {
});
}
module.exports = function (server, db) {
server.get('/', (req, res) => indexRoute(req, res, db));
server.get('/store-api', (req, res) => getItemsRoute(req, res, db));
server.get('/api', (req, res) => getItemsRoute(req, res, db));
server.get('/how-to-buy', (req, res) => howToBuyRoute(req, res, db));
server.get('/contacts', (req, res) => contactsRoute(req, res, db));
server.get('/comments', (req, res) => commentsRoute(req, res, db));

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,7 @@ doctype
html(lang='ru')
head
meta(charset='utf-8')
meta(http-equiv='Cоntent-Type' cоntent='text/html;' charset='utf-8')
title Digital Shop
// Materialize CSS
link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css")

View File

@ -66,7 +66,7 @@ main.main-section
a#catLi.active(href='#' data-category='all') Все товары:
each val in categories
li
a#catLi(href='#' data-category=val) #{val}
a#catLi(href='#' data-category=val.toLowerCase()) #{val}
// Category Block END
// Filter Block

View File

@ -17,7 +17,7 @@ main.main-section
li
a(href='/') Главная
li
a#breadcrumbBtn(href='/' data-category=category) #{category}
a#breadcrumbBtn(href='/' data-category=category.toLowerCase()) #{category}
li #{title}
hr
.product-title.block-title

View File

@ -1,7 +1,6 @@
import { Component } from "../core/component";
import { apiService } from "../services/api.service";
import { renderItemsOne } from "../templates/itemsCategory.template";
import { renderItems } from "../templates/items.template";
import { renderItemsRefactor } from "../templates/itemsRefactor.template";
export class CategoryComponent extends Component {
constructor(id, {items}, {filter}) {
@ -27,8 +26,9 @@ export class CategoryComponent extends Component {
}
async function showItems(category) {
const fData = await apiService.getItemsOne(category),
html = renderItemsOne(category, fData);
const targetCategory = await apiService.getCategory(category);
const fData = await apiService.getItemsOneRefactor(category),
html = renderItemsRefactor(targetCategory, fData);
this.items.onHide();
this.items.insertItems(html);
@ -43,9 +43,9 @@ async function buttonHandler(e) {
this.items.onShow();
btnActiveLink(e);
const category = e.target.dataset.category.toLowerCase(),
fData = await apiService.getItemsOne(category),
html = renderItemsOne(category, fData);
const category = await apiService.getCategory(e.target.dataset.category),
fData = await apiService.getItemsOneRefactor(e.target.dataset.category),
html = renderItemsRefactor(category, fData);
this.items.onHide();
this.items.insertItems(html);
@ -56,9 +56,9 @@ async function buttonHandler(e) {
this.items.onShow();
btnActiveLink(e);
const fData = await apiService.getItems(),
categories = Object.keys(fData),
html = renderItems(categories, fData);
const fData = await apiService.getItemsRefactor();
const categories = await apiService.getCategories();
const html = renderItemsRefactor(categories, fData);
this.items.onHide();
this.items.insertItems(html);
@ -69,13 +69,13 @@ async function buttonHandler(e) {
function btnActiveLink(e) {
Array.from(e.target.parentNode.parentNode.querySelectorAll('#catLi')).forEach(li => li.classList.remove('active'));
e.target.classList.add('active');
localStorage.setItem('currentCategory', e.target.dataset.category.toLowerCase());
localStorage.setItem('currentCategory', e.target.dataset.category);
}
// Окраска li по нажатию на breadcrumb
function breadcrumbActiveLink(category) {
const links = this.$el.querySelectorAll('#catLi');
Array.from(links).forEach(li => li.classList.remove('active'));
Array.from(links).forEach(li => li.dataset.category.toLowerCase() === category ? li.classList.add('active') : false);
Array.from(links).forEach(li => li.dataset.category.toLowerCase() === category ? localStorage.setItem('currentCategory', li.dataset.category.toLowerCase()) : false);
Array.from(links).forEach(li => li.dataset.category === category ? li.classList.add('active') : false);
Array.from(links).forEach(li => li.dataset.category === category ? localStorage.setItem('currentCategory', li.dataset.category) : false);
}

View File

@ -1,7 +1,6 @@
import { Component } from "../core/component";
import { apiService } from "../services/api.service";
import { renderItems } from "../templates/items.template";
import { renderItemsOne } from "../templates/itemsCategory.template";
import { renderItemsRefactor } from "../templates/itemsRefactor.template";
export class FilterComponent extends Component {
constructor(id, {items}) {
@ -30,9 +29,9 @@ async function sortByAllHandler(e) {
const sorting = e.target.id;
this.items.onShow();
const fData = await apiService.getItems(sorting),
categories = Object.keys(fData),
html = renderItems(categories, fData);
const fData = await apiService.getItemsRefactor(sorting);
const categories = await apiService.getCategories();
const html = renderItemsRefactor(categories, fData);
this.items.onHide();
this.items.insertItems(html);
@ -44,11 +43,11 @@ async function sortByOneHandler(e) {
if (!localStorage.getItem('sortByAll')) {
if (e.target.id) {
const sorting = e.target.id;
this.items.onShow();
const category = localStorage.getItem('currentCategory'),
fData = await apiService.getItemsOne(category, sorting),
html = renderItemsOne(category, fData);
const category = await apiService.getCategory(localStorage.getItem('currentCategory')),
fData = await apiService.getItemsOneRefactor(localStorage.getItem('currentCategory'), sorting),
html = renderItemsRefactor(category, fData);
this.items.onHide();
this.items.insertItems(html);

View File

@ -1,7 +1,7 @@
import { Component } from "../core/component";
import { apiService } from "../services/api.service";
import { renderItems } from "../templates/items.template";
import { insertCount } from "../other/counter";
import { renderItemsRefactor } from "../templates/itemsRefactor.template";
export class ItemsComponent extends Component {
constructor(id, {loader}) {
@ -20,16 +20,11 @@ export class ItemsComponent extends Component {
localStorage.setItem('sortByAll', 'true'); // установка значения для компонента Filter
this.$el.addEventListener('click', addItem.bind(this));
if (!localStorage.getItem('category')) { // Получаем все товары и выводим их если нету ключа category в ls
const fData = await apiService.getItems(),
categories = Object.keys(fData);
if (categories.length) {
const html = renderItems(categories, fData);
const fData = await apiService.getItemsRefactor();
const categories = await apiService.getCategories();
const html = renderItemsRefactor(categories, fData);
this.insertItems(html);
this.btnColor();
} else {
this.roster.innerHTML = 'Товаров на сайте пока что нету';
}
this.loader.hide();
}

View File

@ -7,9 +7,11 @@ export class Modal {
}
init() {
if (this.open != null) {
this.open.addEventListener('click', openHandler.bind(this));
this.close.addEventListener('click', closeHandler.bind(this));
}
}
show() {
this.$el.classList.remove('hide');

View File

@ -83,9 +83,11 @@ export class CartModal extends Modal {
}
defaultBtnColor(id) {
if (this.items.roster) {
if (this.items.roster.querySelector(`#addItem[data-id="${id}"]`)) {
this.items.roster.querySelector(`#addItem[data-id="${id}"]`).classList.remove('orange');
this.items.roster.querySelector(`#addItem[data-id="${id}"] i`).innerHTML = 'shopping_cart';
}
}
}
}

View File

@ -3,9 +3,11 @@ import { Modal } from "../core/modal";
export class PayModal extends Modal {
constructor (id, open, close) {
super(id, open, close);
if (this.open != null) {
this.open.addEventListener('click', this.openHandler.bind(this));
this.close.addEventListener('click', this.closeHandler.bind(this));
}
}
closeHandler() {
this.$el.querySelector('#purchaseInfo').onsubmit = null;

View File

@ -6,13 +6,31 @@ class ApiService {
this.url = baseUrl;
}
async getItems(sorting) {
async getCategory(category) {
try {
const request = `${this.url}api?token=${API_TOKEN}&category=${encodeURIComponent(category)}`;
return useRequest(request);
} catch (err) {
console.error(err);
}
}
async getCategories() {
try {
const request = `${this.url}api?token=${API_TOKEN}&categories=all`;
return useRequest(request);
} catch (err) {
console.error(err);
}
}
async getItemsRefactor(sorting) {
try {
if (sorting) {
const request = `${this.url}store-api?auth=${API_TOKEN}&option=all&sorting=${sorting}`;
const request = `${this.url}api?token=${API_TOKEN}&items=all&sorting=${sorting}`;
return useRequest(request);
} else {
const request = `${this.url}store-api?auth=${API_TOKEN}&option=all`;
const request = `${this.url}api?token=${API_TOKEN}&items=all`;
return useRequest(request);
}
@ -21,13 +39,13 @@ class ApiService {
}
}
async getItemsOne(category, sorting) {
async getItemsOneRefactor(category, sorting) {
try {
if (sorting) {
const request = `${this.url}store-api?auth=${API_TOKEN}&category=${category}&sorting=${sorting}`;
const request = `${this.url}api?token=${API_TOKEN}&items=all&category=${encodeURIComponent(category.toLowerCase())}&sorting=${sorting}`;
return useRequest(request);
} else {
const request = `${this.url}store-api?auth=${API_TOKEN}&category=${category}`;
const request = `${this.url}api?token=${API_TOKEN}&items=all&category=${encodeURIComponent(category.toLowerCase())}`;
return useRequest(request);
}
} catch (err) {

View File

@ -1,53 +0,0 @@
export function renderItemsOne(category, items) {
let html = '';
html += `<div class="items-category">
<h2 class="small-title">${category}</h2>
</div>`;
items.forEach(item => {
if (item && item._id != undefined) {
html += `
<div data-id="${item._id}" data-title="${item.title}" data-price="${item.price}" class="items-list">
<div class="items-list__name">
<div class="list-icon">
<img src="./img/service-icons/${item.image}" alt="#">
</div>
<div class="list-title">
<a href="/product/${item._id}">${item.title}</a>
</div>
</div>
<div class="items-list__info">
<div class="list-date">
<small>${item.date}</small>
</div>
<div class="list-count">
<span>${item.count} шт.</span>
</div>
<div class="list-one">
<span>Цена за 1 шт.</span>
</div>
<div class="list-price">
<span>${item.price.toFixed(2)}₽</span>
</div>
<div class="list-buttons">
<button data-id="${item._id}" data-title="${item.title}" data-date="${item.date}" data-count="${item.count}" data-price="${item.price}" id="payOpen" class="btn-small waves-effect waves-light">Купить</button>
<button data-id="${item._id}" data-title="${item.title}" data-date="${item.date}" data-count="${item.count}" data-price="${item.price}" id="addItem" class="btn-small waves-effect waves-light"><i
class="material-icons">shopping_cart</i></button>
</div>
</div>
</div>
`
} else {
html += `
<div class="items-list">
<div class="items-list__name">
<div class="list-title">
<span>В этой категории пока что нету товаров</span>
</div>
</div>
</div>`;
}
});
return html;
}

View File

@ -1,18 +1,20 @@
export function renderItems(categories, items) {
export function renderItemsRefactor(categories, items) {
const arrayCategories = categories;
const arrayItems = items;
let html = '';
categories.forEach(category => {
arrayCategories.forEach(category => {
html += `<div class="items-category">
<h2 class="small-title">${category}</h2>
<h2 class="small-title">${category.title}</h2>
</div>`;
items[category].forEach(item => {
if (item && item._id != undefined) {
arrayItems.forEach(item => {
if (item.category.toLowerCase() === category.title.toLowerCase()) {
html += `
<div data-id="${item._id}" data-title="${item.title}" data-price="${item.price}" class="items-list">
<div class="items-list__name">
<div class="list-icon">
<img src="./img/service-icons/${item.image}" alt="#">
<img src="./img/service-icons/${category.img}" alt="#">
</div>
<div class="list-title">
<a href="/product/${item._id}">${item.title}</a>
@ -20,7 +22,7 @@ export function renderItems(categories, items) {
</div>
<div class="items-list__info">
<div class="list-date">
<small>${item.date}</small>
<small>${item.date.split('T')[0]}</small>
</div>
<div class="list-count">
<span>${item.count} шт.</span>
@ -37,20 +39,10 @@ export function renderItems(categories, items) {
class="material-icons">shopping_cart</i></button>
</div>
</div>
</div>
`
} else {
html += `
<div class="items-list">
<div class="items-list__name">
<div class="list-title">
<span>В этой категории пока что нету товаров</span>
</div>
</div>
</div>
`
</div>`;
}
});
})
});
return html;