Fix routing issues. Fix panel layout.
This commit is contained in:
@@ -1 +1,2 @@
|
||||
REACT_APP_TITLE=Deighton AR System
|
||||
REACT_APP_TITLE=Deighton AR System
|
||||
REACT_APP_SUPPORT_EMAIL=support@kss.us.com
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import EventEmitter from 'eventemitter3'
|
||||
import io from 'socket.io-client'
|
||||
import autobind from 'autobind-decorator'
|
||||
|
||||
const authTokenName = 'AuthToken'
|
||||
|
||||
@@ -28,6 +29,7 @@ class APIError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
@autobind
|
||||
class API extends EventEmitter {
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { Component, Fragment } from 'react'
|
||||
import { Login, Logout, ResetPassword, ForgotPassword, ConfirmEmail, ProtectedRoute } from './Auth'
|
||||
import { Login, Logout, ResetPassword, ForgotPassword, ConfirmEmail, ProtectedRoute, DefaultRoute } from './Auth'
|
||||
import { Home } from './Home'
|
||||
import { Profile } from './Profile'
|
||||
import { Users } from './Users'
|
||||
@@ -92,16 +92,17 @@ export class App extends Component {
|
||||
</Box>
|
||||
</Column.Item>
|
||||
<Switch>
|
||||
<Route path='/login' component={Login} />
|
||||
<Route path='/confirm-email' component={ConfirmEmail} />
|
||||
<Route path='/reset-password' component={ResetPassword} />
|
||||
<Route path='/forgot-password' component={ForgotPassword} />
|
||||
<ProtectedRoute path='/profile' component={Profile} />
|
||||
<ProtectedRoute path='/users' render={props => (<Users {...props} onChangeTitle={this.handleChangeTitle} />)} />
|
||||
<ProtectedRoute path='/teams' component={Users} />
|
||||
<ProtectedRoute path='/system' component={Users} />
|
||||
<ProtectedRoute path='/logout' component={Logout} />
|
||||
<ProtectedRoute path='/' render={props => (<Home {...props} onChangeTitle={this.handleChangeTitle} />)} />
|
||||
<Route exact path='/login' component={Login} />
|
||||
<Route exact path='/logout' component={Logout} />
|
||||
<Route exact path='/confirm-email' component={ConfirmEmail} />
|
||||
<Route exact path='/reset-password' component={ResetPassword} />
|
||||
<Route exact path='/forgot-password' component={ForgotPassword} />
|
||||
<ProtectedRoute exact path='/profile' component={Profile} />
|
||||
<ProtectedRoute exact admin path='/users' render={props => (<Users {...props} onChangeTitle={this.handleChangeTitle} />)} />
|
||||
<ProtectedRoute exact admin path='/teams' component={Users} />
|
||||
<ProtectedRoute exact admin path='/system' component={Users} />
|
||||
<ProtectedRoute exact admin path='/home' render={props => (<Home {...props} onChangeTitle={this.handleChangeTitle} />)} />
|
||||
<DefaultRoute />
|
||||
</Switch>
|
||||
<Column.Item>
|
||||
<Box background={colorInfo.headerButtonBackground} borderTop={{ width: sizeInfo.headerBorderWidth, color: colorInfo.headerBorder }}>
|
||||
|
||||
@@ -2,6 +2,7 @@ import React from 'react'
|
||||
import { api } from 'src/API'
|
||||
import PropTypes from 'prop-types'
|
||||
import { MessageModal, WaitModal } from '../Modal'
|
||||
import { Logout } from '.'
|
||||
import autobind from 'autobind-decorator'
|
||||
|
||||
export class ConfirmEmail extends React.Component {
|
||||
@@ -17,7 +18,8 @@ export class ConfirmEmail extends React.Component {
|
||||
}
|
||||
|
||||
componentDidMount(props) {
|
||||
let emailToken = new URLSearchParams(decodeURIComponent(window.location.search)).get('email-token')
|
||||
const emailToken = new URLSearchParams(decodeURIComponent(window.location.search)).get('email-token')
|
||||
|
||||
this.setState({ waitModal: { message: 'Validating Email...' } })
|
||||
if (emailToken) {
|
||||
api.confirmEmail(emailToken).then((response) => {
|
||||
@@ -29,21 +31,17 @@ export class ConfirmEmail extends React.Component {
|
||||
this.props.history.replace('/login')
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
const supportEmail = 'support@kingstonsoftware.solutions' // TODO: From configuration
|
||||
const message = err.message.includes('The token was not found')
|
||||
? 'This email address may have already been confirmed.'
|
||||
: `Please contact ${supportEmail} to request a new user invitation`
|
||||
this.setState({
|
||||
waitModal: null,
|
||||
messageModal: {
|
||||
title: 'Error Verifying Email...',
|
||||
message: `We couldn't complete that request. ${message}`
|
||||
icon: 'hand',
|
||||
message: `Please contact ${process.env.REACT_APP_SUPPORT_EMAIL} to request another confirmation email.`,
|
||||
detail: err.message
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.props.history.replace('/login')
|
||||
this.props.history.replace('/')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,14 +52,23 @@ export class ConfirmEmail extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { messageModal, waitModal } = this.state
|
||||
|
||||
if (api.loggedInUser) {
|
||||
return <Logout redirect={`${window.location.pathname}${window.location.search}`} />
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<WaitModal active={!!this.state.waitModal}
|
||||
message={this.state.waitModal ? this.state.waitModal.message : ''} />
|
||||
<WaitModal
|
||||
active={!!waitModal}
|
||||
message={waitModal ? waitModal.message : ''} />
|
||||
|
||||
<MessageModal error open={!!this.state.messageModal}
|
||||
title={this.state.messageModal ? this.state.messageModal.title : ''}
|
||||
message={this.state.messageModal ? this.state.messageModal.message : ''}
|
||||
<MessageModal
|
||||
open={!!messageModal}
|
||||
icon={messageModal ? messageModal.icon : ''}
|
||||
message={messageModal ? messageModal.message : ''}
|
||||
detail={messageModal ? messageModal.title : ''}
|
||||
onDismiss={this.handleMessageModalDismiss} />
|
||||
</div>
|
||||
)
|
||||
|
||||
47
website/src/Auth/DefaultRoute.js
Normal file
47
website/src/Auth/DefaultRoute.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import React, { Fragment, Component } from 'react'
|
||||
import { api } from 'src/API'
|
||||
import { Route, Redirect } from 'react-router-dom'
|
||||
import { Column } from 'ui'
|
||||
import autobind from 'autobind-decorator'
|
||||
|
||||
export class DefaultRoute extends Component {
|
||||
@autobind
|
||||
updateComponent() {
|
||||
this.forceUpdate()
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
api.addListener('login', this.updateComponent)
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
api.removeListener('login', this.updateComponent)
|
||||
}
|
||||
|
||||
render() {
|
||||
const user = api.loggedInUser
|
||||
let redirect = null
|
||||
|
||||
if (user) {
|
||||
if (!user.pending) {
|
||||
redirect = <Redirect to={user.administrator ? '/home' : '/profile'} />
|
||||
}
|
||||
} else {
|
||||
redirect = <Redirect to='/login' />
|
||||
}
|
||||
|
||||
return (
|
||||
<Route
|
||||
path='/'
|
||||
render={() => {
|
||||
return (
|
||||
<Fragment>
|
||||
<Column.Item grow />
|
||||
{redirect}
|
||||
</Fragment>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { Image, Text, Column, Row, BoundInput, BoundButton, Box } from 'ui'
|
||||
import { MessageModal, WaitModal } from '../Modal'
|
||||
import { api } from 'src/API'
|
||||
import { FormBinder } from 'react-form-binder'
|
||||
import { Logout } from '.'
|
||||
import headerLogo from 'images/deighton.png'
|
||||
import { sizeInfo, colorInfo } from 'ui/style'
|
||||
import autobind from 'autobind-decorator'
|
||||
@@ -65,6 +66,10 @@ export class ForgotPassword extends Component {
|
||||
render() {
|
||||
const { binder, waitModal, messageModal } = this.state
|
||||
|
||||
if (api.loggedInUser) {
|
||||
return <Logout redirect={`${window.location.pathname}${window.location.search}`} />
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Column.Item grow />
|
||||
|
||||
@@ -1,21 +1,36 @@
|
||||
import React from 'react'
|
||||
import React, { Component, Fragment } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { api } from 'src/API'
|
||||
import { Column } from 'ui'
|
||||
|
||||
export class Logout extends React.Component {
|
||||
export class Logout extends Component {
|
||||
static propTypes = {
|
||||
history: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
|
||||
redirect: PropTypes.string,
|
||||
}
|
||||
|
||||
componentDidMount(event) {
|
||||
api.logout().then(() => {
|
||||
if (this.props.history) {
|
||||
this.props.history.replace('/login')
|
||||
const { history, redirect } = this.props
|
||||
const cb = () => {
|
||||
if (history && redirect) {
|
||||
try {
|
||||
history.replace(redirect)
|
||||
} catch (error) {
|
||||
history.replace('/login')
|
||||
}
|
||||
} else {
|
||||
window.location.replace('/login')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
api.logout().then(cb, cb)
|
||||
}
|
||||
|
||||
render() {
|
||||
return null
|
||||
return (
|
||||
<Fragment>
|
||||
<Column.Item grow />
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,7 @@ import autobind from 'autobind-decorator'
|
||||
|
||||
export class ProtectedRoute extends React.Component {
|
||||
static propTypes = {
|
||||
location: PropTypes.shape({
|
||||
pathname: PropTypes.string,
|
||||
search: PropTypes.string,
|
||||
}),
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
roles: ['administrator']
|
||||
location: PropTypes.shape({ pathname: PropTypes.string, search: PropTypes.string }),
|
||||
}
|
||||
|
||||
@autobind
|
||||
@@ -30,7 +23,7 @@ export class ProtectedRoute extends React.Component {
|
||||
}
|
||||
|
||||
render(props) {
|
||||
let user = api.loggedInUser
|
||||
const user = api.loggedInUser
|
||||
|
||||
if (user) {
|
||||
if (user.pending) {
|
||||
@@ -40,8 +33,8 @@ export class ProtectedRoute extends React.Component {
|
||||
} else if (user.administrator) {
|
||||
return <Route {...this.props} />
|
||||
}
|
||||
} else {
|
||||
return <Redirect to={`/login?redirect=${this.props.location.pathname}${this.props.location.search}`} />
|
||||
}
|
||||
|
||||
return <Redirect to={`/login?redirect=${this.props.location.pathname}${this.props.location.search}`} />
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { Component, Fragment } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Box, Text, Image, Column, Row, BoundInput, BoundButton } from 'ui'
|
||||
import { Logout } from '.'
|
||||
import { MessageModal, WaitModal } from '../Modal'
|
||||
import { api } from 'src/API'
|
||||
import { FormBinder } from 'react-form-binder'
|
||||
@@ -32,7 +33,39 @@ export class ResetPassword extends Component {
|
||||
this.state = {
|
||||
binder: new FormBinder({}, ResetPassword.bindings),
|
||||
messageModal: null,
|
||||
waitModal: null
|
||||
waitModal: null,
|
||||
tokenConfirmed: false,
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount(props) {
|
||||
if (this.state.tokenConfirmed) {
|
||||
return
|
||||
}
|
||||
|
||||
const passwordToken = new URLSearchParams(decodeURIComponent(window.location.search)).get('password-token')
|
||||
|
||||
this.setState({ waitModal: { message: 'Confirming password reset...' } })
|
||||
if (passwordToken) {
|
||||
api.confirmResetPassword(passwordToken).then((response) => {
|
||||
this.setState({ waitModal: null })
|
||||
if (response && response.valid) {
|
||||
this.setState({ tokenConfirmed: true })
|
||||
} else {
|
||||
this.props.history.replace('/')
|
||||
}
|
||||
}).catch((err) => {
|
||||
this.setState({
|
||||
waitModal: null,
|
||||
messageModal: {
|
||||
icon: 'hand',
|
||||
message: `We were unable to confirm you requested a password reset. Please request another reset email.`,
|
||||
detail: err.message
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.props.history.replace('/')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,8 +87,9 @@ export class ResetPassword extends Component {
|
||||
waitModal: null,
|
||||
messageModal: {
|
||||
icon: 'hand',
|
||||
title: 'There was a problem changing your password',
|
||||
message: 'There was a problem changing your password. Please request another reset email.',
|
||||
detail: err.message,
|
||||
noRetry: true,
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -63,12 +97,20 @@ export class ResetPassword extends Component {
|
||||
|
||||
@autobind
|
||||
handleMessageModalDismiss() {
|
||||
this.setState({ messageModal: null })
|
||||
if (this.state.messageModal.noRetry) {
|
||||
this.props.history.replace('/login')
|
||||
} else {
|
||||
this.setState({ messageModal: null })
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { messageModal, waitModal, binder } = this.state
|
||||
|
||||
if (api.loggedInUser) {
|
||||
return <Logout redirect={`${window.location.pathname}${window.location.search}`} />
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Column.Item grow />
|
||||
@@ -132,8 +174,8 @@ export class ResetPassword extends Component {
|
||||
<MessageModal
|
||||
open={!!messageModal}
|
||||
icon={messageModal ? messageModal.icon : ''}
|
||||
title={messageModal ? messageModal.title : ''}
|
||||
message={messageModal ? messageModal.message : ''}
|
||||
detail={messageModal ? messageModal.title : ''}
|
||||
onDismiss={this.handleMessageModalDismiss} />
|
||||
|
||||
<WaitModal active={!!waitModal}
|
||||
|
||||
@@ -3,4 +3,5 @@ export { Logout } from './Logout'
|
||||
export { ResetPassword } from './ResetPassword'
|
||||
export { ForgotPassword } from './ForgotPassword'
|
||||
export { ConfirmEmail } from './ConfirmEmail'
|
||||
export { DefaultRoute } from './DefaultRoute'
|
||||
export { ProtectedRoute } from './ProtectedRoute'
|
||||
|
||||
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
|
||||
import autobind from 'autobind-decorator'
|
||||
import { Modal, Button, Icon, Column, Row, Text, BoundInput, BoundButton } from 'ui'
|
||||
import { FormBinder } from 'react-form-binder'
|
||||
import { sizeInfo } from 'ui/style'
|
||||
|
||||
export class ChangePasswordModal extends React.Component {
|
||||
static propTypes = {
|
||||
@@ -66,7 +67,7 @@ export class ChangePasswordModal extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Modal dimmer='inverted' open={this.props.open} onClose={this.handleClose} closeOnDimmerClick={false}>
|
||||
<Modal dimmer='inverted' open={this.props.open} width={sizeInfo.modalWidth}>
|
||||
<form id='passwordForm' onSubmit={this.handleSubmit}>
|
||||
<Column.Item color='black' icon='edit'>
|
||||
<Text size='large'>Change Password</Text>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import React from 'react'
|
||||
import React, { Fragment, Component } from 'react'
|
||||
import { ProfileForm } from './ProfileForm'
|
||||
import { api } from 'src/API'
|
||||
import { WaitModal, MessageModal, ChangePasswordModal, ChangeEmailModal } from '../Modal'
|
||||
import { Column, Row } from 'ui'
|
||||
import { sizeInfo } from 'ui/style'
|
||||
import autobind from 'autobind-decorator'
|
||||
|
||||
export class Profile extends React.Component {
|
||||
export class Profile extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
@@ -129,26 +131,37 @@ export class Profile extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<ProfileForm
|
||||
user={this.state.user}
|
||||
onSaved={this.handleSaved}
|
||||
onSelectImage={this.handleSelectImage}
|
||||
onChangePassword={this.handleChangePassword}
|
||||
onChangeEmail={this.handleChangeEmail}
|
||||
userImageUrl={this.state.userImageUrl} />
|
||||
<Fragment>
|
||||
<Column.Item grow />
|
||||
<Column.Item>
|
||||
<Row>
|
||||
<Row.Item grow />
|
||||
<Row.Item width={sizeInfo.modalWidth}>
|
||||
<ProfileForm
|
||||
user={this.state.user}
|
||||
onSaved={this.handleSaved}
|
||||
onSelectImage={this.handleSelectImage}
|
||||
onChangePassword={this.handleChangePassword}
|
||||
onChangeEmail={this.handleChangeEmail}
|
||||
userImageUrl={this.state.userImageUrl} />
|
||||
</Row.Item>
|
||||
<Row.Item grow />
|
||||
</Row>
|
||||
</Column.Item>
|
||||
<Column.Item>
|
||||
<MessageModal error open={!!this.state.messageModal}
|
||||
title={this.state.messageModal ? this.state.messageModal.title : ''}
|
||||
message={this.state.messageModal ? this.state.messageModal.message : ''}
|
||||
onDismiss={this.handleMessageModalDismiss} />
|
||||
|
||||
<MessageModal error open={!!this.state.messageModal}
|
||||
title={this.state.messageModal ? this.state.messageModal.title : ''}
|
||||
message={this.state.messageModal ? this.state.messageModal.message : ''}
|
||||
onDismiss={this.handleMessageModalDismiss} />
|
||||
<ChangeEmailModal open={!!this.state.changeEmailModal} onDismiss={this.handleChangeEmailDismiss} />
|
||||
|
||||
<ChangeEmailModal open={!!this.state.changeEmailModal} onDismiss={this.handleChangeEmailDismiss} />
|
||||
<WaitModal active={!!this.state.waitModal} message={this.state.waitModal ? this.state.waitModal.message : ''} />
|
||||
|
||||
<WaitModal active={!!this.state.waitModal} message={this.state.waitModal ? this.state.waitModal.message : ''} />
|
||||
|
||||
<ChangePasswordModal open={!!this.state.changePasswordModal} onDismiss={this.handleChangePasswordDismiss} />
|
||||
</div>
|
||||
<ChangePasswordModal open={!!this.state.changePasswordModal} onDismiss={this.handleChangePasswordDismiss} />
|
||||
</Column.Item>
|
||||
<Column.Item grow />
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Column, Button, BoundInput, BoundButton } from 'ui'
|
||||
import { Column, Row, Box, Button, BoundInput, BoundButton } from 'ui'
|
||||
import { sizeInfo, colorInfo } from 'ui/style'
|
||||
import { regExpPattern } from 'regexp-pattern'
|
||||
import { FormBinder } from 'react-form-binder'
|
||||
import autobind from 'autobind-decorator'
|
||||
@@ -90,32 +91,39 @@ export class ProfileForm extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { binder } = this.state
|
||||
|
||||
return (
|
||||
<form onSubmit={this.handleSubmit} id='profileForm'>
|
||||
<Column stackable>
|
||||
<Column.Item>
|
||||
<BoundInput label='First Name' name='firstName'
|
||||
binder={this.state.binder} />
|
||||
</Column.Item>
|
||||
<Column.Item>
|
||||
<BoundInput label='Last Name' name='lastName'
|
||||
binder={this.state.binder} />
|
||||
</Column.Item>
|
||||
<Column.Item>
|
||||
<BoundInput label='Email' name='email' message='Required. Must be a valid email address.'
|
||||
binder={this.state.binder} />
|
||||
</Column.Item>
|
||||
<Column.Item>
|
||||
<Button fluid content={'Change Email'} label=' '
|
||||
onClick={this.props.onChangeEmail} />
|
||||
<Button fluid content={'Change Password'} label=' '
|
||||
onClick={this.props.onChangePassword} />
|
||||
</Column.Item>
|
||||
<Column.Item>
|
||||
<BoundButton submit primary size='medium' content='Save' label=' ' name='save'
|
||||
binder={this.state.binder} />
|
||||
</Column.Item>
|
||||
</Column>
|
||||
<Box border={{ width: sizeInfo.headerBorderWidth, color: colorInfo.headerBorder }} radius={sizeInfo.formBoxRadius}>
|
||||
<Row>
|
||||
<Row.Item width={sizeInfo.formRowSpacing} />
|
||||
<Row.Item>
|
||||
<Column stackable>
|
||||
<Column.Item>
|
||||
<BoundInput label='First Name' name='firstName'
|
||||
binder={binder} />
|
||||
</Column.Item>
|
||||
<Column.Item>
|
||||
<BoundInput label='Last Name' name='lastName'
|
||||
binder={binder} />
|
||||
</Column.Item>
|
||||
<Column.Item>
|
||||
<BoundInput label='Email' name='email' message='Required. Must be a valid email address.'
|
||||
binder={binder} />
|
||||
</Column.Item>
|
||||
<Column.Item>
|
||||
<Button text={'Change Email'} label=' '
|
||||
onClick={this.props.onChangeEmail} />
|
||||
<Button text={'Change Password'} label=' '
|
||||
onClick={this.props.onChangePassword} />
|
||||
<BoundButton submit size='medium' text='Save' label=' ' name='save'
|
||||
binder={binder} />
|
||||
</Column.Item>
|
||||
</Column>
|
||||
</Row.Item>
|
||||
</Row>
|
||||
</Box>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -195,7 +195,6 @@ export class Users extends Component {
|
||||
@autobind
|
||||
handleRemoveModalDismiss(yes) {
|
||||
if (yes) {
|
||||
// TODO: Pass the _id back from the dialog input data
|
||||
const selectedUserId = this.state.selectedUser._id
|
||||
const selectedIndex = this.state.users.findIndex((user) => (user._id === selectedUserId))
|
||||
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import Radium from 'radium'
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { sizeInfo } from './style'
|
||||
|
||||
// See https://www.flaticon.com/packs/free-basic-ui-elements
|
||||
|
||||
@Radium
|
||||
export class Icon extends Component {
|
||||
static propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
size: PropTypes.number,
|
||||
margin: PropTypes.number,
|
||||
style: PropTypes.object,
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
@@ -33,11 +36,11 @@ export class Icon extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
let { size, name, margin } = this.props
|
||||
let { size, name, margin, style } = this.props
|
||||
let source = Icon.svgs[name] || Icon.svgs['placeholder']
|
||||
|
||||
size -= margin * 2
|
||||
|
||||
return <img style={{ width: size, height: size, margin }} src={source} />
|
||||
return <img style={[{ width: size, height: size, margin }, style]} src={source} />
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,10 @@ export class PanelButton extends Component {
|
||||
]}
|
||||
onClick={onClick}>
|
||||
<div style={{ position: 'relative' }}>
|
||||
<Icon name={icon} size={sizeInfo.panelButtonIcon} margin={sizeInfo.panelButtonIconMargin} />
|
||||
<Icon
|
||||
name={icon} size={sizeInfo.panelButtonIcon}
|
||||
margin={sizeInfo.panelButtonIconMargin}
|
||||
style={{ position: 'relative', top: sizeInfo.panelButtonIconOffset }} />
|
||||
<span style={{
|
||||
position: 'absolute',
|
||||
top: sizeInfo.panelButtonTextOffset,
|
||||
|
||||
@@ -61,9 +61,10 @@ const sizeInfo = {
|
||||
panelButton: 200,
|
||||
panelButtonIcon: 170,
|
||||
panelButtonIconMargin: 0,
|
||||
panelButtonIconOffset: -10,
|
||||
panelButtonBorderRadius: 25,
|
||||
panelButtonBorderWidth: 2,
|
||||
panelButtonTextOffset: 125,
|
||||
panelButtonTextOffset: 120,
|
||||
panelButtonSpacing: 30,
|
||||
|
||||
formBoxRadius: 5,
|
||||
|
||||
Reference in New Issue
Block a user