update it
This commit is contained in:
parent
269c20c8c6
commit
544f60d25f
|
@ -50,6 +50,9 @@ class App extends Component {
|
||||||
sidebar: {
|
sidebar: {
|
||||||
toggled: false
|
toggled: false
|
||||||
},
|
},
|
||||||
|
modal: {
|
||||||
|
visible: false
|
||||||
|
},
|
||||||
error: {
|
error: {
|
||||||
status: false,
|
status: false,
|
||||||
message: ''
|
message: ''
|
||||||
|
@ -64,7 +67,7 @@ class App extends Component {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const title = 'Next, EPC ' + Package.version;
|
const title = 'Next, EPC ' + Package.version;
|
||||||
const session = this.props.session;
|
const session = this.props.session;
|
||||||
|
@ -75,7 +78,7 @@ class App extends Component {
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
<Header onMenuClick={this.onToogleSidebar}/>
|
<Header onMenuAction={this.onToogleSidebar}/>
|
||||||
<BodyContainer>
|
<BodyContainer>
|
||||||
<Sidebar toggled={this.state.sidebar.toggled}/>
|
<Sidebar toggled={this.state.sidebar.toggled}/>
|
||||||
<ContentContainer>
|
<ContentContainer>
|
||||||
|
|
|
@ -9,6 +9,9 @@ import ThumbnailIcon from './Thumbnail';
|
||||||
|
|
||||||
import Session from '../lib/session';
|
import Session from '../lib/session';
|
||||||
|
|
||||||
|
import Logout from './Logout';
|
||||||
|
import Dimmed from './Dimmed';
|
||||||
|
|
||||||
const Wrapper = styled.div`
|
const Wrapper = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -45,27 +48,64 @@ const Thumbnail = styled.div`
|
||||||
right: 1rem;
|
right: 1rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
async function logout (e) {
|
|
||||||
const session = new Session()
|
|
||||||
await session.signout()
|
|
||||||
|
|
||||||
// @FIXME next/router not working reliably so using window.location
|
|
||||||
window.location = '/'
|
|
||||||
}
|
|
||||||
|
|
||||||
class Header extends Component {
|
class Header extends Component {
|
||||||
|
state = {
|
||||||
|
logout: {
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logoutHandler = {
|
||||||
|
show: () => {
|
||||||
|
this.setState({
|
||||||
|
logout: {
|
||||||
|
...this.state.logout,
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
hide: () => {
|
||||||
|
this.setState({
|
||||||
|
logout: {
|
||||||
|
...this.state.logout,
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
action: async () => {
|
||||||
|
const session = new Session()
|
||||||
|
await session.signout()
|
||||||
|
|
||||||
|
// @FIXME next/router not working reliably so using window.location
|
||||||
|
window.location = '/'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {
|
||||||
|
logoutHandler
|
||||||
|
} = this;
|
||||||
|
|
||||||
|
const {
|
||||||
|
logout
|
||||||
|
} = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<Menu onClick={this.props.onMenuClick}>
|
<Menu onClick={this.props.onMenuAction}>
|
||||||
<MenuIcon/>
|
<MenuIcon/>
|
||||||
</Menu>
|
</Menu>
|
||||||
<Title>
|
<Title>
|
||||||
Next, EPC
|
Next, EPC
|
||||||
</Title>
|
</Title>
|
||||||
<Thumbnail onClick={logout}>
|
<Thumbnail onClick={this.logoutHandler.show}>
|
||||||
<ThumbnailIcon size="2rem" color={oc['pink'][4]} />
|
<ThumbnailIcon size="2rem" color={oc['pink'][4]} />
|
||||||
</Thumbnail>
|
</Thumbnail>
|
||||||
|
<Logout
|
||||||
|
{...logout}
|
||||||
|
onHide={logoutHandler.hide}
|
||||||
|
onAction={logoutHandler.action} />
|
||||||
|
<Dimmed visible={logout.visible} />
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
import { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import oc from 'open-color';
|
||||||
|
|
||||||
|
import Modal from './Modal';
|
||||||
|
|
||||||
|
const TitleWrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding-top: 2rem;
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: ${oc.gray[8]};
|
||||||
|
|
||||||
|
background: ${oc.gray[2]};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ButtonsWrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Button = styled.div`
|
||||||
|
padding-top: 0.2rem;
|
||||||
|
padding-bottom: 0.2rem;
|
||||||
|
flex: 1;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
transition: all .3s;
|
||||||
|
|
||||||
|
color: white;
|
||||||
|
background: ${props => oc[props.color][7]};
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: ${props => oc[props.color][6]};
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background: ${props => oc[props.color][8]};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
Button.propType = {
|
||||||
|
color: PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
|
class Logout extends Component {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
visible: PropTypes.bool,
|
||||||
|
color: PropTypes.string,
|
||||||
|
onHide: PropTypes.func,
|
||||||
|
onAction: PropTypes.func,
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
visible,
|
||||||
|
color,
|
||||||
|
onHide,
|
||||||
|
onAction,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal visible={visible} onHide={onHide}>
|
||||||
|
<TitleWrapper>
|
||||||
|
Are you sure you want to logout?
|
||||||
|
</TitleWrapper>
|
||||||
|
<ButtonsWrapper>
|
||||||
|
<Button color="teal"
|
||||||
|
onClick={onAction}>
|
||||||
|
OK
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={onHide}
|
||||||
|
color="gray">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</ButtonsWrapper>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Logout;
|
|
@ -0,0 +1,99 @@
|
||||||
|
import { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import onClickOutside from 'react-onclickoutside';
|
||||||
|
import {media, transitions} from '../lib/style-utils';
|
||||||
|
import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup';
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
|
||||||
|
z-index: 10;
|
||||||
|
|
||||||
|
width: ${ props => props.width };
|
||||||
|
|
||||||
|
${media.mobile`
|
||||||
|
width: calc(100% - 2rem);
|
||||||
|
`}
|
||||||
|
|
||||||
|
.modal-enter {
|
||||||
|
animation: ${transitions.slideDown} .5s ease-in-out;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-leave {
|
||||||
|
animation: ${transitions.slideUp} .5s ease-in-out;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
Wrapper.propTypes = {
|
||||||
|
width: PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
|
const ModalBox = styled.div`
|
||||||
|
background: white;
|
||||||
|
border: 1px solid rgba(0,0,0,0.3);
|
||||||
|
`
|
||||||
|
|
||||||
|
class Modal extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
visible: PropTypes.bool,
|
||||||
|
onHide: PropTypes.func,
|
||||||
|
width: PropTypes.string
|
||||||
|
}
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
width: '400px'
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClickOutside = (e) => {
|
||||||
|
const { visible, onHide } = this.props;
|
||||||
|
|
||||||
|
if(!visible) return null;
|
||||||
|
onHide();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleKeyUp = (e) => {
|
||||||
|
const { onHide } = this.props
|
||||||
|
if (e.keyCode === 27) {
|
||||||
|
onHide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps, prevState) {
|
||||||
|
if(prevProps.visible !== this.props.visible) {
|
||||||
|
if(this.props.visible) {
|
||||||
|
document.body.addEventListener('keyup', this.handleKeyPress);
|
||||||
|
} else {
|
||||||
|
document.body.removeEventListener('keyup', this.handleKeyPress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
const {visible, children, width} = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Wrapper width={width}>
|
||||||
|
<CSSTransitionGroup
|
||||||
|
transitionName="modal"
|
||||||
|
transitionEnterTimeout={500}
|
||||||
|
transitionLeaveTimeout={500}>
|
||||||
|
{
|
||||||
|
visible && (<ModalBox>{children}</ModalBox>)
|
||||||
|
}
|
||||||
|
</CSSTransitionGroup>
|
||||||
|
</Wrapper>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default onClickOutside(Modal);
|
|
@ -24,6 +24,7 @@
|
||||||
"react": "^15.5.4",
|
"react": "^15.5.4",
|
||||||
"react-dom": "^15.5.4",
|
"react-dom": "^15.5.4",
|
||||||
"react-icons": "^2.2.5",
|
"react-icons": "^2.2.5",
|
||||||
|
"react-onclickoutside": "^5.11.1",
|
||||||
"react-transition-group": "^1.1.3",
|
"react-transition-group": "^1.1.3",
|
||||||
"sequelize": "^3.30.4",
|
"sequelize": "^3.30.4",
|
||||||
"sqlite3": "^3.1.8",
|
"sqlite3": "^3.1.8",
|
||||||
|
|
|
@ -6,6 +6,7 @@ body {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
|
-webkit-font-smoothing: subpixel-antialiased;
|
||||||
|
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: 'Roboto', sans-serif;
|
||||||
background: #f1f3f5;
|
background: #f1f3f5;
|
||||||
|
|
|
@ -1295,6 +1295,14 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
|
||||||
safe-buffer "^5.0.1"
|
safe-buffer "^5.0.1"
|
||||||
sha.js "^2.4.8"
|
sha.js "^2.4.8"
|
||||||
|
|
||||||
|
create-react-class@^15.5.x:
|
||||||
|
version "15.5.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.5.3.tgz#fb0f7cae79339e9a179e194ef466efa3923820fe"
|
||||||
|
dependencies:
|
||||||
|
fbjs "^0.8.9"
|
||||||
|
loose-envify "^1.3.1"
|
||||||
|
object-assign "^4.1.1"
|
||||||
|
|
||||||
cross-env@^3.1.2:
|
cross-env@^3.1.2:
|
||||||
version "3.2.4"
|
version "3.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-3.2.4.tgz#9e0585f277864ed421ce756f81a980ff0d698aba"
|
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-3.2.4.tgz#9e0585f277864ed421ce756f81a980ff0d698aba"
|
||||||
|
@ -2675,7 +2683,7 @@ oauth-sign@~0.8.1:
|
||||||
version "0.8.2"
|
version "0.8.2"
|
||||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
|
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
|
||||||
|
|
||||||
object-assign@^4.0.1, object-assign@^4.1.0:
|
object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||||
|
|
||||||
|
@ -3063,6 +3071,12 @@ react-icons@^2.2.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
react-icon-base "2.0.7"
|
react-icon-base "2.0.7"
|
||||||
|
|
||||||
|
react-onclickoutside@^5.11.1:
|
||||||
|
version "5.11.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-5.11.1.tgz#00314e52567cf55faba94cabbacd119619070623"
|
||||||
|
dependencies:
|
||||||
|
create-react-class "^15.5.x"
|
||||||
|
|
||||||
react-proxy@^3.0.0-alpha.0:
|
react-proxy@^3.0.0-alpha.0:
|
||||||
version "3.0.0-alpha.1"
|
version "3.0.0-alpha.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-3.0.0-alpha.1.tgz#4400426bcfa80caa6724c7755695315209fa4b07"
|
resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-3.0.0-alpha.1.tgz#4400426bcfa80caa6724c7755695315209fa4b07"
|
||||||
|
|
Loading…
Reference in New Issue