Last active
July 10, 2017 03:45
-
-
Save yutin1987/286fd05e2b71d41d95b66c978fa5184f to your computer and use it in GitHub Desktop.
input
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, { PropTypes, Component } from 'react'; | |
import { StyleSheet, View, TouchableOpacity, Image } from 'react-native'; | |
import { Input } from 'component'; | |
import length from 'lodash/size'; | |
import isArray from 'lodash/isArray'; | |
import Cropper from 'react-native-cropper'; | |
import color from 'color'; | |
import size from 'size'; | |
import Text from '../Text/Text'; | |
import Icon from '../Icon/Icon'; | |
const sh = StyleSheet.create({ | |
viewport: { | |
flex: 1, | |
}, | |
singleWrap: { | |
flex: 1, | |
alignItems: 'center', | |
justifyContent: 'center', | |
marginBottom: 12, | |
}, | |
multiWrap: { | |
flex: 1, | |
flexDirection: 'row', | |
flexWrap: 'wrap', | |
alignItems: 'flex-start', | |
justifyContent: 'space-between', | |
}, | |
picture: { | |
flex: 1, | |
borderColor: color.textAssist, | |
borderWidth: 1, | |
marginBottom: 10, | |
}, | |
insert: { | |
flex: 1, | |
alignItems: 'center', | |
justifyContent: 'center', | |
borderColor: color.textAssist, | |
borderWidth: 1, | |
marginBottom: 10, | |
}, | |
insertText: { | |
marginTop: 5, | |
}, | |
}); | |
export default class InputPicture extends Component { | |
static displayName = 'InputPicture'; | |
static propTypes = { | |
value: PropTypes.arrayOf(PropTypes.string), | |
tipShort: PropTypes.string, | |
maxSize: PropTypes.number, | |
pictureWidth: PropTypes.number, | |
pictureHeight: PropTypes.number, | |
onChange: PropTypes.func, | |
}; | |
static defaultProps = { | |
name: '', | |
value: [], | |
placeholder: '', | |
maxSize: 1, | |
pictureWidth: 512, | |
pictureHeight: 512, | |
onChange: () => {}, | |
} | |
state = { | |
box: 100, | |
picture: [], | |
} | |
onEdit = () => { | |
const { value } = this.props; | |
if (isArray(value) && length(value) > 0) { | |
this.setState({ picture: value }); | |
} | |
}; | |
onComplete = () => this.props.onChange(this.state.picture); | |
onLayout = (e) => { | |
const { width } = e.nativeEvent.layout; | |
this.setState({ box: (width - 10) / 2 }); | |
} | |
onInsert = async () => { | |
const base64 = await this.getPhotoFromAlbum(); | |
const { picture } = this.state; | |
if (base64) { | |
picture.push(`data:image/jpeg;base64, ${base64}`); | |
this.setState({ picture }); | |
} | |
} | |
onModify = async (idx) => { | |
const base64 = await this.getPhotoFromAlbum(); | |
const { picture } = this.state; | |
if (base64) { | |
picture[idx] = `data:image/jpeg;base64, ${base64}`; | |
this.setState({ picture }); | |
} | |
} | |
getPhotoFromAlbum = async () => { | |
const { pictureWidth, pictureHeight } = this.props; | |
return await Cropper.getPhotoFromAlbum({ width: pictureWidth, height: pictureHeight }); | |
} | |
render() { | |
const { maxSize, tipShort } = this.props; | |
const { box, picture } = this.state; | |
const surplus = maxSize - picture.length; | |
const scale = maxSize > 1 ? 1 : 1.5; | |
return ( | |
<Input | |
{...this.props} | |
onEdit={this.onEdit} | |
onComplete={this.onComplete} | |
display={picture.length && `已選取${picture.length}張照片`} | |
tipShort={tipShort || `剩餘${surplus}張相片`} | |
> | |
<View style={maxSize > 1 ? sh.multiWrap : sh.singleWrap} onLayout={this.onLayout}> | |
{picture.map((uri, idx) => ( | |
<View key={idx} style={{ width: box * scale, height: box * scale }}> | |
<TouchableOpacity style={sh.viewport} onPress={() => this.onModify(idx)}> | |
<Image style={sh.picture} source={{ uri }} /> | |
</TouchableOpacity> | |
</View> | |
))} | |
{surplus > 0 && | |
<View key="add" style={{ width: box * scale, height: box * scale }}> | |
<TouchableOpacity style={sh.insert} onPress={this.onInsert}> | |
<Icon name="photo" size={size.button} color={color.textAssist} /> | |
<Text color={color.textAssist} style={sh.insertText}>新增照片</Text> | |
</TouchableOpacity> | |
</View> | |
} | |
</View> | |
</Input> | |
); | |
} | |
} |
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, { PropTypes, Component } from 'react'; | |
import { StyleSheet, TextInput } from 'react-native'; | |
import { Input } from 'component'; | |
import color from 'color'; | |
import size from 'size'; | |
const sh = StyleSheet.create({ | |
input: { | |
flex: 1, | |
fontSize: size.font.text, | |
color: color.text, | |
}, | |
}); | |
export default class InputText extends Component { | |
static displayName = 'InputText'; | |
static propTypes = { | |
name: PropTypes.string, | |
value: PropTypes.string, | |
placeholder: PropTypes.string, | |
tipShort: PropTypes.string, | |
maxLength: PropTypes.number, | |
onChange: PropTypes.func, | |
}; | |
static defaultProps = { | |
name: '', | |
value: '', | |
placeholder: '', | |
maxLength: 140, | |
onChange: () => {}, | |
} | |
state = { | |
value: '', | |
} | |
onChange = (value) => this.setState({ value }); | |
onEdit = () => this.setState({ value: this.props.value }); | |
onComplete = () => this.props.onChange(this.state.value); | |
render() { | |
const { name, placeholder, maxLength, tipShort, value: propValue } = this.props; | |
const { value } = this.state; | |
const surplus = maxLength - (value || '').length; | |
return ( | |
<Input | |
{...this.props} | |
onEdit={this.onEdit} | |
onComplete={this.onComplete} | |
display={propValue} | |
tipShort={tipShort || `剩餘${surplus}個字`} | |
> | |
<TextInput | |
style={sh.input} | |
autoFocus | |
multiline | |
maxLength={maxLength} | |
placeholder={placeholder || name} | |
value={value} | |
onChangeText={this.onChange} | |
/> | |
</Input> | |
); | |
} | |
} |
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, { PropTypes, Component } from 'react'; | |
import { StyleSheet, Switch, View, Alert, TouchableOpacity } from 'react-native'; | |
import { Input, InputTimeRange, Text, Label } from 'component'; | |
import moment from 'moment-timezone'; | |
import range from 'lodash/range'; | |
import filter from 'lodash/filter'; | |
import get from 'lodash/get'; | |
import map from 'lodash/map'; | |
import color from 'color'; | |
import size from 'size'; | |
const sh = StyleSheet.create({ | |
placeholder: { | |
flex: 1, | |
alignItems: 'center', | |
justifyContent: 'center', | |
}, | |
button: { | |
flexDirection: 'row', | |
borderTopColor: color.border, | |
borderTopWidth: StyleSheet.hairlineWidth, | |
alignItems: 'center', | |
height: size.itembar * 0.8, | |
}, | |
buttonDisplay: { | |
flex: 1, | |
flexDirection: 'row', | |
alignItems: 'center', | |
}, | |
buttonValue: { | |
marginTop: 3, | |
marginLeft: 5, | |
}, | |
}); | |
export default class InputWorktime extends Component { | |
static displayName = 'InputWorktime'; | |
static propTypes = { | |
value: PropTypes.arrayOf(PropTypes.shape()), | |
name: PropTypes.string, | |
placeholder: PropTypes.string, | |
onChange: PropTypes.func, | |
}; | |
static defaultProps = { | |
name: '', | |
value: [], | |
placeholder: '', | |
maxLength: 140, | |
onChange: () => {}, | |
} | |
state = { | |
enable: [false, false, false, false, false, false, false], | |
timeRange: [{}, {}, {}, {}, {}, {}, {}], | |
} | |
onEdit = () => { | |
const { value } = this.props; | |
const { enable, timeRange } = this.state; | |
range(0, 7).forEach((day) => { | |
enable[day] = get(value, `[${day}].enable`, false); | |
timeRange[day] = { | |
start: get(value, `[${day}].start`, 0), | |
end: get(value, `[${day}].end`, 24 * 60), | |
}; | |
}); | |
this.setState({ enable, timeRange }); | |
}; | |
onComplete = () => { | |
const { enable, timeRange } = this.state; | |
this.props.onChange( | |
range(0, 7).map((day) => ({ | |
enable: !!enable[day], | |
start: get(timeRange, `[${day}].start`, 0), | |
end: get(timeRange, `[${day}].end`, 24 * 60), | |
})) | |
); | |
}; | |
onValueComplete = (day, value) => { | |
const { timeRange } = this.state; | |
timeRange[day] = value; | |
this.setState({ timeRange }); | |
}; | |
onSwitchChnage = (day, value) => { | |
const { enable } = this.state; | |
enable[day] = !!value; | |
this.setState({ enable }); | |
} | |
onEditPress = (day, ref) => { | |
const { enable } = this.state; | |
if (enable[day]) return ref.onEdit(); | |
return Alert.alert( | |
null, | |
`是否將${moment.weekdays(day)}設為營業日?`, | |
[ | |
{ text: '取消' }, | |
{ | |
text: '設為營業日', | |
onPress: () => { | |
this.onSwitchChnage(day, true); | |
ref.onEdit(); | |
}, | |
}, | |
] | |
); | |
} | |
renderButton = (data, state, ref) => { | |
const { day } = data; | |
const { enable } = this.state; | |
return ( | |
<TouchableOpacity onPress={() => this.onEditPress(day, ref)}> | |
<View style={sh.button}> | |
<View style={sh.buttonDisplay}> | |
<Label color={color.primary}>{moment.weekdays(day)}</Label> | |
<Text style={sh.buttonValue} weight="light" color={color.textAssist}> | |
{enable[day] ? data.display || '24小時' : '休假日'} | |
</Text> | |
</View> | |
<Switch | |
value={!!enable[day]} | |
onValueChange={(value) => this.onSwitchChnage(day, value)} | |
/> | |
</View> | |
</TouchableOpacity> | |
); | |
} | |
render() { | |
const { name, placeholder, value } = this.props; | |
const { timeRange } = this.state; | |
return ( | |
<Input | |
{...this.props} | |
onEdit={this.onEdit} | |
onComplete={this.onComplete} | |
display={ | |
filter(map( | |
value || [], | |
(o, day) => (o.enable ? moment.weekdaysMin(day) : null) | |
), (o) => !!o).join(', ') | |
} | |
> | |
<View style={sh.placeholder}> | |
<Label>{placeholder || name}</Label> | |
</View> | |
{range(0, 7).map((day) => ( | |
<InputTimeRange | |
key={day} | |
day={day} | |
disabled | |
name={`設定${moment.weekdays(day)}`} | |
value={timeRange[day]} | |
renderButton={this.renderButton} | |
onChange={(time) => this.onValueComplete(day, time)} | |
/> | |
))} | |
</Input> | |
); | |
} | |
} |
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, PropTypes } from 'react'; | |
import { Animated, ScrollView } from 'react-native'; | |
import { | |
NextButton, | |
NavigationView, | |
InputAddress, | |
InputPicture, | |
InputText, | |
InputWorktime, | |
Margin, | |
} from 'component'; | |
export default class MemberRequisition extends Component { | |
static displayName = 'MemberRequisition'; | |
static propTypes = { | |
nav: PropTypes.objectOf(PropTypes.func), | |
}; | |
state = { | |
nickname: null, | |
picture: null, | |
provider: null, | |
address: null, | |
open: null, | |
} | |
onNicknameChange = (nickname) => this.setState({ nickname }); | |
onPhotoChange = (picture) => this.setState({ picture }); | |
onProviderChange = (provider) => this.setState({ provider }); | |
onAddressChange = (address) => this.setState({ address }); | |
onOpenChange = (open) => this.setState({ open }); | |
nextAnimated = new Animated.Value(0); | |
render() { | |
const { nav } = this.props; | |
const { nickname, picture, provider, address, open } = this.state; | |
return ( | |
<NavigationView | |
title="申請成為職人" | |
onLeftPress={nav.pop} | |
> | |
<ScrollView> | |
<Margin> | |
<InputText | |
name="撰寫職人名稱" | |
placeholder="希望顧客怎麼稱呼您?" | |
tip={'職人的名稱會公開顯示於Bunninn平台上,因此不建議使用全名或本名。\n\n可以是簡短容易記憶的暱稱,不建議超過四個字,顧客需要透過暱稱找到您。'} | |
tipTitle="簡短容易記憶" | |
value={nickname} | |
onChange={this.onNicknameChange} | |
/> | |
<InputPicture | |
name="上傳職人相片" | |
placeholder="有相片可以認識您嗎?" | |
value={picture} | |
onChange={this.onPhotoChange} | |
/> | |
<InputText | |
name="撰寫店名" | |
placeholder="您有個好記憶的店名嗎?" | |
value={provider} | |
onChange={this.onProviderChange} | |
/> | |
<InputAddress | |
name="撰寫店址" | |
placeholder="您的顧客該去哪裡找您?" | |
tipTitle="詳細的地址" | |
tipShort="詳細的地址有助於減少顧客找到您的時間" | |
tip={'詳細的地址有助於減少顧客找到您的時間,建議清楚告知幾號幾樓及櫃位號碼,如有公寓/大廈或商圈名稱會更棒。\n\n例如:臺北市大安區大安路1段77號東區地下街A03櫃'} | |
value={address} | |
onChange={this.onAddressChange} | |
/> | |
<InputWorktime | |
name="設定營業時段" | |
placeholder="星期幾可以與您預約?" | |
value={open} | |
onChange={this.onOpenChange} | |
/> | |
<NextButton>申請</NextButton> | |
</Margin> | |
</ScrollView> | |
</NavigationView> | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment