My goal is simple. When I have a schedule in the same day as the current day, I want the switch to be on. And if not I want the switch to be off. This is controlled by the validateIsOut function.
I have the option to add new schedules or remove them, and when I do it the toggle is always one step behind. If I add an event for the current day, the switch do not moves. Then if I delete this event, the switch turns on (is always one step behind)
export default function AwayOn() {
//Other code irrelevant for this issue
//############################//
// USE-EFFECTS //
//############################//
//useEffect to populate the collaborators dropdown.
useEffect(() => {
getUserData();
}, []);
useEffect(() => {
validateIsOut();
}, [schedules]);
//############################//
// USE_STATE //
//############################//
//State to control if user is away or not
const [isOut, setIsOut] = useState(false);
//State with test schedules
const [schedules, setSchedules] = useState({
"2024-08-01": [{ name: "Meeting 1", data: "teste" }],
"2024-08-20": [{ name: "Meeting 1", data: "teste" }],
"2024-08-21": [{ name: "Meeting 2", data: "teste" }],
});
//Other code irrelevant for this issue
//############################//
// FUNCTIONS //
//############################//
//Function to add a new schedule
const addNewSchedule = () => {
const newSchedule = {
name: newRegisterTitle,
data: newRegisterDescription,
};
const dateKey = newRegisterDate.toISOString().split("T")[0];
setSchedules((prevItems) => {
return {
...prevItems,
[dateKey]: [newSchedule],
};
});
setOpenModal(false);
setNewRegisterTitle("");
setNewRegisterDescription("");
setNewRegisterDate(new Date());
};
//Function to close the modal
const closeModal = () => {
setOpenModal(false);
setNewRegisterDate(new Date());
setNewRegisterDescription("");
setNewRegisterTitle("");
setDeleteRegister(false);
};
//Function to delete an existing schedule
const deleteSchedule = () => {
const dateKey = newRegisterDate.toISOString().split("T")[0];
setSchedules((prevItems) => {
const updatedItems = { ...prevItems };
delete updatedItems[dateKey];
return updatedItems;
});
closeModal();
};
//Other code irrelevant for this issue
const validateIsOut = () => {
let today = new Date().toISOString().split("T")[0];
if (schedules[today]) {
console.log("User is out");
setIsOut(true);
} else {
console.log("User is present");
setIsOut(false);
}
};
//++++++++++++++++++++++++++RETURN++++++++++++++++++++++++++++++//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
return (
<>
<View style={backgroundStyles.container}>
<Header />
<ImageBackground
source={require("../../assets/image/LOGOTIPO_MECWIDE_M_ONLY.png")}
style={backgroundStyles.backgroundImage}
imageStyle={backgroundStyles.imageBackgroundStyle}
></ImageBackground>
<View style={styles.header}>
<View style={styles.headerContainerTitle}>
<Text style={globalStyles.headerTitle}>{title[lang]}</Text>
</View>
<View style={styles.headerRight}></View>
</View>
<View
style={[
globalStyles.mb20,
{ flexDirection: "row", alignItems: "center" },
]}
>
<Switch
trackColor={{ false: "#767577", true: "#0050F2" }}
thumbColor={isOut ? "#f4f3f4" : "#f4f3f4"}
ios_backgroundColor="#3e3e3e"
value={isOut}
disabled={true}
style={globalStyles.mr10}
/>
<Text style={[globalStyles.whiteColor]}>{toggle2[lang]}</Text>
</View>
<View
style={[globalStyles.mb20, globalStyles.flex1, { maxHeight: 350 }]}
>
<Agenda
items={allDates}
renderItem={(item, isFirst) => (
<TouchableOpacity style={styles.item}>
<Text style={[styles.itemText, globalStyles.bold]}>
{item.name}
</Text>
<Text style={styles.itemText}>{item.data}</Text>
</TouchableOpacity>
)}
pastScrollRange={0}
futureScrollRange={2}
style={{ borderRadius: 10 }}
/>
</View>
{!isOtherUserStatus && (
<TouchableOpacity
style={[btnsStyles.submitButton, btnsStyles.shadow]}
onPress={() => setOpenModal(true)}
>
<Text style={btnsStyles.submitButtonText}>{btn1[lang]}</Text>
</TouchableOpacity>
)}
<Modal
animationType="slide"
transparent={true}
visible={openModal}
onRequestClose={closeModal}
>
<View style={modalStyles.modalBackground}>
<View style={modalStyles.modalContent}>
<View style={styles.modalHeader}>
<Text
style={[
globalStyles.greyColor3,
globalStyles.bold,
{ fontSize: 16 },
]}
>
{modalTitle[lang]}
</Text>
<AntDesign
name="closecircle"
size={24}
color="#333333"
onPress={closeModal}
/>
</View>
<View style={[globalStyles.mb10, styles.rowCenter]}>
<Text>{toggle3[lang]}</Text>
<Switch
trackColor={{ false: "#0050F2", true: "red" }}
thumbColor={deleteRegister ? "#f4f3f4" : "#f4f3f4"}
ios_backgroundColor="#0050F2"
onValueChange={toggleSwitchSchedule}
value={deleteRegister}
style={[globalStyles.mr10, globalStyles.ml10]}
/>
<Text>{toggle4[lang]}</Text>
</View>
<View
style={[
globalStyles.mb20,
styles.rowCenter,
{
justifyContent: "flex-start",
},
]}
>
<Text style={globalStyles.mr10}>{date[lang]} </Text>
{Platform.OS === "android" && (
<View style={[{ flexDirection: "row" }, styles.lineWrapper]}>
<TouchableOpacity
onPress={() => {
setShow(true);
setMode("date");
}}
style={{ width: 150 }}
>
<View
style={[
autoCompleteDropsStyles.textAreaContainer,
styles.androidCalendar,
]}
>
<AntDesign name="calendar" size={25} color="#333" />
<Text style={globalStyles.greyColor3}>
{newRegisterDate.toLocaleDateString()}
</Text>
</View>
</TouchableOpacity>
</View>
)}
{Platform.OS === "android" && show && (
<DateTimePicker
testID="dateTimePicker"
value={newRegisterDate}
mode={mode}
is24Hour={true}
display="default"
onChange={handleDateChange}
/>
)}
{Platform.OS === "ios" && (
<View>
<DateTimePicker
testID="dateTimePicker"
value={newRegisterDate}
mode="date"
is24Hour={true}
display="default"
onChange={handleDateChange}
themeVariant="light"
style={[
styles.rowCenter,
{
justifyContent: "center",
width: 100,
},
]}
/>
</View>
)}
</View>
<TextInput
style={[
autoCompleteDropsStyles.textAreaContainer,
styles.titleInput,
deleteRegister && { opacity: 0.5 },
]}
placeholder={titleInput[lang]}
multiline={false}
placeholderTextColor={"#000"}
value={newRegisterTitle}
onChangeText={handleTitleChange}
editable={!deleteRegister}
/>
<TextInput
style={[
autoCompleteDropsStyles.textAreaContainer,
styles.descriptionInput,
deleteRegister && { opacity: 0.5 },
]}
placeholder={descriptionInput[lang]}
multiline={true}
placeholderTextColor={"#000"}
value={newRegisterDescription}
onChangeText={handleDescriptionChange}
editable={!deleteRegister}
/>
{!deleteRegister && (
<TouchableOpacity
style={[
btnsStyles.submitButton,
btnsStyles.shadow,
{
opacity:
!newRegisterTitle || !newRegisterDescription ? 0.5 : 1,
},
]}
onPress={() => {
addNewSchedule();
validateIsOut();
}}
disabled={!newRegisterTitle || !newRegisterDescription}
>
<Text style={btnsStyles.submitButtonText}>{btn2[lang]}</Text>
</TouchableOpacity>
)}
{deleteRegister && (
<TouchableOpacity
style={[btnsStyles.deleteButton, btnsStyles.shadow]}
onPress={() => {
deleteSchedule();
validateIsOut();
}}
>
<Text style={btnsStyles.submitButtonText}>{btn3[lang]}</Text>
</TouchableOpacity>
)}
</View>
</View>
</Modal>
</View>
<Footer />
</>
);
}
//++++++++++++++++++++++++++++STYLES++++++++++++++++++++++++++++//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
const styles = StyleSheet.create({
androidCalendar: {
flexDirection: "row",
justifyContent: "space-evenly",
alignItems: "center",
marginBottom: 0,
backgroundColor: "#EEE",
borderColor: "#EEE",
},
descriptionInput: {
height: 60,
backgroundColor: "#EEE",
borderColor: "#EEE",
textAlignVertical: "top",
},
header: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
marginBottom: 30,
},
headerContainerTitle: {
display: "flex",
flexDirection: "row",
alignItems: "center",
},
headerRight: {
flexDirection: "row",
alignItems: "center",
},
item: {
backgroundColor: "lightblue",
flex: 1,
borderRadius: 5,
padding: 10,
marginRight: 10,
marginTop: 25,
paddingBottom: 20,
},
itemText: {
color: "#000",
fontSize: 14,
},
lineWrapper: {
flexDirection: "row",
width: "100%",
justifyContent: "space-between",
},
modalHeader: {
flexDirection: "row",
justifyContent: "space-between",
alignContent: "center",
marginBottom: 20,
},
rowCenter: {
flexDirection: "row",
alignItems: "center",
},
titleInput: {
height: 30,
backgroundColor: "#EEE",
borderColor: "#EEE",
},
});
I already tried the use of useEffect but is not working. I also tried use setTimeOut when I call the validateIsOut function but is not working too.
2
Answers
Thank you very much for the help! It worked for me!
Instead of
write it like this
Put this useEffect after this useState.