Files
cally/components/pages/grocery/GroceryList.tsx
2024-11-01 01:12:19 +01:00

299 lines
11 KiB
TypeScript

import {FlatList, StyleSheet} from "react-native";
import React, {useEffect, useState} from "react";
import {Text, TouchableOpacity, View} from "react-native-ui-lib";
import GroceryItem from "./GroceryItem";
import {GroceryCategory, GroceryFrequency, useGroceryContext,} from "@/contexts/GroceryContext";
import HeaderTemplate from "@/components/shared/HeaderTemplate";
import {AntDesign} from "@expo/vector-icons";
import EditGroceryItem from "./EditGroceryItem";
import {ProfileType, useAuthContext} from "@/contexts/AuthContext";
import {IGrocery} from "@/hooks/firebase/types/groceryData";
import AddPersonIcon from "@/assets/svgs/AddPersonIcon";
const GroceryList = ({onInputFocus}: {onInputFocus: (y: number) => void}) => {
const {
groceries,
updateGroceryItem,
isAddingGrocery,
setIsAddingGrocery,
addGrocery,
} = useGroceryContext();
const {profileData} = useAuthContext();
const [approvedGroceries, setapprovedGroceries] = useState<IGrocery[]>(
groceries?.filter((item) => item.approved)
);
const [pendingGroceries, setPendingGroceries] = useState<IGrocery[]>(
groceries?.filter((item) => !item.approved)
);
const [category, setCategory] = useState<GroceryCategory>(
GroceryCategory.None
);
const [title, setTitle] = useState<string>("");
const [submit, setSubmitted] = useState<boolean>(false);
const [pendingVisible, setPendingVisible] = useState<boolean>(true);
const [approvedVisible, setApprovedVisible] = useState<boolean>(true);
// Group approved groceries by category
const approvedGroceriesByCategory = approvedGroceries?.reduce(
(groups: any, item: IGrocery) => {
const category = item.category || "Uncategorized";
if (!groups[category]) {
groups[category] = [];
}
groups[category].push(item);
return groups;
},
{}
);
useEffect(() => {
if (submit) {
if (title?.length > 2 && title?.length <= 25) {
addGrocery({
id: "",
title: title,
category: category,
approved: profileData?.userType === ProfileType.PARENT,
recurring: false,
frequency: GroceryFrequency.Never,
bought: false,
});
setIsAddingGrocery(false);
setSubmitted(false);
setTitle("");
}
}
}, [submit]);
useEffect(() => {
setapprovedGroceries(groceries?.filter((item) => item.approved));
setPendingGroceries(groceries?.filter((item) => !item.approved));
}, [groceries]);
return (
<View marginH-20 marginB-45>
<HeaderTemplate
message={"Welcome to your grocery list"}
isWelcome={false}
isGroceries={true}
>
<View row centerV>
<View
backgroundColor="#e2eed8"
paddingH-15
paddingV-8
marginR-5
centerV
style={{borderRadius: 50}}
>
<Text text70BL color="#46a80a" style={styles.counterText}>
{approvedGroceries?.length} list{" "}
{approvedGroceries?.length === 1 ? (
<Text text70BL color="#46a80a" style={styles.counterText}>
item
</Text>
) : (
<Text text70BL color="#46a80a" style={styles.counterText}>
items
</Text>
)}
</Text>
</View>
<View
backgroundColor="#faead2"
padding-8
paddingH-12
marginR-15
style={{borderRadius: 50}}
>
<Text text70 style={styles.counterText} color="#e28800">
{pendingGroceries?.length} pending
</Text>
</View>
<TouchableOpacity>
<AddPersonIcon width={24}/>
</TouchableOpacity>
</View>
</HeaderTemplate>
{/* Pending Approval Section */}
<View row spread marginT-40 marginB-10 centerV>
<View row centerV>
<Text style={styles.subHeader}>Pending Approval</Text>
{pendingVisible && (
<AntDesign
name="down"
size={17}
style={styles.dropIcon}
color="#9f9f9f"
onPress={() => {
setPendingVisible(false);
}}
/>
)}
{!pendingVisible && (
<AntDesign
name="right"
size={15}
style={styles.dropIcon}
color="#9f9f9f"
onPress={() => {
setPendingVisible(true);
}}
/>
)}
</View>
<View
centerV
style={{
aspectRatio: 1,
width: 35,
backgroundColor: "#faead2",
borderRadius: 50,
}}
>
<Text style={styles.counterNr} center color="#e28800">
{pendingGroceries?.length.toString()}
</Text>
</View>
</View>
{pendingGroceries?.length > 0
? pendingVisible && (
<FlatList
data={pendingGroceries}
renderItem={({item}) => (
<GroceryItem
item={item}
handleItemApproved={(id, changes) =>
updateGroceryItem({...changes, id: id})
}
onInputFocus={onInputFocus}
/>
)}
keyExtractor={(item) => item.id.toString()}
/>
)
: pendingVisible && (
<Text style={styles.noItemTxt}>No items pending approval.</Text>
)}
{/* Approved Section */}
<View row spread marginT-40 marginB-0 centerV>
<View row centerV>
<Text style={styles.subHeader}>Shopping List</Text>
{approvedVisible && (
<AntDesign
name="down"
size={17}
style={styles.dropIcon}
color="#9f9f9f"
onPress={() => {
setApprovedVisible(false);
}}
/>
)}
{!approvedVisible && (
<AntDesign
name="right"
size={15}
style={styles.dropIcon}
color="#9f9f9f"
onPress={() => {
setApprovedVisible(true);
}}
/>
)}
</View>
<View
centerV
style={{
aspectRatio: 1,
width: 35,
backgroundColor: "#e2eed8",
borderRadius: 50,
}}
>
<Text style={styles.counterNr} center color="#46a80a">
{approvedGroceries?.length.toString()}
</Text>
</View>
</View>
{isAddingGrocery && (
<View style={{marginTop: 8}}>
<EditGroceryItem
editGrocery={{
title: title,
setCategory: setCategory,
category: category,
setTitle: setTitle,
setSubmit: setSubmitted,
closeEdit: () => setIsAddingGrocery(false)
}}
onInputFocus={onInputFocus}
/>
</View>
)}
{/* Render Approved Groceries Grouped by Category */}
{approvedGroceries?.length > 0
? approvedVisible && (
<FlatList
data={Object.keys(approvedGroceriesByCategory)}
renderItem={({item: category}) => (
<View key={category}>
{/* Render Category Header */}
<Text text80M style={{marginTop: 10}} color="#666">
{category}
</Text>
{/* Render Grocery Items for this Category */}
{approvedGroceriesByCategory[category].map(
(grocery: IGrocery) => (
<GroceryItem
key={grocery.id}
item={grocery}
handleItemApproved={(id, changes) =>
updateGroceryItem({...changes, id: id})
}
onInputFocus={onInputFocus}
/>
)
)}
</View>
)}
keyExtractor={(category) => category}
/>
)
: approvedVisible && (
<Text style={styles.noItemTxt}>No approved items.</Text>
)}
</View>
);
};
const styles = StyleSheet.create({
dropIcon: {
marginHorizontal: 10,
},
noItemTxt: {
fontFamily: "Manrope_400Regular",
fontSize: 14,
},
counterText: {
fontSize: 14,
fontFamily: "PlusJakartaSans_600SemiBold",
},
subHeader: {
fontSize: 15,
fontFamily: "Manrope_700Bold",
},
counterNr: {
fontFamily: "PlusJakartaSans_600SemiBold",
fontSize: 14
}
});
export default GroceryList;