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) { function indexRoute(req, res, dbo) {
dbo.collection('storeInfo').find().toArray((err, result) => { dbo.collection('categories').find().toArray((err, result) => {
if (err) throw err; const categories = result.map(category => category.title[0].toUpperCase() + category.title.slice(1));
const array = Object.keys(result[0].items)
const categories = array.map(cat => {
return cat[0].toUpperCase() + cat.slice(1);
});
res.render('index', { res.render('index', {
pageName: 'index', pageName: 'index',
categories categories
}); });
}) });
} }
// API
function getItemsRoute(req, res, dbo) { function getItemsRoute(req, res, dbo) {
if (req.query.auth === 'yYNfW8ynVO18L1TW5qIkILM1WtWgrVZz') { if (req.query.token === 'yYNfW8ynVO18L1TW5qIkILM1WtWgrVZz') {
if (req.query.option === 'all' && !req.query.sorting) { if (req.query.items === 'all' && !req.query.category && !req.query.sorting) {
dbo.collection('storeInfo').find().toArray((err, result) => { dbo.collection('items').find().toArray((err, result) => {
if (err) throw err; res.send(result);
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);
}); });
} else if (!req.query.option && req.query.category && req.query.sorting === 'descending') { } else if (req.query.items === 'all' && req.query.sorting && !req.query.category) {
dbo.collection('storeInfo').find().toArray((err, result) => { if (req.query.sorting === 'ascending') {
if (err) throw err; dbo.collection('items').find().sort({price: 1}).toArray((err, result) => {
const items = result[0].items[req.query.category]; res.send(result);
items.sort((a, b) => b.price - a.price) // фильтр по убыванию по цене });
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.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 {
res.send('Введите параметр по убыванию или возрастанию.');
}
} 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.category && req.query.sorting === 'older') { } else if (req.query.items === 'all' && req.query.category && req.query.sorting) {
dbo.collection('storeInfo').find().toArray((err, result) => { if (req.query.sorting === 'ascending') {
if (err) throw err; dbo.collection('items').find({category: req.query.category}).sort({price: 1}).toArray((err, result) => {
const items = result[0].items[req.query.category]; res.send(result);
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({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('Введите параметр по убыванию или возрастанию.');
}
} else if (req.query.categories === 'all') {
dbo.collection('categories').find().toArray((err, result) => {
res.send(result);
}); });
} else if (!req.query.option && req.query.category && req.query.sorting === 'newer') { } else if (req.query.category) {
dbo.collection('storeInfo').find().toArray((err, result) => { dbo.collection('categories').find({title: req.query.category}).toArray((err, result) => {
if (err) throw err; res.send(result);
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.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('Товары в этой категории не найдены или такой категории нет')
}
})
} 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.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.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 { } else {
res.send('Запрос неверный'); res.send('Запрос неверный.');
} }
} else { } else {
res.send('Неверный токен'); res.send('Неверный токен.');
} }
} }
function onePageItemRoute(req, res, dbo) { function onePageItemRoute(req, res, dbo) {
dbo.collection('storeInfo').find().toArray((err, result) => { dbo.collection('items').find({_id: new ObjectID(req.params.id)}).toArray((err, result) => {
if (err) throw err; const item = result[0];
const items = result[0].items; dbo.collection('categories').find({title: item.category}).toArray((err, result) => {
const keys = Object.keys(result[0].items); const category = result[0];
let itemFind = false; res.render('product', {
keys.forEach(key => { title: item.title,
items[key].forEach(item => { image: category.img,
if (item._id != undefined) { count: item.count,
if (item._id == req.params.id) { category: item.category[0].toUpperCase() + item.category.slice(1),
itemFind = true; price: item.price,
res.render('product', { description: item.description,
title: item.title, date: item.date,
image: item.image, id: item._id
count: item.count,
category: item.category[0].toUpperCase() + item.category.slice(1),
price: item.price,
description: item.description,
date: item.date
});
}
}
}) })
}); });
if (!itemFind) res.send('Error 404');
}) })
} }
@ -146,10 +122,9 @@ function myOrdersRoute(req, res) {
}); });
} }
module.exports = function (server, db) { module.exports = function (server, db) {
server.get('/', (req, res) => indexRoute(req, res, 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('/how-to-buy', (req, res) => howToBuyRoute(req, res, db));
server.get('/contacts', (req, res) => contactsRoute(req, res, db)); server.get('/contacts', (req, res) => contactsRoute(req, res, db));
server.get('/comments', (req, res) => commentsRoute(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') html(lang='ru')
head head
meta(charset='utf-8') meta(charset='utf-8')
meta(http-equiv='Cоntent-Type' cоntent='text/html;' charset='utf-8')
title Digital Shop title Digital Shop
// Materialize CSS // Materialize CSS
link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.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') Все товары: a#catLi.active(href='#' data-category='all') Все товары:
each val in categories each val in categories
li li
a#catLi(href='#' data-category=val) #{val} a#catLi(href='#' data-category=val.toLowerCase()) #{val}
// Category Block END // Category Block END
// Filter Block // Filter Block

View File

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

View File

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

View File

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

View File

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

View File

@ -7,8 +7,10 @@ export class Modal {
} }
init() { init() {
this.open.addEventListener('click', openHandler.bind(this)); if (this.open != null) {
this.close.addEventListener('click', closeHandler.bind(this)); this.open.addEventListener('click', openHandler.bind(this));
this.close.addEventListener('click', closeHandler.bind(this));
}
} }
show() { show() {

View File

@ -83,9 +83,11 @@ export class CartModal extends Modal {
} }
defaultBtnColor(id) { defaultBtnColor(id) {
if (this.items.roster.querySelector(`#addItem[data-id="${id}"]`)) { if (this.items.roster) {
this.items.roster.querySelector(`#addItem[data-id="${id}"]`).classList.remove('orange'); if (this.items.roster.querySelector(`#addItem[data-id="${id}"]`)) {
this.items.roster.querySelector(`#addItem[data-id="${id}"] i`).innerHTML = 'shopping_cart'; 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,8 +3,10 @@ import { Modal } from "../core/modal";
export class PayModal extends Modal { export class PayModal extends Modal {
constructor (id, open, close) { constructor (id, open, close) {
super(id, open, close); super(id, open, close);
this.open.addEventListener('click', this.openHandler.bind(this)); if (this.open != null) {
this.close.addEventListener('click', this.closeHandler.bind(this)); this.open.addEventListener('click', this.openHandler.bind(this));
this.close.addEventListener('click', this.closeHandler.bind(this));
}
} }
closeHandler() { closeHandler() {

View File

@ -6,13 +6,31 @@ class ApiService {
this.url = baseUrl; 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 { try {
if (sorting) { 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); return useRequest(request);
} else { } 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); return useRequest(request);
} }
@ -21,13 +39,13 @@ class ApiService {
} }
} }
async getItemsOne(category, sorting) { async getItemsOneRefactor(category, sorting) {
try { try {
if (sorting) { 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); return useRequest(request);
} else { } 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); return useRequest(request);
} }
} catch (err) { } 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 = ''; let html = '';
categories.forEach(category => { arrayCategories.forEach(category => {
html += `<div class="items-category"> html += `<div class="items-category">
<h2 class="small-title">${category}</h2> <h2 class="small-title">${category.title}</h2>
</div>`; </div>`;
items[category].forEach(item => { arrayItems.forEach(item => {
if (item && item._id != undefined) { if (item.category.toLowerCase() === category.title.toLowerCase()) {
html += ` html += `
<div data-id="${item._id}" data-title="${item.title}" data-price="${item.price}" class="items-list"> <div data-id="${item._id}" data-title="${item.title}" data-price="${item.price}" class="items-list">
<div class="items-list__name"> <div class="items-list__name">
<div class="list-icon"> <div class="list-icon">
<img src="./img/service-icons/${item.image}" alt="#"> <img src="./img/service-icons/${category.img}" alt="#">
</div> </div>
<div class="list-title"> <div class="list-title">
<a href="/product/${item._id}">${item.title}</a> <a href="/product/${item._id}">${item.title}</a>
@ -20,7 +22,7 @@ export function renderItems(categories, items) {
</div> </div>
<div class="items-list__info"> <div class="items-list__info">
<div class="list-date"> <div class="list-date">
<small>${item.date}</small> <small>${item.date.split('T')[0]}</small>
</div> </div>
<div class="list-count"> <div class="list-count">
<span>${item.count} шт.</span> <span>${item.count} шт.</span>
@ -37,20 +39,10 @@ export function renderItems(categories, items) {
class="material-icons">shopping_cart</i></button> class="material-icons">shopping_cart</i></button>
</div> </div>
</div> </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; return html;