accessibiliuty
Former-commit-id: 342820102ceb82a5e6921c05d47a4fcfe366251d
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
<script type="module" src="/components/search.mjs"></script>
|
<script type="module" src="/components/search.mjs"></script>
|
||||||
<script type="module" src="/components/basket.mjs"></script>
|
<script type="module" src="/components/basket.mjs"></script>
|
||||||
<script type="module" src="/components/basket-popout.mjs"></script>
|
<script type="module" src="/components/basket-popout.mjs"></script>
|
||||||
|
<script type="module" src="/components/accessability-popout.mjs"></script>
|
||||||
<script type="module" src="/components/notificationbar.mjs"></script>
|
<script type="module" src="/components/notificationbar.mjs"></script>
|
||||||
<script type="module" src="/components/storefront.mjs"></script>
|
<script type="module" src="/components/storefront.mjs"></script>
|
||||||
<script type="module" src="/components/tag.mjs"></script>
|
<script type="module" src="/components/tag.mjs"></script>
|
||||||
|
|||||||
310
client/public/components/accessability-popout.mjs
Normal file
310
client/public/components/accessability-popout.mjs
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
import { RegisterComponent, Component } from './components.mjs';
|
||||||
|
|
||||||
|
class AccessabilityPopout extends Component {
|
||||||
|
static __IDENTIFY() { return 'accessability-popout'; }
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super(AccessabilityPopout);
|
||||||
|
}
|
||||||
|
|
||||||
|
OnMount() {
|
||||||
|
const size = localStorage.getItem('font-size');
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/3514784/what-is-the-best-way-to-detect-a-mobile-device
|
||||||
|
this.isMobile = false;
|
||||||
|
if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) ||
|
||||||
|
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0, 4))) {
|
||||||
|
this.isMobile = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (size) {
|
||||||
|
case 'Small':
|
||||||
|
this.setSmallFontSize();
|
||||||
|
break;
|
||||||
|
case 'Large':
|
||||||
|
this.setLargeFontSize();
|
||||||
|
break;
|
||||||
|
case 'Normal':
|
||||||
|
default:
|
||||||
|
this.setNormalFontSize();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
fontSize: size,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Render() {
|
||||||
|
return {
|
||||||
|
template: /* html */`
|
||||||
|
<span id="accessability-wrapper">
|
||||||
|
<div class="accessability">
|
||||||
|
<svg id="accessability-icon" class="menu-item" stroke-width="2px" width="45px" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 122.88 122.88"><title>accessibility</title><path d="M61.44,0A61.46,61.46,0,1,1,18,18,61.21,61.21,0,0,1,61.44,0Zm-.39,74.18L52.1,98.91a4.94,4.94,0,0,1-2.58,2.83A5,5,0,0,1,42.7,95.5l6.24-17.28a26.3,26.3,0,0,0,1.17-4,40.64,40.64,0,0,0,.54-4.18c.24-2.53.41-5.27.54-7.9s.22-5.18.29-7.29c.09-2.63-.62-2.8-2.73-3.3l-.44-.1-18-3.39A5,5,0,0,1,27.08,46a5,5,0,0,1,5.05-7.74l19.34,3.63c.77.07,1.52.16,2.31.25a57.64,57.64,0,0,0,7.18.53A81.13,81.13,0,0,0,69.9,42c.9-.1,1.75-.21,2.6-.29l18.25-3.42A5,5,0,0,1,94.5,39a5,5,0,0,1,1.3,7,5,5,0,0,1-3.21,2.09L75.15,51.37c-.58.13-1.1.22-1.56.29-1.82.31-2.72.47-2.61,3.06.08,1.89.31,4.15.61,6.51.35,2.77.81,5.71,1.29,8.4.31,1.77.6,3.19,1,4.55s.79,2.75,1.39,4.42l6.11,16.9a5,5,0,0,1-6.82,6.24,4.94,4.94,0,0,1-2.58-2.83L63,74.23,62,72.4l-1,1.78Zm.39-53.52a8.83,8.83,0,1,1-6.24,2.59,8.79,8.79,0,0,1,6.24-2.59Zm36.35,4.43a51.42,51.42,0,1,0,15,36.35,51.27,51.27,0,0,0-15-36.35Z"></path></svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="accessability-popup" class="popup">
|
||||||
|
<div class="popup-header">
|
||||||
|
<span class="popup-title">Accessability Settings</span>
|
||||||
|
<button class="toggler">
|
||||||
|
<span class="cross-line cross-line-top"></span>
|
||||||
|
<span class="cross-line cross-line-bottom"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="popup-content">
|
||||||
|
<div class="popup-content-item">
|
||||||
|
Text size: <span class="text-size">{this.state.fontSize}</span>
|
||||||
|
<div class="text-size-controls">
|
||||||
|
<button class="text-size-control small">aa</button>
|
||||||
|
<button class="text-size-control normal">aA</button>
|
||||||
|
<button class="text-size-control large">AA</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
`,
|
||||||
|
style: `
|
||||||
|
#accessability-wrapper {
|
||||||
|
flex-basis: 4%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accessability {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accessability:hover {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
#accessability-icon {
|
||||||
|
padding-top: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.show {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#accessability-popup {
|
||||||
|
font-size: 0.5em;
|
||||||
|
position: absolute;
|
||||||
|
background-color: #AB8FFF;
|
||||||
|
border: 1px solid #222;
|
||||||
|
right: 0;
|
||||||
|
width: 400px;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (pointer:none), (pointer:coarse), screen and (max-width: 900px) {
|
||||||
|
#accessability-popup {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
font-size: 1.5em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggler {
|
||||||
|
position: absolute;
|
||||||
|
right: 2px;
|
||||||
|
top: 2px;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
height: 2em;
|
||||||
|
width: 2em;
|
||||||
|
z-index: 50;
|
||||||
|
transition: all 0.2s ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cross-line {
|
||||||
|
background: #222;
|
||||||
|
box-shadow: #222 0px 0px 2px;
|
||||||
|
position: absolute;
|
||||||
|
height: 2px;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toggler:hover .cross-line {
|
||||||
|
background: #777;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cross-line-top {
|
||||||
|
top: 50%;
|
||||||
|
transform: rotate(45deg) translatey(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cross-line-bottom {
|
||||||
|
bottom: 50%;
|
||||||
|
transform: rotate(-45deg) translatey(50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: left;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-content-item {
|
||||||
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-size-controls {
|
||||||
|
flex-basis: 50%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-size-control {
|
||||||
|
padding: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
background: #222;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 1.5em;
|
||||||
|
font-weight: bold;
|
||||||
|
transition: all 0.2s ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-size-control:hover {
|
||||||
|
background: #777;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-size-control.small {
|
||||||
|
font-size: 0.7em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-size-control.normal {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-size-control.large {
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
setSmallFontSize() {
|
||||||
|
localStorage.setItem('font-size', 'Small');
|
||||||
|
// check if screen is mobile first
|
||||||
|
if (!this.isMobile) {
|
||||||
|
document.body.style.fontSize = '12px';
|
||||||
|
} else {
|
||||||
|
document.body.style.fontSize = '16px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setNormalFontSize() {
|
||||||
|
localStorage.setItem('font-size', 'Normal');
|
||||||
|
if (!this.isMobile) {
|
||||||
|
document.body.style.fontSize = '16px';
|
||||||
|
} else {
|
||||||
|
document.body.style.fontSize = '25px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setLargeFontSize() {
|
||||||
|
localStorage.setItem('font-size', 'Large');
|
||||||
|
if (!this.isMobile) {
|
||||||
|
document.body.style.fontSize = '24px';
|
||||||
|
} else {
|
||||||
|
document.body.style.fontSize = '40px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OnRender() {
|
||||||
|
const accessabilityWrapper = this.root.querySelector('#accessability-wrapper');
|
||||||
|
const accessabilityToggler = this.root.querySelector('.accessability');
|
||||||
|
const popup = this.root.querySelector('.popup');
|
||||||
|
const closeButton = this.root.querySelector('.toggler');
|
||||||
|
|
||||||
|
accessabilityToggler.addEventListener('click', () => {
|
||||||
|
popup.classList.toggle('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
closeButton.addEventListener('click', () => {
|
||||||
|
popup.classList.remove('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
const toggler = this.root.querySelector('.toggler');
|
||||||
|
toggler.addEventListener('click', () => {
|
||||||
|
popup.classList.remove('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
// allow "click off to close", allowing for the users mouse to start clicking and dragging inside the popup
|
||||||
|
// without closing it if the mouse leaves the popup
|
||||||
|
let isMouseInside = true;
|
||||||
|
|
||||||
|
accessabilityWrapper.addEventListener('mouseleave', () => {
|
||||||
|
isMouseInside = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
accessabilityWrapper.addEventListener('mouseenter', () => {
|
||||||
|
isMouseInside = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('click', () => {
|
||||||
|
if (!isMouseInside) {
|
||||||
|
popup.classList.remove('show');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// text size controls
|
||||||
|
const small = this.root.querySelector('.small');
|
||||||
|
const normal = this.root.querySelector('.normal');
|
||||||
|
const large = this.root.querySelector('.large');
|
||||||
|
|
||||||
|
small.addEventListener('click', () => {
|
||||||
|
this.setSmallFontSize();
|
||||||
|
this.setState({ fontSize: 'Small' });
|
||||||
|
});
|
||||||
|
|
||||||
|
normal.addEventListener('click', () => {
|
||||||
|
this.setNormalFontSize();
|
||||||
|
this.setState({ fontSize: 'Normal' });
|
||||||
|
});
|
||||||
|
|
||||||
|
large.addEventListener('click', () => {
|
||||||
|
this.setLargeFontSize();
|
||||||
|
this.setState({ fontSize: 'Large' });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterComponent(AccessabilityPopout);
|
||||||
@@ -85,15 +85,25 @@ class BasketPopout extends Component {
|
|||||||
super(BasketPopout);
|
super(BasketPopout);
|
||||||
}
|
}
|
||||||
|
|
||||||
OnLocalBasketUpdate() {
|
async OnLocalBasketUpdate() {
|
||||||
const basket = localStorage.getItem('basket');
|
const basket = localStorage.getItem('basket');
|
||||||
|
|
||||||
if (basket) {
|
if (basket) {
|
||||||
try {
|
try {
|
||||||
const basketJSON = JSON.parse(basket);
|
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());
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
items: basketJSON.items,
|
items: basketJSON.items,
|
||||||
total: basketJSON.total,
|
total: basketJSON.total,
|
||||||
|
subtotal: res.data.subtotal,
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
@@ -102,6 +112,7 @@ class BasketPopout extends Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
items: {},
|
items: {},
|
||||||
total: 0,
|
total: 0,
|
||||||
|
subtotal: 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,14 +135,16 @@ class BasketPopout extends Component {
|
|||||||
<div id="basket-popup" class="popup">
|
<div id="basket-popup" class="popup">
|
||||||
<div class="popup-header">
|
<div class="popup-header">
|
||||||
<span class="popup-title">Basket</span>
|
<span class="popup-title">Basket</span>
|
||||||
<span class="popup-close">×</span>
|
<button class="toggler">
|
||||||
|
<span class="cross-line cross-line-top"></span>
|
||||||
|
<span class="cross-line cross-line-bottom"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="popup-content-header">
|
||||||
|
{this.state.total} Items
|
||||||
</div>
|
</div>
|
||||||
<div class="popup-content">
|
<div class="popup-content">
|
||||||
<div class="popup-content-header">
|
${this.state.items ? Object.keys(this.state.items).map((key) => {
|
||||||
Total {this.state.total}
|
|
||||||
</div>
|
|
||||||
<span class="popup-content-item-title">Items</span>
|
|
||||||
${Object.keys(this.state.items).map((key) => {
|
|
||||||
const item = this.state.items[key];
|
const item = this.state.items[key];
|
||||||
return /* html */`
|
return /* html */`
|
||||||
<div class="popup-content-item">
|
<div class="popup-content-item">
|
||||||
@@ -144,9 +157,11 @@ class BasketPopout extends Component {
|
|||||||
</super-compact-listing-component>
|
</super-compact-listing-component>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}).join('')}
|
}).join('')
|
||||||
|
: ''}
|
||||||
</div>
|
</div>
|
||||||
<div class="popup-footer">
|
<div class="popup-footer">
|
||||||
|
<span class="popup-footer-total">Subtotal: £${parseFloat(this.state.subtotal).toFixed(2)}</span>
|
||||||
<a href="/basket"><button class="popup-footer-button">View Basket</button></a>
|
<a href="/basket"><button class="popup-footer-button">View Basket</button></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -197,7 +212,7 @@ class BasketPopout extends Component {
|
|||||||
max-height: 550px;
|
max-height: 550px;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 5px;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -206,10 +221,56 @@ class BasketPopout extends Component {
|
|||||||
|
|
||||||
@media (pointer:none), (pointer:coarse), screen and (max-width: 900px) {
|
@media (pointer:none), (pointer:coarse), screen and (max-width: 900px) {
|
||||||
#basket-popup {
|
#basket-popup {
|
||||||
position: fixed;
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
max-width: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
font-size: 1.5em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggler {
|
||||||
|
position: absolute;
|
||||||
|
right: 2px;
|
||||||
|
top: 2px;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
height: 2em;
|
||||||
|
width: 2em;
|
||||||
|
z-index: 50;
|
||||||
|
transition: all 0.2s ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cross-line {
|
||||||
|
background: #222;
|
||||||
|
box-shadow: #222 0px 0px 2px;
|
||||||
|
position: absolute;
|
||||||
|
height: 2px;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#toggler:hover .cross-line {
|
||||||
|
background: #777;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cross-line-top {
|
||||||
|
top: 50%;
|
||||||
|
transform: rotate(45deg) translatey(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cross-line-bottom {
|
||||||
|
bottom: 50%;
|
||||||
|
transform: rotate(-45deg) translatey(50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-content {
|
.popup-content {
|
||||||
@@ -247,30 +308,78 @@ class BasketPopout extends Component {
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.popup-footer {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
padding-top: 7px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-footer-total {
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-footer-button {
|
||||||
|
font-size: 1.4em;
|
||||||
|
font-weight: bold;
|
||||||
|
background-color: #AB8FFF;
|
||||||
|
border: 1px solid #222;
|
||||||
|
color: #222;
|
||||||
|
padding: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
transition: all 0.2s ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-footer-button:hover {
|
||||||
|
background-color: #222;
|
||||||
|
color: #AB8FFF;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
OnRender() {
|
OnRender() {
|
||||||
// set up basket
|
const basketWrapper = this.root.querySelector('#basket-wrapper');
|
||||||
const basketToggler = this.root.querySelector('.basket');
|
const basketToggler = this.root.querySelector('.basket');
|
||||||
|
const popup = this.root.querySelector('.popup');
|
||||||
|
const closeButton = this.root.querySelector('.toggler');
|
||||||
|
|
||||||
basketToggler.addEventListener('click', () => {
|
basketToggler.addEventListener('click', () => {
|
||||||
const popup = this.root.querySelector('.popup');
|
|
||||||
popup.classList.toggle('show');
|
popup.classList.toggle('show');
|
||||||
|
|
||||||
popup.addEventListener('click', (e) => {
|
|
||||||
if (e.target.classList.contains('popup-close')) {
|
|
||||||
popup.classList.remove('show');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// allow "click off to close"
|
closeButton.addEventListener('click', () => {
|
||||||
// document.addEventListener('click', (e) => {
|
popup.classList.remove('show');
|
||||||
// if (!popup.contains(e.target)) {
|
});
|
||||||
// popup.classList.remove('show');
|
|
||||||
// }
|
const toggler = this.root.querySelector('.toggler');
|
||||||
// });
|
toggler.addEventListener('click', () => {
|
||||||
|
popup.classList.remove('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
// allow "click off to close", allowing for the users mouse to start clicking and dragging inside the popup
|
||||||
|
// without closing it if the mouse leaves the popup
|
||||||
|
let isMouseInside = true;
|
||||||
|
|
||||||
|
basketWrapper.addEventListener('mouseleave', () => {
|
||||||
|
isMouseInside = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
basketWrapper.addEventListener('mouseenter', () => {
|
||||||
|
isMouseInside = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('mouseup', () => {
|
||||||
|
if (!isMouseInside) {
|
||||||
|
popup.classList.remove('show');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,17 +173,19 @@ input[type=number] {
|
|||||||
margin-block-end: 0.83em;
|
margin-block-end: 0.83em;
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: #1A1A1A;
|
background-color: #222;
|
||||||
border: none;
|
border: none;
|
||||||
color: #FFFFFF;
|
color: #F5F6F6;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
transition: all 0.2s ease-in;
|
||||||
}
|
}
|
||||||
|
|
||||||
.add-to-basket-button:hover {
|
.add-to-basket-button:hover {
|
||||||
background-color: #FFFFFF;
|
background-color: #F5F6F6;
|
||||||
color: #1A1A1A;
|
outline: 2px solid #222;
|
||||||
|
color: #222;
|
||||||
}
|
}
|
||||||
|
|
||||||
.add-to-favorites-button:hover {
|
.add-to-favorites-button:hover {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class ProductList extends Component {
|
|||||||
return /* html */`
|
return /* html */`
|
||||||
<div class="augment-panel">
|
<div class="augment-panel">
|
||||||
<div class="augment-panel-header">
|
<div class="augment-panel-header">
|
||||||
<span class="augment-panel-header-text">Refine search results</span>
|
<span class="augment-panel-header-text">Refine results</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="augment-panel-body">
|
<div class="augment-panel-body">
|
||||||
<div class="augment-panel-body-row">
|
<div class="augment-panel-body-row">
|
||||||
@@ -56,7 +56,6 @@ class ProductList extends Component {
|
|||||||
|
|
||||||
Render() {
|
Render() {
|
||||||
const augmentPanel = this.GenerateAugmentPanel(this.state.augmentable);
|
const augmentPanel = this.GenerateAugmentPanel(this.state.augmentable);
|
||||||
console.log(augmentPanel);
|
|
||||||
|
|
||||||
if (this.state.page * this.state.per_page >= this.state.total) {
|
if (this.state.page * this.state.per_page >= this.state.total) {
|
||||||
this.keepLoading = false;
|
this.keepLoading = false;
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ class ProductListing extends Component {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="product-name">{this.state.name} {this.state.id}</div>
|
<div class="product-name">{this.state.name} {this.state.id}</div>
|
||||||
${this.state.discount
|
${this.state.discountbar
|
||||||
? `<span class="product-listing-price-full">£${parseFloat(this.state.price).toFixed(2)}</span><span class="product-listing-price-new">£${parseFloat(this.state.discount).toFixed(2)}</span>`
|
? `<span class="product-listing-price-full">£${parseFloat(this.state.price).toFixed(2)}</span><span class="product-listing-price-new">£${parseFloat(this.state.discount).toFixed(2)}</span>`
|
||||||
: `<span class="product-listing-price">£${parseFloat(this.state.price).toFixed(2)}</span>`}
|
: `<span class="product-listing-price">£${parseFloat(this.state.price).toFixed(2)}</span>`}
|
||||||
<div class="product-description">${this.state.description || this.state.name + ' ' + this.state.tag}</div>
|
<div class="product-description">${this.state.description || this.state.name + ' ' + this.state.tag}</div>
|
||||||
@@ -149,7 +149,7 @@ class ProductListing extends Component {
|
|||||||
|
|
||||||
<div class="product-add-to-basket">
|
<div class="product-add-to-basket">
|
||||||
<button class="add-to-basket-button">Add to Basket</button>
|
<button class="add-to-basket-button">Add to Basket</button>
|
||||||
<img class="add-to-favorites-button" src="https://www.svgrepo.com/show/25921/heart.svg" width="45px" stroke="#222" stroke-width="2px" alt="Add to Favorites" title="Add to Favorites">
|
<!-- <img class="add-to-favorites-button" src="https://www.svgrepo.com/show/25921/heart.svg" width="45px" stroke="#222" stroke-width="2px" alt="Add to Favorites" title="Add to Favorites"> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="collapsible-menu">
|
<div class="collapsible-menu">
|
||||||
@@ -231,7 +231,6 @@ class ProductListing extends Component {
|
|||||||
// if it is a brick, get potential modifier from the drop down menu
|
// if it is a brick, get potential modifier from the drop down menu
|
||||||
const brick = this.state.type === 'brick';
|
const brick = this.state.type === 'brick';
|
||||||
const modifier = brick ? this.root.querySelector('.brick-colour-selector-select').value : undefined;
|
const modifier = brick ? this.root.querySelector('.brick-colour-selector-select').value : undefined;
|
||||||
console.log(modifier);
|
|
||||||
|
|
||||||
AddProductToBasket(this.state.id, this.state.type, Math.abs(parseInt(quantityInput.value)), modifier);
|
AddProductToBasket(this.state.id, this.state.type, Math.abs(parseInt(quantityInput.value)), modifier);
|
||||||
quantityInput.value = 1;
|
quantityInput.value = 1;
|
||||||
|
|||||||
@@ -41,9 +41,10 @@
|
|||||||
<search-component style="width: 100%;"></search-component>
|
<search-component style="width: 100%;"></search-component>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<img id="fave-icon" class="menu-item" src="https://www.svgrepo.com/show/25921/heart.svg" width="45px" stroke="#222" stroke-width="2px" alt="">
|
<!-- <img id="fave-icon" class="menu-item" src="https://www.svgrepo.com/show/25921/heart.svg" width="45px" stroke="#222" stroke-width="2px" alt=""> -->
|
||||||
|
|
||||||
<basket-popout-component></basket-popout-component>
|
<basket-popout-component></basket-popout-component>
|
||||||
|
|
||||||
|
<accessability-popout-component></accessability-popout-component>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
<script type="module" src="/components/search.mjs"></script>
|
<script type="module" src="/components/search.mjs"></script>
|
||||||
<script type="module" src="/components/basket.mjs"></script>
|
<script type="module" src="/components/basket.mjs"></script>
|
||||||
<script type="module" src="/components/basket-popout.mjs"></script>
|
<script type="module" src="/components/basket-popout.mjs"></script>
|
||||||
|
<script type="module" src="/components/accessability-popout.mjs"></script>
|
||||||
<script type="module" src="/components/notificationbar.mjs"></script>
|
<script type="module" src="/components/notificationbar.mjs"></script>
|
||||||
<script type="module" src="/components/storefront.mjs"></script>
|
<script type="module" src="/components/storefront.mjs"></script>
|
||||||
<script type="module" src="/components/tag.mjs"></script>
|
<script type="module" src="/components/tag.mjs"></script>
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ limited-margin {
|
|||||||
|
|
||||||
/* small screen */
|
/* small screen */
|
||||||
@media screen and (max-width: 900px) {
|
@media screen and (max-width: 900px) {
|
||||||
|
body {
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
limited-margin {
|
limited-margin {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
@@ -34,7 +38,6 @@ limited-margin {
|
|||||||
@media (pointer:none), (pointer:coarse) {
|
@media (pointer:none), (pointer:coarse) {
|
||||||
body {
|
body {
|
||||||
zoom: 120%;
|
zoom: 120%;
|
||||||
font-size: 25px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
limited-margin {
|
limited-margin {
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
<script type="module" src="/components/search.mjs"></script>
|
<script type="module" src="/components/search.mjs"></script>
|
||||||
<script type="module" src="/components/basket.mjs"></script>
|
<script type="module" src="/components/basket.mjs"></script>
|
||||||
<script type="module" src="/components/basket-popout.mjs"></script>
|
<script type="module" src="/components/basket-popout.mjs"></script>
|
||||||
|
<script type="module" src="/components/accessability-popout.mjs"></script>
|
||||||
|
<script type="module" src="/components/accessability-popout.mjs"></script>
|
||||||
<script type="module" src="/components/notificationbar.mjs"></script>
|
<script type="module" src="/components/notificationbar.mjs"></script>
|
||||||
<script type="module" src="/components/storefront.mjs"></script>
|
<script type="module" src="/components/storefront.mjs"></script>
|
||||||
<script type="module" src="/components/tag.mjs"></script>
|
<script type="module" src="/components/tag.mjs"></script>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
<script type="module" src="/components/search.mjs"></script>
|
<script type="module" src="/components/search.mjs"></script>
|
||||||
<script type="module" src="/components/basket.mjs"></script>
|
<script type="module" src="/components/basket.mjs"></script>
|
||||||
<script type="module" src="/components/basket-popout.mjs"></script>
|
<script type="module" src="/components/basket-popout.mjs"></script>
|
||||||
|
<script type="module" src="/components/accessability-popout.mjs"></script>
|
||||||
<script type="module" src="/components/notificationbar.mjs"></script>
|
<script type="module" src="/components/notificationbar.mjs"></script>
|
||||||
<script type="module" src="/components/storefront.mjs"></script>
|
<script type="module" src="/components/storefront.mjs"></script>
|
||||||
<script type="module" src="/components/tag.mjs"></script>
|
<script type="module" src="/components/tag.mjs"></script>
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
<script type="module" src="/components/search.mjs"></script>
|
<script type="module" src="/components/search.mjs"></script>
|
||||||
<script type="module" src="/components/basket.mjs"></script>
|
<script type="module" src="/components/basket.mjs"></script>
|
||||||
<script type="module" src="/components/basket-popout.mjs"></script>
|
<script type="module" src="/components/basket-popout.mjs"></script>
|
||||||
|
<script type="module" src="/components/accessability-popout.mjs"></script>
|
||||||
<script type="module" src="/components/notificationbar.mjs"></script>
|
<script type="module" src="/components/notificationbar.mjs"></script>
|
||||||
<script type="module" src="/components/storefront.mjs"></script>
|
<script type="module" src="/components/storefront.mjs"></script>
|
||||||
<script type="module" src="/components/tag.mjs"></script>
|
<script type="module" src="/components/tag.mjs"></script>
|
||||||
|
|||||||
@@ -15,10 +15,7 @@
|
|||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "portsoc",
|
"extends": "portsoc",
|
||||||
"rules": {
|
"rules": {
|
||||||
"indent": [
|
"indent": "off"
|
||||||
"error",
|
|
||||||
4
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"root": true,
|
"root": true,
|
||||||
"env": {
|
"env": {
|
||||||
|
|||||||
@@ -26,11 +26,7 @@ function Init() {
|
|||||||
Server.App.get('/api/auth/orders/');
|
Server.App.get('/api/auth/orders/');
|
||||||
Server.App.get('/api/auth/order/:id');
|
Server.App.get('/api/auth/order/:id');
|
||||||
|
|
||||||
Server.App.get('/api/auth/basket/');
|
Server.App.post('/api/basket/price', Helpers.CalculateBasketPrice);
|
||||||
Server.App.put('/api/auth/basket/:id');
|
|
||||||
Server.App.post('/api/auth/basket/:id');
|
|
||||||
Server.App.delete('/api/auth/basket/:id');
|
|
||||||
Server.App.delete('/api/auth/basket/');
|
|
||||||
|
|
||||||
Logger.Module('API', 'API Routes Initialized');
|
Logger.Module('API', 'API Routes Initialized');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,16 @@ function Special(req, res, next) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function CalculateBasketPrice(req, res) {
|
||||||
|
res.send({
|
||||||
|
data: {
|
||||||
|
subtotal: 10,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
Special,
|
Special,
|
||||||
|
CalculateBasketPrice,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user