mirror of
https://github.com/urosran/cally.git
synced 2025-07-17 02:25:10 +00:00
added birthday input
This commit is contained in:
@ -3,6 +3,7 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
Colors,
|
Colors,
|
||||||
|
DateTimePicker,
|
||||||
Dialog,
|
Dialog,
|
||||||
Image,
|
Image,
|
||||||
KeyboardAwareScrollView,
|
KeyboardAwareScrollView,
|
||||||
@ -53,6 +54,11 @@ const MyGroup: React.FC<MyGroupProps> = ({
|
|||||||
const [firstName, setFirstName] = useState("");
|
const [firstName, setFirstName] = useState("");
|
||||||
const [lastName, setLastName] = useState("");
|
const [lastName, setLastName] = useState("");
|
||||||
const [email, setEmail] = useState("");
|
const [email, setEmail] = useState("");
|
||||||
|
const [birthday, setBirthday] = useState<Date>(() => {
|
||||||
|
const date = new Date();
|
||||||
|
date.setFullYear(date.getFullYear() - 3);
|
||||||
|
return date;
|
||||||
|
});
|
||||||
|
|
||||||
const { profileData } = useAuthContext();
|
const { profileData } = useAuthContext();
|
||||||
|
|
||||||
@ -66,7 +72,8 @@ const MyGroup: React.FC<MyGroupProps> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const { mutateAsync: createSubUser, isLoading, isError } = useCreateSubUser();
|
const { mutateAsync: createSubUser, isLoading, isError } = useCreateSubUser();
|
||||||
const { data: familyMembers, refetch: refetchFamilyMembers } = useGetFamilyMembers(true);
|
const { data: familyMembers, refetch: refetchFamilyMembers } =
|
||||||
|
useGetFamilyMembers(true);
|
||||||
const { user } = useAuthContext();
|
const { user } = useAuthContext();
|
||||||
const {
|
const {
|
||||||
pickImage,
|
pickImage,
|
||||||
@ -115,6 +122,7 @@ const MyGroup: React.FC<MyGroupProps> = ({
|
|||||||
firstName,
|
firstName,
|
||||||
lastName: selectedStatus === ProfileType.FAMILY_DEVICE ? "" : lastName,
|
lastName: selectedStatus === ProfileType.FAMILY_DEVICE ? "" : lastName,
|
||||||
email: email || `placeholder_${uuidv4().split("-")[0]}@family.device`,
|
email: email || `placeholder_${uuidv4().split("-")[0]}@family.device`,
|
||||||
|
birthday: birthday,
|
||||||
password: uuidv4(),
|
password: uuidv4(),
|
||||||
userType: selectedStatus as ProfileType,
|
userType: selectedStatus as ProfileType,
|
||||||
});
|
});
|
||||||
@ -146,8 +154,24 @@ const MyGroup: React.FC<MyGroupProps> = ({
|
|||||||
setFirstName("");
|
setFirstName("");
|
||||||
setLastName("");
|
setLastName("");
|
||||||
setEmail("");
|
setEmail("");
|
||||||
|
|
||||||
|
const date = new Date();
|
||||||
|
date.setFullYear(date.getFullYear() - 3);
|
||||||
|
setBirthday(date);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const getMaxDate = () => {
|
||||||
|
const date = new Date();
|
||||||
|
date.setFullYear(date.getFullYear() - 3); // Minimum age: 3 years
|
||||||
|
return date;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getMinDate = () => {
|
||||||
|
const date = new Date();
|
||||||
|
date.setFullYear(date.getFullYear() - 18); // Maximum age: 18 years
|
||||||
|
return date;
|
||||||
|
};
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return (
|
return (
|
||||||
<View marginB-70>
|
<View marginB-70>
|
||||||
@ -524,6 +548,24 @@ const MyGroup: React.FC<MyGroupProps> = ({
|
|||||||
blurOnSubmit={false}
|
blurOnSubmit={false}
|
||||||
returnKeyType="next"
|
returnKeyType="next"
|
||||||
/>
|
/>
|
||||||
|
<Text style={styles.jakarta12}>Birthday</Text>
|
||||||
|
<DateTimePicker
|
||||||
|
editable={!isLoading}
|
||||||
|
mode="date"
|
||||||
|
minimumDate={getMinDate()}
|
||||||
|
maximumDate={getMaxDate()}
|
||||||
|
style={[styles.inputField, { paddingVertical: 0 }]}
|
||||||
|
value={birthday}
|
||||||
|
onChange={(date) => {
|
||||||
|
if (date) {
|
||||||
|
const validDate = new Date(date);
|
||||||
|
if (!isNaN(validDate.getTime())) {
|
||||||
|
setBirthday(validDate);
|
||||||
|
console.log("Selected birthday:", validDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import * as ImagePicker from "expo-image-picker";
|
|||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Colors,
|
Colors,
|
||||||
|
DateTimePicker,
|
||||||
Image,
|
Image,
|
||||||
Picker,
|
Picker,
|
||||||
Text,
|
Text,
|
||||||
@ -52,6 +53,16 @@ const MyProfile = () => {
|
|||||||
const [previousSelectedColor, setPreviousSelectedColor] = useState<string>(
|
const [previousSelectedColor, setPreviousSelectedColor] = useState<string>(
|
||||||
profileData?.eventColor ?? colorMap.pink
|
profileData?.eventColor ?? colorMap.pink
|
||||||
);
|
);
|
||||||
|
const [birthday, setBirthday] = useState<Date>(() => {
|
||||||
|
if (profileData?.birthday) {
|
||||||
|
if (profileData.birthday.toDate) {
|
||||||
|
return profileData.birthday.toDate();
|
||||||
|
}
|
||||||
|
const date = new Date(profileData.birthday);
|
||||||
|
return isNaN(date.getTime()) ? new Date() : date;
|
||||||
|
}
|
||||||
|
return new Date();
|
||||||
|
});
|
||||||
|
|
||||||
const [showDeleteDialog, setShowDeleteDialog] = useState<boolean>(false);
|
const [showDeleteDialog, setShowDeleteDialog] = useState<boolean>(false);
|
||||||
|
|
||||||
@ -98,8 +109,8 @@ const MyProfile = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (familyMembers) {
|
if (familyMembers) {
|
||||||
const colors = familyMembers
|
const colors = familyMembers
|
||||||
.filter(member => member?.eventColor && member.uid !== user?.uid)
|
.filter((member) => member?.eventColor && member.uid !== user?.uid)
|
||||||
.map(member => member.eventColor!);
|
.map((member) => member.eventColor!);
|
||||||
setTakenColors(colors);
|
setTakenColors(colors);
|
||||||
}
|
}
|
||||||
}, [familyMembers]);
|
}, [familyMembers]);
|
||||||
@ -111,6 +122,16 @@ const MyProfile = () => {
|
|||||||
setTimeZone(
|
setTimeZone(
|
||||||
profileData.timeZone || Localization.getCalendars()[0].timeZone!
|
profileData.timeZone || Localization.getCalendars()[0].timeZone!
|
||||||
);
|
);
|
||||||
|
if (profileData?.birthday) {
|
||||||
|
if (profileData.birthday.toDate) {
|
||||||
|
setBirthday(profileData.birthday.toDate());
|
||||||
|
} else {
|
||||||
|
const date = new Date(profileData.birthday);
|
||||||
|
if (!isNaN(date.getTime())) {
|
||||||
|
setBirthday(date);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [profileData]);
|
}, [profileData]);
|
||||||
|
|
||||||
@ -267,6 +288,27 @@ const MyProfile = () => {
|
|||||||
setLastName(value);
|
setLastName(value);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<Text text80 marginT-10 marginB-7 style={styles.label}>
|
||||||
|
Birthday
|
||||||
|
</Text>
|
||||||
|
<DateTimePicker
|
||||||
|
style={styles.txtBox}
|
||||||
|
mode="date"
|
||||||
|
value={birthday}
|
||||||
|
onChange={(date) => {
|
||||||
|
if (date) {
|
||||||
|
const validDate = new Date(date);
|
||||||
|
if (!isNaN(validDate.getTime())) {
|
||||||
|
setBirthday(validDate);
|
||||||
|
updateUserData({
|
||||||
|
newUserData: {
|
||||||
|
birthday: validDate,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<Text text80 marginT-10 marginB-7 style={styles.label}>
|
<Text text80 marginT-10 marginB-7 style={styles.label}>
|
||||||
Email address
|
Email address
|
||||||
</Text>
|
</Text>
|
||||||
@ -284,36 +326,83 @@ const MyProfile = () => {
|
|||||||
Color Preference
|
Color Preference
|
||||||
</Text>
|
</Text>
|
||||||
<View row spread>
|
<View row spread>
|
||||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.pink)} disabled={takenColors.includes(colorMap.pink)}>
|
<TouchableOpacity
|
||||||
<View style={[styles.colorBox, {opacity: takenColors.includes(colorMap.pink) ? 0.1 : 1}]} backgroundColor={colorMap.pink}>
|
onPress={() => handleChangeColor(colorMap.pink)}
|
||||||
|
disabled={takenColors.includes(colorMap.pink)}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.colorBox,
|
||||||
|
{ opacity: takenColors.includes(colorMap.pink) ? 0.1 : 1 },
|
||||||
|
]}
|
||||||
|
backgroundColor={colorMap.pink}
|
||||||
|
>
|
||||||
{selectedColor == colorMap.pink && (
|
{selectedColor == colorMap.pink && (
|
||||||
<AntDesign name="check" size={30} color="white" />
|
<AntDesign name="check" size={30} color="white" />
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.lightPink)} disabled={takenColors.includes(colorMap.lightPink)}>
|
<TouchableOpacity
|
||||||
<View style={[styles.colorBox, {opacity: takenColors.includes(colorMap.lightPink) ? 0.1 : 1}]} backgroundColor={colorMap.lightPink}>
|
onPress={() => handleChangeColor(colorMap.lightPink)}
|
||||||
|
disabled={takenColors.includes(colorMap.lightPink)}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.colorBox,
|
||||||
|
{ opacity: takenColors.includes(colorMap.lightPink) ? 0.1 : 1 },
|
||||||
|
]}
|
||||||
|
backgroundColor={colorMap.lightPink}
|
||||||
|
>
|
||||||
{selectedColor == colorMap.lightPink && (
|
{selectedColor == colorMap.lightPink && (
|
||||||
<AntDesign name="check" size={30} color="black" />
|
<AntDesign name="check" size={30} color="black" />
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.orange)} disabled={takenColors.includes(colorMap.orange)}>
|
<TouchableOpacity
|
||||||
<View style={[styles.colorBox, {opacity: takenColors.includes(colorMap.orange) ? 0.1 : 1}]} backgroundColor={colorMap.orange}>
|
onPress={() => handleChangeColor(colorMap.orange)}
|
||||||
|
disabled={takenColors.includes(colorMap.orange)}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.colorBox,
|
||||||
|
{ opacity: takenColors.includes(colorMap.orange) ? 0.1 : 1 },
|
||||||
|
]}
|
||||||
|
backgroundColor={colorMap.orange}
|
||||||
|
>
|
||||||
{selectedColor == colorMap.orange && (
|
{selectedColor == colorMap.orange && (
|
||||||
<AntDesign name="check" size={30} color="white" />
|
<AntDesign name="check" size={30} color="white" />
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.lightOrange)} disabled={takenColors.includes(colorMap.lightOrange)}>
|
<TouchableOpacity
|
||||||
<View style={[styles.colorBox, {opacity: takenColors.includes(colorMap.lightOrange) ? 0.1 : 1}]} backgroundColor={colorMap.lightOrange}>
|
onPress={() => handleChangeColor(colorMap.lightOrange)}
|
||||||
|
disabled={takenColors.includes(colorMap.lightOrange)}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.colorBox,
|
||||||
|
{
|
||||||
|
opacity: takenColors.includes(colorMap.lightOrange) ? 0.1 : 1,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
backgroundColor={colorMap.lightOrange}
|
||||||
|
>
|
||||||
{selectedColor == colorMap.lightOrange && (
|
{selectedColor == colorMap.lightOrange && (
|
||||||
<AntDesign name="check" size={30} color="black" />
|
<AntDesign name="check" size={30} color="black" />
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.green)}disabled={takenColors.includes(colorMap.green)}>
|
<TouchableOpacity
|
||||||
<View style={[styles.colorBox, {opacity: takenColors.includes(colorMap.green) ? 0.1 : 1}]} backgroundColor={colorMap.green}>
|
onPress={() => handleChangeColor(colorMap.green)}
|
||||||
|
disabled={takenColors.includes(colorMap.green)}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.colorBox,
|
||||||
|
{ opacity: takenColors.includes(colorMap.green) ? 0.1 : 1 },
|
||||||
|
]}
|
||||||
|
backgroundColor={colorMap.green}
|
||||||
|
>
|
||||||
{selectedColor == colorMap.green && (
|
{selectedColor == colorMap.green && (
|
||||||
<AntDesign name="check" size={30} color="white" />
|
<AntDesign name="check" size={30} color="white" />
|
||||||
)}
|
)}
|
||||||
@ -321,36 +410,85 @@ const MyProfile = () => {
|
|||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
<View row spread marginT-10>
|
<View row spread marginT-10>
|
||||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.lightGreen)} disabled={takenColors.includes(colorMap.lightGreen)}>
|
<TouchableOpacity
|
||||||
<View style={[styles.colorBox, {opacity: takenColors.includes(colorMap.lightGreen) ? 0.1 : 1}]} backgroundColor={colorMap.lightGreen}>
|
onPress={() => handleChangeColor(colorMap.lightGreen)}
|
||||||
|
disabled={takenColors.includes(colorMap.lightGreen)}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.colorBox,
|
||||||
|
{
|
||||||
|
opacity: takenColors.includes(colorMap.lightGreen) ? 0.1 : 1,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
backgroundColor={colorMap.lightGreen}
|
||||||
|
>
|
||||||
{selectedColor == colorMap.lightGreen && (
|
{selectedColor == colorMap.lightGreen && (
|
||||||
<AntDesign name="check" size={30} color="black" />
|
<AntDesign name="check" size={30} color="black" />
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.teal)} disabled={takenColors.includes(colorMap.teal)}>
|
<TouchableOpacity
|
||||||
<View style={[styles.colorBox, {opacity: takenColors.includes(colorMap.teal) ? 0.1 : 1}]} backgroundColor={colorMap.teal}>
|
onPress={() => handleChangeColor(colorMap.teal)}
|
||||||
|
disabled={takenColors.includes(colorMap.teal)}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.colorBox,
|
||||||
|
{ opacity: takenColors.includes(colorMap.teal) ? 0.1 : 1 },
|
||||||
|
]}
|
||||||
|
backgroundColor={colorMap.teal}
|
||||||
|
>
|
||||||
{selectedColor == colorMap.teal && (
|
{selectedColor == colorMap.teal && (
|
||||||
<AntDesign name="check" size={30} color="white" />
|
<AntDesign name="check" size={30} color="white" />
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.lightTeal)} disabled={takenColors.includes(colorMap.lightTeal)}>
|
<TouchableOpacity
|
||||||
<View style={[styles.colorBox, {opacity: takenColors.includes(colorMap.lightTeal) ? 0.1 : 1}]} backgroundColor={colorMap.lightTeal}>
|
onPress={() => handleChangeColor(colorMap.lightTeal)}
|
||||||
|
disabled={takenColors.includes(colorMap.lightTeal)}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.colorBox,
|
||||||
|
{ opacity: takenColors.includes(colorMap.lightTeal) ? 0.1 : 1 },
|
||||||
|
]}
|
||||||
|
backgroundColor={colorMap.lightTeal}
|
||||||
|
>
|
||||||
{selectedColor == colorMap.lightTeal && (
|
{selectedColor == colorMap.lightTeal && (
|
||||||
<AntDesign name="check" size={30} color="black" />
|
<AntDesign name="check" size={30} color="black" />
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.purple)} disabled={takenColors.includes(colorMap.purple)}>
|
<TouchableOpacity
|
||||||
<View style={[styles.colorBox, {opacity: takenColors.includes(colorMap.purple) ? 0.1 : 1}]} backgroundColor={colorMap.purple}>
|
onPress={() => handleChangeColor(colorMap.purple)}
|
||||||
|
disabled={takenColors.includes(colorMap.purple)}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.colorBox,
|
||||||
|
{ opacity: takenColors.includes(colorMap.purple) ? 0.1 : 1 },
|
||||||
|
]}
|
||||||
|
backgroundColor={colorMap.purple}
|
||||||
|
>
|
||||||
{selectedColor == colorMap.purple && (
|
{selectedColor == colorMap.purple && (
|
||||||
<AntDesign name="check" size={30} color="white" />
|
<AntDesign name="check" size={30} color="white" />
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.lightPurple)} disabled={takenColors.includes(colorMap.lightPurple)}>
|
<TouchableOpacity
|
||||||
<View style={[styles.colorBox, {opacity: takenColors.includes(colorMap.lightPurple) ? 0.1 : 1}]} backgroundColor={colorMap.lightPurple}>
|
onPress={() => handleChangeColor(colorMap.lightPurple)}
|
||||||
|
disabled={takenColors.includes(colorMap.lightPurple)}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.colorBox,
|
||||||
|
{
|
||||||
|
opacity: takenColors.includes(colorMap.lightPurple) ? 0.1 : 1,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
backgroundColor={colorMap.lightPurple}
|
||||||
|
>
|
||||||
{selectedColor == colorMap.lightPurple && (
|
{selectedColor == colorMap.lightPurple && (
|
||||||
<AntDesign name="check" size={30} color="black" />
|
<AntDesign name="check" size={30} color="black" />
|
||||||
)}
|
)}
|
||||||
|
Reference in New Issue
Block a user