|
|
@@ -1,102 +1,92 @@ |
|
|
|
import React, { Component } from "react"; |
|
|
|
import React, { useEffect, useState } from "react"; |
|
|
|
import { View } from "react-native"; |
|
|
|
import { |
|
|
|
Button, |
|
|
|
Portal, |
|
|
|
Dialog, |
|
|
|
TextInput, |
|
|
|
List, |
|
|
|
Text, |
|
|
|
useTheme, |
|
|
|
} from "react-native-paper"; |
|
|
|
import Styles from "../ui/Styles"; |
|
|
|
import TextInput from "../ui/TextInput"; |
|
|
|
|
|
|
|
export default class TextInputModal extends Component { |
|
|
|
constructor(props) { |
|
|
|
super(props); |
|
|
|
const { value, variant, isRequired = true } = props; |
|
|
|
this.state = { |
|
|
|
value, |
|
|
|
isValid: this.checkInputIsValid(value, variant, isRequired), |
|
|
|
showModal: false, |
|
|
|
}; |
|
|
|
} |
|
|
|
export default function TextInputModal({ |
|
|
|
modalTitle, |
|
|
|
modalDescription, |
|
|
|
initialValue = "", |
|
|
|
label, |
|
|
|
onOk, |
|
|
|
isRequired = true, |
|
|
|
variant = "text", |
|
|
|
}) { |
|
|
|
const [value, setValue] = useState(initialValue); |
|
|
|
const [showModal, setShowModal] = useState(false); |
|
|
|
const [isValid, setIsValid] = useState(true); |
|
|
|
const theme = useTheme(); |
|
|
|
|
|
|
|
_hideModal = () => { |
|
|
|
const { value } = this.props; |
|
|
|
this.setState({ showModal: false, value }); |
|
|
|
const variants = { |
|
|
|
text: "default", |
|
|
|
email: "email-address", |
|
|
|
numeric: "numeric", |
|
|
|
}; |
|
|
|
const keyboardType = variants[variant]; |
|
|
|
|
|
|
|
getKeyboardType = (variant) => { |
|
|
|
const variants = { |
|
|
|
text: "default", |
|
|
|
email: "email-address", |
|
|
|
numeric: "numeric", |
|
|
|
}; |
|
|
|
return variants[variant]; |
|
|
|
}; |
|
|
|
|
|
|
|
checkInputIsValid = (value, variant, isRequired) => { |
|
|
|
if (isRequired && !value) return false; |
|
|
|
let isValid = variant === "numeric" ? !isNaN(value) : true; |
|
|
|
return isValid; |
|
|
|
}; |
|
|
|
|
|
|
|
onChange = (value, variant, isRequired) => { |
|
|
|
const isValid = this.checkInputIsValid(value, variant, isRequired); |
|
|
|
this.setState({ value, isValid }); |
|
|
|
}; |
|
|
|
useEffect(() => { |
|
|
|
if (isRequired && !value) { |
|
|
|
setIsValid(false); |
|
|
|
} else { |
|
|
|
setIsValid(variant === "numeric" ? !isNaN(value) : true); |
|
|
|
} |
|
|
|
}, [value, variant, isRequired]); |
|
|
|
|
|
|
|
render() { |
|
|
|
const { value, isValid, showModal } = this.state; |
|
|
|
const { |
|
|
|
label, |
|
|
|
onOk, |
|
|
|
modalTitle, |
|
|
|
modalDescription, |
|
|
|
variant = "text", |
|
|
|
isRequired, |
|
|
|
} = this.props; |
|
|
|
return ( |
|
|
|
<View> |
|
|
|
<Portal> |
|
|
|
<Dialog onDismiss={this._hideModal} visible={showModal}> |
|
|
|
<Dialog.Title>{modalTitle}</Dialog.Title> |
|
|
|
<Dialog.ScrollArea style={{ maxHeight: 170, paddingHorizontal: 0 }}> |
|
|
|
<View style={{ padding: 10 }}> |
|
|
|
<TextInput |
|
|
|
style={Styles.input} |
|
|
|
value={variant === "numeric" ? value.toString() : value} |
|
|
|
keyboardType={this.getKeyboardType(variant)} |
|
|
|
secureTextEntry={variant === "password"} |
|
|
|
onChangeText={(value) => |
|
|
|
this.onChange(value, variant, isRequired) |
|
|
|
} |
|
|
|
/> |
|
|
|
{modalDescription ? <Text /> : null} |
|
|
|
</View> |
|
|
|
</Dialog.ScrollArea> |
|
|
|
<Dialog.Actions> |
|
|
|
<Button primary onPress={this._hideModal}> |
|
|
|
Cancel |
|
|
|
</Button> |
|
|
|
<Button |
|
|
|
primary |
|
|
|
disabled={!isValid} |
|
|
|
onPress={() => |
|
|
|
this.setState({ showModal: false }, () => onOk(value)) |
|
|
|
} |
|
|
|
> |
|
|
|
Ok |
|
|
|
</Button> |
|
|
|
</Dialog.Actions> |
|
|
|
</Dialog> |
|
|
|
</Portal> |
|
|
|
<List.Item |
|
|
|
title={label} |
|
|
|
description={value} |
|
|
|
onPress={() => this.setState({ showModal: true })} |
|
|
|
/> |
|
|
|
</View> |
|
|
|
); |
|
|
|
} |
|
|
|
return ( |
|
|
|
<> |
|
|
|
<Portal> |
|
|
|
<Dialog |
|
|
|
onDismiss={() => setShowModal(false)} |
|
|
|
visible={showModal} |
|
|
|
style={{ backgroundColor: theme.colors.background }} |
|
|
|
> |
|
|
|
<Dialog.Title>{modalTitle}</Dialog.Title> |
|
|
|
<Dialog.ScrollArea style={{ maxHeight: 170, paddingHorizontal: 0 }}> |
|
|
|
<View style={{ padding: 10 }}> |
|
|
|
<TextInput |
|
|
|
style={Styles.input} |
|
|
|
value={variant === "numeric" ? value.toString() : value} |
|
|
|
keyboardType={keyboardType} |
|
|
|
secureTextEntry={variant === "password"} |
|
|
|
onChangeText={setValue} |
|
|
|
/> |
|
|
|
{modalDescription ? <Text>{modalDescription}</Text> : null} |
|
|
|
</View> |
|
|
|
</Dialog.ScrollArea> |
|
|
|
<Dialog.Actions> |
|
|
|
<Button onPress={() => setShowModal(false)} mode="outlined"> |
|
|
|
Cancel |
|
|
|
</Button> |
|
|
|
<Button |
|
|
|
disabled={!isValid} |
|
|
|
onPress={() => { |
|
|
|
setShowModal(false); |
|
|
|
onOk(value); |
|
|
|
}} |
|
|
|
mode="contained" |
|
|
|
style={{ marginLeft: 20 }} |
|
|
|
> |
|
|
|
Save |
|
|
|
</Button> |
|
|
|
</Dialog.Actions> |
|
|
|
</Dialog> |
|
|
|
</Portal> |
|
|
|
<List.Item |
|
|
|
title={label} |
|
|
|
description={initialValue} |
|
|
|
onPress={() => { |
|
|
|
setShowModal(true); |
|
|
|
setValue(""); |
|
|
|
}} |
|
|
|
/> |
|
|
|
</> |
|
|
|
); |
|
|
|
} |