update it

This commit is contained in:
Sukchan Lee 2017-06-01 10:45:55 +09:00
parent 269c20c8c6
commit 544f60d25f
7 changed files with 262 additions and 13 deletions

View File

@ -50,6 +50,9 @@ class App extends Component {
sidebar: {
toggled: false
},
modal: {
visible: false
},
error: {
status: false,
message: ''
@ -64,7 +67,7 @@ class App extends Component {
}
})
}
render() {
const title = 'Next, EPC ' + Package.version;
const session = this.props.session;
@ -75,7 +78,7 @@ class App extends Component {
<title>{title}</title>
</Head>
<Header onMenuClick={this.onToogleSidebar}/>
<Header onMenuAction={this.onToogleSidebar}/>
<BodyContainer>
<Sidebar toggled={this.state.sidebar.toggled}/>
<ContentContainer>

View File

@ -9,6 +9,9 @@ import ThumbnailIcon from './Thumbnail';
import Session from '../lib/session';
import Logout from './Logout';
import Dimmed from './Dimmed';
const Wrapper = styled.div`
display: flex;
align-items: center;
@ -45,27 +48,64 @@ const Thumbnail = styled.div`
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 {
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() {
const {
logoutHandler
} = this;
const {
logout
} = this.state;
return (
<Wrapper>
<Menu onClick={this.props.onMenuClick}>
<Menu onClick={this.props.onMenuAction}>
<MenuIcon/>
</Menu>
<Title>
Next, EPC
</Title>
<Thumbnail onClick={logout}>
<Thumbnail onClick={this.logoutHandler.show}>
<ThumbnailIcon size="2rem" color={oc['pink'][4]} />
</Thumbnail>
<Logout
{...logout}
onHide={logoutHandler.hide}
onAction={logoutHandler.action} />
<Dimmed visible={logout.visible} />
</Wrapper>
)
}

View File

@ -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;

99
webui/components/Modal.js Normal file
View File

@ -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);

View File

@ -24,6 +24,7 @@
"react": "^15.5.4",
"react-dom": "^15.5.4",
"react-icons": "^2.2.5",
"react-onclickoutside": "^5.11.1",
"react-transition-group": "^1.1.3",
"sequelize": "^3.30.4",
"sqlite3": "^3.1.8",

View File

@ -6,6 +6,7 @@ body {
box-sizing: border-box;
-webkit-appearance: none;
-webkit-font-smoothing: subpixel-antialiased;
font-family: 'Roboto', sans-serif;
background: #f1f3f5;

View File

@ -1295,6 +1295,14 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
safe-buffer "^5.0.1"
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:
version "3.2.4"
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"
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"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@ -3063,6 +3071,12 @@ react-icons@^2.2.5:
dependencies:
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:
version "3.0.0-alpha.1"
resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-3.0.0-alpha.1.tgz#4400426bcfa80caa6724c7755695315209fa4b07"