various bug fixes
Former-commit-id: da0453942ecc85342884748cced864053111e0ff
This commit is contained in:
@@ -61,8 +61,8 @@ export function RemoveProductFromBasket(product, type, amount, brickModifier = '
|
||||
product += '~' + brickModifier;
|
||||
}
|
||||
|
||||
if (basket.items[product] > amount) {
|
||||
basket.items[product] -= amount;
|
||||
if (basket.items[product].quantity > amount) {
|
||||
basket.items[product].quantity -= amount;
|
||||
} else {
|
||||
delete basket.items[product];
|
||||
}
|
||||
@@ -76,6 +76,39 @@ export function RemoveProductFromBasket(product, type, amount, brickModifier = '
|
||||
}
|
||||
}
|
||||
|
||||
export function SetProductInBasket(product, type, amount, brickModifier = 'none') {
|
||||
if (localStorage.getItem('basket') === null || !localStorage.getItem('basket')) {
|
||||
return;
|
||||
}
|
||||
const basket = JSON.parse(localStorage.getItem('basket'));
|
||||
|
||||
if (type === 'brick') {
|
||||
product += '~' + brickModifier;
|
||||
}
|
||||
|
||||
if (amount === 0) {
|
||||
delete basket.items[product];
|
||||
} else {
|
||||
if (basket.items[product]) {
|
||||
basket.total -= basket.items[product].quantity;
|
||||
basket.items[product].quantity = amount;
|
||||
} else {
|
||||
basket.items[product] = {
|
||||
quantity: amount,
|
||||
type,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
basket.total += amount;
|
||||
|
||||
localStorage.setItem('basket', JSON.stringify(basket));
|
||||
|
||||
if (basketCallback) {
|
||||
basketCallback();
|
||||
}
|
||||
}
|
||||
|
||||
export function GetBasketTotal() {
|
||||
if (localStorage.getItem('basket') === null || !localStorage.getItem('basket')) {
|
||||
return 0;
|
||||
@@ -86,8 +119,25 @@ export function GetBasketTotal() {
|
||||
return basket.total;
|
||||
}
|
||||
|
||||
export function GetBasketTotalPrice() {
|
||||
|
||||
export async function GetBasketTotalPrice() {
|
||||
if (localStorage.getItem('basket') === null || !localStorage.getItem('basket')) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const basket = JSON.parse(localStorage.getItem('basket'));
|
||||
|
||||
const res = await fetch('/api/basket/price', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(basket),
|
||||
}).then(res => res.json());
|
||||
|
||||
if (res.error) {
|
||||
return 0;
|
||||
}
|
||||
return res.data.subtotal;
|
||||
}
|
||||
|
||||
class BasketPopout extends Component {
|
||||
@@ -103,19 +153,11 @@ class BasketPopout extends Component {
|
||||
if (basket) {
|
||||
try {
|
||||
const basketJSON = JSON.parse(basket);
|
||||
|
||||
const res = await fetch('/api/basket/price', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(basketJSON),
|
||||
}).then(res => res.json());
|
||||
|
||||
const subtotal = await GetBasketTotalPrice();
|
||||
this.setState({
|
||||
items: basketJSON.items,
|
||||
total: basketJSON.total,
|
||||
subtotal: res.data.subtotal,
|
||||
subtotal,
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AddProductToBasket, GetBasketTotal, RemoveProductFromBasket } from './basket-popout.mjs';
|
||||
import { AddProductToBasket, SetProductInBasket, RemoveProductFromBasket, GetBasketTotal, GetBasketTotalPrice } from './basket-popout.mjs';
|
||||
import { RegisterComponent, Component } from './components.mjs';
|
||||
|
||||
class Basket extends Component {
|
||||
@@ -32,7 +32,7 @@ class Basket extends Component {
|
||||
Your Basket
|
||||
</div>
|
||||
<div class="basket-header-total">
|
||||
Total: {this.state.total} items
|
||||
Total: <span class="basket-total">{this.state.total}</span> items
|
||||
</div>
|
||||
</div>
|
||||
<div class="basket-items">
|
||||
@@ -60,6 +60,13 @@ class Basket extends Component {
|
||||
`;
|
||||
}).join('')}
|
||||
</div>
|
||||
<div class="basket-footer">
|
||||
<!-- subtotal -->
|
||||
<div class="basket-footer-subtotal">
|
||||
Subtotal: £<span class="basket-subtotal">0.00</span>
|
||||
</div>
|
||||
<button class="basket-footer-button" type="button">Checkout</button>
|
||||
<button class="basket-footer-button" type="button">Checkout As Guest</button>
|
||||
</div>
|
||||
`,
|
||||
style: `
|
||||
@@ -137,7 +144,16 @@ class Basket extends Component {
|
||||
};
|
||||
}
|
||||
|
||||
async UpdateSubtotal() {
|
||||
const subtotal = await GetBasketTotalPrice();
|
||||
const basketSubtotal = this.root.querySelector('.basket-subtotal');
|
||||
if (basketSubtotal) {
|
||||
basketSubtotal.innerText = parseFloat(subtotal).toFixed(2);
|
||||
}
|
||||
}
|
||||
|
||||
OnRender() {
|
||||
this.UpdateSubtotal();
|
||||
this.root.querySelectorAll('.basket-item-listing').forEach((listing) => {
|
||||
// listen to mutations on the attribute stock because the stock is updated once the
|
||||
// super compact listing is loaded and the stock is updated
|
||||
@@ -158,7 +174,6 @@ class Basket extends Component {
|
||||
...this.state,
|
||||
}, false);
|
||||
}
|
||||
|
||||
// update the stock number
|
||||
const stockNumber = mutation.target.parentElement.querySelector('.stock-number');
|
||||
stockNumber.innerText = stock;
|
||||
@@ -173,6 +188,7 @@ class Basket extends Component {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// set up each button to update the quantity and remove if it is zero
|
||||
this.root.querySelectorAll('.product-quantity-button').forEach((button) => {
|
||||
button.addEventListener('click', (event) => {
|
||||
@@ -197,7 +213,16 @@ class Basket extends Component {
|
||||
}
|
||||
if (item.quantity === 0) {
|
||||
RemoveProductFromBasket(id, item.type, item.quantity, modifier);
|
||||
this.UpdateSubtotal();
|
||||
delete this.state.items[compositeId];
|
||||
|
||||
return this.setState({
|
||||
...this.state,
|
||||
total: GetBasketTotal(),
|
||||
items: {
|
||||
...this.state.items,
|
||||
},
|
||||
});
|
||||
}
|
||||
} else if (event.target.classList.contains('increase-quantity')) {
|
||||
if (item.quantity < item.stock) {
|
||||
@@ -206,7 +231,16 @@ class Basket extends Component {
|
||||
}
|
||||
} else if (event.target.classList.contains('remove-quantity')) {
|
||||
RemoveProductFromBasket(id, item.type, item.quantity, modifier);
|
||||
this.UpdateSubtotal();
|
||||
delete this.state.items[compositeId];
|
||||
|
||||
return this.setState({
|
||||
...this.state,
|
||||
total: GetBasketTotal(),
|
||||
items: {
|
||||
...this.state.items,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// update the total
|
||||
@@ -217,7 +251,72 @@ class Basket extends Component {
|
||||
...this.state.items,
|
||||
[compositeId]: item,
|
||||
},
|
||||
});
|
||||
}, false);
|
||||
|
||||
// update the total so it doesn't need to be rendered again
|
||||
const total = this.root.querySelector('.basket-total');
|
||||
total.innerText = this.state.total;
|
||||
// and the same on the item
|
||||
const itemTotal = clickedItem.querySelector('.quantity-input');
|
||||
itemTotal.value = parseInt(item.quantity);
|
||||
this.UpdateSubtotal();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// do the same but with the input field
|
||||
this.root.querySelectorAll('.quantity-input').forEach((input) => {
|
||||
input.addEventListener('change', (event) => {
|
||||
let clickedItem = event.target.parentElement;
|
||||
let listing = clickedItem.querySelector('.basket-item-listing');
|
||||
if (!listing) {
|
||||
clickedItem = clickedItem.parentElement;
|
||||
listing = clickedItem.querySelector('.basket-item-listing');
|
||||
}
|
||||
|
||||
const id = listing.getAttribute('id');
|
||||
const modifier = listing.getAttribute('modifier');
|
||||
const compositeId = id + (modifier ? `~${modifier}` : '');
|
||||
const item = this.state.items[compositeId];
|
||||
|
||||
// update the quantity
|
||||
if (event.target.value < 0) {
|
||||
event.target.value = 0;
|
||||
}
|
||||
if (event.target.value > item.stock) {
|
||||
event.target.value = item.stock;
|
||||
}
|
||||
item.quantity = parseInt(event.target.value);
|
||||
|
||||
SetProductInBasket(id, item.type, item.quantity, modifier);
|
||||
this.UpdateSubtotal();
|
||||
|
||||
if (item.quantity === 0) {
|
||||
delete this.state.items[compositeId];
|
||||
|
||||
return this.setState({
|
||||
...this.state,
|
||||
total: GetBasketTotal(),
|
||||
items: {
|
||||
...this.state.items,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// update the total
|
||||
this.setState({
|
||||
...this.state,
|
||||
total: GetBasketTotal(),
|
||||
items: {
|
||||
...this.state.items,
|
||||
[compositeId]: item,
|
||||
},
|
||||
}, false);
|
||||
|
||||
|
||||
// update the total so it doesn't need to be rendered again
|
||||
const total = this.root.querySelector('.basket-total');
|
||||
total.innerText = this.state.total;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -110,7 +110,6 @@ async function SumPrices(setsArray, quantityArray) {
|
||||
}
|
||||
|
||||
let sum = 0;
|
||||
console.log(dbres);
|
||||
for (let i = 0; i < dbres.rows.length; i++) {
|
||||
sum += parseFloat(dbres.rows[i].price) * parseFloat(quantityArray[i]);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,18 @@ function getFormatedTimeString() {
|
||||
// levelSource is the level that the source will log at ie, if levelSource is
|
||||
// LEVEL_WARN, it will only log if the current level is at or above LEVEL_WARN.
|
||||
function internalLog(type, message, cConsoleColour, levelSource) {
|
||||
message = [message].map(x => {
|
||||
if (typeof x === 'object') {
|
||||
return JSON.stringify(x);
|
||||
}
|
||||
|
||||
if (Array.isArray(x)) {
|
||||
return x.join(' ');
|
||||
}
|
||||
|
||||
return x;
|
||||
}).join(' ');
|
||||
|
||||
if (Options.logToConsole && (Options.logLevel <= levelSource)) {
|
||||
console.log(`${getFormatedTimeString()} [${cConsoleColour(type)}] ${message}`);
|
||||
}
|
||||
@@ -48,14 +60,18 @@ function internalLog(type, message, cConsoleColour, levelSource) {
|
||||
}
|
||||
}
|
||||
|
||||
const Info = (...messages) => internalLog('INFO', messages.join(' '), clc.greenBright, LEVEL_INFO);
|
||||
const Warn = (...messages) => internalLog('WARN', messages.join(' '), clc.yellowBright, LEVEL_WARN);
|
||||
const Error = (...messages) => internalLog('ERROR', messages.join(' '), clc.redBright, LEVEL_STICK);
|
||||
const Panic = (...messages) => internalLog('PANIC', messages.join(' '), clc.bgRedBright, LEVEL_STICK);
|
||||
const Debug = (...messages) => internalLog('DEBUG', messages.join(' '), clc.cyanBright, LEVEL_DEBUG);
|
||||
const Info = (...messages) => internalLog('INFO', messages, clc.greenBright, LEVEL_INFO);
|
||||
const Warn = (...messages) => internalLog('WARN', messages, clc.yellowBright, LEVEL_WARN);
|
||||
const Error = (...messages) => internalLog('ERROR', messages, clc.redBright, LEVEL_STICK);
|
||||
const Panic = (...messages) => internalLog('PANIC', messages, clc.bgRedBright, LEVEL_STICK);
|
||||
const Debug = (...messages) => internalLog('DEBUG', messages, clc.cyanBright, LEVEL_DEBUG);
|
||||
const Module = (module, ...messages) => internalLog(`MODULE [${module}]`, ` ${messages.join(' ')}`, clc.blue, LEVEL_INFO);
|
||||
const Database = (...messages) => internalLog('PSQL', `[DB] ${messages.join(' ')}`, clc.blue, LEVEL_INFO);
|
||||
const ExpressLogger = (req, res, next) => {
|
||||
// don't spam the console with 1000000 bloody requests for thumbnails
|
||||
if (req.originalUrl.startsWith('/api/cdn/')) {
|
||||
return next();
|
||||
}
|
||||
internalLog('HTTP', `[${req.method}] ${req.originalUrl} FROM ${req.headers['x-forwarded-for'] || req.socket.remoteAddress}`, clc.magenta, LEVEL_VERBOSE);
|
||||
next();
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const BrickController = require('../controllers/brick-controller.js');
|
||||
const SetController = require('../controllers/set-controller.js');
|
||||
const Logger = require('../logger.js');
|
||||
|
||||
// AppEng Deadline
|
||||
const EndDate = new Date(1651269600 * 1000);
|
||||
@@ -37,12 +38,20 @@ async function CalculateBasketPrice(req, res) {
|
||||
}
|
||||
}
|
||||
|
||||
let setSubtotal = await SetController.SumPrices(setList, setQuantities);
|
||||
let brickSubtotal = await BrickController.SumPrices(brickList, brickQuantities);
|
||||
Logger.Debug(`Set list: ${setList} Brick list: ${brickList}`);
|
||||
let setSubtotal = setList > 0
|
||||
? await SetController.SumPrices(setList, setQuantities)
|
||||
: 0;
|
||||
let brickSubtotal = brickList > 0
|
||||
? await BrickController.SumPrices(brickList, brickQuantities)
|
||||
: 0;
|
||||
|
||||
|
||||
if (setSubtotal.error) setSubtotal = 0;
|
||||
if (brickSubtotal.error) brickSubtotal = 0;
|
||||
|
||||
Logger.Debug(`Set subtotal: ${setSubtotal} Brick subtotal: ${brickSubtotal} Total: ${parseFloat(setSubtotal) + parseFloat(brickSubtotal)}`);
|
||||
|
||||
res.send({
|
||||
data: {
|
||||
subtotal: parseFloat(setSubtotal) + parseFloat(brickSubtotal),
|
||||
|
||||
Reference in New Issue
Block a user