From 87cc21d9c655da07e79c3452092637db9f61a095 Mon Sep 17 00:00:00 2001
From: Ben <36240171+benkyd@users.noreply.github.com>
Date: Tue, 26 Apr 2022 17:42:57 +0100
Subject: [PATCH] ampersand search query bug fix
Former-commit-id: 5b72eeabea7458d1bcbc13f9642b39350b1b3267
---
client/public/components/basket.mjs | 182 ++++++++++++++++--
client/public/components/product-listing.mjs | 3 +-
client/public/components/search.mjs | 8 +-
.../components/super-compact-listing.mjs | 9 +-
client/public/components/tag.mjs | 2 +-
.../public/components/templates/navbar.html | 2 +-
client/public/search/index.html | 4 +-
src/controllers/controller-master.js | 2 +-
src/routes/helpers.js | 7 +
9 files changed, 193 insertions(+), 26 deletions(-)
diff --git a/client/public/components/basket.mjs b/client/public/components/basket.mjs
index 25de764..3b473f2 100644
--- a/client/public/components/basket.mjs
+++ b/client/public/components/basket.mjs
@@ -14,35 +14,189 @@ class Basket extends Component {
this.setState({
...basketItems,
}, false);
- console.log(basketItems, this.state);
+ } else {
+ this.setState({
+ items: {},
+ total: 0,
+ }, false);
}
-
}
Render() {
return {
template: /* html */`
- {this.state.name}
+
+
+
+
+ ${Object.keys(this.state.items).map((key) => {
+ const item = this.state.items[key];
+ console.log(key, item);
+ const modifier = key.includes('~');
+ return /* html */`
+
+
+
+
+
+
+
+ 0 in stock
+
+
+
+ `;
+ }).join('')}
+
+
`,
style: `
- .tag {
- font-size: 0.8em;
- padding: 0.2em 0.5em;
- margin-right: 0.3em;
- margin-top: 0.2em;
- margin-bottom: 0.2em;
- line-height: 1.3em;
- font-weight: bold;
- background-color: #F2CA52;
+ .basket {
+ padding-top: 10px;
+ }
+
+ .basket-header {
+ display: flex;
+ font-size: 2em;
+ justify-content: space-between;
+ align-items: center;
+ padding: 10px;
+ border-bottom: 1px solid #ccc;
+ }
+
+ .basket-item {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ }
+
+ .basket-item-listing {
+ width: 100%;
+ margin: 0 auto;
+ font-size: 1.3em;
+ }
+
+ .product-quantity-selector {
+ flex-basis: 40%;
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;
+ font-size: 1em;
+ }
+
+ .product-quantity-button {
cursor: pointer;
+ font-size: 1.7em;
+ border: #1A1A1A solid 1px;
+ background-color: #F5F6F6;
+ border-radius: 0.2em;
+ width: 1.5em;
+ height: 1.5em;
+ }
+
+ .remove-quantity {
+ font-size: 1em;
+ width: fit-content;
+ }
+
+ /* https://www.w3schools.com/howto/howto_css_hide_arrow_number.asp */
+ input::-webkit-outer-spin-button,
+ input::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+ }
+ input[type=number] {
+ -moz-appearance: textfield;
+ }
+
+ .quantity-input {
+ height: 2.2em;
+ width: 3.7em;
+ background-color: #F5F6F6;
+ border-top: #1A1A1A solid 1px;
+ border-bottom: #1A1A1A solid 1px;
+ border-right: none;
+ border-left: none;
+ text-align: center;
+ font-size: 1.2em;
}
`,
};
}
OnRender() {
- this.root.addEventListener('click', () => {
- this.root.classList.toggle('tag-selected');
+ 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
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ if (mutation.attributeName === 'stock') {
+ const stock = parseInt(mutation.target.getAttribute('stock'));
+
+ // update the stock number
+ const stockNumber = mutation.target.parentElement.querySelector('.stock-number');
+ stockNumber.innerText = stock;
+ const stockMax = mutation.target.parentElement.querySelector('.quantity-input');
+ stockMax.setAttribute('max', stock);
+ }
+ });
+ });
+ observer.observe(listing, {
+ attributes: true,
+ attributeFilter: ['stock'],
+ });
+ });
+
+ // 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) => {
+ const item = event.target.parentElement.parentElement;
+ const id = item.getAttribute('id');
+ const type = item.getAttribute('type');
+ const modifier = item.getAttribute('modifier');
+ const quantity = parseInt(item.querySelector('.quantity-input').value);
+ const stock = parseInt(item.querySelector('.stock-number').innerText);
+
+ // update the quantity
+ if (event.target.classList.contains('reduce-quantity')) {
+ if (quantity > 0) {
+ item.querySelector('.quantity-input').value = quantity - 1;
+ }
+ } else if (event.target.classList.contains('increase-quantity')) {
+ if (quantity < stock) {
+ item.querySelector('.quantity-input').value = quantity + 1;
+ }
+ } else if (event.target.classList.contains('remove-quantity')) {
+ // remove the item from the basket
+ // delete this.state.items[id];
+ // this.setState({
+ // items: this.state.items,
+ // }, true);
+ }
+
+ // update the total
+ this.setState({
+ total: Object.keys(this.state.items).reduce((total, key) => {
+ const item = this.state.items[key];
+ return total + (item.quantity * item.price);
+ }, 0),
+ }, true);
+
+ // update the basket in local storage
+ // localStorage.setItem('basket', JSON.stringify(this.state));
+ });
});
}
}
diff --git a/client/public/components/product-listing.mjs b/client/public/components/product-listing.mjs
index 1254470..5b8e46d 100644
--- a/client/public/components/product-listing.mjs
+++ b/client/public/components/product-listing.mjs
@@ -111,8 +111,7 @@ class ProductListing extends Component {
`;
}
-
- console.log(this.state);
+
return {
template: /* html */`
diff --git a/client/public/components/search.mjs b/client/public/components/search.mjs
index c885dc5..ec1dd37 100644
--- a/client/public/components/search.mjs
+++ b/client/public/components/search.mjs
@@ -118,6 +118,8 @@ class Search extends Component {
return;
}
+ value = encodeURIComponent(value);
+
const route = `/api/search?q=${value}&per_page=10`;
fetch(route).then((response) => {
return response.json();
@@ -148,8 +150,10 @@ class Search extends Component {
if (e.keyCode === 13) {
const searchTerm = e.target.value;
- if (searchTerm.length > 0) {
- window.location.href = `/search?q=${searchTerm}`;
+ const encodedSearchTerm = encodeURIComponent(searchTerm);
+
+ if (encodedSearchTerm.length > 0) {
+ window.location.href = `/search?q=${encodedSearchTerm}`;
}
}
});
diff --git a/client/public/components/super-compact-listing.mjs b/client/public/components/super-compact-listing.mjs
index e915e68..cf5b5fb 100644
--- a/client/public/components/super-compact-listing.mjs
+++ b/client/public/components/super-compact-listing.mjs
@@ -1,7 +1,6 @@
import { RegisterComponent, Component } from './components.mjs';
// super compact listing is interoperable through types which makes it exteremeely poggers and also portable
-
class SuperCompactProductListing extends Component {
static __IDENTIFY() { return 'super-compact-listing'; }
@@ -18,6 +17,8 @@ class SuperCompactProductListing extends Component {
const tags = product.tags;
const colours = product.colours;
+ this.setAttribute('stock', product.stock);
+
this.setState({
...this.getState,
name,
@@ -53,7 +54,7 @@ class SuperCompactProductListing extends Component {

+ src="/api/cdn/${this.state.id}${this.state.bigimage ? '' : '-thumb'}.png">
${modifierPreview}
@@ -61,7 +62,7 @@ class SuperCompactProductListing extends Component {
${this.state.modifier ? `Colour: ${this.state.colours[this.state.modifier].name}` : ''}
${this.state.tags
- ? this.state.tags.map(tag => ``).join('')
+ ? this.state.tags.map(tag => ``).join('')
: ``}
@@ -108,6 +109,8 @@ class SuperCompactProductListing extends Component {
}
.product-image {
+ max-height: 150px;
+ max-width: 150px;
object-fit: scale-down;
object-position: center;
}
diff --git a/client/public/components/tag.mjs b/client/public/components/tag.mjs
index 6239552..380fb31 100644
--- a/client/public/components/tag.mjs
+++ b/client/public/components/tag.mjs
@@ -30,7 +30,7 @@ class Tag extends Component {
OnRender() {
this.root.addEventListener('click', () => {
- this.root.classList.toggle('tag-selected');
+ window.location.href = `/search?q=${this.state.name}`;
});
}
}
diff --git a/client/public/components/templates/navbar.html b/client/public/components/templates/navbar.html
index e0ff304..a47e68e 100644
--- a/client/public/components/templates/navbar.html
+++ b/client/public/components/templates/navbar.html
@@ -27,7 +27,7 @@