Last active
June 8, 2017 00:01
-
-
Save andrewhl/61864bf936b4f1ccfd52bdf8e1a2ae20 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* @flow */ | |
import React, { Component } from 'react'; | |
import { connect } from 'react-redux'; | |
import { Container, Header, Left, Button, Body, Title, Right, Icon, Text } from 'native-base'; | |
import { TouchableWithoutFeedback, Keyboard, Alert } from 'react-native'; | |
import { getFormValues, isPristine, isValid } from 'redux-form'; | |
import AddItemFormContainer from '../../components/AddItemFormContainer'; | |
import * as itemsModule from '../../../../redux/modules/items'; | |
import BackButton from './components/BackButton'; | |
import SubmitButton from './components/SubmitButton'; | |
import type { | |
Navigation, | |
navigationOptions, | |
navigationOptionsFunction, | |
} from '../../../../../types/navigation'; | |
type props = { | |
navigation: Navigation, | |
screenProps: Array<mixed>, | |
}; | |
export class AddItem extends Component { | |
props: props; | |
state = { | |
submitting: false, | |
}; | |
componentWillReceiveProps(nextProps) { | |
if (nextProps.valid === this.props.valid) { | |
return; | |
} | |
this.props.navigation.setParams({ | |
valid: this.props.valid, | |
values: this.props.values, | |
pristine: this.props.pristine, | |
addItem: this.props.addItem, | |
}); | |
} | |
static navigationOptions: navigationOptionsFunction = ({ navigation }): navigationOptions => ({ | |
title: 'Add item', | |
headerLeft: <BackButton form={navigation.state.params} navigation={navigation} />, | |
headerRight: <SubmitButton form={navigation.state.params} navigation={navigation} />, | |
}); | |
render(): React.Element<*> { | |
return ( | |
<TouchableWithoutFeedback onPress={Keyboard.dismiss}> | |
<Container> | |
<AddItemFormContainer ref={node => (this.form = node)} /> | |
</Container> | |
</TouchableWithoutFeedback> | |
); | |
} | |
} | |
const mapStateToProps = (state: Object): Object => ({ | |
values: getFormValues('addItem')(state), | |
pristine: isPristine('addItem')(state), | |
valid: isValid('addItem')(state), | |
items: state.items, | |
}); | |
const mapDispatchToProps = { | |
addItem: itemsModule.add, | |
}; | |
export default connect(mapStateToProps, mapDispatchToProps)(AddItem); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react'; | |
import Collapsible from 'react-native-collapsible'; | |
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'; | |
import moment from 'moment'; | |
import { Field } from 'redux-form'; | |
import { View, List, Item, Input, Picker, Text, Left, Body, ListItem } from 'native-base'; | |
import { DatePickerIOS } from 'react-native'; | |
import style from './style'; | |
type props = { | |
input: { | |
onChange: () => void, | |
restInput: Array<mixed>, | |
}, | |
}; | |
const renderTitleField = ({ input: { onChange, ...restInput } }: props): React.Element<*> => | |
<Input | |
style={style.inputField} | |
onChangeText={onChange} | |
placeholder="Title" | |
{...restInput} | |
/>; | |
const renderShapeField = ({ input: { onChange, ...restInput } }: props): React.Element<*> => | |
<Picker | |
iosHeader="Shape" | |
mode="dropdown" | |
selectedValue={restInput.value} | |
onValueChange={onChange} | |
> | |
<Picker.Item label="Select" value="select" /> | |
<Picker.Item label="Round" value="round" /> | |
<Picker.Item label="Flat" value="flat" /> | |
<Picker.Item label="Cubic" value="cubic" /> | |
<Picker.Item label="Other" value="other" /> | |
</Picker>; | |
const renderSizeField = ({ input: { onChange, ...restInput } }: props): React.Element<*> => | |
<Picker | |
iosHeader="Size" | |
mode="dropdown" | |
selectedValue={restInput.value} | |
onValueChange={onChange} | |
> | |
<Picker.Item label="Select" value="select" /> | |
<Picker.Item label="Big" value="big" /> | |
<Picker.Item label="Small" value="small" /> | |
<Picker.Item label="Other" value="other" /> | |
</Picker>; | |
const renderCreatedAtField = ({ input: { onChange, ...restInput } }: props): React.Element<*> => | |
<DatePickerIOS | |
date={new Date(restInput.value)} | |
mode="date" | |
onDateChange={onChange} | |
{...restInput} | |
/>; | |
const required = value => (value ? undefined : 'Required'); | |
type formProps = { | |
created_at: Date, | |
}; | |
class AddItemFormComponent extends Component { | |
props: formProps; | |
state = { | |
createdAtIsCollapsed: true, | |
}; | |
render() { | |
return ( | |
<View style={style.wrapper}> | |
<KeyboardAwareScrollView> | |
<List style={style.group}> | |
<ListItem style={style.formField}> | |
<Left> | |
<Text>Title</Text> | |
</Left> | |
<Body> | |
<Field | |
name="title" | |
component={renderTitleField} | |
validate={required} | |
/> | |
</Body> | |
</ListItem> | |
<ListItem> | |
<Left> | |
<Text>Shape</Text> | |
</Left> | |
<Body> | |
<Field | |
name="shape" | |
component={renderShapeField} | |
validate={required} | |
/> | |
</Body> | |
</ListItem> | |
<ListItem> | |
<Left> | |
<Text>Size</Text> | |
</Left> | |
<Body> | |
<Field | |
name="size" | |
component={renderSizeField} | |
validate={required} | |
/> | |
</Body> | |
</ListItem> | |
<ListItem noBorder onPress={this.toggleCreatedAt}> | |
<Left> | |
<Text>Created At</Text> | |
</Left> | |
<Body> | |
{this.renderCreatedAt()} | |
</Body> | |
</ListItem> | |
<Collapsible collapsed={this.state.createdAtIsCollapsed}> | |
<View> | |
<Field | |
name="created_at" | |
component={renderCreatedAtField} | |
validate={required} | |
/> | |
</View> | |
</Collapsible> | |
</List> | |
</KeyboardAwareScrollView> | |
</View> | |
); | |
} | |
renderCreatedAt() { | |
const createdAt = moment(this.props.created_at); | |
return <Text>{createdAt.format('LL')}</Text>; | |
} | |
toggleCreatedAt = () => { | |
this.setState({ | |
createdAtIsCollapsed: ! this.state.createdAtIsCollapsed, | |
}); | |
}; | |
} | |
export default AddItemFormComponent; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { reduxForm, formValueSelector } from 'redux-form'; | |
import { connect } from 'react-redux'; | |
import AddItemFormComponent from './AddItemFormComponent'; | |
const validate = (values) => { | |
const errors = {}; | |
if (values.size === 'select') { | |
errors.size = 'Please select a size.'; | |
} | |
if (values.shape === 'select') { | |
errors.shape = 'Please select a shape.'; | |
} | |
return errors; | |
}; | |
let AddItemFormContainer: React.Element<*> = reduxForm({ | |
form: 'addItem', | |
validate, | |
})(AddItemFormComponent); | |
const mapStateToProps = (state: Object): Object => { | |
const selector = formValueSelector('addItem'); | |
const createdAt = selector(state, 'created_at'); | |
return { | |
created_at: createdAt, | |
initialValues: { | |
created_at: new Date(), | |
shape: 'Select', | |
size: 'Select', | |
}, | |
}; | |
}; | |
const mergeProps = (stateProps, dispatchProps, ownProps) => | |
Object.assign({}, stateProps, dispatchProps, ownProps); | |
AddItemFormContainer = connect(mapStateToProps, null, mergeProps)(AddItemFormContainer); | |
export default AddItemFormContainer; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment