mirror of
https://github.com/urosran/cally.git
synced 2025-07-16 18:16:17 +00:00
735 lines
23 KiB
TypeScript
735 lines
23 KiB
TypeScript
import {
|
|
Avatar,
|
|
Button,
|
|
Card,
|
|
Colors,
|
|
DateTimePicker,
|
|
Dialog,
|
|
Image,
|
|
KeyboardAwareScrollView,
|
|
PanningProvider,
|
|
Picker,
|
|
Text,
|
|
TextField,
|
|
TextFieldRef,
|
|
TouchableOpacity,
|
|
View,
|
|
} from "react-native-ui-lib";
|
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
import { ImageBackground, Platform, StyleSheet } from "react-native";
|
|
import { PickerSingleValue } from "react-native-ui-lib/src/components/picker/types";
|
|
import { useCreateSubUser } from "@/hooks/firebase/useCreateSubUser";
|
|
import { ProfileType, useAuthContext } 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 KeyboardManager, {
|
|
PreviousNextView,
|
|
} from "react-native-keyboard-manager";
|
|
import { ScrollView } from "react-native-gesture-handler";
|
|
import { useUploadProfilePicture } from "@/hooks/useUploadProfilePicture";
|
|
import UserOptions from "./UserOptions";
|
|
import { colorMap } from "@/constants/colorMap";
|
|
import { useFocusEffect } from "@react-navigation/core";
|
|
|
|
type MyGroupProps = {
|
|
onNewUserClick: boolean;
|
|
setOnNewUserClick: React.Dispatch<React.SetStateAction<boolean>>;
|
|
};
|
|
|
|
const MyGroup: React.FC<MyGroupProps> = ({
|
|
onNewUserClick,
|
|
setOnNewUserClick,
|
|
}) => {
|
|
const [showAddUserDialog, setShowAddUserDialog] = useState(false);
|
|
const [selectedStatus, setSelectedStatus] = useState<
|
|
string | PickerSingleValue
|
|
>(ProfileType.CHILD);
|
|
const [firstName, setFirstName] = useState("");
|
|
const [lastName, setLastName] = 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 [newUserId, setNewUserId] = useState("");
|
|
|
|
const lNameRef = useRef<TextFieldRef>(null);
|
|
const emailRef = useRef<TextFieldRef>(null);
|
|
|
|
const [showQRCodeDialog, setShowQRCodeDialog] = useState<string | boolean>(
|
|
false
|
|
);
|
|
|
|
const { mutateAsync: createSubUser, isLoading, isError } = useCreateSubUser();
|
|
const { data: familyMembers, refetch: refetchFamilyMembers } =
|
|
useGetFamilyMembers(true);
|
|
const { user } = useAuthContext();
|
|
const {
|
|
pickImage,
|
|
changeProfilePicture,
|
|
handleClearImage,
|
|
pfpUri,
|
|
profileImageAsset,
|
|
} = useUploadProfilePicture(newUserId);
|
|
|
|
useFocusEffect(
|
|
useCallback(() => {
|
|
refetchFamilyMembers();
|
|
}, [refetchFamilyMembers])
|
|
);
|
|
|
|
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`,
|
|
birthday: birthday,
|
|
password: uuidv4(),
|
|
userType: selectedStatus as ProfileType,
|
|
});
|
|
console.log(res);
|
|
|
|
if (!isError) {
|
|
setOnNewUserClick(false);
|
|
|
|
if (res?.data?.userId) {
|
|
if (profileImageAsset) {
|
|
await changeProfilePicture(profileImageAsset);
|
|
setShowQRCodeDialog(res.data.userId);
|
|
} else {
|
|
setTimeout(() => {
|
|
setShowQRCodeDialog(res.data.userId);
|
|
}, 500);
|
|
}
|
|
|
|
handleClearImage();
|
|
}
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (Platform.OS === "ios") KeyboardManager.setEnableAutoToolbar(true);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
setFirstName("");
|
|
setLastName("");
|
|
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
|
|
return (
|
|
<View marginB-70>
|
|
<ScrollView>
|
|
<View>
|
|
{!parents.length && !children.length && !caregivers.length && (
|
|
<Text text70 marginV-10>
|
|
{isLoading ? "Loading...." : "No user devices added"}
|
|
</Text>
|
|
)}
|
|
|
|
{(!!parents.length || !!children.length) && (
|
|
<View style={styles.card}>
|
|
<Text style={styles.subTit} marginB-10>
|
|
Family
|
|
</Text>
|
|
{[...parents, ...children]?.map((member, index) => (
|
|
<Card
|
|
enableShadow={false}
|
|
elevation={0}
|
|
key={`${member.firstName}_${member.lastName}_${index}`}
|
|
style={styles.familyCard}
|
|
row
|
|
centerV
|
|
paddingT-10
|
|
>
|
|
{member.pfp ? (
|
|
<ImageBackground
|
|
style={[
|
|
styles.pfp,
|
|
(member.eventColor && {
|
|
borderWidth: 2,
|
|
borderColor: member.eventColor,
|
|
}) ||
|
|
undefined,
|
|
]}
|
|
source={{ uri: member.pfp || undefined }}
|
|
/>
|
|
) : (
|
|
<View
|
|
style={[
|
|
styles.pfp,
|
|
{ backgroundColor: member.eventColor || colorMap.pink },
|
|
]}
|
|
/>
|
|
)}
|
|
<View row marginL-10 centerV>
|
|
<Text style={styles.name}>
|
|
{member.firstName} {member.lastName}
|
|
</Text>
|
|
</View>
|
|
<View flexG />
|
|
<View row centerV gap-10>
|
|
<Text style={styles.userType}>
|
|
{member.userType === ProfileType.PARENT
|
|
? `Admin${member.uid === user?.uid ? " (You)" : ""}`
|
|
: "Child"}
|
|
</Text>
|
|
<UserMenu
|
|
setShowQRCodeDialog={(val) => setShowQRCodeDialog(val)}
|
|
showQRCodeDialog={showQRCodeDialog === member?.uid}
|
|
user={member}
|
|
/>
|
|
{profileData?.userType === ProfileType.PARENT &&
|
|
user?.uid != member.uid && <UserOptions user={member} />}
|
|
</View>
|
|
</Card>
|
|
))}
|
|
</View>
|
|
)}
|
|
|
|
{!!caregivers.length && (
|
|
<View style={styles.card}>
|
|
<Text style={styles.subTit} marginB-10>
|
|
Caregivers
|
|
</Text>
|
|
{caregivers?.map((member) => (
|
|
<Card
|
|
enableShadow={false}
|
|
elevation={0}
|
|
key={`${member.firstName}_${member.lastName}`}
|
|
style={styles.familyCard}
|
|
row
|
|
centerV
|
|
paddingT-10
|
|
>
|
|
{member.pfp ? (
|
|
<ImageBackground
|
|
style={[
|
|
styles.pfp,
|
|
(member.eventColor && {
|
|
borderWidth: 2,
|
|
borderColor: member.eventColor,
|
|
}) ||
|
|
undefined,
|
|
]}
|
|
source={{ uri: member.pfp || undefined }}
|
|
/>
|
|
) : (
|
|
<View
|
|
style={[
|
|
styles.pfp,
|
|
{ backgroundColor: member.eventColor || colorMap.pink },
|
|
]}
|
|
/>
|
|
)}
|
|
<View row marginL-10 centerV>
|
|
<Text style={styles.name}>
|
|
{member.firstName} {member.lastName}
|
|
</Text>
|
|
</View>
|
|
<View flexG />
|
|
<View row centerV gap-10>
|
|
<Text style={styles.userType}>Caregiver</Text>
|
|
<UserMenu
|
|
setShowQRCodeDialog={(val) => setShowQRCodeDialog(val)}
|
|
showQRCodeDialog={showQRCodeDialog === member?.uid}
|
|
user={member}
|
|
/>
|
|
{profileData?.userType === ProfileType.PARENT && (
|
|
<UserOptions user={member} />
|
|
)}
|
|
</View>
|
|
</Card>
|
|
))}
|
|
</View>
|
|
)}
|
|
|
|
{!!familyDevices.length && (
|
|
<View style={styles.card}>
|
|
<Text style={styles.subTit} marginB-10>
|
|
Family Devices
|
|
</Text>
|
|
{familyDevices?.map((member, index) => (
|
|
<Card
|
|
enableShadow={false}
|
|
elevation={0}
|
|
key={`${member.firstName}_${index}`}
|
|
style={styles.familyCard}
|
|
row
|
|
centerV
|
|
paddingT-10
|
|
>
|
|
{member.pfp ? (
|
|
<ImageBackground
|
|
style={[
|
|
styles.pfp,
|
|
(member.eventColor && {
|
|
borderWidth: 2,
|
|
borderColor: member.eventColor,
|
|
}) ||
|
|
undefined,
|
|
]}
|
|
imageStyle={{ borderRadius: 10.56 }}
|
|
source={{ uri: member.pfp || undefined }}
|
|
/>
|
|
) : (
|
|
<View
|
|
style={[
|
|
styles.pfp,
|
|
{ backgroundColor: member.eventColor || colorMap.pink },
|
|
]}
|
|
/>
|
|
)}
|
|
<View row marginL-10 centerV>
|
|
<Text style={styles.name}>{member.firstName}</Text>
|
|
</View>
|
|
<View flexG />
|
|
<View row centerV gap-10>
|
|
<Text style={styles.userType}>Family Device</Text>
|
|
<UserMenu
|
|
setShowQRCodeDialog={(val) => setShowQRCodeDialog(val)}
|
|
showQRCodeDialog={showQRCodeDialog === member?.uid}
|
|
user={member}
|
|
/>
|
|
{profileData?.userType === ProfileType.PARENT && (
|
|
<UserOptions user={member} />
|
|
)}
|
|
</View>
|
|
</Card>
|
|
))}
|
|
</View>
|
|
)}
|
|
</View>
|
|
</ScrollView>
|
|
|
|
<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={onNewUserClick}
|
|
onDismiss={() => setOnNewUserClick(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={() => {
|
|
setOnNewUserClick(false);
|
|
}}
|
|
>
|
|
<CircledXIcon />
|
|
</TouchableOpacity>
|
|
</View>
|
|
<View style={styles.divider} spread />
|
|
|
|
<View row centerV gap-20 marginV-20>
|
|
{pfpUri ? (
|
|
<Image
|
|
height={65.54}
|
|
width={65.54}
|
|
style={{ borderRadius: 25 }}
|
|
source={{ uri: pfpUri }}
|
|
/>
|
|
) : (
|
|
<View
|
|
height={65.54}
|
|
width={65.54}
|
|
children={
|
|
<ProfileIcon color={"#d6d6d6"} width={37} height={37} />
|
|
}
|
|
backgroundColor={Colors.grey60}
|
|
style={{ borderRadius: 25 }}
|
|
center
|
|
/>
|
|
)}
|
|
|
|
{pfpUri ? (
|
|
<TouchableOpacity onPress={handleClearImage}>
|
|
<Text
|
|
color={Colors.red40}
|
|
style={styles.jakarta13}
|
|
marginL-15
|
|
>
|
|
Clear user photo
|
|
</Text>
|
|
</TouchableOpacity>
|
|
) : (
|
|
<TouchableOpacity onPress={pickImage}>
|
|
<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"
|
|
/>
|
|
<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);
|
|
}
|
|
}
|
|
}}
|
|
/>*/}
|
|
</>
|
|
)}
|
|
|
|
{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: 12,
|
|
paddingHorizontal: 21,
|
|
paddingVertical: 20,
|
|
},
|
|
bottomButton: {
|
|
position: "absolute",
|
|
bottom: 50,
|
|
backgroundColor: "#e8156c",
|
|
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,
|
|
},
|
|
pfp: {
|
|
aspectRatio: 1,
|
|
width: 37.03,
|
|
borderRadius: 10.56,
|
|
overflow: "hidden",
|
|
},
|
|
userType: {
|
|
fontFamily: "Manrope_500Medium",
|
|
fontSize: 12,
|
|
color: "#858585",
|
|
},
|
|
name: {
|
|
fontFamily: "Manrope_600SemiBold",
|
|
fontSize: 16,
|
|
},
|
|
});
|
|
|
|
export default MyGroup;
|