tablet view fixes, grocery item fix

This commit is contained in:
ivic00
2024-11-27 20:17:48 +01:00
parent 4b5900c652
commit 01b4fc2e33
6 changed files with 171 additions and 155 deletions

View File

@ -9,6 +9,7 @@ import { useGetFamilyMembers } from "@/hooks/firebase/useGetFamilyMembers";
import { ImageBackground, StyleSheet } from "react-native";
import { colorMap } from "@/constants/colorMap";
import { ScrollView } from "react-native-gesture-handler";
import { ProfileType } from "@/contexts/AuthContext";
const TabletChoresPage = () => {
const { data: users } = useGetFamilyMembers();
@ -32,20 +33,23 @@ const TabletChoresPage = () => {
<TabletContainer>
<ScrollView horizontal>
<View row gap-25 padding-25>
{users?.map((user, index) => (
<View>
{users
?.filter(member => member.userType !== ProfileType.FAMILY_DEVICE)
.map((user, index) => (
<View key={index}>
<View row centerV>
{user.pfp ? (
<ImageBackground
source={{ uri: user.pfp }}
style={[
styles.pfp,
(user.eventColor && {
borderWidth: 2,
borderColor: user.eventColor,
}) ||
undefined,
]}
style={
styles.pfp
}
imageStyle={(user.eventColor && {
borderWidth: 2,
borderColor: user.eventColor,
}) ||
undefined
}
borderRadius={13.33}
/>
) : (

View File

@ -1,53 +1,57 @@
import { View, Text } from "react-native-ui-lib";
import React from "react";
import React, { useEffect } from "react";
import { useGetFamilyMembers } from "@/hooks/firebase/useGetFamilyMembers";
import { ImageBackground, StyleSheet } from "react-native";
import { colorMap } from "@/constants/colorMap";
import { ProfileType } from "@/contexts/AuthContext";
const UsersList = () => {
const { data: familyMembers } = useGetFamilyMembers();
const { data: familyMembers, refetch: refetchFamilyMembers } =
useGetFamilyMembers();
useEffect(() => {
refetchFamilyMembers();
}, []);
const capitalizeFirstLetter = (str: string) => {
if (!str) return '';
if (!str) return "";
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
};
return (
<View centerH paddingT-10>
{familyMembers?.map((member, index) => (
<>
{member.pfp ? (
<ImageBackground
key={index}
source={{ uri: member.pfp }}
style={[
styles.pfp,
(member.eventColor && {
borderWidth: 2,
borderColor: member.eventColor,
}) ||
undefined,
]}
borderRadius={100}
/>
) : (
<View
key={index}
style={styles.pfp}
center
backgroundColor={member.eventColor || colorMap.teal}
children={
<Text color="white">
{member.firstName.at(0)}
{member.lastName.at(0)}
</Text>
}
/>
)}
<Text style={styles.fName}>{member.firstName}</Text>
<Text style={styles.role}>{capitalizeFirstLetter(member.userType)}</Text>
</>
))}
{familyMembers
?.filter((member) => member.userType !== ProfileType.FAMILY_DEVICE)
.map((member, index) => (
<>
{member.pfp ? (
<ImageBackground
key={index}
source={{ uri: member.pfp }}
style={styles.pfp}
borderRadius={200}
imageStyle={{ borderWidth: 2, borderColor: "red" }}
/>
) : (
<View
key={index}
style={styles.pfp}
center
backgroundColor={member.eventColor || colorMap.teal}
children={
<Text color="white">
{member.firstName.at(0)}
{member.lastName.at(0)}
</Text>
}
/>
)}
<Text style={styles.fName}>{member.firstName}</Text>
<Text style={styles.role}>
{capitalizeFirstLetter(member.userType)}
</Text>
</>
))}
</View>
);
};

View File

@ -6,9 +6,9 @@ import EditGroceryFrequency from "./EditGroceryFrequency";
import EditGroceryItem from "./EditGroceryItem";
import { ImageBackground, StyleSheet } from "react-native";
import { IGrocery } from "@/hooks/firebase/types/groceryData";
import firestore from "@react-native-firebase/firestore";
import { UserProfile } from "@/hooks/firebase/types/profileTypes";
import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
import { useGetUserById } from "@/hooks/firebase/useGetUserById";
const GroceryItem = ({
item,
@ -21,6 +21,7 @@ const GroceryItem = ({
}) => {
const { updateGroceryItem } = useGroceryContext();
const { profileData } = useAuthContext();
const { data: creator } = useGetUserById(item.creatorId);
const isParent = profileData?.userType === ProfileType.PARENT;
const [openFreqEdit, setOpenFreqEdit] = useState<boolean>(false);
@ -29,37 +30,8 @@ const GroceryItem = ({
const [category, setCategory] = useState<GroceryCategory>(
item.category ?? GroceryCategory.None
);
const [itemCreator, setItemCreator] = useState<UserProfile>(null);
const closeEdit = () => {
setIsEditingTitle(false);
};
const handleTitleChange = (newTitle: string) => {
updateGroceryItem({ id: item?.id, title: newTitle });
};
const handleCategoryChange = (newCategory: GroceryCategory) => {
updateGroceryItem({ id: item?.id, category: newCategory });
};
useEffect(() => {
console.log(item);
getItemCreator(item?.creatorId);
}, []);
const getItemCreator = async (uid: string | undefined) => {
if (uid) {
const documentSnapshot = await firestore()
.collection("Profiles")
.doc(uid)
.get();
if (documentSnapshot.exists) {
setItemCreator(documentSnapshot.data() as UserProfile);
}
}
};
const closeEdit = () => setIsEditingTitle(false);
const getInitials = (firstName: string, lastName: string) => {
return `${firstName.charAt(0)}${lastName.charAt(0)}`;
@ -71,23 +43,27 @@ const GroceryItem = ({
style={{
borderRadius: 17,
marginVertical: 5,
paddingHorizontal: isEditingTitle ? 0 : 13,
paddingVertical: isEditingTitle ? 0 : 10,
height: 44.64,
backgroundColor: item.bought ? "#cbcbcb" : "white",
overflow: "hidden",
}}
backgroundColor="white"
centerV
>
<View row spread>
<View
row
spread
centerV
style={{
paddingHorizontal: isEditingTitle ? 0 : 13,
paddingVertical: isEditingTitle ? 0 : 10,
minHeight: 44.64,
}}
>
<EditGroceryFrequency
visible={openFreqEdit}
key={item.id}
item={item}
onClose={() => {
setOpenFreqEdit(false);
}}
onClose={() => setOpenFreqEdit(false)}
/>
{isEditingTitle ? (
<EditGroceryItem
editGrocery={{
@ -102,12 +78,11 @@ const GroceryItem = ({
onInputFocus={onInputFocus}
/>
) : (
<View>
<View flex>
{isParent ? (
<TouchableOpacity onPress={() => setIsEditingTitle(true)}>
<Text
text70T
black
style={[
styles.title,
{
@ -121,7 +96,6 @@ const GroceryItem = ({
) : (
<Text
text70T
black
style={[styles.title, { color: item.bought ? "red" : "black" }]}
>
{item.title}
@ -129,31 +103,25 @@ const GroceryItem = ({
)}
</View>
)}
{!item.approved ? (
<View row centerV marginB-10>
<View row centerV>
{isParent && (
<>
<AntDesign
name="check"
size={24}
style={{
color: "green",
marginRight: 15,
}}
onPress={
isParent
? () => handleItemApproved(item.id, { approved: true })
: null
style={{ color: "green", marginRight: 15 }}
onPress={() =>
handleItemApproved(item.id, { approved: true })
}
/>
<AntDesign
name="close"
size={24}
style={{ color: "red" }}
onPress={
isParent
? () => handleItemApproved(item.id, { approved: false })
: null
onPress={() =>
handleItemApproved(item.id, { approved: false })
}
/>
</>
@ -176,69 +144,69 @@ const GroceryItem = ({
)
)}
</View>
{!item.approved && (
<View>
<View centerH>
<View height={0.7} backgroundColor="#e7e7e7" width={"98%"} />
<>
<View paddingH-20>
<View height={0.7} backgroundColor="#e7e7e7" width="100%" />
</View>
<View paddingL-0 paddingT-12 flexS row centerV>
{profileData?.pfp ? (
<View
row
centerV
style={{
paddingHorizontal: 13,
paddingVertical: 10,
}}
>
{creator?.pfp ? (
<ImageBackground
source={require("../../../assets/images/child-picture.png")}
source={{ uri: creator.pfp }}
style={{
height: 24.64,
aspectRatio: 1,
borderRadius: 22,
overflow: "hidden",
borderWidth: 2,
borderColor: profileData.eventColor
borderColor: creator.eventColor || undefined,
marginRight: 8,
}}
/>
) : (
<View
style={{
position: "relative",
width: 24.64,
aspectRatio: 1,
marginRight: 4,
marginRight: 8,
backgroundColor: "#ccc",
borderRadius: 100,
justifyContent: "center",
alignItems: "center",
}}
>
<View
style={{
backgroundColor: "#ccc",
justifyContent: "center",
alignItems: "center",
borderRadius: 100, // Circular shape
width: "100%",
height: "100%",
}}
<Text
style={{ color: "#fff", fontSize: 12, fontWeight: "bold" }}
>
<Text
style={{
color: "#fff",
fontSize: 12,
fontWeight: "bold",
}}
>
{itemCreator
? getInitials(itemCreator.firstName, itemCreator.lastName)
: ""}
</Text>
</View>
{creator
? getInitials(creator.firstName, creator.lastName)
: ""}
</Text>
</View>
)}
<Text color="#858585" style={styles.authorTxt}>
Requested by {itemCreator?.firstName}
Requested by {creator?.firstName}
</Text>
</View>
</View>
</>
)}
</View>
);
};
const styles = StyleSheet.create({
authorTxt: { fontFamily: "Manrope_500Medium", fontSize: 12 },
authorTxt: {
fontFamily: "Manrope_500Medium",
fontSize: 12,
},
checkbox: {
borderRadius: 50,
borderWidth: 0.7,

View File

@ -11,7 +11,12 @@ import {
} from "react-native-ui-lib";
import React, { useEffect, useRef, useState } from "react";
import { useSignIn } from "@/hooks/firebase/useSignIn";
import { Dimensions, KeyboardAvoidingView, Platform, StyleSheet } from "react-native";
import {
Dimensions,
KeyboardAvoidingView,
Platform,
StyleSheet,
} from "react-native";
import Toast from "react-native-toast-message";
import KeyboardManager from "react-native-keyboard-manager";
import { SafeAreaView } from "react-native-safe-area-context";
@ -28,24 +33,24 @@ const SignInPage = () => {
const isTablet: boolean = Device.deviceType === DeviceType.TABLET;
const [isPortrait, setIsPortrait] = useState(() => {
const dim = Dimensions.get('screen');
const dim = Dimensions.get("screen");
return dim.height >= dim.width;
});
useEffect(() => {
const subscription = Dimensions.addEventListener('change', ({ screen }) => {
});
useEffect(() => {
const subscription = Dimensions.addEventListener("change", ({ screen }) => {
setIsPortrait(screen.height >= screen.width);
});
return () => subscription.remove();
}, []);
const getTopPadding = () => {
return () => subscription.remove();
}, []);
const getTopPadding = () => {
if (Device.deviceType === DeviceType.TABLET) {
return isPortrait ? "50%" : "15%";
}
return "20%"; // non-tablet case, regardless of orientation
};
};
const { mutateAsync: signIn, error, isError, isLoading } = useSignIn();
@ -68,9 +73,12 @@ const SignInPage = () => {
};
return (
<SafeAreaView style={{ flex: 1, alignItems: isTablet ? "center" : undefined}}>
<SafeAreaView style={{ flex: 1 }}>
<KeyboardAwareScrollView
contentContainerStyle={{ flexGrow: 1 }}
contentContainerStyle={{
flexGrow: 1,
alignItems: isTablet ? "center" : undefined,
}}
enableOnAndroid
>
<View
@ -79,7 +87,7 @@ const SignInPage = () => {
padding: 21,
paddingBottom: 45,
paddingTop: isLoading ? "20%" : getTopPadding(),
width: isLoading ? '100%' : (isTablet ? 629 : undefined),
width: isLoading ? "100%" : isTablet ? 629 : undefined,
}}
>
<View gap-13 width={"100%"} marginB-20>
@ -92,9 +100,9 @@ const SignInPage = () => {
</View>
<KeyboardAvoidingView
style={{ width: "100%" }}
style={{ width: "100%", flex: 1 }}
contentContainerStyle={{ justifyContent: "center" }}
keyboardVerticalOffset={50}
keyboardVerticalOffset={Platform.OS === "ios" ? 50 : 200}
behavior={Platform.OS === "ios" ? "padding" : "height"}
>
<TextField
@ -187,6 +195,7 @@ const SignInPage = () => {
<LoaderScreen
overlay
message={"Signing in..."}
containerStyle={{ width: Dimensions.get('screen').width }}
backgroundColor={Colors.white}
color={Colors.grey40}
/>

View File

@ -75,12 +75,12 @@ const SignUpPage = () => {
<SafeAreaView
style={{
flex: 1,
alignItems: isTablet ? "center" : undefined,
width: "100%",
}}
>
<KeyboardAwareScrollView
contentContainerStyle={{ flexGrow: 1 }}
contentContainerStyle={{ flexGrow: 1,
alignItems: isTablet ? "center" : undefined,
width: '100%' }}
enableOnAndroid
>
<View

View File

@ -0,0 +1,31 @@
import { useQuery } from "react-query";
import { UserProfile } from "@/hooks/firebase/types/profileTypes";
import firestore from "@react-native-firebase/firestore";
export const useGetUserById = (uid: string | undefined) => {
return useQuery({
queryKey: ["getUserById", uid],
queryFn: async (): Promise<UserProfile | null> => {
if (!uid) return null;
try {
const doc = await firestore()
.collection("Profiles")
.doc(uid)
.get();
if (!doc.exists) return null;
const data = doc.data();
return {
...data,
uid: doc.id,
} as UserProfile;
} catch (error) {
console.error("Error retrieving user:", error);
return null;
}
},
enabled: !!uid
});
};