Files
cally/components/pages/settings/user_settings_views/MyGroup.tsx
2024-10-20 01:44:20 +02:00

558 lines
22 KiB
TypeScript

import {
Avatar,
Button,
Card,
Colors,
Dialog,
FloatingButton,
KeyboardAwareScrollView,
PanningProvider,
Picker,
Text,
TextField,
TextFieldRef,
TouchableOpacity,
View,
} from "react-native-ui-lib";
import React, {useEffect, useRef, useState} from "react";
import {ScrollView, StyleSheet} from "react-native";
import {PickerSingleValue} from "react-native-ui-lib/src/components/picker/types";
import {useCreateSubUser} from "@/hooks/firebase/useCreateSubUser";
import {ProfileType} from "@/contexts/AuthContext";
import {useGetFamilyMembers} from "@/hooks/firebase/useGetFamilyMembers";
import UserMenu from "@/components/pages/settings/user_settings_views/UserMenu";
import {uuidv4} from "@firebase/util";
import QRIcon from "@/assets/svgs/QRIcon";
import EmailIcon from "@/assets/svgs/EmailIcon";
import CircledXIcon from "@/assets/svgs/CircledXIcon";
import ProfileIcon from "@/assets/svgs/ProfileIcon";
import NavToDosIcon from "@/assets/svgs/NavToDosIcon";
import Ionicons from "@expo/vector-icons/Ionicons";
import {PreviousNextView} from "react-native-keyboard-manager";
const MyGroup = () => {
const [showAddUserDialog, setShowAddUserDialog] = useState(false);
const [showNewUserInfoDialog, setShowNewUserInfoDialog] = useState(false);
const [selectedStatus, setSelectedStatus] = useState<
string | PickerSingleValue
>(ProfileType.CHILD);
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [email, setEmail] = useState("");
const lNameRef = useRef<TextFieldRef>(null);
const emailRef = useRef<TextFieldRef>(null);
const [showQRCodeDialog, setShowQRCodeDialog] = useState("");
const {mutateAsync: createSubUser, isLoading, isError} = useCreateSubUser();
const {data: familyMembers} = useGetFamilyMembers(true);
const parents =
familyMembers?.filter((x) => x.userType === ProfileType.PARENT) ?? [];
const children =
familyMembers?.filter((x) => x.userType === ProfileType.CHILD) ?? [];
const caregivers =
familyMembers?.filter((x) => x.userType === ProfileType.CAREGIVER) ?? [];
const familyDevices =
familyMembers?.filter((x) => x.userType === ProfileType.FAMILY_DEVICE) ??
[];
const handleCreateSubUser = async () => {
if (
!firstName ||
(selectedStatus !== ProfileType.FAMILY_DEVICE && !lastName)
) {
console.error("First name and last name are required");
return;
}
if (selectedStatus !== ProfileType.FAMILY_DEVICE && !email) {
console.error("Email is required for non-family device users");
return;
}
if (email && !email.includes("@")) {
console.error("Invalid email address");
return;
}
const res = await createSubUser({
firstName,
lastName: selectedStatus === ProfileType.FAMILY_DEVICE ? "" : lastName,
email: email || `placeholder_${uuidv4().split("-")[0]}@family.device`,
password: uuidv4(),
userType: selectedStatus as ProfileType,
});
console.log(res);
if (!isError) {
setShowNewUserInfoDialog(false);
if (res?.data?.userId) {
setTimeout(() => {
setShowQRCodeDialog(res.data.userId);
}, 500);
}
}
};
useEffect(() => {
setFirstName("");
setLastName("");
setEmail("");
}, [])
// @ts-ignore
return (
<View style={{flex: 1, minHeight: 500}}>
<View>
<ScrollView style={styles.card}>
{!parents.length && !children.length && !caregivers.length && (
<Text text70 marginV-10>
{isLoading ? "Loading...." : "No user devices added"}
</Text>
)}
{(!!parents.length || !!children.length) && (
<>
<Text style={styles.subTit} marginV-10>
Family
</Text>
{[...parents, ...children]?.map((member, index) => (
<Card
enableShadow={false}
elevation={0}
key={`${member.firstName}_${member.lastName}_${index}`}
style={styles.familyCard}
row
centerV
padding-10
>
<Avatar
source={{uri: "https://via.placeholder.com/60"}}
size={40}
backgroundColor={Colors.grey60}
/>
<View marginL-10>
<Text text70M>
{member.firstName} {member.lastName}
</Text>
<Text text90 grey40>
{member.userType === ProfileType.PARENT
? "Admin (You)"
: "Child"}
</Text>
</View>
<View flex-1/>
<UserMenu
setShowQRCodeDialog={(val) => setShowQRCodeDialog("")}
showQRCodeDialog={showQRCodeDialog === member?.uid}
userId={member?.uid!}
/>
</Card>
))}
</>
)}
{!!caregivers.length && (
<>
<Text text70 marginB-10 marginT-15>
Caregivers
</Text>
{caregivers?.map((member) => (
<Card
enableShadow={false}
elevation={0}
key={`${member.firstName}_${member.lastName}`}
style={styles.familyCard}
row
centerV
padding-10
>
<Avatar
source={{uri: "https://via.placeholder.com/60"}}
size={40}
backgroundColor={Colors.grey60}
/>
<View marginL-10>
<Text text70M>
{member.firstName} {member.lastName}
</Text>
<Text text90 grey40>
Caregiver
</Text>
</View>
<UserMenu
setShowQRCodeDialog={(val) => setShowQRCodeDialog("")}
showQRCodeDialog={showQRCodeDialog === member?.uid}
userId={member?.uid!}
/>
</Card>
))}
</>
)}
{!!familyDevices.length && (
<>
<Text text70 marginB-10 marginT-15>
Family Devices
</Text>
{familyDevices?.map((member, index) => (
<Card
enableShadow={false}
elevation={0}
key={`${member.firstName}_${member.lastName}_${index}`}
style={styles.familyCard}
row
centerV
padding-10
>
<Avatar
source={{uri: "https://via.placeholder.com/60"}}
size={40}
backgroundColor={Colors.grey60}
/>
<View marginL-10>
<Text text70M>{member.firstName}</Text>
<Text text90 grey40>
Family Device
</Text>
</View>
<UserMenu
setShowQRCodeDialog={(val) => setShowQRCodeDialog("")}
showQRCodeDialog={showQRCodeDialog === member?.uid}
userId={member?.uid!}
/>
</Card>
))}
</>
)}
</ScrollView>
</View>
<FloatingButton
fullWidth
hideBackgroundOverlay
visible
button={{
label: "+ Add a user device",
onPress: () => setShowAddUserDialog(true),
style: styles.bottomButton,
}}
/>
<Dialog
visible={showAddUserDialog}
onDismiss={() => setShowAddUserDialog(false)}
panDirection={PanningProvider.Directions.DOWN}
>
<Card
paddingH-25
paddingT-40
paddingB-20
gap-10
centerH
borderRadius={20}
>
<Text style={styles.dialogTitle} marginB-35>
Add a new user device
</Text>
<Button backgroundColor={"#FD1775"} style={styles.dialogBtn}>
<QRIcon/>
<Text style={styles.dialogBtnLbl} marginL-7>
Show a QR Code
</Text>
</Button>
<Button
style={styles.dialogBtn}
backgroundColor={"#05A8B6"}
onPress={() => {
setShowAddUserDialog(false);
setTimeout(() => {
setShowNewUserInfoDialog(true);
}, 500);
}}
>
<EmailIcon/>
<Text style={styles.dialogBtnLbl} marginL-7>
Enter email address
</Text>
</Button>
<TouchableOpacity
onPress={() => setShowAddUserDialog(false)}
center
marginT-30
>
<Text style={styles.dialogBackBtn}>Return to user settings</Text>
</TouchableOpacity>
</Card>
</Dialog>
<Dialog
panDirection={PanningProvider.Directions.DOWN}
visible={showNewUserInfoDialog}
onDismiss={() => setShowNewUserInfoDialog(false)}
>
<PreviousNextView>
<KeyboardAwareScrollView>
<Card padding-25 style={styles.dialogCard}>
<View row spread>
<Text style={{fontFamily: "Manrope_500Medium", fontSize: 16}}>
New User Information
</Text>
<TouchableOpacity onPress={() => {
setShowNewUserInfoDialog(false)
}}>
<CircledXIcon/>
</TouchableOpacity>
</View>
<View style={styles.divider} spread/>
<View row centerV gap-20 marginV-20>
<View
height={65.54}
width={65.54}
children={
<ProfileIcon color={"#d6d6d6"} width={37} height={37}/>
}
backgroundColor={Colors.grey60}
style={{borderRadius: 25}}
center
/>
<TouchableOpacity onPress={() => {
}}>
<Text color="#50be0c" style={styles.jakarta13} marginL-15>
Upload User Profile Photo
</Text>
</TouchableOpacity>
</View>
<Text style={styles.jakarta12}>Member Status</Text>
<View style={styles.viewPicker}>
<Picker
editable={!isLoading}
value={selectedStatus}
onChange={(item) => setSelectedStatus(item)}
showSearch
floatingPlaceholder
style={styles.inViewPicker}
trailingAccessory={
<View style={{
justifyContent: "center",
alignItems: "center",
height: "100%",
marginTop: -38,
paddingRight: 15
}}>
<Ionicons name={"chevron-down"} style={{alignSelf: "center"}} size={20}
color={"#000000"}/>
</View>
}
>
<Picker.Item label="Child" value={ProfileType.CHILD}/>
<Picker.Item label="Parent" value={ProfileType.PARENT}/>
<Picker.Item label="Caregiver" value={ProfileType.CAREGIVER}/>
<Picker.Item
label="Family Device"
value={ProfileType.FAMILY_DEVICE}
/>
</Picker>
</View>
<Text style={styles.jakarta12}>
{selectedStatus === ProfileType.FAMILY_DEVICE
? "Device Name"
: "First Name"}
</Text>
<TextField
editable={!isLoading}
placeholder={
selectedStatus === ProfileType.FAMILY_DEVICE
? "Device name"
: "First name"
}
value={firstName}
onChangeText={setFirstName}
style={styles.inputField}
onSubmitEditing={() => {
lNameRef.current?.focus()
}}
blurOnSubmit={false}
returnKeyType="next"
/>
{selectedStatus !== ProfileType.FAMILY_DEVICE && (
<>
<Text style={styles.jakarta12}>Last Name</Text>
<TextField
ref={lNameRef}
editable={!isLoading}
placeholder="Last name"
value={lastName}
onChangeText={setLastName}
style={styles.inputField}
onSubmitEditing={() => {
emailRef.current?.focus()
}}
blurOnSubmit={false}
returnKeyType="next"
/>
</>
)}
{selectedStatus !== ProfileType.FAMILY_DEVICE && (
<>
<Text style={styles.jakarta12}>Email Address (Optional)</Text>
<TextField
ref={emailRef}
editable={!isLoading}
placeholder="Email address"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
autoCapitalize="none"
style={styles.inputField}
returnKeyType="done"
/>
</>
)}
<Button
disabled={
!firstName ||
(selectedStatus !== ProfileType.FAMILY_DEVICE && !lastName) ||
isLoading
}
label={isLoading ? "Adding..." : "Add group member"}
backgroundColor="#fd1775"
labelStyle={{
fontFamily: "PlusJakartaSans_500Medium",
fontSize: 15,
marginLeft: 7,
}}
style={{marginTop: 20, backgroundColor: "#fd1775"}}
iconSource={() => <NavToDosIcon width={22} color={"white"}/>}
onPress={handleCreateSubUser}
/>
</Card>
</KeyboardAwareScrollView>
</PreviousNextView>
</Dialog>
</View>
);
};
const styles = StyleSheet.create({
dialogBtn: {
height: 47,
width: 279,
},
dialogTitle: {fontFamily: "Manrope_600SemiBold", fontSize: 22},
dialogBackBtn: {
fontFamily: "PlusJakartaSans_500Medium",
fontSize: 15,
color: "#a7a7a7",
},
card: {
marginVertical: 15,
backgroundColor: "white",
width: "100%",
borderRadius: 15,
padding: 20,
},
bottomButton: {
position: "absolute",
bottom: 80,
width: "100%",
},
familyCard: {
marginBottom: 10,
borderRadius: 10,
backgroundColor: Colors.white,
width: "100%",
},
inputField: {
fontFamily: "PlusJakartaSans_500Medium",
fontSize: 13,
color: "#565656",
borderRadius: 50,
paddingVertical: 12,
paddingHorizontal: 16,
backgroundColor: Colors.grey80,
marginBottom: 16,
borderColor: Colors.grey50,
borderWidth: 1,
height: 40,
},
picker: {
borderRadius: 50,
paddingVertical: 12,
paddingHorizontal: 16,
backgroundColor: Colors.grey80,
marginBottom: 16,
borderColor: Colors.grey50,
borderWidth: 1,
marginTop: -20,
height: 40,
zIndex: 10,
},
viewPicker: {
borderRadius: 50,
backgroundColor: Colors.grey80,
marginBottom: 16,
borderColor: Colors.grey50,
borderWidth: 1,
marginTop: 0,
height: 40,
zIndex: 10,
},
inViewPicker: {
borderRadius: 50,
paddingVertical: 12,
paddingHorizontal: 16,
marginBottom: 16,
marginTop: -20,
height: 40,
zIndex: 10,
},
label: {
marginBottom: 5,
fontSize: 12,
color: Colors.grey40,
},
dialogCard: {
borderRadius: 10,
gap: 10,
},
subTit: {
fontFamily: "Manrope_500Medium",
fontSize: 15,
},
dialogBtnLbl: {
fontFamily: "PlusJakartaSans_500Medium",
fontSize: 15,
color: "white",
},
divider: {height: 0.7, backgroundColor: "#e6e6e6", width: "100%"},
jakarta12: {
fontFamily: "PlusJakartaSans_500Medium",
fontSize: 12,
color: "#a1a1a1",
},
jakarta13: {
fontFamily: "PlusJakartaSans_500Medium",
fontSize: 13,
},
});
export default MyGroup;