mirror of
https://github.com/urosran/cally.git
synced 2025-07-10 15:17:17 +00:00
228 lines
7.1 KiB
TypeScript
228 lines
7.1 KiB
TypeScript
import { Image, Text, TouchableOpacity, View } from "react-native-ui-lib";
|
|
import React, { useEffect, useState } from "react";
|
|
import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
|
|
import { StyleSheet } from "react-native";
|
|
import { colorMap } from "@/constants/colorMap";
|
|
import { useAtom, useSetAtom } from "jotai";
|
|
import { isFamilyViewAtom, settingsPageIndex } from "../pages/calendar/atoms";
|
|
import { useGetFamilyMembers } from "@/hooks/firebase/useGetFamilyMembers";
|
|
import { UserProfile } from "@/hooks/firebase/types/profileTypes";
|
|
import CachedImage from "expo-cached-image";
|
|
import { router } from "expo-router";
|
|
|
|
const HeaderTemplate = (props: {
|
|
message: string;
|
|
isWelcome: boolean;
|
|
children?: React.ReactNode;
|
|
link?: React.ReactNode;
|
|
isCalendar?: boolean;
|
|
isToDos?: boolean;
|
|
isBrainDump?: boolean;
|
|
isGroceries?: boolean;
|
|
}) => {
|
|
const { user, profileData } = useAuthContext();
|
|
|
|
const { data: members, refetch } = useGetFamilyMembers();
|
|
const [children, setChildren] = useState<UserProfile[]>([]);
|
|
const [isFamilyView] = useAtom(isFamilyViewAtom);
|
|
const setSettingsPageIndexAtom = useSetAtom(settingsPageIndex);
|
|
|
|
const headerHeight: number =
|
|
(props.isCalendar && 65.54) ||
|
|
(props.isToDos && 84) ||
|
|
(props.isGroceries && 72.09) ||
|
|
65.54;
|
|
|
|
const handlePfpPress = () => {
|
|
setSettingsPageIndexAtom(1);
|
|
router.push("/settings");
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
pfp: {
|
|
height: headerHeight,
|
|
aspectRatio: 1,
|
|
borderRadius: 22,
|
|
overflow: "hidden",
|
|
marginRight: 20,
|
|
backgroundColor: profileData?.eventColor ?? colorMap.pink,
|
|
zIndex: 100,
|
|
},
|
|
pfpTxt: {
|
|
fontFamily: "Manrope_500Medium",
|
|
fontSize: 30,
|
|
color: "white",
|
|
},
|
|
childrenPfpArr: {
|
|
width: 65.54,
|
|
position: "absolute",
|
|
bottom: -12.44,
|
|
left: (children.length > 3 && -9) || 0,
|
|
height: 27.32,
|
|
},
|
|
childrenPfp: {
|
|
aspectRatio: 1,
|
|
width: 27.32,
|
|
backgroundColor: "#fd1575",
|
|
borderRadius: 50,
|
|
position: "absolute",
|
|
borderWidth: 2,
|
|
borderColor: "#f2f2f2",
|
|
},
|
|
bottomMarg: {
|
|
marginBottom: isFamilyView ? 30 : 15,
|
|
},
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (members) {
|
|
const childrenMembers = members.filter(
|
|
(member) =>
|
|
member.userType === ProfileType.CHILD ||
|
|
member.userType === ProfileType.CAREGIVER ||
|
|
member.userType === ProfileType.PARENT
|
|
);
|
|
setChildren(childrenMembers);
|
|
}
|
|
}, []);
|
|
|
|
return (
|
|
<View row centerV marginV-15 style={styles.bottomMarg}>
|
|
{profileData?.pfp ? (
|
|
<View>
|
|
<TouchableOpacity onPress={handlePfpPress}>
|
|
<CachedImage
|
|
source={{ uri: profileData.pfp }}
|
|
style={[
|
|
styles.pfp,
|
|
(profileData.eventColor && {
|
|
borderWidth: 2,
|
|
borderColor: profileData.eventColor,
|
|
}) ||
|
|
undefined,
|
|
]}
|
|
cacheKey={profileData.pfp}
|
|
/>
|
|
</TouchableOpacity>
|
|
{isFamilyView && props.isCalendar && children.length > 0 && (
|
|
<View style={styles.childrenPfpArr} row>
|
|
{children.slice(0, 3).map((child, index) => {
|
|
const bgColor: string = child.eventColor || colorMap.pink;
|
|
return child.pfp ? (
|
|
<Image
|
|
source={{ uri: child.pfp }}
|
|
style={[styles.childrenPfp, { left: index * 19 }]}
|
|
/>
|
|
) : (
|
|
<TouchableOpacity onPress={handlePfpPress}>
|
|
<View
|
|
style={[
|
|
styles.childrenPfp,
|
|
{ left: index * 19, backgroundColor: bgColor },
|
|
]}
|
|
center
|
|
>
|
|
<Text style={{ color: "white" }}>
|
|
{child?.firstName?.at(0)}
|
|
{child?.firstName?.at(1)}
|
|
</Text>
|
|
</View>
|
|
</TouchableOpacity>
|
|
);
|
|
})}
|
|
{children?.length > 3 && (
|
|
<View style={[styles.childrenPfp, { left: 3 * 19 }]} center>
|
|
<Text
|
|
style={{
|
|
color: "white",
|
|
fontFamily: "Manrope_600SemiBold",
|
|
fontSize: 12,
|
|
}}
|
|
>
|
|
+{children.length - 3}
|
|
</Text>
|
|
</View>
|
|
)}
|
|
</View>
|
|
)}
|
|
</View>
|
|
) : (
|
|
<>
|
|
<TouchableOpacity onPress={handlePfpPress}>
|
|
<View style={[styles.pfp, { zIndex: 200 }]} center>
|
|
<Text style={styles.pfpTxt}>
|
|
{profileData?.firstName?.at(0)}
|
|
{profileData?.lastName?.at(0)}
|
|
</Text>
|
|
</View>
|
|
</TouchableOpacity>
|
|
{isFamilyView && props.isCalendar && children.length > 0 && (
|
|
<View style={styles.childrenPfpArr} row>
|
|
{children.slice(0, 3).map((child, index) => {
|
|
const bgColor: string = child.eventColor || colorMap.pink;
|
|
return child.pfp ? (
|
|
<Image
|
|
source={{ uri: child.pfp }}
|
|
style={[styles.childrenPfp, { left: index * 19 }]}
|
|
/>
|
|
) : (
|
|
<TouchableOpacity onPress={handlePfpPress}>
|
|
<View
|
|
style={[
|
|
styles.childrenPfp,
|
|
{ left: index * 19, backgroundColor: bgColor },
|
|
]}
|
|
center
|
|
>
|
|
<Text style={{ color: "white" }}>
|
|
{child?.firstName?.at(0)}
|
|
{child?.firstName?.at(1)}
|
|
</Text>
|
|
</View>
|
|
</TouchableOpacity>
|
|
);
|
|
})}
|
|
{children?.length > 3 && (
|
|
<View style={[styles.childrenPfp, { left: 3 * 19 }]} center>
|
|
<Text
|
|
style={{
|
|
color: "white",
|
|
fontFamily: "Manrope_600SemiBold",
|
|
fontSize: 12,
|
|
}}
|
|
>
|
|
+{children.length - 3}
|
|
</Text>
|
|
</View>
|
|
)}
|
|
</View>
|
|
)}
|
|
</>
|
|
)}
|
|
<View gap-3>
|
|
{props.isWelcome && (
|
|
<Text
|
|
text70L
|
|
style={{
|
|
fontSize: 19,
|
|
fontFamily: "Manrope_400Regular",
|
|
}}
|
|
>
|
|
Welcome, {profileData?.firstName}!
|
|
</Text>
|
|
)}
|
|
<Text
|
|
text70B
|
|
style={{ fontSize: 18, fontFamily: "Manrope_600SemiBold" }}
|
|
>
|
|
{props.message}
|
|
</Text>
|
|
{props.children && <View>{props.children}</View>}
|
|
{props.link && <View marginT-8>{props.link}</View>}
|
|
</View>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default HeaderTemplate;
|