Component Items

This commit is contained in:
Sergey Yarkov 2019-11-17 16:14:49 +03:00
parent 1edfb84bc8
commit 65b57dc819
12 changed files with 232 additions and 52 deletions

View File

@ -1,46 +1,64 @@
const MongoClient = require('mongodb').MongoClient; const MongoClient = require('mongodb').MongoClient;
const routes = { const routes = {
// Index // Index
indexRoute: function(req, res) { indexRoute: function (req, res) {
res.render('index', { MongoClient.connect('mongodb://localhost:27017/digital_store', {
pageName: 'index' useNewUrlParser: true,
useUnifiedTopology: true
}, (err, db) => {
if (err) throw err;
const dbo = db.db('digital_store');
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);
});
res.render('index', {
pageName: 'index',
categories
});
db.close();
})
}); });
}, },
// How-to-buy // How-to-buy
howToBuyRoute: function(req, res) { howToBuyRoute: function (req, res) {
res.render('how-to-buy', { res.render('how-to-buy', {
pageName: 'how-to-buy' pageName: 'how-to-buy'
}); });
}, },
// Contacts // Contacts
contactsRoute: function(req, res) { contactsRoute: function (req, res) {
res.render('contacts', { res.render('contacts', {
pageName: 'contacts' pageName: 'contacts'
}); });
}, },
// Comments // Comments
commentsRoute: function(req, res) { commentsRoute: function (req, res) {
res.render('comments', { res.render('comments', {
pageName: 'comments' pageName: 'comments'
}); });
}, },
// My-orders // My-orders
myOrdersRoute: function(req, res) { myOrdersRoute: function (req, res) {
res.render('my-orders', { res.render('my-orders', {
pageName: 'my-orders' pageName: 'my-orders'
}); });
}, },
// GetItems // GetItems
getItemsRoute: function(req, res) { getItemsRoute: function (req, res) {
const queryOptions = { const queryOptions = {
auth: 'yYNfW8ynVO18L1TW5qIkILM1WtWgrVZz', auth: 'yYNfW8ynVO18L1TW5qIkILM1WtWgrVZz',
option: 'all' option: 'all'
} }
res.setHeader("Cache-Control", "public, max-age=20");
if (req.query.auth === queryOptions.auth) { if (req.query.auth === queryOptions.auth) {
if (req.query.option === queryOptions.option) { if (req.query.option === queryOptions.option) {
@ -57,20 +75,39 @@ const routes = {
db.close(); db.close();
}) })
}); });
} else if (!req.query.option && req.query.category) {
MongoClient.connect('mongodb://localhost:27017/digital_store', {
useNewUrlParser: true,
useUnifiedTopology: true
}, (err, db) => {
if (err) throw err;
const dbo = db.db('digital_store');
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('Товары в этой категории не найдены или такой категории нет')
}
db.close();
})
});
} else { } else {
res.send('Invalid'); res.send('Запрос неверный');
} }
} else { } else {
res.send('Invalid'); res.send('Неверный токен');
} }
} }
} }
module.exports = function(server) { module.exports = function (server) {
server.get('/', routes.indexRoute); server.get('/', routes.indexRoute);
server.get('/how-to-buy', routes.howToBuyRoute); server.get('/how-to-buy', routes.howToBuyRoute);
server.get('/contacts', routes.contactsRoute); server.get('/contacts', routes.contactsRoute);
server.get('/comments', routes.commentsRoute); server.get('/comments', routes.commentsRoute);
server.get('/my-orders', routes.myOrdersRoute); server.get('/my-orders', routes.myOrdersRoute);
server.get('/store-api', routes.getItemsRoute); server.get('/store-api', routes.getItemsRoute);
} }

File diff suppressed because one or more lines are too long

23
dist/views/index.pug vendored
View File

@ -63,21 +63,10 @@ main.main-section
.category-items .category-items
ul ul
li li
a.active(href='#') Все товары: a.active(href='#' data-category='all') Все товары:
li each val in categories
a(href='#') Steam li
li a(href='#' data-category=val) #{val}
a(href='#') VKontakte
li
a(href='#') Origin
li
a(href='#') Warface
li
a(href='#') Uplay
li
a(href='#') Fortnite
li
a(href='#') Instagram
// Category Block END // Category Block END
// Filter Block // Filter Block
@ -110,9 +99,9 @@ main.main-section
.items-title.block-title .items-title.block-title
i.material-icons list i.material-icons list
h2.small-title Список товаров: h2.small-title Список товаров:
#loader.progress
.indeterminate(style="width: 40%")
#roster #roster
#loader.progress.hide
.indeterminate(style="width: 40%")
#pagination.items-pagination #pagination.items-pagination
.divider .divider
ul.pagination ul.pagination

14
package-lock.json generated
View File

@ -1261,6 +1261,15 @@
} }
} }
}, },
"axios-cache-adapter": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/axios-cache-adapter/-/axios-cache-adapter-2.5.0.tgz",
"integrity": "sha512-YcMPdMoqmSLoZx7A5YD/PdYGuX6/Y9M2tHBhaIXvXrPeGgNnbW7nb3+uArWlT53WGHLfclnu2voMmS7jGXVg6A==",
"requires": {
"cache-control-esm": "1.0.0",
"lodash": "^4.17.11"
}
},
"babel-loader": { "babel-loader": {
"version": "8.0.6", "version": "8.0.6",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz",
@ -1650,6 +1659,11 @@
"unset-value": "^1.0.0" "unset-value": "^1.0.0"
} }
}, },
"cache-control-esm": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/cache-control-esm/-/cache-control-esm-1.0.0.tgz",
"integrity": "sha512-Fa3UV4+eIk4EOih8FTV6EEsVKO0W5XWtNs6FC3InTfVz+EjurjPfDXY5wZDo/lxjDxg5RjNcurLyxEJBcEUx9g=="
},
"camelcase": { "camelcase": {
"version": "5.3.1", "version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",

View File

@ -21,6 +21,7 @@
"dependencies": { "dependencies": {
"@babel/polyfill": "^7.7.0", "@babel/polyfill": "^7.7.0",
"axios": "^0.19.0", "axios": "^0.19.0",
"axios-cache-adapter": "^2.5.0",
"express": "^4.17.1", "express": "^4.17.1",
"mongodb": "^3.3.4", "mongodb": "^3.3.4",
"pug": "^2.0.4" "pug": "^2.0.4"

View File

@ -0,0 +1,37 @@
import { Component } from "../core/component";
import { apiService } from "../services/api.service";
import { renderItemsOne } from "../templates/itemsOne.template";
import { renderItems } from "../templates/items.template";
export class CategoryComponent extends Component {
constructor(id, {items}) {
super(id);
this.items = items;
}
init() {
if (this.$el) {
this.$el.addEventListener('click', buttonHandler.bind(this));
}
}
}
async function buttonHandler(e) {
e.preventDefault();
if (e.target.dataset.category && e.target.dataset.category != 'all') {
this.items.onShow();
const category = e.target.dataset.category.toLowerCase();
const fData = await apiService.getItemsOne(category);
const html = renderItemsOne(category, fData);
this.items.onHide();
document.querySelector('#roster').insertAdjacentHTML('afterbegin', html);
} else if (e.target.dataset.category === 'all') {
this.items.onShow();
const fData = await apiService.getItems(),
categories = Object.keys(fData);
const html = renderItems(categories, fData);
this.items.onHide();
document.querySelector('#roster').insertAdjacentHTML('afterbegin', html);
}
}

View File

@ -1,12 +1,11 @@
import { Component } from "../core/component"; import { Component } from "../core/component";
import { apiService } from "../services/api.service"; import { apiService } from "../services/api.service";
import { renderItem } from "../templates/item.template"; import { renderItems } from "../templates/items.template";
export class ItemsComponent extends Component { export class ItemsComponent extends Component {
constructor(id, {loader}) { constructor(id, {loader}) {
super(id); super(id);
this.loader = loader; this.loader = loader;
this.loader.show();
} }
async init() { async init() {
@ -15,9 +14,22 @@ export class ItemsComponent extends Component {
const fData = await apiService.getItems(), const fData = await apiService.getItems(),
categories = Object.keys(fData); categories = Object.keys(fData);
const html = renderItem(categories, fData); if (categories.length) {
this.$el.querySelector('#roster').insertAdjacentHTML('afterbegin', html); const html = renderItems(categories, fData);
this.loader.hide(); this.$el.querySelector('#roster').insertAdjacentHTML('afterbegin', html);
} else {
this.$el.querySelector('#roster').innerHTML = 'Товаров на сайте пока что нету';
}
this.loader.hide();
} }
} }
onHide() {
this.$el.querySelector('#roster').innerHTML = '';
this.loader.hide();
}
onShow() {
this.$el.querySelector('#roster').innerHTML = '';
this.loader.show();
}
} }

View File

@ -6,6 +6,10 @@ export class Component {
init() {} init() {}
onShow() {}
onHide() {}
hide() { hide() {
this.$el ? this.$el.classList.add('hide') : false this.$el ? this.$el.classList.add('hide') : false
} }

View File

@ -3,9 +3,11 @@ import { InformationComponent } from "./components/information.component.js";
import { CartComponent } from "./components/cart.component.js"; import { CartComponent } from "./components/cart.component.js";
import { LoaderComponent } from "./components/loader.component.js"; import { LoaderComponent } from "./components/loader.component.js";
import { ItemsComponent } from "./components/items.component.js"; import { ItemsComponent } from "./components/items.component.js";
import { CategoryComponent } from "./components/category.component.js";
const header = new HeaderComponent('header'); const header = new HeaderComponent('header');
const loader = new LoaderComponent('loader'); const loader = new LoaderComponent('loader');
const information = new InformationComponent('information'); const information = new InformationComponent('information');
const cart = new CartComponent('cart'); const cart = new CartComponent('cart');
const items = new ItemsComponent('items', {loader}); const items = new ItemsComponent('items', {loader});
const category = new CategoryComponent('category', {items});

View File

@ -1,4 +1,5 @@
const axios = require('axios'); const axios = require('axios');
const API_TOKEN = 'yYNfW8ynVO18L1TW5qIkILM1WtWgrVZz';
class ApiService { class ApiService {
constructor(baseUrl) { constructor(baseUrl) {
@ -7,7 +8,16 @@ class ApiService {
async getItems() { async getItems() {
try { try {
const request = `${this.url}store-api?auth=yYNfW8ynVO18L1TW5qIkILM1WtWgrVZz&option=all`; const request = `${this.url}store-api?auth=${API_TOKEN}&option=all`;
return useRequest(request);
} catch (err) {
console.error(err);
}
}
async getItemsOne(category) {
try {
const request = `${this.url}store-api?auth=${API_TOKEN}&category=${category}`;
return useRequest(request); return useRequest(request);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
@ -20,4 +30,4 @@ async function useRequest(request) {
return await JSON.parse(response.request.response); return await JSON.parse(response.request.response);
} }
export const apiService = new ApiService('http://localhost:3000/'); export const apiService = new ApiService('http://localhost:3000/', API_TOKEN);

View File

@ -1,4 +1,4 @@
export function renderItem(categories, items) { export function renderItems(categories, items) {
let html = ''; let html = '';
@ -15,7 +15,7 @@ export function renderItem(categories, items) {
<img src="./img/service-icons/${item.image}" alt="#"> <img src="./img/service-icons/${item.image}" alt="#">
</div> </div>
<div class="list-title"> <div class="list-title">
<a href="#">${item.title}</a> <a href="/item/${item._id}">${item.title}</a>
</div> </div>
</div> </div>
<div class="items-list__info"> <div class="items-list__info">

View File

@ -0,0 +1,50 @@
export function renderItemsOne(category, items) {
let html = '';
html += `<div class="items-category">
<h2 class="small-title">${category}</h2>
</div>`;
items.forEach(item => {
if (item) {
html += `
<div 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="/item/${item._id}">${item.title}</a>
</div>
</div>
<div class="items-list__info">
<div class="list-count">
<span>${item.count} шт.</span>
</div>
<div class="list-one">
<span>Цена за 1 шт.</span>
</div>
<div class="list-price">
<span>${item.price}</span>
</div>
<div class="list-buttons">
<button class="btn-small waves-effect waves-light">Купить</button>
<button 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;
}