Files
cally/components/pages/todos/AddChoreDialog.tsx
2024-10-20 20:45:09 +02:00

288 lines
8.2 KiB
TypeScript

import {View, Text, Button, Switch, PickerModes} from "react-native-ui-lib";
import React, { useRef, useState } from "react";
import PointsSlider from "@/components/shared/PointsSlider";
import { repeatOptions, useToDosContext } from "@/contexts/ToDosContext";
import { Feather, AntDesign, Ionicons } from "@expo/vector-icons";
import {
Dialog,
TextField,
DateTimePicker,
Picker,
ButtonSize,
} from "react-native-ui-lib";
import { PanningDirectionsEnum } from "react-native-ui-lib/src/incubator/panView";
import { Dimensions, StyleSheet } from "react-native";
import DropModalIcon from "@/assets/svgs/DropModalIcon";
import { IToDo } from "@/hooks/firebase/types/todoData";
import AssigneesDisplay from "@/components/shared/AssigneesDisplay";
import {useGetFamilyMembers} from "@/hooks/firebase/useGetFamilyMembers";
interface IAddChoreDialog {
isVisible: boolean;
setIsVisible: (value: boolean) => void;
selectedTodo?: IToDo;
}
const defaultTodo = {
id: "",
title: "",
points: 10,
date: new Date(),
rotate: false,
repeatType: "Every week",
assignees: []
};
const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => {
const { addToDo, updateToDo } = useToDosContext();
const [todo, setTodo] = useState<IToDo>(
addChoreDialogProps.selectedTodo ?? defaultTodo
);
const [selectedAssignees, setSelectedAssignees] = useState<string[]>(addChoreDialogProps?.selectedTodo?.assignees ?? []);
const { width, height } = Dimensions.get("screen");
const [points, setPoints] = useState<number>(todo.points);
const {data: members} = useGetFamilyMembers();
const handleClose = () => {
setTodo(defaultTodo);
setSelectedAssignees([]);
addChoreDialogProps.setIsVisible(false);
};
const handleChange = (text: string) => {
const numericValue = parseInt(text, 10);
if (!isNaN(numericValue) && numericValue >= 0 && numericValue <= 100) {
setPoints(numericValue);
} else if (text === "") {
setPoints(0);
}
};
return (
<Dialog
bottom={true}
height={"90%"}
width={width}
panDirection={PanningDirectionsEnum.DOWN}
onDismiss={() => handleClose}
containerStyle={{
borderRadius: 10,
backgroundColor: "white",
alignSelf: "stretch",
padding: 0,
paddingTop: 4,
margin: 0,
}}
visible={addChoreDialogProps.isVisible}
>
<View row spread>
<Button
color="#05a8b6"
style={styles.topBtn}
label="Cancel"
onPress={() => {
handleClose();
}}
/>
<View marginT-12>
<DropModalIcon
onPress={() => {
handleClose();
}}
/>
</View>
<Button
color="#05a8b6"
style={styles.topBtn}
label="Save"
onPress={() => {
try {
if (addChoreDialogProps.selectedTodo) {
updateToDo({ ...todo, points: points, assignees: selectedAssignees });
} else {
addToDo({
...todo,
done: false,
points: points,
assignees: selectedAssignees
});
}
handleClose();
} catch (error) {
console.error(error);
}
}}
/>
</View>
<TextField
placeholder="Add a To Do"
autoFocus
value={todo?.title}
onChangeText={(text) => {
setTodo((oldValue: IToDo) => ({ ...oldValue, title: text }));
}}
placeholderTextColor="#2d2d30"
text60R
marginT-15
marginL-30
/>
<View style={styles.divider} marginT-8 />
<View marginL-30 centerV>
<View row marginB-10>
{todo?.date && (
<View row centerV>
<Feather name="calendar" size={25} color="#919191" />
<DateTimePicker
value={todo.date}
text70
marginL-8
onChange={(date) => {
setTodo((oldValue: IToDo) => ({ ...oldValue, date: date }));
}}
/>
</View>
)}
</View>
<View row centerV>
<AntDesign name="clockcircleo" size={24} color="#919191" />
<Picker
marginL-8
placeholder="Select Repeat Type"
value={todo?.repeatType}
onChange={(value) => {
if (value) {
if (value.toString() == "None") {
setTodo((oldValue) => ({
...oldValue,
date: null,
repeatType: "None",
}));
} else {
setTodo((oldValue) => ({
...oldValue,
date: new Date(),
repeatType: value.toString(),
}));
}
}
}}
topBarProps={{ title: "Repeat" }}
style={{ marginVertical: 5 }}
>
{repeatOptions.map((option) => (
<Picker.Item
key={option.value}
label={option.label}
value={option.value}
/>
))}
</Picker>
</View>
</View>
<View style={styles.divider} />
<View marginH-30 marginB-10 row centerV>
<Ionicons name="person-circle-outline" size={28} color="#919191" />
<Text text70R marginL-10>
Assignees
</Text>
<View flex-1/>
<Picker
marginL-8
value={selectedAssignees}
onChange={(value) => {
setSelectedAssignees([...selectedAssignees, ...value]);
}}
style={{ marginVertical: 5 }}
mode={PickerModes.MULTI}
renderInput={() =>
<Button
size={ButtonSize.small}
paddingH-8
iconSource={() => (
<Ionicons name="add-outline" size={20} color="#ea156c"/>
)}
style={{
marginLeft: "auto",
borderRadius: 8,
backgroundColor: "#ffe8f1",
borderColor: "#ea156c",
borderWidth: 1,
}}
color="#ea156c"
label="Assign"
labelStyle={{fontFamily: "Manrope_600SemiBold", fontSize: 14}}
/>
}
>
{members?.map((member) => (
<Picker.Item
key={member.uid}
label={member?.firstName + " " + member?.lastName}
value={member?.uid!}
/>
))}
</Picker>
</View>
<View row marginL-27 marginT-0>
<AssigneesDisplay selectedAttendees={selectedAssignees} setSelectedAttendees={setSelectedAssignees}/>
</View>
<View row centerV style={styles.rotateSwitch}>
<Text text80>Take Turns</Text>
<Switch
onColor={"#ea156c"}
value={todo.rotate}
marginL-10
onValueChange={(value) =>
setTodo((oldValue) => ({ ...oldValue, rotate: value }))
}
/>
</View>
<View style={styles.divider} />
<View marginH-30 marginB-15 row centerV>
<Ionicons name="gift-outline" size={25} color="#919191" />
<Text text70BL marginL-10>
Reward Points
</Text>
</View>
<PointsSlider
points={points}
setPoints={setPoints}
handleChange={handleChange}
/>
</Dialog>
);
};
export default AddChoreDialog;
const styles = StyleSheet.create({
divider: { height: 1, backgroundColor: "#e4e4e4", marginVertical: 15 },
gradient: {
height: "25%",
position: "absolute",
bottom: 0,
width: "100%",
},
buttonContainer: {
position: "absolute",
bottom: 25,
width: "100%",
},
button: {
backgroundColor: "rgb(253, 23, 117)",
paddingVertical: 20,
},
topBtn: {
backgroundColor: "white",
color: "#05a8b6",
},
rotateSwitch: {
marginLeft: 35,
marginBottom: 10,
marginTop: 25,
},
});