Browse Source

Decoupling logic of getting date and time from the UI that implements

the component
master
GabrielTrettel 3 years ago
parent
commit
837bf69f95
  1. 204
      src/app/components/DatePicker.js
  2. 202
      src/app/components/forms/FormDatePicker.js

204
src/app/components/DatePicker.js

@ -0,0 +1,204 @@
import React, { useState } from "react";
import {
Modal,
StyleSheet,
Text,
TouchableHighlight,
View,
Platform,
TouchableOpacity,
Alert,
} from "react-native";
import DateTimePicker from "@react-native-community/datetimepicker";
import moment from "moment";
import colors from "../config/colors";
export default function DatePicker(props) {
const [disabled, setDisabled] = useState(props.disabled);
const { textStyle, defaultDate } = props;
const [date, setDate] = useState(moment(defaultDate));
const [show, setShow] = useState(false);
const [auxDate, setAuxDate] = useState(moment());
const [mode, setMode] = useState("date");
const [time, setTime] = useState(moment(defaultDate));
const validateTimeInput = (selectedDate) => {
if (
!moment().isSameOrAfter(selectedDate) &&
new Date(moment()).getDay() == new Date(date).getDay()
) {
Alert.alert("Horário inválido", "Selecione um horário válido", [
{ text: "OK", onPress: () => renderDatePicker() },
]);
return false;
}
return true;
};
const onChange = (e, selectedDate) => {
setAuxDate(moment(selectedDate)); // variavel auxiliar para não alterar a data com a rolagem, apenas com o done
};
const androidOnChange = (e, selectedDate) => {
console.log("selectedDate: " + selectedDate + " " + mode);
setShow(false);
if (selectedDate) {
if (mode == "date") {
setDate(moment(selectedDate));
props.onDateChange(date);
setMode("time");
setShow(true); // to show the picker again in time mode
} else {
if (validateTimeInput(selectedDate)) {
setTime(moment(selectedDate));
props.onTimeChange(moment(selectedDate));
setShow(false);
setMode("date");
} else {
setTime(moment());
}
}
}
};
const onCancelPress = () => {
setShow(false);
};
const onDonePress = () => {
setShow(false);
if (mode == "date") {
setDate(moment(auxDate)); //atualizar a data com a variável auxiliar
props.onDateChange(auxDate);
setMode("time");
setShow(true); // to show the picker again in time mode
} else {
if (validateTimeInput(auxDate)) {
setTime(moment(auxDate));
props.onTimeChange(auxDate);
setShow(false);
setMode("date");
} else {
setTime(moment());
}
}
};
const renderDatePicker = () => {
return (
<DateTimePicker
timeZoneOffsetInDays={-1}
value={new Date(auxDate)}
mode={mode}
is24Hour={true}
locale={"pt-br"}
minimumDate={new Date(moment().subtract(1, "month"))}
maximumDate={new Date(moment())}
// formatChosenDate={(selectedDate) => {
// if (mode == "date") {
// return moment(selectedDate).format("DD/mm/YYYY");
// } else {
// return moment(selectedDate).format("HH:mm");
// }
// }} //formatar a data e hora do selected date
display={Platform.OS === "ios" ? "spinner" : "default"}
onChange={Platform.OS === "ios" ? onChange : androidOnChange}
/>
);
};
return (
<View>
<TouchableOpacity disabled={disabled} onPress={() => setShow(true)}>
{props.children}
</TouchableOpacity>
{Platform.OS !== "ios" && show && renderDatePicker()}
{Platform.OS === "ios" && show && (
<Modal
transparent={true}
animationType="slide"
visible={show}
supportedOrientations={["portrait"]}
onRequestClose={() => setShow(false)}
>
<View style={{ flex: 1 }}>
<TouchableHighlight
style={{
flex: 1,
alignItems: "flex-end",
flexDirection: "row",
}}
activeOpacity={1}
visible={show}
onPress={() => setShow(false)}
>
<TouchableHighlight
underlayColor={"#ffffff"}
style={{
flex: 1,
borderTopColor: "#d3d3d3",
borderTopWidth: 1,
}}
// onPress={() => console.log("datepicker clicked")}
>
<View
style={{
backgroundColor: "#ffffff",
height: 256,
overflow: "hidden",
}}
>
<View style={{ marginTop: 20 }}>{renderDatePicker()}</View>
<TouchableHighlight
underlayColor={"transparent"}
onPress={() => onCancelPress()}
style={[styles.btnText, styles.btnCancel]}
>
<Text style={{ color: colors.primary }}>Cancelar</Text>
</TouchableHighlight>
<TouchableHighlight
underlayColor={"transparent"}
onPress={() => onDonePress()}
style={[styles.btnText, styles.btnDone]}
>
<Text style={{ color: colors.primary }}>Confirmar</Text>
</TouchableHighlight>
</View>
</TouchableHighlight>
</TouchableHighlight>
</View>
</Modal>
)}
</View>
);
}
DatePicker.defaultProps = {
textStyle: {},
defaultDate: moment(),
onDateChange: () => {},
onTimeChange: () => {},
};
const styles = StyleSheet.create({
btnCancel: {
left: 0,
},
btnDone: {
right: 0,
},
btnText: {
position: "absolute",
top: 0,
height: 42,
paddingHorizontal: 20,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
},
});

202
src/app/components/forms/FormDatePicker.js

@ -16,114 +16,22 @@ import moment from "moment";
import colors from "../../config/colors"; import colors from "../../config/colors";
import { dimensions } from "../../config/dimensions"; import { dimensions } from "../../config/dimensions";
import { showMessage } from "react-native-flash-message"; import { showMessage } from "react-native-flash-message";
import DatePicker from "../../components/DatePicker";
const FormDatePicker = (props) => { const FormDatePicker = (props) => {
const [disabled, setDisabled] = useState(props.disabled);
const { textStyle, defaultDate } = props;
const [date, setDate] = useState(moment(defaultDate));
const [show, setShow] = useState(false);
const [auxDate, setAuxDate] = useState(moment());
const [mode, setMode] = useState("date");
const [time, setTime] = useState(moment(defaultDate));
const validateTimeInput = (selectedDate) => {
if (!(moment().isSameOrAfter(selectedDate)) && new Date(moment()).getDay() == new Date(date).getDay()) {
Alert.alert(
"Horário inválido",
"Selecione um horário válido",
[
{ text: "OK", onPress: () => renderDatePicker() }
]
);
return false;
}
return true;
}
const onChange = (e, selectedDate) => {
setAuxDate(moment(selectedDate)); // variavel auxiliar para não alterar a data com a rolagem, apenas com o done
};
const androidOnChange = (e, selectedDate) => {
setShow(false);
if (selectedDate) {
if (mode == "date") {
setDate(moment(selectedDate));
props.onDateChange(selectedDate);
setMode("time");
setShow(true); // to show the picker again in time mode
}
else {
if (validateTimeInput(selectedDate)) {
setTime(moment(selectedDate));
props.onTimeChange(selectedDate);
setShow(false);
setMode("date");
}
else{
setTime(moment());
}
}
}
};
const onCancelPress = () => {
setShow(false);
};
const onDonePress = () => {
setShow(false);
if (mode == "date") {
setDate(moment(auxDate)); //atualizar a data com a variável auxiliar
props.onDateChange(auxDate);
setMode("time");
setShow(true); // to show the picker again in time mode
}
else {
if (validateTimeInput(auxDate)) {
setTime(moment(auxDate));
props.onTimeChange(auxDate);
setShow(false);
setMode("date");
}
else{
setTime(moment());
}
}
};
const renderDatePicker = () => {
console.log("date " + props.date + " time " + props.time)
return ( return (
<DateTimePicker
timeZoneOffsetInDays={-1}
value={new Date(auxDate)}
mode={mode}
is24Hour={true}
locale={"pt-br"}
minimumDate={new Date(moment().subtract(1, "month"))}
maximumDate={new Date(moment())}
formatChosenDate={(selectedDate) => {
if (mode == "date") {
return moment(selectedDate).format("DD/MM/YYYY");
} else {
return moment(selectedDate).format("HH:mm");
}
}} //formatar a data e hora do selected date
display={Platform.OS === "ios" ? "spinner" : "default"}
onChange={Platform.OS === "ios" ? onChange : androidOnChange}
/>
);
};
return (
<TouchableOpacity disabled={disabled} onPress={() => setShow(true)}>
<DatePicker
textStyle={{
borderColor: colors.gray,
borderWidth: 3,
}}
defaultDate={new Date()}
onDateChange={props.onDateChange}
onTimeChange={props.onTimeChange}
>
<View <View
style={{ style={{
flex: 1,
width: "100%", width: "100%",
flexDirection: "row", flexDirection: "row",
alignItems: "center", alignItems: "center",
@ -139,100 +47,22 @@ const FormDatePicker = (props) => {
</View> </View>
<View style={styles.dateInput}> <View style={styles.dateInput}>
<Text style={{ fontSize: dimensions.text.default }}> <Text style={{ fontSize: dimensions.text.default }}>
{" "}{date.format("DD/MM/YYYY")} {" | "} {time.format("HH:mm")}
{" "}
{props.date.format("DD/MM/YYYY")} {" | "}{" "}
{props.time.format("HH:mm")}
</Text> </Text>
<View> <View>
<Text style={{ color: colors.primary }}> <Text style={{ color: colors.primary }}>
{(props.subtitle ? props.subtitle : " Defina a data do evento")}
{props.subtitle ? props.subtitle : " Defina a data do evento"}
</Text> </Text>
</View> </View>
</View> </View>
</View> </View>
{Platform.OS !== "ios" && show && renderDatePicker()}
{Platform.OS === "ios" && show && (
<Modal
transparent={true}
animationType="slide"
visible={show}
supportedOrientations={["portrait"]}
onRequestClose={() => setShow(false)}
>
<View style={{ flex: 1 }}>
<TouchableHighlight
style={{
flex: 1,
alignItems: "flex-end",
flexDirection: "row",
}}
activeOpacity={1}
visible={show}
onPress={() => setShow(false)}
>
<TouchableHighlight
underlayColor={"#ffffff"}
style={{
flex: 1,
borderTopColor: "#d3d3d3",
borderTopWidth: 1,
}}
// onPress={() => console.log("datepicker clicked")}
>
<View
style={{
backgroundColor: "#ffffff",
height: 256,
overflow: "hidden",
}}
>
<View style={{ marginTop: 20 }}>{renderDatePicker()}</View>
<TouchableHighlight
underlayColor={"transparent"}
onPress={() => onCancelPress()}
style={[styles.btnText, styles.btnCancel]}
>
<Text style={{ color: colors.primary }}>Cancelar</Text>
</TouchableHighlight>
<TouchableHighlight
underlayColor={"transparent"}
onPress={() => onDonePress()}
style={[styles.btnText, styles.btnDone]}
>
<Text style={{ color: colors.primary }}>Confirmar</Text>
</TouchableHighlight>
</View>
</TouchableHighlight>
</TouchableHighlight>
</View>
</Modal>
)}
</TouchableOpacity>
</DatePicker>
); );
}; };
FormDatePicker.defaultProps = {
textStyle: {},
defaultDate: moment(),
onDateChange: () => { },
onTimeChange: () => { },
};
const styles = StyleSheet.create({ const styles = StyleSheet.create({
btnCancel: {
left: 0,
},
btnDone: {
right: 0,
},
btnText: {
position: "absolute",
top: 0,
height: 42,
paddingHorizontal: 20,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
},
dateInput: { dateInput: {
paddingLeft: 16, paddingLeft: 16,
height: "100%", height: "100%",

Loading…
Cancel
Save