Nós vamos agora criar o timepicker, que é o que usaremos para selecionar o horário da notificação.
Vamos criar tanto o do diário, que é apenas horário. E também o da semana, que é um picker de dia da semana + horário.
Antes de começar, vamos instalar a lib que vamos usar para o timepicker
npx expo install @react-native-community/[email protected]
npm i @react-native-community/datetimepicker
npm install @react-native-community/datetimepicker --save
Vamos criar o componente, que será criado semelhante aos que criamos agora pouco. “Components → HabitPage → TimeDataPicker → index.jsx”
Vamos criar a nossa estrutura, que vai receber algumas props que já foram criadas, como o nosso “frequency”, e algumas que vamos criar.
import React from "react";
export default function TimeDatePicker({
frequency,
dayNotification,
timeNotification,
setDayNotification,
setTimeNotification,
}) {
return (
<View>
</View>
);
}
Agora vamos criar alguns estados, que são
import React, { useState } from "react";
import { View } from "react-native";
export default function TimeDatePicker({
frequency,
dayNotification,
timeNotification,
setDayNotification,
setTimeNotification,
}) {
const [date, setDate] = useState(new Date());
const [mode, setMode] = useState("date");
const [show, setShow] = useState(false);
const [selected, setSelected] = useState("-");
return (
<View>
</View>
);
}
Agora iremos criar dois estados, que são os que vão capturar o dia da semana e o horário.
import React, { useState } from "react";
import { View } from "react-native";
export default function TimeDatePicker({
frequency,
dayNotification,
timeNotification,
setDayNotification,
setTimeNotification,
}) {
const [date, setDate] = useState(new Date());
const [mode, setMode] = useState("date");
const [show, setShow] = useState(false);
const [selected, setSelected] = useState("-");
const [notificationDate, setNotificationDate] = useState();
const [notificationTime, setNotificationTime] = useState();
return (
<View>
</View>
);
}
Assim como o da frequência, a data desse nosso dropdown é pouca coisa, então vamos criar na própria página.
import React, { useState } from "react";
import { View } from "react-native";
export default function TimeDatePicker({
frequency,
dayNotification,
timeNotification,
setDayNotification,
setTimeNotification,
}) {
const [date, setDate] = useState(new Date());
const [mode, setMode] = useState("date");
const [show, setShow] = useState(false);
const [selected, setSelected] = useState("-");
const [notificationDate, setNotificationDate] = useState();
const [notificationTime, setNotificationTime] = useState();
const data = [
{ key: "Domingo", value: "Dom" },
{ key: "Segunda", value: "Seg" },
{ key: "Terça", value: "Ter" },
{ key: "Quarta", value: "Qua" },
{ key: "Quinta", value: "Qui" },
{ key: "Sexta", value: "Sex" },
{ key: "Sábado", value: "Sab" },
];
return (
<View>
</View>
);
}
Vamos agora criar a estrutura, que é:
import React, { useState } from "react";
import {
View,
Text,
Platform,
TouchableOpacity,
StyleSheet,
Image,
} from "react-native";
import DateTimePicker from "@react-native-community/datetimepicker";
export default function TimeDatePicker({
frequency,
dayNotification,
timeNotification,
setDayNotification,
setTimeNotification,
}) {
const [date, setDate] = useState(new Date());
const [mode, setMode] = useState("date");
const [show, setShow] = useState(false);
const [selected, setSelected] = useState("-");
const [notificationDate, setNotificationDate] = useState();
const [notificationTime, setNotificationTime] = useState();
const data = [
{ key: "Domingo", value: "Dom" },
{ key: "Segunda", value: "Seg" },
{ key: "Terça", value: "Ter" },
{ key: "Quarta", value: "Qua" },
{ key: "Quinta", value: "Qui" },
{ key: "Sexta", value: "Sex" },
{ key: "Sábado", value: "Sab" },
];
return (
<View>
<TouchableOpacity style={styles.button} onPress={() => showMode("time")}>
<Text style={styles.buttonText}>Selecione a hora</Text>
</TouchableOpacity>
<View style={styles.textContainer}>
{frequency === "Diário" ? (
<Text style={styles.notificationText}>Dia do hábito: Diário</Text>
) : null}
{frequency === "Semanal" ? (
<Text style={styles.notificationText}>
Dia do hábito: {notificationDate}
</Text>
) : null}
<Text style={styles.notificationText}>
Horário do hábito: {notificationTime}
</Text>
</View>
{show && (
<DateTimePicker
testID="DateTimePicker"
value={date}
mode={mode}
is24Hour={true}
display="default"
onChange={onChange}
/>
)}
</View>
);
}
const styles = StyleSheet.create({
button: {
borderWidth: 1,
borderColor: "white",
paddingVertical: 15,
paddingHorizontal: 20,
borderRadius: 5,
justifyContent: "center",
alignItems: "center",
marginTop: 15,
},
buttonText: {
color: "white",
fontSize: 18,
fontWeight: "bold",
},
textContainer: {
marginVertical: 20,
},
notificationText: {
fontSize: 18,
color: "white",
},
});
Vamos agora criar a nossa função principal, que é o “onChange”, ela que vai registrar tudo que precisamos para poder exibir e salvar os dados de hora e dia.
import React, { useState } from "react";
import { View } from "react-native";
import DateTimePicker from "@react-native-community/datetimepicker";
export default function TimeDatePicker({
frequency,
dayNotification,
timeNotification,
setDayNotification,
setTimeNotification,
}) {
const [date, setDate] = useState(new Date());
const [mode, setMode] = useState("date");
const [show, setShow] = useState(false);
const [selected, setSelected] = useState("-");
const [notificationDate, setNotificationDate] = useState();
const [notificationTime, setNotificationTime] = useState();
const onChange = (_, selectedDate) => {
const currentDate = selectedDate || date;
setShow(Platform.OS === "ios");
setDate(currentDate);
let tempDate = new Date(currentDate);
const notficationHour = tempDate.getHours().toString().padStart(2, "0");
const notficationMin = tempDate.getMinutes().toString().padStart(2, "0");
let dateNotification;
if (frequency === "Semanal") {
dateNotification = selected;
}
const timeNotification = `${notficationHour}:${notficationMin}`;
setNotificationDate(dateNotification);
setNotificationTime(timeNotification);
if (frequency === "Diário") {
setDayNotification("Diário");
} else {
setDayNotification(dateNotification);
}
setTimeNotification(timeNotification);
};
const showMode = (currentMode) => {
setShow(true);
setMode(currentMode);
};
useEffect(() => {
if (dayNotification && timeNotification) {
setNotificationDate(dayNotification);
setNotificationTime(timeNotification);
}
}, []);
const data = [
{ key: "Domingo", value: "Dom" },
{ key: "Segunda", value: "Seg" },
{ key: "Terça", value: "Ter" },
{ key: "Quarta", value: "Qua" },
{ key: "Quinta", value: "Qui" },
{ key: "Sexta", value: "Sex" },
{ key: "Sábado", value: "Sab" },
];
return (
<View>
<TouchableOpacity style={styles.button} onPress={() => showMode("time")}>
<Text style={styles.buttonText}>Selecione a hora</Text>
</TouchableOpacity>
<View style={styles.textContainer}>
{frequency === "Diário" ? (
<Text style={styles.notificationText}>Dia do hábito: Diário</Text>
) : null}
{frequency === "Semanal" ? (
<Text style={styles.notificationText}>
Dia do hábito: {notificationDate}
</Text>
) : null}
<Text style={styles.notificationText}>
Horário do hábito: {notificationTime}
</Text>
</View>
{show && (
<DateTimePicker
testID="DateTimePicker"
value={date}
mode={mode}
is24Hour={true}
display="default"
onChange={onChange}
/>
)}
</View>
);
}
const styles = StyleSheet.create({
button: {
borderWidth: 1,
borderColor: "white",
paddingVertical: 15,
paddingHorizontal: 20,
borderRadius: 5,
justifyContent: "center",
alignItems: "center",
marginTop: 15,
},
buttonText: {
color: "white",
fontSize: 18,
fontWeight: "bold",
},
});
E por último, antes de poder testar tudo, vamos colocar o dropdown da semana. (Aqui adicionamos também o estilo do select, cuidado para não passar sem ver)
import React, { useState } from "react";
import {
View,
Text,
Platform,
TouchableOpacity,
StyleSheet,
Image,
} from "react-native";
import DateTimePicker from "@react-native-community/datetimepicker";
import { SelectList } from "react-native-dropdown-select-list";
export default function TimeDatePicker({
frequency,
dayNotification,
timeNotification,
setDayNotification,
setTimeNotification,
}) {
const [date, setDate] = useState(new Date());
const [mode, setMode] = useState("date");
const [show, setShow] = useState(false);
const [selected, setSelected] = useState("-");
const [notificationDate, setNotificationDate] = useState();
const [notificationTime, setNotificationTime] = useState();
const onChange = (_, selectedDate) => {
const currentDate = selectedDate || date;
setShow(Platform.OS === "ios");
setDate(currentDate);
let tempDate = new Date(currentDate);
const notficationHour = tempDate.getHours().toString().padStart(2, "0");
const notficationMin = tempDate.getMinutes().toString().padStart(2, "0");
let dateNotification;
if (frequency === "Semanal") {
dateNotification = selected;
}
const timeNotification = `${notficationHour}:${notficationMin}`;
setNotificationDate(dateNotification);
setNotificationTime(timeNotification);
if (frequency === "Diário") {
setDayNotification("Diário");
} else {
setDayNotification(dateNotification);
}
setTimeNotification(timeNotification);
};
const showMode = (currentMode) => {
setShow(true);
setMode(currentMode);
};
useEffect(() => {
if (dayNotification && timeNotification) {
setNotificationDate(dayNotification);
setNotificationTime(timeNotification);
}
}, []);
const data = [
{ key: "Domingo", value: "Dom" },
{ key: "Segunda", value: "Seg" },
{ key: "Terça", value: "Ter" },
{ key: "Quarta", value: "Qua" },
{ key: "Quinta", value: "Qui" },
{ key: "Sexta", value: "Sex" },
{ key: "Sábado", value: "Sab" },
];
return (
<View>
{frequency === "Semanal" ? (
<SelectList
data={data}
search={false}
setSelected={setSelected}
onSelect={() => {
onChange();
}}
placeholder={selected}
boxStyles={styles.boxStyle}
inputStyles={styles.inputStyle}
dropdownStyles={styles.dropdownStyle}
dropdownItemStyles={styles.dropdownItemStyle}
dropdownTextStyles={styles.dropdownTextStyle}
arrowicon={
<Image
source={require("../../../assets/icons/arrowDropdown.png")}
style={styles.arrow}
/>
}
/>
) : null}
<TouchableOpacity style={styles.button} onPress={() => showMode("time")}>
<Text style={styles.buttonText}>Selecione a hora</Text>
</TouchableOpacity>
<View style={styles.textContainer}>
{frequency === "Diário" ? (
<Text style={styles.notificationText}>Dia do hábito: Diário</Text>
) : null}
{frequency === "Semanal" ? (
<Text style={styles.notificationText}>
Dia do hábito: {notificationDate}
</Text>
) : null}
<Text style={styles.notificationText}>
Horário do hábito: {notificationTime}
</Text>
</View>
{show && (
<DateTimePicker
testID="DateTimePicker"
value={date}
mode={mode}
is24Hour={true}
display="default"
onChange={onChange}
/>
)}
</View>
);
}
const styles = StyleSheet.create({
button: {
borderWidth: 1,
borderColor: "white",
paddingVertical: 15,
paddingHorizontal: 20,
borderRadius: 5,
justifyContent: "center",
alignItems: "center",
marginTop: 15,
},
buttonText: {
color: "white",
fontSize: 18,
fontWeight: "bold",
},
textContainer: {
marginVertical: 20,
},
notificationText: {
fontSize: 18,
color: "white"
fontWeight: "bold",
},
boxStyle: {
borderWidth: 1,
borderColor: "white",
paddingHorizontal: 20,
paddingVertical: 15,
},
inputStyle: {
color: "white",
},
dropdownStyle: {
borderWidth: 0,
maxHeight: 100,
},
dropdownItemStyle: {
borderWidth: 1,
borderColor: "#BBBB",
borderRadius: 10,
marginBottom: 15,
},
dropdownTextStyle: {
color: "#BBBBBB",
},
arrow: {
width: 20,
height: 20,
},
});
Com isso feito, basta colocarmos na página “HabitPage” para poder verificar se está funcionando e também passarmos as props. "Pages → HabitPage → index.jsx”
import { useNavigation } from "@react-navigation/native";
import React, { useEffect, useRef, useState } from "react";
import {
View,
Text,
StyleSheet,
Image,
TouchableOpacity,
ScrollView,
} from "react-native";
import SelectHabit from "../../components/HabitPage/SelectHabit";
import SelectFrequency from "../../components/HabitPage/SelectFrequency";
import Notification from "../../components/HabitPage/Notification";
import TimeDatePicker from "../../components/HabitPage/TimeDatePicker";
export default function HabitPage({ route }) {
const navigation = useNavigation();
const [habitInput, setHabitInput] = useState();
const [frequencyInput, setFrequencyInput] = useState();
const [notificationToggle, setNotificationToggle] = useState();
const [dayNotification, setDayNotification] = useState();
const [timeNotification, setTimeNotification] = useState();
const { create, habit } = route.params;
return (
<View style={styles.container}>
<ScrollView>
<View>
<TouchableOpacity
style={styles.bakcPageBtn}
onPress={() => navigation.goBack()}
>
<Image
source={require("../../assets/icons/arrowBack.png")}
style={styles.arrowBack}
/>
</TouchableOpacity>
<View style={styles.mainContent}>
<Text style={styles.title}>Configurações {"\\n"} de hábito</Text>
<Text style={styles.inputText}>Área</Text>
<View style={styles.inputContainer}>
<Text style={styles.area}>{habitArea}</Text>
</View>
<Text style={styles.inputText}>Hábito</Text>
<SelectHabit habit={habit} habitInput={setHabitInput} />
<Text style={styles.inputText}>Frequência</Text>
<SelectFrequency
habitFrequency={habit?.habitFrequency}
frequencyInput={setFrequencyInput}
/>
{frequencyInput === "Mensal" ? null : (
<Notification
notificationToggle={notificationToggle}
setNotificationToggle={setNotificationToggle}
/>
)}
{notificationToggle ? (
frequencyInput === "Mensal" ? null : (
<TimeDatePicker
frequency={frequencyInput}
dayNotification={dayNotification}
timeNotification={timeNotification}
setDayNotification={setDayNotification}
setTimeNotification={setTimeNotification}
/>
)
) : null}
</View>
</View>
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "rgba(21, 21, 21, 0.98)",
},
bakcPageBtn: {
width: 40,
height: 40,
margin: 25,
},
arrowBack: {
width: 40,
height: 40,
},
mainContent: {
width: 250,
alignSelf: "center",
},configButton: {
alignItems: "center",
},
title: {
fontWeight: "bold",
textAlign: "center",
color: "white",
fontSize: 30,
},
inputText: {
color: "white",
fontSize: 16,
marginTop: 35,
marginBottom: 10,
marginLeft: 5,
},
inputContainer: {
borderWidth: 1,
borderColor: "#FFFFFF",
borderRadius: 10,
paddingHorizontal: 20,
paddingVertical: 15,
},
area: {
color: "#BBBBBB",
fontSize: 15,
},
});