Add actual start time to team
This commit is contained in:
Binary file not shown.
@@ -4,7 +4,6 @@ export let teamSchema = new Schema(
|
|||||||
{
|
{
|
||||||
name: { type: String },
|
name: { type: String },
|
||||||
start: { type: Date },
|
start: { type: Date },
|
||||||
stop: { type: Date },
|
|
||||||
},
|
},
|
||||||
{ timestamps: true, id: false }
|
{ timestamps: true, id: false }
|
||||||
)
|
)
|
||||||
|
|||||||
6393
website/package-lock.json
generated
6393
website/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,7 @@
|
|||||||
"animejs": "^2.2.0",
|
"animejs": "^2.2.0",
|
||||||
"autobind-decorator": "^2.1.0",
|
"autobind-decorator": "^2.1.0",
|
||||||
"eventemitter3": "^2.0.3",
|
"eventemitter3": "^2.0.3",
|
||||||
|
"moment": "^2.22.1",
|
||||||
"npm": "^5.7.1",
|
"npm": "^5.7.1",
|
||||||
"prop-types": "^15.5.10",
|
"prop-types": "^15.5.10",
|
||||||
"radium": "^0.22.0",
|
"radium": "^0.22.0",
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import React from 'react'
|
import React from "react"
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from "prop-types"
|
||||||
import autobind from 'autobind-decorator'
|
import autobind from "autobind-decorator"
|
||||||
import { Row, Column, BoundInput, BoundButton, List } from 'ui'
|
import { Row, Column, BoundInput, BoundButton, List, FormIconButton } from "ui"
|
||||||
import { FormBinder } from 'react-form-binder'
|
import { FormBinder } from "react-form-binder"
|
||||||
import { sizeInfo } from 'ui/style'
|
import { sizeInfo } from "ui/style"
|
||||||
import { api } from 'src/API'
|
import moment from "moment"
|
||||||
|
import { api } from "src/API"
|
||||||
|
|
||||||
export class TeamForm extends React.Component {
|
export class TeamForm extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@@ -16,21 +17,24 @@ export class TeamForm extends React.Component {
|
|||||||
|
|
||||||
static bindings = {
|
static bindings = {
|
||||||
name: {
|
name: {
|
||||||
isValid: (r, v) => (v !== '')
|
isValid: (r, v) => v !== "",
|
||||||
|
},
|
||||||
|
start: {
|
||||||
|
isValid: (r, v) => v === "" || moment(v).isValid(),
|
||||||
},
|
},
|
||||||
remove: {
|
remove: {
|
||||||
noValue: true,
|
noValue: true,
|
||||||
isVisible: (r) => (r._id),
|
isVisible: (r) => r._id,
|
||||||
},
|
},
|
||||||
reset: {
|
reset: {
|
||||||
noValue: true,
|
noValue: true,
|
||||||
isDisabled: (r) => {
|
isDisabled: (r) => {
|
||||||
return !r.anyModified
|
return !r.anyModified
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
submit: {
|
submit: {
|
||||||
noValue: true,
|
noValue: true,
|
||||||
isDisabled: (r) => (!r.anyModified || !r.allValid),
|
isDisabled: (r) => !r.anyModified || !r.allValid,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,8 +42,12 @@ export class TeamForm extends React.Component {
|
|||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
binder: new FormBinder(props.team, TeamForm.bindings, this.props.onModifiedChanged),
|
binder: new FormBinder(
|
||||||
users: []
|
props.team,
|
||||||
|
TeamForm.bindings,
|
||||||
|
this.props.onModifiedChanged
|
||||||
|
),
|
||||||
|
users: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getUsersForTeam(props.team._id)
|
this.getUsersForTeam(props.team._id)
|
||||||
@@ -48,19 +56,26 @@ export class TeamForm extends React.Component {
|
|||||||
@autobind
|
@autobind
|
||||||
getUsersForTeam(teamId) {
|
getUsersForTeam(teamId) {
|
||||||
if (teamId) {
|
if (teamId) {
|
||||||
api.listUsersForTeam(teamId).then((list) => {
|
api
|
||||||
list.items.sort((a, b) => (a.lastName.localeCompare(b.lastName)))
|
.listUsersForTeam(teamId)
|
||||||
this.setState({ users: list.items })
|
.then((list) => {
|
||||||
}).catch(() => {
|
list.items.sort((a, b) => a.lastName.localeCompare(b.lastName))
|
||||||
this.setState({ users: [] })
|
this.setState({ users: list.items })
|
||||||
})
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.setState({ users: [] })
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
if (nextProps.team !== this.props.team) {
|
if (nextProps.team !== this.props.team) {
|
||||||
this.setState({
|
this.setState({
|
||||||
binder: new FormBinder(nextProps.team, TeamForm.bindings, nextProps.onModifiedChanged)
|
binder: new FormBinder(
|
||||||
|
nextProps.team,
|
||||||
|
TeamForm.bindings,
|
||||||
|
nextProps.onModifiedChanged
|
||||||
|
),
|
||||||
})
|
})
|
||||||
|
|
||||||
this.getUsersForTeam(nextProps.team._id)
|
this.getUsersForTeam(nextProps.team._id)
|
||||||
@@ -82,18 +97,30 @@ export class TeamForm extends React.Component {
|
|||||||
handleReset() {
|
handleReset() {
|
||||||
const { team, onModifiedChanged } = this.props
|
const { team, onModifiedChanged } = this.props
|
||||||
|
|
||||||
this.setState({ binder: new FormBinder(team, TeamForm.bindings, onModifiedChanged) })
|
this.setState({
|
||||||
|
binder: new FormBinder(team, TeamForm.bindings, onModifiedChanged),
|
||||||
|
})
|
||||||
|
|
||||||
if (onModifiedChanged) {
|
if (onModifiedChanged) {
|
||||||
onModifiedChanged(false)
|
onModifiedChanged(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
handleStartNow() {
|
||||||
|
if (this.startTimeInput) {
|
||||||
|
this.startTimeInput.handleChange(moment().format())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { binder, users } = this.state
|
const { binder, users } = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form style={{ width: '100%', height: '100%', overflow: 'scroll' }} id='teamForm' onSubmit={this.handleSubmit}>
|
<form
|
||||||
|
style={{ width: "100%", height: "100%", overflow: "scroll" }}
|
||||||
|
id="teamForm"
|
||||||
|
onSubmit={this.handleSubmit}>
|
||||||
<Column>
|
<Column>
|
||||||
<Column.Item height={sizeInfo.formColumnSpacing} />
|
<Column.Item height={sizeInfo.formColumnSpacing} />
|
||||||
<Column.Item>
|
<Column.Item>
|
||||||
@@ -102,29 +129,79 @@ export class TeamForm extends React.Component {
|
|||||||
<Row.Item grow>
|
<Row.Item grow>
|
||||||
<Column>
|
<Column>
|
||||||
<Column.Item>
|
<Column.Item>
|
||||||
<BoundInput label='Name' name='name' message='Must not be empty' binder={binder} />
|
<BoundInput
|
||||||
|
label="Name"
|
||||||
|
name="name"
|
||||||
|
message="Must not be empty"
|
||||||
|
binder={binder}
|
||||||
|
/>
|
||||||
</Column.Item>
|
</Column.Item>
|
||||||
<Column.Item height={300}>
|
<Column.Item height={300}>
|
||||||
<List items={users} render={(item) => (
|
<List
|
||||||
<List.Item key={item._id}>
|
items={users}
|
||||||
<List.Icon name='profile' size={sizeInfo.dropdownIconSize} />
|
render={(item) => (
|
||||||
<List.Text>{item.firstName + ' ' + item.lastName}</List.Text>
|
<List.Item key={item._id}>
|
||||||
</List.Item>
|
<List.Icon
|
||||||
)} />
|
name="profile"
|
||||||
|
size={sizeInfo.dropdownIconSize}
|
||||||
|
/>
|
||||||
|
<List.Text>
|
||||||
|
{item.firstName + " " + item.lastName}
|
||||||
|
</List.Text>
|
||||||
|
</List.Item>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Column.Item>
|
||||||
|
<Column.Item height={sizeInfo.formColumnSpacing} />
|
||||||
|
<Column.Item>
|
||||||
|
<Row>
|
||||||
|
<Row.Item grow={1}>
|
||||||
|
<BoundInput
|
||||||
|
ref={(ref) => (this.startTimeInput = ref)}
|
||||||
|
label="Start Time"
|
||||||
|
name="start"
|
||||||
|
binder={binder}
|
||||||
|
message="Must enter a valid date and time"
|
||||||
|
/>
|
||||||
|
</Row.Item>
|
||||||
|
<Row.Item width={sizeInfo.formRowSpacing} />
|
||||||
|
<Row.Item>
|
||||||
|
<FormIconButton
|
||||||
|
icon="clock"
|
||||||
|
onClick={this.handleStartNow}
|
||||||
|
/>
|
||||||
|
</Row.Item>
|
||||||
|
<Row.Item grow={2} />
|
||||||
|
</Row>
|
||||||
</Column.Item>
|
</Column.Item>
|
||||||
<Column.Item height={sizeInfo.formColumnSpacing} />
|
<Column.Item height={sizeInfo.formColumnSpacing} />
|
||||||
<Column.Item minHeight={sizeInfo.buttonHeight}>
|
<Column.Item minHeight={sizeInfo.buttonHeight}>
|
||||||
<Row>
|
<Row>
|
||||||
<Row.Item>
|
<Row.Item>
|
||||||
<BoundButton text='Reset' name='reset' binder={binder} onClick={this.handleReset} />
|
<BoundButton
|
||||||
|
text="Reset"
|
||||||
|
name="reset"
|
||||||
|
binder={binder}
|
||||||
|
onClick={this.handleReset}
|
||||||
|
/>
|
||||||
</Row.Item>
|
</Row.Item>
|
||||||
<Row.Item grow />
|
<Row.Item grow />
|
||||||
<Row.Item>
|
<Row.Item>
|
||||||
<BoundButton text='Remove' name='remove' binder={binder} onClick={this.props.onRemove} />
|
<BoundButton
|
||||||
|
text="Remove"
|
||||||
|
name="remove"
|
||||||
|
binder={binder}
|
||||||
|
onClick={this.props.onRemove}
|
||||||
|
/>
|
||||||
</Row.Item>
|
</Row.Item>
|
||||||
<Row.Item width={sizeInfo.formRowSpacing} />
|
<Row.Item width={sizeInfo.formRowSpacing} />
|
||||||
<Row.Item>
|
<Row.Item>
|
||||||
<BoundButton submit='teamForm' text={binder._id ? 'Save' : 'Add'} name='submit' binder={binder} />
|
<BoundButton
|
||||||
|
submit="teamForm"
|
||||||
|
text={binder._id ? "Save" : "Add"}
|
||||||
|
name="submit"
|
||||||
|
binder={binder}
|
||||||
|
/>
|
||||||
</Row.Item>
|
</Row.Item>
|
||||||
</Row>
|
</Row>
|
||||||
</Column.Item>
|
</Column.Item>
|
||||||
|
|||||||
16
website/src/assets/icons/clock.svg
Normal file
16
website/src/assets/icons/clock.svg
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="74px" height="74px" viewBox="0 0 74 74" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 49.3 (51167) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>clock</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Login" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="Images-&-Icons" transform="translate(-824.000000, -467.000000)" fill="#E2DEDE" fill-rule="nonzero">
|
||||||
|
<g id="clock" transform="translate(824.000000, 467.000000)">
|
||||||
|
<path d="M54.8,35.6 L39.4,35.6 L39.4,20.2 C39.4,18.9850133 38.4149867,18 37.2,18 C35.9850133,18 35,18.9850133 35,20.2 L35,37.8 C35,39.0149867 35.9850133,40 37.2,40 L54.8,40 C56.0149867,40 57,39.0149867 57,37.8 C57,36.5850133 56.0149867,35.6 54.8,35.6 Z" id="Shape"></path>
|
||||||
|
<path d="M37.1445312,0 C16.925332,0 0,16.3356445 0,36.8554688 C0,57.1829219 16.7531953,74 37.1445312,74 C57.6867578,74 74,57.0526992 74,36.8554688 C74,16.4853789 57.5163555,0 37.1445312,0 Z M37.1445313,69.6929688 C19.0538438,69.6929688 4.30703125,54.9461563 4.30703125,36.8554688 C4.30703125,18.9241992 19.0538438,4.30703125 37.1445313,4.30703125 C55.0758008,4.30703125 69.6929688,18.9241992 69.6929688,36.8554688 C69.6929688,54.9461563 55.0758008,69.6929688 37.1445313,69.6929688 Z" id="Shape"></path>
|
||||||
|
<path d="M37.6454082,9 C22.0310434,9 9,21.6614158 9,37.3545918 C9,52.9849515 21.9627015,66 37.6454082,66 C53.3532704,66 66,52.9579056 66,37.3545918 C66,21.7198699 53.2801301,9 37.6454082,9 Z M37.6454082,61.6668367 C24.482625,61.6668367 13.3331633,50.517375 13.3331633,37.3545918 C13.3331633,24.1252117 24.2556429,13.3331633 37.6454082,13.3331633 C50.8747883,13.3331633 61.6668367,24.1252117 61.6668367,37.3545918 C61.6668367,50.7443571 50.8747883,61.6668367 37.6454082,61.6668367 Z" id="Shape"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react'
|
import React from "react"
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from "prop-types"
|
||||||
import { Text, Icon } from 'ui'
|
import { Text, Icon } from "ui"
|
||||||
import { sizeInfo } from 'ui/style'
|
import { sizeInfo } from "ui/style"
|
||||||
|
|
||||||
export class BoundEmailIcon extends React.Component {
|
export class BoundEmailIcon extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@@ -27,7 +27,11 @@ export class BoundEmailIcon extends React.Component {
|
|||||||
<div>
|
<div>
|
||||||
<Text> </Text>
|
<Text> </Text>
|
||||||
<br />
|
<br />
|
||||||
<Icon name={value ? 'confirmed' : 'warning'} size={sizeInfo.formBoundIcon} margin={sizeInfo.formBoundIconMargin} />
|
<Icon
|
||||||
|
name={value ? "confirmed" : "warning"}
|
||||||
|
size={sizeInfo.formBoundIcon}
|
||||||
|
margin={sizeInfo.formBoundIconMargin}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react'
|
import React from "react"
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from "prop-types"
|
||||||
import { Input, Text } from 'ui'
|
import { Input, Text } from "ui"
|
||||||
import autobind from 'autobind-decorator'
|
import autobind from "autobind-decorator"
|
||||||
|
|
||||||
export class BoundInput extends React.Component {
|
export class BoundInput extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@@ -10,7 +10,7 @@ export class BoundInput extends React.Component {
|
|||||||
label: PropTypes.string,
|
label: PropTypes.string,
|
||||||
binder: PropTypes.object.isRequired,
|
binder: PropTypes.object.isRequired,
|
||||||
password: PropTypes.bool,
|
password: PropTypes.bool,
|
||||||
placeholder: PropTypes.string
|
placeholder: PropTypes.string,
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -19,12 +19,12 @@ export class BoundInput extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
handleChange(e) {
|
handleChange(newValue) {
|
||||||
const { binder, name } = this.props
|
const { binder, name } = this.props
|
||||||
const state = binder.getFieldState(name)
|
const state = binder.getFieldState(name)
|
||||||
|
|
||||||
if (!state.readOnly && !state.disabled) {
|
if (!state.readOnly && !state.disabled) {
|
||||||
this.setState(binder.updateFieldValue(name, e.target.value))
|
this.setState(binder.updateFieldValue(name, newValue))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,17 +43,21 @@ export class BoundInput extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ width: '100%' }}>
|
<div style={{ width: "100%" }}>
|
||||||
<Text>{label}</Text>
|
<Text>{label}</Text>
|
||||||
<br />
|
<br />
|
||||||
<Input value={value}
|
<Input
|
||||||
|
value={value}
|
||||||
visible
|
visible
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
password={password}
|
password={password}
|
||||||
name={name}
|
name={name}
|
||||||
onChange={this.handleChange}
|
onChange={(e) => this.handleChange(e.target.value)}
|
||||||
placeholder={placeholder} />
|
placeholder={placeholder}
|
||||||
<Text size='small' color='alert' hidden={valid}>{message}</Text>
|
/>
|
||||||
|
<Text size="small" color="alert" hidden={valid}>
|
||||||
|
{message}
|
||||||
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
62
website/src/ui/FormIconButton.js
Normal file
62
website/src/ui/FormIconButton.js
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import Radium from "radium"
|
||||||
|
import PropTypes from "prop-types"
|
||||||
|
import React, { Component } from "react"
|
||||||
|
import { colorInfo, sizeInfo } from "./style"
|
||||||
|
import { Text, Icon } from "."
|
||||||
|
|
||||||
|
@Radium
|
||||||
|
export class FormIconButton extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
visible: PropTypes.bool,
|
||||||
|
// disabled: PropTypes.bool,
|
||||||
|
icon: PropTypes.string,
|
||||||
|
onClick: PropTypes.func,
|
||||||
|
}
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
visible: true,
|
||||||
|
disabled: false,
|
||||||
|
width: sizeInfo.buttonWidth,
|
||||||
|
}
|
||||||
|
|
||||||
|
static style = {
|
||||||
|
icon: {
|
||||||
|
borderWidth: 0,
|
||||||
|
borderRadius: sizeInfo.formButtonIconBorderRadius,
|
||||||
|
background: colorInfo.buttonBackgroundHover,
|
||||||
|
outline: "none",
|
||||||
|
padding: sizeInfo.formButtonIconPadding,
|
||||||
|
":hover": {
|
||||||
|
background: colorInfo.buttonBackground,
|
||||||
|
},
|
||||||
|
":disabled": {
|
||||||
|
background: colorInfo.buttonDisabledBackground,
|
||||||
|
},
|
||||||
|
":active": {
|
||||||
|
background: colorInfo.buttonBackgroundActive,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { icon, visible } = this.props
|
||||||
|
|
||||||
|
if (!visible) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Text> </Text>
|
||||||
|
<br />
|
||||||
|
<Icon
|
||||||
|
name={icon}
|
||||||
|
size={sizeInfo.formButtonIcon}
|
||||||
|
margin={sizeInfo.formButtonIconMargin}
|
||||||
|
style={FormIconButton.style.icon}
|
||||||
|
onClick={this.props.onClick}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import Radium from 'radium'
|
import Radium from "radium"
|
||||||
import React, { Component } from 'react'
|
import React, { Component } from "react"
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from "prop-types"
|
||||||
import { sizeInfo } from './style'
|
import { sizeInfo } from "./style"
|
||||||
|
|
||||||
// See https://www.flaticon.com/packs/free-basic-ui-elements
|
// See https://www.flaticon.com/packs/free-basic-ui-elements
|
||||||
|
|
||||||
@@ -12,6 +12,7 @@ export class Icon extends Component {
|
|||||||
size: PropTypes.number,
|
size: PropTypes.number,
|
||||||
margin: PropTypes.number,
|
margin: PropTypes.number,
|
||||||
style: PropTypes.object,
|
style: PropTypes.object,
|
||||||
|
onClick: PropTypes.func,
|
||||||
}
|
}
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@@ -20,28 +21,35 @@ export class Icon extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static svgs = {
|
static svgs = {
|
||||||
logout: require('icons/logout.svg'),
|
logout: require("icons/logout.svg"),
|
||||||
thumb: require('icons/thumb.svg'),
|
thumb: require("icons/thumb.svg"),
|
||||||
profile: require('icons/profile.svg'),
|
profile: require("icons/profile.svg"),
|
||||||
admin: require('icons/admin.svg'),
|
admin: require("icons/admin.svg"),
|
||||||
hand: require('icons/hand.svg'),
|
hand: require("icons/hand.svg"),
|
||||||
users: require('icons/users.svg'),
|
users: require("icons/users.svg"),
|
||||||
team: require('icons/team.svg'),
|
team: require("icons/team.svg"),
|
||||||
teams: require('icons/teams.svg'),
|
teams: require("icons/teams.svg"),
|
||||||
system: require('icons/system.svg'),
|
system: require("icons/system.svg"),
|
||||||
confirmed: require('icons/confirmed.svg'),
|
confirmed: require("icons/confirmed.svg"),
|
||||||
help: require('icons/help.svg'),
|
help: require("icons/help.svg"),
|
||||||
warning: require('icons/warning.svg'),
|
warning: require("icons/warning.svg"),
|
||||||
edit: require('icons/edit.svg'),
|
edit: require("icons/edit.svg"),
|
||||||
placeholder: require('icons/placeholder.svg'),
|
placeholder: require("icons/placeholder.svg"),
|
||||||
|
clock: require("icons/clock.svg"),
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { size, name, margin, style } = this.props
|
let { size, name, margin, style } = this.props
|
||||||
let source = Icon.svgs[name] || Icon.svgs['placeholder']
|
let source = Icon.svgs[name] || Icon.svgs["placeholder"]
|
||||||
|
|
||||||
size -= margin * 2
|
size -= margin * 2
|
||||||
|
|
||||||
return <img style={[{ width: size, height: size, margin }, style]} src={source} />
|
return (
|
||||||
|
<img
|
||||||
|
style={[{ width: size, height: size, margin }, style]}
|
||||||
|
src={source}
|
||||||
|
onClick={this.props.onClick}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import Radium from 'radium'
|
import Radium from "radium"
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from "prop-types"
|
||||||
import React, { Component } from 'react'
|
import React, { Component } from "react"
|
||||||
import { colorInfo, sizeInfo, fontInfo } from 'ui/style'
|
import { colorInfo, sizeInfo, fontInfo } from "ui/style"
|
||||||
|
|
||||||
// See https://stackoverflow.com/a/6891562/576235 for why we wrap the <input /> element
|
// See https://stackoverflow.com/a/6891562/576235 for why we wrap the <input /> element
|
||||||
|
|
||||||
@@ -10,12 +10,12 @@ export class Input extends Component {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
password: PropTypes.bool,
|
password: PropTypes.bool,
|
||||||
placeholder: PropTypes.string,
|
placeholder: PropTypes.string,
|
||||||
width: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
|
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
visible: PropTypes.bool,
|
visible: PropTypes.bool,
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
value: PropTypes.string,
|
value: PropTypes.string,
|
||||||
|
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
}
|
}
|
||||||
|
|
||||||
static style = {
|
static style = {
|
||||||
@@ -24,10 +24,10 @@ export class Input extends Component {
|
|||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
borderColor: colorInfo.border,
|
borderColor: colorInfo.border,
|
||||||
backgroundColor: colorInfo.inputBackground,
|
backgroundColor: colorInfo.inputBackground,
|
||||||
borderStyle: 'solid',
|
borderStyle: "solid",
|
||||||
borderRadius: sizeInfo.inputBorderRadius,
|
borderRadius: sizeInfo.inputBorderRadius,
|
||||||
':focus': {
|
":focus": {
|
||||||
outline: 'none'
|
outline: "none",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -37,24 +37,40 @@ export class Input extends Component {
|
|||||||
borderWidth: 0,
|
borderWidth: 0,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
margin: 0,
|
margin: 0,
|
||||||
width: '100%',
|
width: "100%",
|
||||||
outline: 'none',
|
outline: "none",
|
||||||
':disabled': {
|
":disabled": {
|
||||||
color: colorInfo.textDisabled,
|
color: colorInfo.textDisabled,
|
||||||
background: colorInfo.inputBackground,
|
background: colorInfo.inputBackground,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { name, width, password, placeholder, onChange, visible, disabled, value } = this.props
|
let {
|
||||||
|
name,
|
||||||
|
width,
|
||||||
|
password,
|
||||||
|
placeholder,
|
||||||
|
onChange,
|
||||||
|
visible,
|
||||||
|
disabled,
|
||||||
|
value,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
width = width || '100%'
|
width = width || "100%"
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={Input.style.div}>
|
<div style={Input.style.div}>
|
||||||
<input name={name} value={value} type={!visible ? 'hidden' : password ? 'password' : 'text'} disabled={disabled}
|
<input
|
||||||
style={[ { width }, Input.style.input ]} placeholder={placeholder} onChange={onChange} />
|
name={name}
|
||||||
|
value={value}
|
||||||
|
type={!visible ? "hidden" : password ? "password" : "text"}
|
||||||
|
disabled={disabled}
|
||||||
|
style={[{ width }, Input.style.input]}
|
||||||
|
placeholder={placeholder}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import Radium from 'radium'
|
import Radium from "radium"
|
||||||
import React, { Component } from 'react'
|
import React, { Component } from "react"
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from "prop-types"
|
||||||
|
|
||||||
@Radium
|
@Radium
|
||||||
export class Row extends Component {
|
export class Row extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
minWidth: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
|
minWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
width: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
|
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
fillParent: PropTypes.bool,
|
fillParent: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,30 +15,41 @@ export class Row extends Component {
|
|||||||
const { children, width, minWidth, fillParent } = this.props
|
const { children, width, minWidth, fillParent } = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={[
|
<div
|
||||||
{ display: 'flex', minWidth, width, flexDirection: 'row' },
|
style={[
|
||||||
fillParent && { position: 'absolute', width: '100%', height: '100%' },
|
{ display: "flex", minWidth, width, flexDirection: "row" },
|
||||||
]}>{children}</div>
|
fillParent && { position: "absolute", width: "100%", height: "100%" },
|
||||||
)
|
]}>
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row.Item = Radium(class RowLayoutItem extends Component {
|
|
||||||
static propTypes = {
|
|
||||||
children: PropTypes.node,
|
|
||||||
minWidth: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
|
|
||||||
width: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
|
|
||||||
grow: PropTypes.bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { children, grow, width, minWidth } = this.props
|
|
||||||
const flexGrow = grow ? 1 : null
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ position: 'relative', width, minWidth, flexGrow }}>
|
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
|
Row.Item = Radium(
|
||||||
|
class RowLayoutItem extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
children: PropTypes.node,
|
||||||
|
minWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
|
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
|
grow: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { children, grow, width, minWidth } = this.props
|
||||||
|
const flexGrow = !grow ? null : typeof grow === "number" ? grow : 1
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: "relative",
|
||||||
|
width,
|
||||||
|
minWidth,
|
||||||
|
flexGrow,
|
||||||
|
}}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,24 +1,25 @@
|
|||||||
export { Anime } from './Anime'
|
export { Anime } from "./Anime"
|
||||||
export { Box } from './Box'
|
export { Box } from "./Box"
|
||||||
export { Button } from './Button'
|
export { Button } from "./Button"
|
||||||
export { HeaderButton } from './HeaderButton'
|
export { FormIconButton } from "./FormIconButton"
|
||||||
export { HeaderText } from './HeaderText'
|
export { HeaderButton } from "./HeaderButton"
|
||||||
export { PanelButton } from './PanelButton'
|
export { HeaderText } from "./HeaderText"
|
||||||
export { Checkbox } from './Checkbox'
|
export { PanelButton } from "./PanelButton"
|
||||||
export { Input } from './Input'
|
export { Checkbox } from "./Checkbox"
|
||||||
export { Image } from './Image'
|
export { Input } from "./Input"
|
||||||
export { Text } from './Text'
|
export { Image } from "./Image"
|
||||||
export { Link } from './Link'
|
export { Text } from "./Text"
|
||||||
export { Icon } from './Icon'
|
export { Link } from "./Link"
|
||||||
export { List } from './List'
|
export { Icon } from "./Icon"
|
||||||
export { Dropdown } from './Dropdown'
|
export { List } from "./List"
|
||||||
export { Modal } from './Modal'
|
export { Dropdown } from "./Dropdown"
|
||||||
export { Dimmer } from './Dimmer'
|
export { Modal } from "./Modal"
|
||||||
export { Loader } from './Loader'
|
export { Dimmer } from "./Dimmer"
|
||||||
export { Row } from './Row'
|
export { Loader } from "./Loader"
|
||||||
export { Column } from './Column'
|
export { Row } from "./Row"
|
||||||
export { BoundButton } from './BoundButton'
|
export { Column } from "./Column"
|
||||||
export { BoundCheckbox } from './BoundCheckbox'
|
export { BoundButton } from "./BoundButton"
|
||||||
export { BoundInput } from './BoundInput'
|
export { BoundCheckbox } from "./BoundCheckbox"
|
||||||
export { BoundEmailIcon } from './BoundEmailIcon'
|
export { BoundInput } from "./BoundInput"
|
||||||
export { BoundDropdown } from './BoundDropdown'
|
export { BoundEmailIcon } from "./BoundEmailIcon"
|
||||||
|
export { BoundDropdown } from "./BoundDropdown"
|
||||||
|
|||||||
@@ -1,36 +1,36 @@
|
|||||||
let colorInfo = {
|
let colorInfo = {
|
||||||
text: '#000000',
|
text: "#000000",
|
||||||
textInverse: '#FFFFFF',
|
textInverse: "#FFFFFF",
|
||||||
textPlaceholder: '#EEEEEE',
|
textPlaceholder: "#EEEEEE",
|
||||||
textAlert: '#FF0000',
|
textAlert: "#FF0000",
|
||||||
textGray: '#B0B0B0',
|
textGray: "#B0B0B0",
|
||||||
textDisabled: '#AAAAAA',
|
textDisabled: "#AAAAAA",
|
||||||
|
|
||||||
border: '#B2B2B2',
|
border: "#B2B2B2",
|
||||||
|
|
||||||
modalShadow: '#000000',
|
modalShadow: "#000000",
|
||||||
modalBackground: '#FFFFFF',
|
modalBackground: "#FFFFFF",
|
||||||
|
|
||||||
inputBackground: '#FFFFFF',
|
inputBackground: "#FFFFFF",
|
||||||
|
|
||||||
buttonBackground: '#3498DB',
|
buttonBackground: "#3498DB",
|
||||||
buttonBackgroundHover: '#3CB0FD',
|
buttonBackgroundHover: "#3CB0FD",
|
||||||
buttonBackgroundActive: '#1A72AC',
|
buttonBackgroundActive: "#1A72AC",
|
||||||
buttonDisabledBackground: '#E0E0E0',
|
buttonDisabledBackground: "#E0E0E0",
|
||||||
|
|
||||||
headerBorder: '#B2B2B2',
|
headerBorder: "#B2B2B2",
|
||||||
headerButtonBackground: '#FAFAFA',
|
headerButtonBackground: "#FAFAFA",
|
||||||
headerButtonBackgroundHover: '#DADADA',
|
headerButtonBackgroundHover: "#DADADA",
|
||||||
headerButtonBackgroundActive: '#AAAAAA',
|
headerButtonBackgroundActive: "#AAAAAA",
|
||||||
|
|
||||||
checkboxUnchecked: '#A0A0A0',
|
checkboxUnchecked: "#A0A0A0",
|
||||||
checkboxUncheckedHover: '#808080',
|
checkboxUncheckedHover: "#808080",
|
||||||
checkmark: '#FFFFFF',
|
checkmark: "#FFFFFF",
|
||||||
|
|
||||||
listBackground: '#FFFFFF',
|
listBackground: "#FFFFFF",
|
||||||
listBackgroundActive: '#E7E5E5',
|
listBackgroundActive: "#E7E5E5",
|
||||||
|
|
||||||
dropdownBackground: '#FFFFFF',
|
dropdownBackground: "#FFFFFF",
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.assign(colorInfo, {
|
Object.assign(colorInfo, {
|
||||||
@@ -58,15 +58,15 @@ const sizeInfo = {
|
|||||||
headerTextOffset: 2,
|
headerTextOffset: 2,
|
||||||
headerButtonMargin: 8,
|
headerButtonMargin: 8,
|
||||||
|
|
||||||
footerTextMargin: '5px 0px 5px 10px',
|
footerTextMargin: "5px 0px 5px 10px",
|
||||||
|
|
||||||
buttonHeight: 40,
|
buttonHeight: 40,
|
||||||
buttonPadding: '0 15px 0 15px',
|
buttonPadding: "0 15px 0 15px",
|
||||||
buttonWidth: 125,
|
buttonWidth: 125,
|
||||||
buttonWideWidth: 225,
|
buttonWideWidth: 225,
|
||||||
|
|
||||||
checkboxSize: 25,
|
checkboxSize: 25,
|
||||||
checkmarkBorder: '0 3px 3px 0',
|
checkmarkBorder: "0 3px 3px 0",
|
||||||
|
|
||||||
panelButton: 200,
|
panelButton: 200,
|
||||||
panelButtonIcon: 170,
|
panelButtonIcon: 170,
|
||||||
@@ -83,22 +83,27 @@ const sizeInfo = {
|
|||||||
formBoundIcon: 30,
|
formBoundIcon: 30,
|
||||||
formBoundIconMargin: 0,
|
formBoundIconMargin: 0,
|
||||||
|
|
||||||
|
formButtonIcon: 24,
|
||||||
|
formButtonIconMargin: 0,
|
||||||
|
formButtonIconBorderRadius: 4,
|
||||||
|
formButtonIconPadding: 3,
|
||||||
|
|
||||||
listBorderWidth: 1,
|
listBorderWidth: 1,
|
||||||
listTopBottomGap: 10,
|
listTopBottomGap: 10,
|
||||||
listIcon: 25,
|
listIcon: 25,
|
||||||
listIconMargin: '5px 10px 5px 10px',
|
listIconMargin: "5px 10px 5px 10px",
|
||||||
|
|
||||||
dropdownIconSize: 20,
|
dropdownIconSize: 20,
|
||||||
dropdownItems: 6,
|
dropdownItems: 6,
|
||||||
dropdownBorderWidth: 1,
|
dropdownBorderWidth: 1,
|
||||||
dropdownIcon: 25,
|
dropdownIcon: 25,
|
||||||
dropdownIconMargin: '5px 10px 5px 10px',
|
dropdownIconMargin: "5px 10px 5px 10px",
|
||||||
|
|
||||||
modalWidth: 450,
|
modalWidth: 450,
|
||||||
modalShadowWidth: 25,
|
modalShadowWidth: 25,
|
||||||
modalMessageIcon: 150,
|
modalMessageIcon: 150,
|
||||||
|
|
||||||
profileWidth: '65vw',
|
profileWidth: "65vw",
|
||||||
|
|
||||||
inputPadding: 5,
|
inputPadding: 5,
|
||||||
inputBorderRadius: 5,
|
inputBorderRadius: 5,
|
||||||
@@ -110,21 +115,21 @@ const sizeInfo = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fontInfo = {
|
const fontInfo = {
|
||||||
family: 'Hind, sans-serif', // https://fonts.google.com/specimen/Hind?selection.family=Hind
|
family: "Hind, sans-serif", // https://fonts.google.com/specimen/Hind?selection.family=Hind
|
||||||
size: {
|
size: {
|
||||||
small: '10pt',
|
small: "10pt",
|
||||||
medium: '12pt',
|
medium: "12pt",
|
||||||
large: '14pt',
|
large: "14pt",
|
||||||
huge: '26pt',
|
huge: "26pt",
|
||||||
header: '18pt',
|
header: "18pt",
|
||||||
footer: '8pt',
|
footer: "8pt",
|
||||||
},
|
},
|
||||||
color: {
|
color: {
|
||||||
'normal': colorInfo.text,
|
normal: colorInfo.text,
|
||||||
'inverse': colorInfo.textInverse,
|
inverse: colorInfo.textInverse,
|
||||||
'alert': colorInfo.textAlert,
|
alert: colorInfo.textAlert,
|
||||||
'dimmed': colorInfo.textGray,
|
dimmed: colorInfo.textGray,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export { colorInfo, sizeInfo, fontInfo }
|
export { colorInfo, sizeInfo, fontInfo }
|
||||||
|
|||||||
Reference in New Issue
Block a user