|
@@ -146,19 +146,17 @@ function cartReducer (state={}, {type, good={}, count=1}) {
|
|
|
return state
|
|
|
}
|
|
|
|
|
|
-const actionCartAdd = (good) => ({type: 'CART_ADD', good})
|
|
|
+const actionCartAdd = (good, count) => ({type: 'CART_ADD', good, count})
|
|
|
const actionCartChange = (good, count) => ({type: 'CART_CHANGE', good, count})
|
|
|
const actionCartRemove = (good) => ({type: 'CART_REMOVE', good})
|
|
|
const actionCartClear = () => ({type: 'CART_CLEAR'})
|
|
|
|
|
|
|
|
|
-store.dispatch(actionCartAdd({_id: '111111'}))
|
|
|
-store.dispatch(actionCartChange({_id: '111111'}, 10))
|
|
|
-
|
|
|
-store.dispatch(actionCartAdd({_id: '22222'}))
|
|
|
-store.dispatch(actionCartRemove({_id: '22222'}))
|
|
|
-
|
|
|
-store.dispatch(actionCartClear())
|
|
|
+// store.dispatch(actionCartAdd({_id: '111111'}))
|
|
|
+// store.dispatch(actionCartChange({_id: '111111'}, 10))
|
|
|
+// store.dispatch(actionCartAdd({_id: '22222'}))
|
|
|
+// store.dispatch(actionCartRemove({_id: '22222'}))
|
|
|
+// store.dispatch(actionCartClear())
|
|
|
|
|
|
|
|
|
|
|
@@ -319,7 +317,7 @@ const actionGoodById = (_id) => (
|
|
|
}`, {q: JSON.stringify([{_id}])}))
|
|
|
)
|
|
|
|
|
|
-const actionGoodsByUser = () => (
|
|
|
+const actionGoodsByUser = (_id) => (
|
|
|
actionPromise('goodByUser', gql(`query oUser($query: String) {
|
|
|
OrderFind(query:$query){
|
|
|
_id orderGoods{
|
|
@@ -337,43 +335,76 @@ const actionGoodsByUser = () => (
|
|
|
}
|
|
|
}
|
|
|
}`,
|
|
|
- {query: JSON.stringify([{}])}))
|
|
|
+ {query: JSON.stringify([{___owner: _id}])}))
|
|
|
)
|
|
|
|
|
|
-
|
|
|
-store.dispatch(actionRootCats())
|
|
|
-
|
|
|
-store.subscribe(() => {
|
|
|
- const {promise} = store.getState()
|
|
|
- const {rootCats} = promise
|
|
|
- if (rootCats?.payload) {
|
|
|
|
|
|
+const actionGoodFind = (word) => (
|
|
|
+ actionPromise('goodFind', gql(`query goodById($q: String) {
|
|
|
+ GoodFind(query: $q) {
|
|
|
+ _id name price description images {
|
|
|
+ url
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }`, {q: JSON.stringify([
|
|
|
+ {
|
|
|
+ $or: [{title: `/${word}/`}, {description: `/${word}/`}, {name: `/${word}/`}] //регулярки пишутся в строках
|
|
|
+ },
|
|
|
+ {
|
|
|
+ sort: [{title: 1}] //сортируем по title алфавитно
|
|
|
+ }
|
|
|
+ ])
|
|
|
+ }
|
|
|
+ ))
|
|
|
+)
|
|
|
|
|
|
- aside.innerHTML = ''
|
|
|
- const regBtn = document.createElement('a')
|
|
|
- regBtn.href = `#/register`
|
|
|
- regBtn.innerText = 'Register'
|
|
|
- const loginBtn = document.createElement('a')
|
|
|
- loginBtn.href = `#/login`
|
|
|
- loginBtn.innerText = 'Login'
|
|
|
- const logoutBtn = document.createElement('button')
|
|
|
- logoutBtn.innerText = 'Logout'
|
|
|
- aside.append(regBtn, loginBtn, logoutBtn)
|
|
|
|
|
|
|
|
|
|
|
|
- logoutBtn.onclick = () => {
|
|
|
- store.dispatch(actionAuthLogout())
|
|
|
- }
|
|
|
- for (const {_id, name} of rootCats?.payload) {
|
|
|
- const link = document.createElement('a')
|
|
|
- link.href = `#/category/${_id}`
|
|
|
- link.innerText = name
|
|
|
- aside.append(link)
|
|
|
+store.subscribe(() => {
|
|
|
+ const {promise} = store.getState()
|
|
|
+ const {rootCats} = promise
|
|
|
+
|
|
|
+ if (rootCats?.status === 'PENDING') {
|
|
|
+ aside.innerHTML = `
|
|
|
+ <div class="spinner-border text-primary" role="status">
|
|
|
+ <span class="visually-hidden">Loading...</span>
|
|
|
+ </div>
|
|
|
+ `
|
|
|
+ } else {
|
|
|
+ if (rootCats?.payload) {
|
|
|
+
|
|
|
+ aside.innerHTML = ''
|
|
|
+ const regBtn = document.createElement('a')
|
|
|
+ regBtn.href = '#/register'
|
|
|
+ regBtn.classList = 'btn btn-primary'
|
|
|
+ regBtn.innerText = 'Register'
|
|
|
+ const loginBtn = document.createElement('a')
|
|
|
+ loginBtn.href = `#/login`
|
|
|
+ loginBtn.classList = 'btn btn-primary'
|
|
|
+ loginBtn.innerText = 'Login'
|
|
|
+ const logoutBtn = document.createElement('button')
|
|
|
+ logoutBtn.innerText = 'Logout'
|
|
|
+ logoutBtn.classList = 'btn btn-primary'
|
|
|
+ aside.append(regBtn, loginBtn, logoutBtn)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ logoutBtn.onclick = () => {
|
|
|
+ store.dispatch(actionAuthLogout())
|
|
|
+ }
|
|
|
+ for (const {_id, name} of rootCats?.payload) {
|
|
|
+ const link = document.createElement('a')
|
|
|
+ link.href = `#/category/${_id}`
|
|
|
+ link.innerText = name
|
|
|
+ aside.append(link)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
|
|
|
+store.dispatch(actionRootCats())
|
|
|
+
|
|
|
|
|
|
|
|
|
function createForm(parent, type, callback) {
|
|
@@ -391,54 +422,75 @@ function createForm(parent, type, callback) {
|
|
|
|
|
|
|
|
|
const createCartPage = (parent) => {
|
|
|
- parent.innerHTML = '';
|
|
|
- const {cart} = store.getState();
|
|
|
+ parent.innerHTML = ''
|
|
|
+ const {cart} = store.getState()
|
|
|
|
|
|
- const clearBtn = document.createElement('button');
|
|
|
+ const clearBtn = document.createElement('button')
|
|
|
clearBtn.innerText = "ОЧИСТИТЬ КОРЗИНУ";
|
|
|
|
|
|
if(Object.keys(cart).length !== 0) {
|
|
|
- main.append(clearBtn);
|
|
|
+ main.append(clearBtn)
|
|
|
}
|
|
|
clearBtn.onclick = () => {
|
|
|
- store.dispatch(actionCartClear());
|
|
|
+ store.dispatch(actionCartClear())
|
|
|
}
|
|
|
for(const item in cart) {
|
|
|
- const {good} = cart[item];
|
|
|
- const {count, good: {_id: id, name: name, price: price, images: [{url}]}} = cart[item];
|
|
|
- const card = document.createElement('div');
|
|
|
+ const {good} = cart[item]
|
|
|
+ const {count, good: {_id: id, name: name, price: price, images: [{url}]}} = cart[item]
|
|
|
+ const card = document.createElement('div')
|
|
|
card.innerHTML = `
|
|
|
<div>
|
|
|
<p>${name}</p>
|
|
|
<img src="${backURL}/${url}">
|
|
|
- <p>${count}</p>
|
|
|
+ <p>${count} шт</p>
|
|
|
<p>${price} грн</p>
|
|
|
</div>
|
|
|
- `;
|
|
|
+ `
|
|
|
|
|
|
- const changeCount = document.createElement('input');
|
|
|
- changeCount.type = 'number';
|
|
|
- changeCount.value = count;
|
|
|
- card.append(changeCount);
|
|
|
+
|
|
|
+ const minusBtn = document.createElement('button')
|
|
|
+ minusBtn.innerText = '-'
|
|
|
+ card.append(minusBtn)
|
|
|
+ minusBtn.onclick = () => {
|
|
|
+ store.dispatch(actionCartAdd(good, -1))
|
|
|
+ }
|
|
|
+
|
|
|
+ const changeCount = document.createElement('input')
|
|
|
+ changeCount.type = 'number'
|
|
|
+ changeCount.value = count
|
|
|
+ card.append(changeCount)
|
|
|
changeCount.oninput = () => {
|
|
|
store.dispatch(actionCartChange(good, changeCount.value))
|
|
|
- };
|
|
|
+ }
|
|
|
|
|
|
- const deleteGood = document.createElement('button');
|
|
|
- deleteGood.innerText = 'X';
|
|
|
- deleteGood.style.display = 'block';
|
|
|
- card.append(deleteGood);
|
|
|
+ const plusBtn = document.createElement('button')
|
|
|
+ plusBtn.innerText = '+'
|
|
|
+ card.append(plusBtn)
|
|
|
+ plusBtn.onclick = () => {
|
|
|
+ store.dispatch(actionCartAdd(good))
|
|
|
+ }
|
|
|
+
|
|
|
+ const deleteGood = document.createElement('button')
|
|
|
+ deleteGood.innerText = 'Удалить'
|
|
|
+ deleteGood.style.display = 'block'
|
|
|
+ card.append(deleteGood)
|
|
|
deleteGood.onclick = () => {
|
|
|
store.dispatch(actionCartRemove(good))
|
|
|
}
|
|
|
|
|
|
- parent.append(card);
|
|
|
+ parent.append(card)
|
|
|
}
|
|
|
|
|
|
- const sendOrder = document.createElement('button');
|
|
|
- sendOrder.innerText = "ОФОРМИТЬ ЗАКАЗ";
|
|
|
+ const sendOrder = document.createElement('button')
|
|
|
+ sendOrder.innerText = "ОФОРМИТЬ ЗАКАЗ"
|
|
|
if(Object.keys(cart).length !== 0) {
|
|
|
- main.append(sendOrder);
|
|
|
+ main.append(sendOrder)
|
|
|
+ }
|
|
|
+ const {auth} = store.getState()
|
|
|
+ if (auth.token) {
|
|
|
+ sendOrder.disabled = false
|
|
|
+ } else {
|
|
|
+ sendOrder.disabled = true
|
|
|
}
|
|
|
sendOrder.onclick = () => {
|
|
|
store.dispatch(actionOrder())
|
|
@@ -469,11 +521,13 @@ window.onhashchange = () => {
|
|
|
goLogin()
|
|
|
},
|
|
|
orders(){
|
|
|
- store.dispatch(actionGoodsByUser())
|
|
|
+ store.dispatch(actionGoodsByUser(_id))
|
|
|
},
|
|
|
cart(){
|
|
|
createCartPage(main)
|
|
|
- },
|
|
|
+ },
|
|
|
+ find(){
|
|
|
+ },
|
|
|
}
|
|
|
if (route in routes) {
|
|
|
routes[route]()
|
|
@@ -484,7 +538,7 @@ window.onhashchange = () => {
|
|
|
store.subscribe(() => {
|
|
|
const [,route] = location.hash.split('/')
|
|
|
if (route === 'cart') {
|
|
|
- createCartPage(main);
|
|
|
+ createCartPage(main)
|
|
|
}
|
|
|
})
|
|
|
|
|
@@ -495,36 +549,47 @@ store.subscribe(() => {
|
|
|
const {promise} = store.getState()
|
|
|
const {catById} = promise
|
|
|
const [,route, _id] = location.hash.split('/')
|
|
|
- if (catById?.payload && route === 'category'){
|
|
|
- const {name} = catById.payload;
|
|
|
- main.innerHTML = `<h1>${name}</h1>`
|
|
|
-
|
|
|
- if (catById.payload.subCategories) {
|
|
|
- for(const {_id, name} of catById.payload.subCategories) {
|
|
|
- const link = document.createElement('a');
|
|
|
- link.href = `#/category/${_id}`;
|
|
|
- link.innerText = name;
|
|
|
- main.append(link);
|
|
|
- }
|
|
|
- }
|
|
|
+
|
|
|
+ if (catById?.status === 'PENDING') {
|
|
|
+ main.innerHTML = `
|
|
|
+ <div class="d-flex justify-content-center">
|
|
|
+ <div class="spinner-border text-primary" role="status">
|
|
|
+ <span class="visually-hidden">Loading...</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ `
|
|
|
+ } else {
|
|
|
+ if (catById?.payload && route === 'category'){
|
|
|
+ const {name} = catById.payload;
|
|
|
+ main.innerHTML = `<h1>${name}</h1>`
|
|
|
|
|
|
- if (catById.payload.goods) {
|
|
|
- for (const good of catById.payload.goods){
|
|
|
- const {_id, name, price, images} = good
|
|
|
- const card = document.createElement('div')
|
|
|
- card.innerHTML = `<h2>${name}</h2>
|
|
|
- <img src="${backURL}/${images[0].url}" />
|
|
|
- <strong>${price} грн</strong>
|
|
|
- <br>
|
|
|
- <a href="#/good/${_id}">Перейти на страницу товара</a>
|
|
|
- `
|
|
|
- const btnCart = document.createElement('button')
|
|
|
- btnCart.innerText = 'Добавить в корзину'
|
|
|
- btnCart.onclick = () => {
|
|
|
- store.dispatch(actionCartAdd(good))
|
|
|
+ if (catById.payload.subCategories) {
|
|
|
+ for(const {_id, name} of catById.payload.subCategories) {
|
|
|
+ const link = document.createElement('a');
|
|
|
+ link.href = `#/category/${_id}`;
|
|
|
+ link.innerText = name;
|
|
|
+ main.append(link);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (catById.payload.goods) {
|
|
|
+ for (const good of catById.payload.goods){
|
|
|
+ const {_id, name, price, images} = good
|
|
|
+ const card = document.createElement('div')
|
|
|
+ card.innerHTML = `<h2>${name}</h2>
|
|
|
+ <img src="${backURL}/${images[0].url}" />
|
|
|
+ <strong>${price} грн</strong>
|
|
|
+ <br>
|
|
|
+ <a href="#/good/${_id}">Перейти на страницу товара</a>
|
|
|
+ `
|
|
|
+ const btnCart = document.createElement('button')
|
|
|
+ btnCart.innerText = 'Добавить в корзину'
|
|
|
+ btnCart.onclick = () => {
|
|
|
+ store.dispatch(actionCartAdd(good))
|
|
|
+ }
|
|
|
+ card.append(btnCart)
|
|
|
+ main.append(card)
|
|
|
}
|
|
|
- card.append(btnCart)
|
|
|
- main.append(card)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -534,23 +599,34 @@ store.subscribe(() => {
|
|
|
const {promise} = store.getState()
|
|
|
const {goodById} = promise
|
|
|
const [,route, _id] = location.hash.split('/');
|
|
|
- if (goodById?.payload && route === 'good') {
|
|
|
- main.innerHTML = '';
|
|
|
- const good = goodById.payload;
|
|
|
- const {_id, name, images, price, description} = good
|
|
|
- const card = document.createElement('div');
|
|
|
- card.innerHTML = `<h2>${name}</h2>
|
|
|
- <img src="${backURL}/${images[0].url}" />
|
|
|
- <strong>${price} грн</strong>
|
|
|
- <h2>${description}</h2>
|
|
|
- `;
|
|
|
- const btnCart = document.createElement('button')
|
|
|
- btnCart.innerText = 'Добавить в корзину'
|
|
|
- btnCart.onclick = () => {
|
|
|
- store.dispatch(actionCartAdd(good))
|
|
|
+
|
|
|
+ if (goodById?.status === 'PENDING') {
|
|
|
+ main.innerHTML = `
|
|
|
+ <div class="d-flex justify-content-center">
|
|
|
+ <div class="spinner-border text-primary" role="status">
|
|
|
+ <span class="visually-hidden">Loading...</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ `
|
|
|
+ } else {
|
|
|
+ if (goodById?.payload && route === 'good') {
|
|
|
+ main.innerHTML = '';
|
|
|
+ const good = goodById.payload;
|
|
|
+ const {_id, name, images, price, description} = good
|
|
|
+ const card = document.createElement('div');
|
|
|
+ card.innerHTML = `<h2>${name}</h2>
|
|
|
+ <img src="${backURL}/${images[0].url}" />
|
|
|
+ <strong>${price} грн</strong>
|
|
|
+ <h2>${description}</h2>
|
|
|
+ `;
|
|
|
+ const btnCart = document.createElement('button')
|
|
|
+ btnCart.innerText = 'Добавить в корзину'
|
|
|
+ btnCart.onclick = () => {
|
|
|
+ store.dispatch(actionCartAdd(good))
|
|
|
+ }
|
|
|
+ card.append(btnCart)
|
|
|
+ main.append(card);
|
|
|
}
|
|
|
- card.append(btnCart)
|
|
|
- main.append(card);
|
|
|
}
|
|
|
}
|
|
|
)
|
|
@@ -563,7 +639,7 @@ store.subscribe(() => {
|
|
|
topContaner.innerHTML = ''
|
|
|
const {id, login} = payload.sub
|
|
|
const name = document.createElement('div')
|
|
|
- name.innerText = `ПРИВЕТ ${login}`
|
|
|
+ name.innerText = `ПРИВЕТ, ${login}`
|
|
|
topContaner.append(name)
|
|
|
const myOrders = document.createElement('a')
|
|
|
myOrders.innerText = 'Мои заказы'
|
|
@@ -580,37 +656,48 @@ store.subscribe(() => {
|
|
|
const {promise} = store.getState()
|
|
|
const {goodByUser} = promise
|
|
|
const [,route] = location.hash.split('/')
|
|
|
- if (goodByUser?.payload && route === 'orders'){
|
|
|
-
|
|
|
- main.innerHTML = ''
|
|
|
-
|
|
|
- if (goodByUser.payload) {
|
|
|
- let totalMoney = 0
|
|
|
-
|
|
|
- for (const order of goodByUser.payload) {
|
|
|
|
|
|
- if (order.orderGoods) {
|
|
|
- for (const {price, count, total, good} of order.orderGoods) {
|
|
|
- if (price !== null && count !== null && total !== null && good !== null) {
|
|
|
- totalMoney += total
|
|
|
- const {_id, name, images} = good
|
|
|
+ if (goodByUser?.status === 'PENDING') {
|
|
|
+ main.innerHTML = `
|
|
|
+ <div class="d-flex justify-content-center">
|
|
|
+ <div class="spinner-border text-primary" role="status">
|
|
|
+ <span class="visually-hidden">Loading...</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ `
|
|
|
+ } else {
|
|
|
+ if (goodByUser?.payload && route === 'orders'){
|
|
|
|
|
|
- const card = document.createElement('div')
|
|
|
- card.innerHTML = `<h2>${name}</h2>
|
|
|
- <img src="${backURL}/${images[0].url}" />
|
|
|
- <strong>Куплено ${count} по ${price} грн. Итого: ${total} грн</strong>
|
|
|
- <br>
|
|
|
- <a href="#/good/${_id}">Перейти на страницу товара</a>
|
|
|
- `
|
|
|
- main.append(card)
|
|
|
+ main.innerHTML = ''
|
|
|
+
|
|
|
+ if (goodByUser.payload) {
|
|
|
+ let totalMoney = 0
|
|
|
+
|
|
|
+ for (const order of goodByUser.payload) {
|
|
|
+
|
|
|
+ if (order.orderGoods) {
|
|
|
+ for (const {price, count, total, good} of order.orderGoods) {
|
|
|
+ if (price !== null && count !== null && total !== null && good !== null) {
|
|
|
+ totalMoney += total
|
|
|
+ const {_id, name, images} = good
|
|
|
+
|
|
|
+ const card = document.createElement('div')
|
|
|
+ card.innerHTML = `<h2>${name}</h2>
|
|
|
+ <img src="${backURL}/${images[0].url}" />
|
|
|
+ <strong>Куплено ${count} по ${price} грн. Итого: ${total} грн</strong>
|
|
|
+ <br>
|
|
|
+ <a href="#/good/${_id}">Перейти на страницу товара</a>
|
|
|
+ `
|
|
|
+ main.append(card)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
-
|
|
|
+ const totalBlock = document.createElement('b')
|
|
|
+ totalBlock.innerText = 'Итого потрачено: ' + totalMoney + ' грн'
|
|
|
+ main.append(totalBlock)
|
|
|
}
|
|
|
- const totalBlock = document.createElement('b')
|
|
|
- totalBlock.innerText = 'Итого потрачено: ' + totalMoney + ' грн'
|
|
|
- main.append(totalBlock)
|
|
|
}
|
|
|
}
|
|
|
})
|
|
@@ -629,5 +716,49 @@ store.subscribe(() => {
|
|
|
|
|
|
|
|
|
|
|
|
+store.subscribe(() => {
|
|
|
+ const {promise} = store.getState()
|
|
|
+ const {goodFind} = promise
|
|
|
+ const [,route] = location.hash.split('/')
|
|
|
|
|
|
|
|
|
+ if (goodFind?.status === 'PENDING') {
|
|
|
+ main.innerHTML = `
|
|
|
+ <div class="spinner-border text-primary" role="status">
|
|
|
+ <span class="visually-hidden">Loading...</span>
|
|
|
+ </div>
|
|
|
+ `
|
|
|
+ } else {
|
|
|
+ if (goodFind?.payload && route === 'find') {
|
|
|
+
|
|
|
+ if (goodFind?.payload.length > 0) {
|
|
|
+
|
|
|
+ main.innerHTML = ''
|
|
|
+ for (const good of goodFind.payload) {
|
|
|
+ const {_id, name, price, images} = good
|
|
|
+ const card = document.createElement('div')
|
|
|
+ card.innerHTML = `<h2>${name}</h2>
|
|
|
+ <img src="${backURL}/${images[0].url}" />
|
|
|
+ <strong>${price} грн</strong>
|
|
|
+ <br>
|
|
|
+ <a href="#/good/${_id}">Перейти на страницу товара</a>
|
|
|
+ `
|
|
|
+ const btnCart = document.createElement('button')
|
|
|
+ btnCart.innerText = 'Добавить в корзину'
|
|
|
+ btnCart.onclick = () => {
|
|
|
+ store.dispatch(actionCartAdd(good))
|
|
|
+ }
|
|
|
+ card.append(btnCart)
|
|
|
+ main.append(card)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ main.innerHTML = 'Результаты не найдены'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+findField.oninput = () => {
|
|
|
+ window.location.hash = `#/find`
|
|
|
+ store.dispatch(actionGoodFind(findField.value))
|
|
|
+}
|