various bug fixes

Former-commit-id: da0453942ecc85342884748cced864053111e0ff
This commit is contained in:
Ben
2022-04-26 20:37:25 +01:00
parent 12d1df4f54
commit df78a9a6e6
6 changed files with 191 additions and 26 deletions

BIN
README.md

Binary file not shown.

View File

@@ -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);

View File

@@ -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;
});
});
}

View File

@@ -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]);
}

View File

@@ -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();
};

View File

@@ -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),