mirror of
https://github.com/urosran/cally.git
synced 2025-07-15 17:47:08 +00:00
244 lines
7.3 KiB
TypeScript
244 lines
7.3 KiB
TypeScript
import { Checkbox, Text, TouchableOpacity, View } from "react-native-ui-lib";
|
|
import React, { useEffect, useState } from "react";
|
|
import { AntDesign } from "@expo/vector-icons";
|
|
import { GroceryCategory, useGroceryContext } from "@/contexts/GroceryContext";
|
|
import EditGroceryFrequency from "./EditGroceryFrequency";
|
|
import EditGroceryItem from "./EditGroceryItem";
|
|
import { ImageBackground, StyleSheet } from "react-native";
|
|
import { IGrocery } from "@/hooks/firebase/types/groceryData";
|
|
import { UserProfile } from "@/hooks/firebase/types/profileTypes";
|
|
import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
|
|
import { useGetUserById } from "@/hooks/firebase/useGetUserById";
|
|
import { useDeleteGrocery } from "@/hooks/firebase/useDeleteGrocery";
|
|
|
|
const GroceryItem = ({
|
|
item,
|
|
handleItemApproved,
|
|
onInputFocus,
|
|
}: {
|
|
item: IGrocery;
|
|
handleItemApproved: (id: string, changes: Partial<IGrocery>) => void;
|
|
onInputFocus: (y: number) => void;
|
|
}) => {
|
|
const { updateGroceryItem } = useGroceryContext();
|
|
const { mutateAsync: deleteGrocery } = useDeleteGrocery();
|
|
const { profileData } = useAuthContext();
|
|
const { data: creator } = useGetUserById(item.creatorId);
|
|
const isParent = profileData?.userType === ProfileType.PARENT;
|
|
const isCaregiver = profileData?.userType === ProfileType.CAREGIVER;
|
|
|
|
const [openFreqEdit, setOpenFreqEdit] = useState<boolean>(false);
|
|
const [isEditingTitle, setIsEditingTitle] = useState<boolean>(false);
|
|
const [newTitle, setNewTitle] = useState<string>(item.title ?? "");
|
|
const [category, setCategory] = useState<GroceryCategory>(
|
|
item.category ?? GroceryCategory.None
|
|
);
|
|
|
|
const closeEdit = () => setIsEditingTitle(false);
|
|
|
|
const getInitials = (firstName: string, lastName: string) => {
|
|
return `${firstName.charAt(0).toUpperCase()}${lastName.charAt(0).toUpperCase()}`;
|
|
};
|
|
|
|
return (
|
|
<View
|
|
key={item.id}
|
|
style={{
|
|
borderRadius: 17,
|
|
marginVertical: 5,
|
|
backgroundColor: item.bought ? "#cbcbcb" : "white",
|
|
overflow: "hidden",
|
|
}}
|
|
>
|
|
<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)}
|
|
/>
|
|
|
|
{isEditingTitle ? (
|
|
<EditGroceryItem
|
|
editGrocery={{
|
|
id: item.id,
|
|
title: newTitle,
|
|
category: category,
|
|
setTitle: setNewTitle,
|
|
setCategory: setCategory,
|
|
closeEdit: closeEdit,
|
|
handleEditSubmit: updateGroceryItem,
|
|
}}
|
|
onInputFocus={onInputFocus}
|
|
/>
|
|
) : (
|
|
<View flex>
|
|
{(isParent || isCaregiver) && !item.bought ? (
|
|
<TouchableOpacity onPress={() => setIsEditingTitle(true)}>
|
|
<Text
|
|
text70T
|
|
style={[
|
|
styles.title,
|
|
{
|
|
textDecorationLine: item.bought ? "line-through" : "none",
|
|
},
|
|
]}
|
|
>
|
|
{item.title}
|
|
</Text>
|
|
</TouchableOpacity>
|
|
) : (
|
|
<Text
|
|
text70T
|
|
style={[styles.title, { textDecorationLine: item.bought ? "line-through" : "none", }]}
|
|
>
|
|
{item.title}
|
|
</Text>
|
|
)}
|
|
</View>
|
|
)}
|
|
|
|
{!item.approved ? (
|
|
<View row centerV>
|
|
{isParent || isCaregiver && (
|
|
<>
|
|
<AntDesign
|
|
name="check"
|
|
size={24}
|
|
style={{ color: "green", marginRight: 15 }}
|
|
onPress={() =>
|
|
handleItemApproved(item.id, { approved: true })
|
|
}
|
|
/>
|
|
<AntDesign
|
|
name="close"
|
|
size={24}
|
|
style={{ color: "red" }}
|
|
onPress={() => {
|
|
handleItemApproved(item.id, { approved: false });
|
|
deleteGrocery(item.id);
|
|
}}
|
|
/>
|
|
</>
|
|
)}
|
|
</View>
|
|
) : (
|
|
!isEditingTitle &&
|
|
(isParent || isCaregiver) && (
|
|
<View row>
|
|
{item.bought &&
|
|
<AntDesign
|
|
name="close"
|
|
size={24}
|
|
style={{ color: "grey", marginRight: 10 }}
|
|
onPress={() => {
|
|
handleItemApproved(item.id, { approved: false });
|
|
deleteGrocery(item.id);
|
|
}}/>
|
|
}
|
|
<Checkbox
|
|
value={item.bought}
|
|
containerStyle={[styles.checkbox, { borderRadius: 50 }]}
|
|
style={styles.checked}
|
|
borderRadius={50}
|
|
color="#fd1575"
|
|
hitSlop={20}
|
|
onValueChange={() =>
|
|
updateGroceryItem({ id: item.id, bought: !item.bought })
|
|
}
|
|
/>
|
|
</View>
|
|
)
|
|
)}
|
|
</View>
|
|
|
|
{!item.approved && (
|
|
<>
|
|
<View paddingH-20>
|
|
<View height={0.7} backgroundColor="#e7e7e7" width="100%" />
|
|
</View>
|
|
<View
|
|
row
|
|
centerV
|
|
style={{
|
|
paddingHorizontal: 13,
|
|
paddingVertical: 10,
|
|
}}
|
|
>
|
|
{creator?.pfp ? (
|
|
<ImageBackground
|
|
source={{ uri: creator.pfp }}
|
|
style={{
|
|
height: 24.64,
|
|
aspectRatio: 1,
|
|
borderRadius: 22,
|
|
overflow: "hidden",
|
|
borderWidth: 2,
|
|
borderColor: creator.eventColor || undefined,
|
|
marginRight: 8,
|
|
}}
|
|
/>
|
|
) : (
|
|
<View
|
|
style={{
|
|
width: 24.64,
|
|
aspectRatio: 1,
|
|
marginRight: 8,
|
|
backgroundColor: creator?.eventColor || "gray",
|
|
borderRadius: 100,
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
}}
|
|
>
|
|
<Text
|
|
style={{ color: "#fff", fontSize: 12, fontWeight: "bold" }}
|
|
>
|
|
{creator
|
|
? getInitials(creator.firstName, creator.lastName)
|
|
: ""}
|
|
</Text>
|
|
</View>
|
|
)}
|
|
<Text color="#858585" style={styles.authorTxt}>
|
|
Requested by {creator?.firstName}
|
|
</Text>
|
|
</View>
|
|
</>
|
|
)}
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
authorTxt: {
|
|
fontFamily: "Manrope_500Medium",
|
|
fontSize: 12,
|
|
},
|
|
checkbox: {
|
|
borderRadius: 50,
|
|
borderWidth: 0.7,
|
|
color: "#bfbfbf",
|
|
borderColor: "#bfbfbf",
|
|
width: 24.64,
|
|
aspectRatio: 1,
|
|
},
|
|
title: {
|
|
fontFamily: "Manrope_500Medium",
|
|
fontSize: 15,
|
|
},
|
|
checked: {
|
|
borderRadius: 50,
|
|
},
|
|
});
|
|
|
|
export default GroceryItem;
|