|
@@ -98,10 +98,17 @@ const actionAuthLogout = () => ({type: 'AUTH_LOGOUT'})
|
|
|
|
|
|
|
|
|
function cartReducer (state={}, {type, good={}, count=1}) {
|
|
|
- if (!state) {
|
|
|
- return {}
|
|
|
- }
|
|
|
|
|
|
+ // if (!state) {
|
|
|
+ // return {}
|
|
|
+ // }
|
|
|
+ if (Object.keys(state).length === 0) {
|
|
|
+ let currCart = JSON.parse(localStorage.cart)
|
|
|
+ if (currCart && Object.keys(currCart).length !== 0) {
|
|
|
+ state = currCart
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// только если в функции задан count по умолчанию вызывать тут
|
|
|
// а так лучше вызвать в типах add и change
|
|
|
// count = +count
|
|
@@ -117,30 +124,36 @@ function cartReducer (state={}, {type, good={}, count=1}) {
|
|
|
if (!count) {
|
|
|
return state
|
|
|
}
|
|
|
- return {
|
|
|
+ let newState = {
|
|
|
...state,
|
|
|
[_id]: {good, count: (count + (state[_id]?.count || 0)) < 0 ? 0 : count + (state[_id]?.count || 0)}
|
|
|
}
|
|
|
+ localStorage.cart = JSON.stringify(newState)
|
|
|
+ return newState
|
|
|
},
|
|
|
CART_CHANGE() {
|
|
|
count = +count
|
|
|
if (!count) {
|
|
|
return state
|
|
|
}
|
|
|
- return {
|
|
|
+ let newState = {
|
|
|
...state,
|
|
|
[_id]: {good, count: count < 0 ? 0 : count}
|
|
|
}
|
|
|
+ localStorage.cart = JSON.stringify(newState)
|
|
|
+ return newState
|
|
|
},
|
|
|
CART_REMOVE() {
|
|
|
let { [_id]: removed, ...newState } = state
|
|
|
+ localStorage.cart = JSON.stringify(newState)
|
|
|
return newState
|
|
|
},
|
|
|
CART_CLEAR() {
|
|
|
+ localStorage.cart = JSON.stringify({})
|
|
|
return {}
|
|
|
},
|
|
|
}
|
|
|
- if (type in types) {
|
|
|
+ if (type in types) {
|
|
|
return types[type]()
|
|
|
}
|
|
|
return state
|
|
@@ -412,9 +425,17 @@ store.dispatch(actionRootCats())
|
|
|
|
|
|
function createForm(parent, type, callback) {
|
|
|
parent.innerHTML = `
|
|
|
- <input id="login${type}" type="text"/>
|
|
|
- <input id="pass${type}" type="password"/>
|
|
|
- <button id="btn${type}">${type}</button>
|
|
|
+ <div class="form">
|
|
|
+ <div class="mb-3">
|
|
|
+ <label for="login${type}" class="form-label">Логин</label>
|
|
|
+ <input class="form-input form-control" id="login${type}" type="text"/>
|
|
|
+ </div>
|
|
|
+ <div class="mb-3">
|
|
|
+ <label for="pass${type}" class="form-label">Пароль</label>
|
|
|
+ <input class="form-input form-control" id="pass${type}" type="password"/>
|
|
|
+ </div>
|
|
|
+ <button class="btn btn-primary" id="btn${type}">${type}</button>
|
|
|
+ </div>
|
|
|
`
|
|
|
return () => window[`btn${type}`].onclick = () => {
|
|
|
store.dispatch(callback(window[`login${type}`].value, window[`pass${type}`].value))
|
|
@@ -429,31 +450,49 @@ const createCartPage = (parent) => {
|
|
|
const {cart} = store.getState()
|
|
|
|
|
|
const clearBtn = document.createElement('button')
|
|
|
- clearBtn.innerText = "ОЧИСТИТЬ КОРЗИНУ";
|
|
|
+ clearBtn.classList = 'btn btn-primary cartBtn'
|
|
|
+ clearBtn.innerText = "ОЧИСТИТЬ КОРЗИНУ"
|
|
|
|
|
|
if(Object.keys(cart).length !== 0) {
|
|
|
- main.append(clearBtn)
|
|
|
+ parent.append(clearBtn)
|
|
|
}
|
|
|
clearBtn.onclick = () => {
|
|
|
store.dispatch(actionCartClear())
|
|
|
}
|
|
|
+
|
|
|
+ const cartPage = document.createElement('div')
|
|
|
+ cartPage.classList = 'cartPage'
|
|
|
+ parent.append(cartPage)
|
|
|
+
|
|
|
+ let cartCounter = 0
|
|
|
for(const item in cart) {
|
|
|
const {good} = cart[item]
|
|
|
const {count, good: {_id: id, name: name, price: price, images: [{url}]}} = cart[item]
|
|
|
+
|
|
|
+ cartCounter += count*price
|
|
|
+
|
|
|
const card = document.createElement('div')
|
|
|
+ card.classList = 'card cartCard'
|
|
|
card.innerHTML = `
|
|
|
- <div>
|
|
|
- <p>${name}</p>
|
|
|
- <img src="${backURL}/${url}">
|
|
|
- <p>${count} шт</p>
|
|
|
- <p>${price} грн</p>
|
|
|
- </div>
|
|
|
- `
|
|
|
-
|
|
|
+ <div class="card-header">
|
|
|
+ <h4 class="card-title">${name}</h4>
|
|
|
+ </div>
|
|
|
+ <img class="card-img-top" src="${backURL}/${url}" />
|
|
|
+ <div class="card-body">
|
|
|
+ <p>${count} шт</p>
|
|
|
+ <p>${price} грн</p>
|
|
|
+ <h6>Итого: ${count*price} грн</h6>
|
|
|
+ </div>
|
|
|
+ `
|
|
|
+
|
|
|
+ const inputGr = document.createElement('div')
|
|
|
+ inputGr.classList = 'inputGr'
|
|
|
+ card.lastElementChild.append(inputGr)
|
|
|
|
|
|
const minusBtn = document.createElement('button')
|
|
|
+ minusBtn.classList = 'btn btn-success'
|
|
|
minusBtn.innerText = '-'
|
|
|
- card.append(minusBtn)
|
|
|
+ inputGr.append(minusBtn)
|
|
|
minusBtn.onclick = () => {
|
|
|
store.dispatch(actionCartAdd(good, -1))
|
|
|
}
|
|
@@ -461,33 +500,41 @@ const createCartPage = (parent) => {
|
|
|
const changeCount = document.createElement('input')
|
|
|
changeCount.type = 'number'
|
|
|
changeCount.value = count
|
|
|
- card.append(changeCount)
|
|
|
+ inputGr.append(changeCount)
|
|
|
changeCount.oninput = () => {
|
|
|
store.dispatch(actionCartChange(good, changeCount.value))
|
|
|
}
|
|
|
|
|
|
const plusBtn = document.createElement('button')
|
|
|
+ plusBtn.classList = 'btn btn-success'
|
|
|
plusBtn.innerText = '+'
|
|
|
- card.append(plusBtn)
|
|
|
+ inputGr.append(plusBtn)
|
|
|
plusBtn.onclick = () => {
|
|
|
store.dispatch(actionCartAdd(good))
|
|
|
}
|
|
|
|
|
|
const deleteGood = document.createElement('button')
|
|
|
+ deleteGood.classList = 'btn btn-success'
|
|
|
deleteGood.innerText = 'Удалить'
|
|
|
deleteGood.style.display = 'block'
|
|
|
- card.append(deleteGood)
|
|
|
+ card.lastElementChild.append(deleteGood)
|
|
|
deleteGood.onclick = () => {
|
|
|
store.dispatch(actionCartRemove(good))
|
|
|
}
|
|
|
|
|
|
- parent.append(card)
|
|
|
+ cartPage.append(card)
|
|
|
}
|
|
|
|
|
|
+ const total = document.createElement('h5')
|
|
|
+ total.classList = 'totalCart'
|
|
|
+ total.innerText = `Всего к оплате: ${cartCounter} грн`
|
|
|
+ parent.append(total)
|
|
|
+
|
|
|
const sendOrder = document.createElement('button')
|
|
|
+ sendOrder.classList = 'btn btn-primary cartBtn'
|
|
|
sendOrder.innerText = "ОФОРМИТЬ ЗАКАЗ"
|
|
|
if(Object.keys(cart).length !== 0) {
|
|
|
- main.append(sendOrder)
|
|
|
+ parent.append(sendOrder)
|
|
|
}
|
|
|
const {auth} = store.getState()
|
|
|
if (auth.token) {
|
|
@@ -509,11 +556,9 @@ window.onhashchange = () => {
|
|
|
const routes = {
|
|
|
category(){
|
|
|
store.dispatch(actionCatById(_id))
|
|
|
- console.log('страница категорий')
|
|
|
},
|
|
|
good(){
|
|
|
store.dispatch(actionGoodById(_id))
|
|
|
- console.log('страница товара')
|
|
|
},
|
|
|
register(){
|
|
|
let goRegister = createForm(main, 'Register', actionFullRegister)
|
|
@@ -561,37 +606,56 @@ store.subscribe(() => {
|
|
|
</div>
|
|
|
</div>
|
|
|
`
|
|
|
- } else {
|
|
|
- if (catById?.payload && route === 'category'){
|
|
|
+ } else {
|
|
|
+ if (catById?.payload && route === 'category'){
|
|
|
+ main.innerHTML = ''
|
|
|
+ const catBody = document.createElement('div')
|
|
|
+ catBody.classList = 'catBody'
|
|
|
+ main.append(catBody)
|
|
|
+
|
|
|
const {name} = catById.payload;
|
|
|
- main.innerHTML = `<h1>${name}</h1>`
|
|
|
+ catBody.innerHTML = `<h1 class="catHead">${name}</h1>`
|
|
|
|
|
|
if (catById.payload.subCategories) {
|
|
|
+ const linkList = document.createElement('div')
|
|
|
+ linkList.classList = 'list-group linkList'
|
|
|
+ catBody.append(linkList)
|
|
|
+
|
|
|
for(const {_id, name} of catById.payload.subCategories) {
|
|
|
- const link = document.createElement('a');
|
|
|
- link.href = `#/category/${_id}`;
|
|
|
- link.innerText = name;
|
|
|
- main.append(link);
|
|
|
+ const link = document.createElement('a')
|
|
|
+ link.classList = 'list-group-item list-group-item-action list-group-item-primary linkItem'
|
|
|
+ link.href = `#/category/${_id}`
|
|
|
+ link.innerText = name
|
|
|
+ catBody.append(link)
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (catById.payload.goods) {
|
|
|
+ const cardBody = document.createElement('div')
|
|
|
+ cardBody.classList = 'cardBody'
|
|
|
+ main.append(cardBody)
|
|
|
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>
|
|
|
+ card.classList = 'card goodCard'
|
|
|
+ card.innerHTML = `
|
|
|
+ <img class="card-img-top" src="${backURL}/${images[0].url}" />
|
|
|
+ <div class="card-body">
|
|
|
+ <h4 class="card-title">${name}</h4>
|
|
|
+ <h5>${price} грн</h5>
|
|
|
+ <a class="btn btn-primary" href="#/good/${_id}">
|
|
|
+ Подробнее
|
|
|
+ </a>
|
|
|
+ </div>
|
|
|
`
|
|
|
const btnCart = document.createElement('button')
|
|
|
- btnCart.innerText = 'Добавить в корзину'
|
|
|
+ btnCart.innerText = 'В корзину'
|
|
|
+ btnCart.classList = 'btn btn-success btnCart'
|
|
|
btnCart.onclick = () => {
|
|
|
store.dispatch(actionCartAdd(good))
|
|
|
}
|
|
|
- card.append(btnCart)
|
|
|
- main.append(card)
|
|
|
+ card.lastElementChild.append(btnCart)
|
|
|
+ cardBody.append(card)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -613,17 +677,21 @@ store.subscribe(() => {
|
|
|
`
|
|
|
} else {
|
|
|
if (goodById?.payload && route === 'good') {
|
|
|
- main.innerHTML = '';
|
|
|
- const good = goodById.payload;
|
|
|
+ main.innerHTML = ''
|
|
|
+ const good = goodById.payload
|
|
|
const {_id, name, images, price, description} = good
|
|
|
- const card = document.createElement('div');
|
|
|
+ const card = document.createElement('div')
|
|
|
+ card.classList = 'goodPage'
|
|
|
card.innerHTML = `<h2>${name}</h2>
|
|
|
<img src="${backURL}/${images[0].url}" />
|
|
|
- <strong>${price} грн</strong>
|
|
|
- <h2>${description}</h2>
|
|
|
- `;
|
|
|
+ <div>
|
|
|
+ <h6>${description}</h6>
|
|
|
+ <strong>Цена - ${price} грн</strong>
|
|
|
+ </div>
|
|
|
+ `
|
|
|
const btnCart = document.createElement('button')
|
|
|
- btnCart.innerText = 'Добавить в корзину'
|
|
|
+ btnCart.innerText = 'В корзину'
|
|
|
+ btnCart.classList = 'btn btn-success btnCart'
|
|
|
btnCart.onclick = () => {
|
|
|
store.dispatch(actionCartAdd(good))
|
|
|
}
|
|
@@ -672,6 +740,9 @@ store.subscribe(() => {
|
|
|
if (goodByUser?.payload && route === 'orders'){
|
|
|
|
|
|
main.innerHTML = ''
|
|
|
+ const cardBody = document.createElement('div')
|
|
|
+ cardBody.classList = 'cardBody'
|
|
|
+ main.append(cardBody)
|
|
|
|
|
|
if (goodByUser.payload) {
|
|
|
let totalMoney = 0
|
|
@@ -679,25 +750,37 @@ store.subscribe(() => {
|
|
|
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)
|
|
|
+ card.classList = 'card goodCard'
|
|
|
+ card.innerHTML = `
|
|
|
+ <img class="card-img-top" src="${backURL}/${images[0].url}" />
|
|
|
+ <div class="card-body">
|
|
|
+ <h4 class="card-title">${name}</h4>
|
|
|
+ <h6>
|
|
|
+ Куплено: ${count} по ${price} грн.
|
|
|
+ </h6>
|
|
|
+ <h6>
|
|
|
+ Итого: ${total} грн
|
|
|
+ </h6>
|
|
|
+ <a class="btn btn-primary" href="#/good/${_id}">
|
|
|
+ Подробнее
|
|
|
+ </a>
|
|
|
+ </div>
|
|
|
+ `
|
|
|
+ cardBody.append(card)
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
- const totalBlock = document.createElement('b')
|
|
|
+ const totalBlock = document.createElement('h3')
|
|
|
totalBlock.innerText = 'Итого потрачено: ' + totalMoney + ' грн'
|
|
|
main.append(totalBlock)
|
|
|
}
|
|
@@ -714,11 +797,10 @@ store.subscribe(() => {
|
|
|
for (const key in cart) {
|
|
|
counter += cart[key].count
|
|
|
}
|
|
|
- cartIcon.innerText = counter
|
|
|
+ cartCounter.innerText = counter
|
|
|
})
|
|
|
|
|
|
|
|
|
-
|
|
|
store.subscribe(() => {
|
|
|
const {promise} = store.getState()
|
|
|
const {goodFind} = promise
|
|
@@ -731,28 +813,37 @@ store.subscribe(() => {
|
|
|
<span class="visually-hidden">Loading...</span>
|
|
|
</div>
|
|
|
`
|
|
|
- } else {
|
|
|
+ } else {
|
|
|
if (goodFind?.payload && route === 'find') {
|
|
|
+ main.innerHTML = ''
|
|
|
+ if (goodFind?.payload.length > 0) {
|
|
|
+
|
|
|
+ const cardBody = document.createElement('div')
|
|
|
+ cardBody.classList = 'cardBody'
|
|
|
+ main.append(cardBody)
|
|
|
|
|
|
- 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>
|
|
|
+ card.classList = 'card goodCard'
|
|
|
+ card.innerHTML = `
|
|
|
+ <img class="card-img-top" src="${backURL}/${images[0].url}" />
|
|
|
+ <div class="card-body">
|
|
|
+ <h4 class="card-title">${name}</h4>
|
|
|
+ <h5>${price} грн</h5>
|
|
|
+ <a class="btn btn-primary" href="#/good/${_id}">
|
|
|
+ Подробнее
|
|
|
+ </a>
|
|
|
+ </div>
|
|
|
`
|
|
|
const btnCart = document.createElement('button')
|
|
|
- btnCart.innerText = 'Добавить в корзину'
|
|
|
+ btnCart.innerText = 'В корзину'
|
|
|
+ btnCart.classList = 'btn btn-success btnCart'
|
|
|
btnCart.onclick = () => {
|
|
|
store.dispatch(actionCartAdd(good))
|
|
|
}
|
|
|
- card.append(btnCart)
|
|
|
- main.append(card)
|
|
|
+ card.lastElementChild.append(btnCart)
|
|
|
+ cardBody.append(card)
|
|
|
}
|
|
|
} else {
|
|
|
main.innerHTML = 'Результаты не найдены'
|