feat(mobile): Adapts design for mobile/tablet

pull/49/head
sovanna 2019-12-26 14:31:37 +01:00
parent 66cd581a47
commit a4c77f3872
5 changed files with 272 additions and 3 deletions

View File

@ -0,0 +1,199 @@
.mobileCloseMenu {
display: flex;
justify-content: flex-end;
padding: 1em 1em 0;
}
/*
##Device = Tablets, Ipads (portrait)
##Screen = B/w 768px to 1024px
*/
@media (min-width: 768px) and (max-width: 1024px) {
body {
font-size: .8rem;
}
#root-shop .productItem {
padding: 2rem 1rem 1rem;
}
#root-shop .productItem .content img {
height: 300px;
}
#root-shop .productItem .content .price {
padding: .5rem;
}
#root-shop .productItem .content h3 {
font-size: 1.5rem;
}
#root-shop .productItem .content ul {
font-size: .6rem;
}
#root-shop .panel .control {
flex-direction: column;
margin-bottom: 1.5rem;
}
#root-shop .panel .control > .description,
#root-shop .panel .control > .crate-mode {
width: 100%;
}
#root-shop .panel .control > .crate-mode {
text-align: left;
}
#root-shop .panel .summary {
flex-direction: column;
}
#root-shop .panel .summary>.summary-price table {
font-size: 1rem;
}
#root-shop .panel .summary>.summary-form form {
width: 100%;
}
#root-shop .panel {
padding: 1.5rem;
}
#root-shop .mobileBtnDisplaySideMenu,
#root-shop .mobileCloseMenu {
display: none;
}
}
/*
##Device = Tablets, Ipads (landscape)
##Screen = B/w 768px to 1024px
*/
@media (min-width: 768px) and (max-width: 1024px) and (orientation: landscape) {
}
/*
##Device = Low Resolution Tablets, Mobiles (Landscape)
##Screen = B/w 481px to 767px
*/
@media (min-width: 481px) and (max-width: 767px) {
}
/*
##Device = Most of the Smartphones Mobiles (Portrait)
##Screen = B/w 320px to 479px
*/
@media (min-width: 320px) and (max-width: 480px) {
#root-shop .layout>aside.aside.menu-opened {
transform: translate3d(0, 0, 0);
transition: transform .3s;
width: 310px;
}
#root-shop .layout>aside.aside.menu-opened + section.main {
transform: translate3d(310px, 0, 0);
transition: transform .3s;
}
#root-shop .layout>aside.aside.menu-opened + section.main:after {
content: '';
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, .8);
top: 0;
bottom: 0;
}
#root-shop .layout>aside.aside {
transform: translate3d(-310px, 0px, 0px);
transition: transform .3s;
position: fixed;
z-index: 1;
left: 0;
width: 310px;
height: 100%;
}
#root-shop .layout>aside.aside:after {
width: 0;
}
#root-shop .layout>aside.aside + section.main {
transform: translate3d(0, 0, 0);
transition: transform .3s;
}
#root-shop .layout>section.main {
flex: 1;
max-width: 100%;
}
#root-shop .productItem {
padding: 2rem 1rem 1rem;
}
#root-shop .productItem .content img {
height: 300px;
}
#root-shop .productItem .content .price {
padding: .5rem;
}
#root-shop .panel {
padding: 1.3rem;
}
#root-shop .panel .control {
flex-direction: column;
margin-bottom: 1.5rem;
}
#root-shop .panel .control > .description,
#root-shop .panel .control > .crate-mode {
width: 100%;
}
#root-shop .panel .control > .crate-mode {
text-align: left;
}
#root-shop .panel .summary {
flex-direction: column;
}
#root-shop .panel .summary>.summary-price table {
font-size: .7rem;
}
#root-shop .panel .summary>.summary-form form {
width: 100%;
}
#root-shop .panel .summary>.summary-price tfoot {
font-size: .85rem;
}
#root-shop .panel .summary>.summary-form form input[type="submit"] {
margin-bottom: 1em;
}
#root-shop .mobileBtnDisplaySideMenu {
background-color: #0d3547;
border-bottom-right-radius: 30px;
border-top-right-radius: 30px;
width: 80px;
padding: 5px 0 5px 10px;
margin-bottom: 15px;
margin-left: -1.3rem;
}
#root-shop table tfoot > tr {
display: flex !important;
justify-content: space-between;
}
}

View File

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 22 22">
<g id="Group_441" data-name="Group 441" transform="translate(-1251 -346)">
<rect id="Rectangle_1020" data-name="Rectangle 1020" width="22" height="22" transform="translate(1251 346)" fill="none"/>
<rect id="Rectangle_1021" data-name="Rectangle 1021" width="2.4" height="24" transform="translate(1269.778 347.808) rotate(45)" fill="#fff"/>
<rect id="Rectangle_1022" data-name="Rectangle 1022" width="2.4" height="24" transform="translate(1271.192 364.778) rotate(135)" fill="#fff"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 594 B

View File

@ -136,6 +136,14 @@ class Layout extends React.PureComponent {
return {
aside: PropTypes.any,
main: PropTypes.any,
mobileSideMenuShouldOpen: PropTypes.bool,
onClickToggleMobileSideMenu: PropTypes.func,
};
}
static get defaultProps() {
return {
mobileSideMenuShouldOpen: false,
};
}
@ -143,14 +151,20 @@ class Layout extends React.PureComponent {
const {
aside,
main,
mobileSideMenuShouldOpen,
onClickToggleMobileSideMenu
} = this.props;
return (
<div className="layout">
<aside className="aside">{aside}</aside>
<aside className={'aside ' + (mobileSideMenuShouldOpen ? 'menu-opened' : '')}>{aside}</aside>
<section className="main">{main}</section>
{mobileSideMenuShouldOpen ? (
<section className="main" onClick={onClickToggleMobileSideMenu}>{main}</section>
) : (
<section className="main">{main}</section>
)}
</div>
);
@ -722,6 +736,8 @@ class OrderPanel extends React.PureComponent {
crate: PropTypes.element,
summaryPrice: PropTypes.element,
form: PropTypes.element,
isMobile: PropTypes.bool,
onClickToggleMobileSideMenu: PropTypes.func,
};
}
@ -733,11 +749,21 @@ class OrderPanel extends React.PureComponent {
crate,
summaryPrice,
form,
isMobile,
onClickToggleMobileSideMenu
} = this.props;
return (
<section className="panel">
{isMobile ? (
<div className="mobileBtnDisplaySideMenu">
<button onClick={onClickToggleMobileSideMenu}>
<img src="/images/shop/icon-add.svg" alt="add" />
</button>
</div>
) : null}
<h2>{title}</h2>
<div className="control">
@ -1026,7 +1052,9 @@ class Backlog extends React.PureComponent {
currency: PropTypes.string,
data: PropTypes.object.isRequired,
items: PropTypes.object,
isMobile: PropTypes.bool,
onClickAddItem: PropTypes.func,
onClickToggleMobileSideMenu: PropTypes.func,
};
}
@ -1042,6 +1070,8 @@ class Backlog extends React.PureComponent {
data,
items,
onClickAddItem,
onClickToggleMobileSideMenu,
isMobile,
} = this.props;
const ordered_items = data.itemIds.map(itemId => items[itemId]);
@ -1072,6 +1102,14 @@ class Backlog extends React.PureComponent {
ref={provided.innerRef}
{...provided.droppableProps}>
{isMobile ? (
<div className="mobileCloseMenu">
<button onClick={onClickToggleMobileSideMenu}>
<img src="/images/shop/icon-close-white.svg" alt="add" />
</button>
</div>
) : null}
{products}
{provided.placeholder && (
@ -1115,6 +1153,7 @@ class Shop extends React.PureComponent {
this.handleClickSelectItem = this.handleClickSelectItem.bind(this);
this.handleClickSubmit = this.handleClickSubmit.bind(this);
this.handleToggleOverlayRemove = this.handleToggleOverlayRemove.bind(this);
this.handleClickToggleMobileSideMenu = this.handleClickToggleMobileSideMenu.bind(this);
}
componentDidMount() {
@ -1401,6 +1440,13 @@ class Shop extends React.PureComponent {
}
}
handleClickToggleMobileSideMenu() {
this.setState({
...this.state,
mobileSideMenuShouldOpen: !this.state.mobileSideMenuShouldOpen,
});
}
checkAlerts(prevItems, newItems) {
console.log('--- START CHECKING CRATE WARNING ---');
@ -1684,6 +1730,7 @@ class Shop extends React.PureComponent {
items,
columns,
rules,
mobileSideMenuShouldOpen,
} = this.state;
return (
@ -1691,16 +1738,22 @@ class Shop extends React.PureComponent {
<Layout
className="shop"
mobileSideMenuShouldOpen={mobileSideMenuShouldOpen}
onClickToggleMobileSideMenu={this.handleClickToggleMobileSideMenu}
aside={
<Backlog
currency={currency}
items={items}
data={columns['backlog']}
onClickAddItem={this.handleClickAddItem}>
onClickAddItem={this.handleClickAddItem}
onClickToggleMobileSideMenu={this.handleClickToggleMobileSideMenu}
isMobile={window.deviceIsMobile()}>
</Backlog>
}
main={(
<OrderPanel
onClickToggleMobileSideMenu={this.handleClickToggleMobileSideMenu}
isMobile={window.deviceIsMobile()}
title="Order hardware"
description="
Drag and drop the cards you want into the crate below to see how the combination would look like. If you have any issues with this ordering system, or if you need other configurations, email us directly anytime at sales@m-****.hk. The price is estimated and must be confirmed by a quote."

View File

@ -1,5 +1,6 @@
const shop_data = {
mobileSideMenuShouldOpen: false,
currentItemHovered: null,
currentMode: 'rack',
currency: 'USD',

View File

@ -1,6 +1,12 @@
{% extends 'section.html' %}
{% block deferred_styles %}
{{ super() }}
<link rel="stylesheet" href="{{ get_url(path='css/order-hardware.css', cachebust=true) }}">
{% endblock %}
{% block hero %}{% endblock %}
@ -24,6 +30,9 @@
return (typeof window.orientation !== 'undefined') || (navigator.userAgent.indexOf('IEMobile') !== -1);
};
window.deviceIsMobile = deviceIsMobile;
return;
if (deviceIsMobile()) {
alert('The online crate configuration tool is not available for mobile browsers yet. Please use a desktop computer or email us at sales@m-l****.hk to get a quote.');
}