Work Item and Activity screens mostly complete

This commit is contained in:
John Lyon-Smith
2018-04-03 17:25:59 -07:00
parent 410d2fde4f
commit 72af9a7035
25 changed files with 512 additions and 141 deletions

View File

@@ -0,0 +1,53 @@
import React from 'react'
import PropTypes from 'prop-types'
import { View, Text } from 'react-native'
import { OptionStrip } from '.'
import autobind from 'autobind-decorator'
export class BoundOptionStrip extends React.Component {
static propTypes = {
name: PropTypes.string.isRequired,
label: PropTypes.string,
binder: PropTypes.object.isRequired,
options: PropTypes.arrayOf(PropTypes.shape({ value: PropTypes.string, text: PropTypes.string })).isRequired,
}
constructor(props) {
super(props)
this.state = props.binder.getFieldState(props.name)
}
@autobind
handleValueChange() {
const { binder, name } = this.props
const state = binder.getFieldState(name)
if (!state.readOnly && !state.disabled) {
this.setState(binder.updateFieldValue(name, !state.value))
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.binder !== this.props.binder) {
this.setState(nextProps.binder.getFieldState(nextProps.name))
}
}
render() {
const { name, label, options } = this.props
const { visible, disabled, value } = this.state
return (
<View style={{
display: visible ? 'flex' : 'none',
flexDirection: 'column',
}}>
<Text style={{ color: 'black', fontSize: 14, marginBottom: 5 }}>{label}</Text>
<OptionStrip
value={value}
options={options}
/>
</View>
)
}
}

View File

@@ -16,12 +16,12 @@ export class BoundSwitch extends React.Component {
}
@autobind
handleValueChange() {
handleValueChange(newValue) {
const { binder, name } = this.props
const state = binder.getFieldState(name)
if (!state.readOnly && !state.disabled) {
this.setState(binder.updateFieldValue(name, !state.value))
this.setState(binder.updateFieldValue(name, newValue))
}
}

View File

@@ -13,6 +13,11 @@ export class Header extends Component {
rightButton: PropTypes.shape(headerButtonShape),
}
static defaultProps = {
rightButton: { icon: 'none' },
leftButton: { icon: 'none' },
}
render() {
const { title, leftButton, rightButton } = this.props

View File

@@ -1,5 +1,5 @@
import React, { Component } from 'react'
import { Image } from 'react-native'
import { Image, View } from 'react-native'
import PropTypes from 'prop-types'
const images = {
@@ -11,6 +11,8 @@ const images = {
rightArrow: require('./images/right-arrow.png'),
search: require('./images/search.png'),
settings: require('./images/settings.png'),
add: require('./images/add.png'),
done: require('./images/done.png'),
}
export class Icon extends Component {
@@ -27,11 +29,14 @@ export class Icon extends Component {
}
render() {
let { size, name, margin, style } = this.props
let source = images[name] || images['hand']
let { name, margin, style } = this.props
let size = this.props.size - (margin * 2)
let source = images[name]
size -= margin * 2
return <Image style={[{ width: size, height: size, margin }, style]} source={source} resizeMode='stretch' />
if (!source) {
return <View style={{ width: size, height: size, margin }} />
} else {
return <Image style={[{ width: size, height: size, margin }, style]} source={source} resizeMode='stretch' />
}
}
}

View File

@@ -0,0 +1,70 @@
import React, { Component } from 'react'
import { View, Text, TouchableHighlight } from 'react-native'
import PropTypes from 'prop-types'
import autobind from 'autobind-decorator';
export class OptionStrip extends Component {
static propTypes = {
options: PropTypes.arrayOf(PropTypes.shape({ value: PropTypes.string, text: PropTypes.string })).isRequired,
value: PropTypes.string.isRequired,
onValueChanged: PropTypes.func,
}
constructor(props) {
super(props)
this.state = {
selectedOption: this.getSelectedOption(props.options, props.value)
}
}
@autobind
getSelectedOption(options, value) {
return options.find((option) => (value === option.value)) || options[0]
}
componentWillReceiveProps(newProps) {
if (newProps.options !== props.options || newProps.value !== props.value) {
this.setState({ selectedIndex: this.getSelectedIndex(newProps.options, newProps.value)})
}
}
@autobind
handlePress(option) {
const { onValueChanged } = this.props
this.setState({ selectedOption: option })
if (onValueChanged) {
onValueChanged(option.value)
}
}
render() {
const { style, options, value } = this.props
const { selectedOption } = this.state
return (
<View style={{ flexDirection: 'row' }}>
{options.map((option, index) => (
<TouchableHighlight
key={index}
underlayColor='#3BB0FD'
style={[
{ flexGrow: 1, flexBasis: 0, height: 40 },
option === selectedOption && { backgroundColor: '#3BB0FD' },
index === 0 && { borderTopLeftRadius: 6, borderBottomLeftRadius: 6 },
index === options.length - 1 && { borderTopRightRadius: 6, borderBottomRightRadius: 6 }
]}
onPress={() => this.handlePress(option)}>
<View style={[
{ flex: 1, justifyContent: 'center', borderTopWidth: 1, borderBottomWidth: 1, borderLeftWidth: 1, borderColor: 'black' },
index === 0 && { borderTopLeftRadius: 6, borderBottomLeftRadius: 6 },
index === options.length - 1 && { borderRightWidth: 1, borderTopRightRadius: 6, borderBottomRightRadius: 6 }
]}>
<Text style={{ alignSelf: 'center', color: 'black' }}>{option.text}</Text>
</View>
</TouchableHighlight>
))}
</View>
)
}
}

View File

@@ -0,0 +1,31 @@
import React from 'react'
import {
StyleSheet,
View,
Image,
TouchableOpacity
} from 'react-native'
import { Icon } from '.'
import autobind from 'autobind-decorator'
// const styles = StyleSheet.create()
export class PhotoButton extends React.Component {
render() {
return (
<TouchableOpacity>
<View style={{
flexDirection: 'row',
width: 100,
height: 60,
borderWidth: 2,
borderColor: 'gray',
borderRadius: 4,
justifyContent: 'center',
}}>
<Icon name='add' size={24} style={{ alignSelf: 'center' }} />
</View>
</TouchableOpacity>
)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

View File

@@ -1,5 +1,8 @@
export { BoundSwitch } from './BoundSwitch'
export { BoundInput } from './BoundInput'
export { BoundButton } from './BoundButton'
export { BoundOptionStrip } from './BoundOptionStrip'
export { Icon } from './Icon'
export { Header } from './Header'
export { PhotoButton } from './PhotoButton'
export { OptionStrip } from './OptionStrip'