diff --git a/client/public/components/basket.mjs b/client/public/components/basket.mjs index f106921..82db116 100644 --- a/client/public/components/basket.mjs +++ b/client/public/components/basket.mjs @@ -7,8 +7,8 @@ import { RegisterComponent, Component } from './components.mjs'; // { // "basket": { // "items": { -// "item1": amount, -// "item2": amount, +// "item1~modifier": { quantity, type }, +// "item2": { quantity, type }, // ... // }, // "total": total @@ -20,7 +20,7 @@ let basketCallback = null; // TODO: Does the localstorage have a problem with mutual exclusion? // TODO: Should the basket be persisted to the server? -export function AddProductToBasket(product, type, amount) { +export function AddProductToBasket(product, type, amount, brickModifier = 'none') { if (localStorage.getItem('basket') === null || !localStorage.getItem('basket')) { localStorage.setItem('basket', JSON.stringify({ items: {}, @@ -30,6 +30,10 @@ export function AddProductToBasket(product, type, amount) { const basket = JSON.parse(localStorage.getItem('basket')); + if (type === 'brick') { + product += '~' + brickModifier; + } + if (basket.items[product]) { basket.items[product].quantity += amount; } else { @@ -48,12 +52,16 @@ export function AddProductToBasket(product, type, amount) { } } -export function RemoveProductFromBasket(product, amount) { +export function RemoveProductFromBasket(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 (basket.items[product] > amount) { basket.items[product] -= amount; } else { diff --git a/client/public/components/css/product-listing.css b/client/public/components/css/product-listing.css index 32cce28..da4345d 100644 --- a/client/public/components/css/product-listing.css +++ b/client/public/components/css/product-listing.css @@ -26,13 +26,15 @@ .product-image-container { flex-grow: 1; - aspect-ratio: 1; + display: flex; + justify-content: center; max-width: 600px; } .active-image { display: block; - width: 100%; + max-width: 100%; + height: 100%; } .product-info { @@ -102,6 +104,22 @@ margin-block-end: 0.83em; } +.brick-colour-selector { + display: flex; + flex-direction: row; + font-size: 1.3em; + justify-content: flex-start; + align-items: center; + margin-block-start: 0.83em; + margin-block-end: 0.83em; +} + +.brick-colour-selector-select { + font-size: 1em; + font-family: inherit; + transform: translateY(-1px); +} + .product-quantity-selector { display: flex; flex-direction: row; @@ -254,3 +272,21 @@ input[type=number] { font-size: 2.3em; font-weight: bold; } + +.brick-colour-container { + width: 100%; + display: flex; + flex-direction: row; + justify-content: flex-start; +} + +.brick-colour-demonstrator { + font-family: inherit; + font-size: 1.5em; + font-weight: bold; + text-shadow: 1px 1px 1px #fff; + width: 40px; + height: 40px; + margin-right: 0.5em; + border: #1A1A1A solid 1px; +} diff --git a/client/public/components/product-listing.mjs b/client/public/components/product-listing.mjs index 848f588..b239549 100644 --- a/client/public/components/product-listing.mjs +++ b/client/public/components/product-listing.mjs @@ -50,6 +50,7 @@ class ProductListing extends Component { } Render() { + // set contents for sets let setContents = ''; if (this.state.type === 'set') { setContents = /* html */` @@ -66,7 +67,7 @@ class ProductListing extends Component { name="${brick.name}" tag="${brick.tag}" type="brick" - price="${brick.price || brick.discount}"> + price="${brick.discount || brick.price}"> `).join('')} @@ -75,6 +76,44 @@ class ProductListing extends Component { `; } + console.log(this.state) + + // brick colour availability for bricks + let brickColourAvailability = ''; + let brickColourSelector = ''; + if (this.state.type === 'brick') { + brickColourAvailability = /* html */` +
+ + +
+ `; + brickColourSelector = /* html */` +
+ Select Brick Colour  + +
+ `; + } + return { template: /* html */`
@@ -101,6 +140,8 @@ class ProductListing extends Component { : `£${parseFloat(this.state.price).toFixed(2)}`}
${this.state.description || this.state.name + ' ' + this.state.tag}
+ ${brickColourSelector} +
@@ -128,6 +169,7 @@ class ProductListing extends Component {
${setContents} + ${brickColourAvailability}
@@ -152,9 +194,8 @@ class ProductListing extends Component { quantityInput.value = 1; quantityInput.addEventListener('change', () => { - if (typeof quantityInput.value !== 'number') { - quantityInput.value = 1; - } + quantityInput.value = parseInt(quantityInput.value); + if (quantityInput.value > this.state.stock) { quantityInput.value = this.state.stock; } diff --git a/client/public/components/search.mjs b/client/public/components/search.mjs index e348064..54880b1 100644 --- a/client/public/components/search.mjs +++ b/client/public/components/search.mjs @@ -11,6 +11,7 @@ class Search extends Component { return { template: /* html */` +
`, style: ` /* Modified version of https://codepen.io/mihaeltomic/pen/vmwMdm */ @@ -56,9 +57,87 @@ class Search extends Component { margin: 0; } } + + .search-results { + display: none; + background-color: #AB8FFF; + flex-wrap: wrap; + font-size: 0.6em; + position: fixed; + width: 65%; + } + + #search-bar:focus + .search-results { + display: flex; + } + + .search-results:hover { + display: flex; + } + + .sc-listing { + margin: 0; + padding: 0; + width: 100%; + } `, }; } + + AppendSearchResults(results, empty = false) { + const searchResults = this.root.querySelector('.search-results'); + searchResults.innerHTML = ''; + if (empty) { + return; + } + + for (const result of results) { + const res = /* html */` + + + `; + searchResults.innerHTML += res; + } + } + + OnRender() { + const searchBar = this.root.querySelector('#search-bar'); + searchBar.value = localStorage.getItem('search-bar'); + const route = `/api/search?q=${searchBar.value}&per_page=10`; + fetch(route).then((response) => { + return response.json(); + }).then((data) => { + this.AppendSearchResults(data.data); + }); + + searchBar.addEventListener('keyup', (e) => { + localStorage.setItem('search-bar', e.target.value); + + if (e.target.value === '') { + this.AppendSearchResults([], true); + return; + } + + // we want this to happen async + const route = `/api/search?q=${e.target.value}&per_page=10`; + fetch(route).then((response) => { + return response.json(); + }).then((data) => { + this.AppendSearchResults(data.data); + }); + + if (e.keyCode === 13) { + const searchTerm = searchBar.value; + if (searchTerm.length > 0) { + window.location.href = `/search?q=${searchTerm}`; + } + } + }); + } } RegisterComponent(Search); diff --git a/client/public/components/storefront.mjs b/client/public/components/storefront.mjs index beef55f..e009ed9 100644 --- a/client/public/components/storefront.mjs +++ b/client/public/components/storefront.mjs @@ -36,7 +36,7 @@ class StoreFront extends Component { diff --git a/client/public/components/super-compact-listing.mjs b/client/public/components/super-compact-listing.mjs index bda30f2..4b95564 100644 --- a/client/public/components/super-compact-listing.mjs +++ b/client/public/components/super-compact-listing.mjs @@ -31,10 +31,13 @@ class SuperCompactProductListing extends Component { style: ` .product-listing { width: 95%; + background-color: #F5F6F6; position: relative; display: flex; flex-direction: row; align-items: center; + padding-left: 10px; + padding-right: 15px; margin: 7px; z-index: 0; cursor: pointer; diff --git a/client/public/components/tag.mjs b/client/public/components/tag.mjs index 9c8f6d5..6239552 100644 --- a/client/public/components/tag.mjs +++ b/client/public/components/tag.mjs @@ -14,12 +14,12 @@ class Tag extends Component { `, style: ` .tag { - padding: 0.3em 1em; - margin-right: 0.3em; - margin-top: 0.3em; - margin-bottom: 0.3em; - line-height: 1.5em; 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; cursor: pointer; diff --git a/client/public/components/templates/navbar.html b/client/public/components/templates/navbar.html index 7ddf634..fe9d56b 100644 --- a/client/public/components/templates/navbar.html +++ b/client/public/components/templates/navbar.html @@ -16,15 +16,12 @@