grocery changes

This commit is contained in:
ivic00
2024-10-07 00:10:51 +02:00
parent fe6e0365a4
commit 2b55c5db0c
5 changed files with 204 additions and 135 deletions

View File

@ -16,6 +16,8 @@ import {
MaterialCommunityIcons, MaterialCommunityIcons,
Octicons, Octicons,
} from "@expo/vector-icons"; } from "@expo/vector-icons";
import MenuIcon from "@/assets/svgs/MenuIcon";
import { router } from "expo-router";
export default function TabLayout() { export default function TabLayout() {
const { mutateAsync: signOut } = useSignOut(); const { mutateAsync: signOut } = useSignOut();
@ -30,6 +32,7 @@ export default function TabLayout() {
backgroundColor: "#f9f8f7", backgroundColor: "#f9f8f7",
height: "100%", height: "100%",
}, },
drawerIcon: () => <MenuIcon />,
}} }}
drawerContent={(props) => { drawerContent={(props) => {
return ( return (

View File

@ -1,6 +1,6 @@
import { View, Text } from "react-native"; import { View, Text } from "react-native";
import React, { useEffect, useState } from "react"; import React, { RefObject, useEffect, useRef, useState } from "react";
import { TextField } from "react-native-ui-lib"; import { TextField, TextFieldRef } from "react-native-ui-lib";
import { import {
GroceryCategory, GroceryCategory,
IGrocery, IGrocery,
@ -21,12 +21,19 @@ interface IEditGrocery {
const EditGroceryItem = ({ editGrocery }: { editGrocery: IEditGrocery }) => { const EditGroceryItem = ({ editGrocery }: { editGrocery: IEditGrocery }) => {
const { fuzzyMatchGroceryCategory } = useGroceryContext(); const { fuzzyMatchGroceryCategory } = useGroceryContext();
const inputRef = useRef<TextFieldRef>(null);
useEffect(() => { useEffect(() => {
if (editGrocery.setCategory) if (editGrocery.setCategory)
editGrocery.setCategory(fuzzyMatchGroceryCategory(editGrocery.title)); editGrocery.setCategory(fuzzyMatchGroceryCategory(editGrocery.title));
}, [editGrocery.title]); }, [editGrocery.title]);
useEffect(() => {
if (inputRef.current) {
inputRef.current.focus(); // Focus on the TextField
}
}, []);
return ( return (
<View <View
style={{ style={{
@ -37,6 +44,7 @@ const EditGroceryItem = ({ editGrocery }: { editGrocery: IEditGrocery }) => {
}} }}
> >
<TextField <TextField
ref={inputRef}
placeholder="Grocery" placeholder="Grocery"
value={editGrocery.title} value={editGrocery.title}
onChangeText={(value) => { onChangeText={(value) => {

View File

@ -54,13 +54,11 @@ const GroceryItem = ({
style={{ borderRadius: 18, marginVertical: 5 }} style={{ borderRadius: 18, marginVertical: 5 }}
backgroundColor="white" backgroundColor="white"
centerV centerV
padding-0 paddingV-12
paddingR-12
paddingL-12
> >
<ListItem <View row spread>
onPress={() => {
setOpenFreqEdit(true);
}}
>
<EditGroceryFrequency <EditGroceryFrequency
visible={openFreqEdit} visible={openFreqEdit}
key={item.id} key={item.id}
@ -69,90 +67,76 @@ const GroceryItem = ({
setOpenFreqEdit(false); setOpenFreqEdit(false);
}} }}
/> />
<ListItem.Part left containerStyle={{ flex: 1, paddingStart: 20 }}> {!isEditingTitle ? (
{!isEditingTitle ? ( <View>
<View> <TouchableOpacity onPress={() => setIsEditingTitle(true)}>
<TouchableOpacity onPress={() => setIsEditingTitle(true)}> <Text text70T>{item.title}</Text>
<Text text70BL>{item.title}</Text> </TouchableOpacity>
</TouchableOpacity> </View>
</View> ) : (
) : ( <EditGroceryItem
<EditGroceryItem editGrocery={{
editGrocery={{ id: item.id,
id: item.id, title: newTitle,
title: newTitle, setTitle: setNewTitle,
setTitle: setNewTitle, category: category,
category: category, updateCategory: updateGroceryItem,
updateCategory: updateGroceryItem, closeEdit: setIsEditingTitle,
closeEdit: setIsEditingTitle, setCategory: setCategory,
setCategory: setCategory, }}
/>
)}
{!item.approved ? (
<View row centerV marginB-10>
<AntDesign
name="check"
size={24}
style={{
color: item.approved ? "green" : "#aaaaaa",
marginRight: 15
}}
onPress={() => {
handleItemApproved(item.id, { approved: true });
}} }}
/> />
)} <AntDesign
</ListItem.Part> name="close"
<ListItem.Part right containerStyle={{ paddingEnd: item.approved ? 20 : 5 }}> size={24}
{!item.approved ? ( style={{ color: item.approved ? "#aaaaaa" : "red" }}
<View row > onPress={() => {
<Button handleItemApproved(item.id, { approved: false });
padding-0 }}
children={
<AntDesign
name="check"
size={24}
style={{
color: item.approved ? "green" : "#aaaaaa",
}}
/>
}
backgroundColor="transparent"
size={Button.sizes.small}
onPress={() => {
handleItemApproved(item.id, { approved: true });
}}
/>
<Button
padding-0
children={
<AntDesign
name="close"
size={24}
style={{ color: item.approved ? "#aaaaaa" : "red" }}
/>
}
backgroundColor="transparent"
size={Button.sizes.small}
onPress={() => {
handleItemApproved(item.id, { approved: false });
}}
/>
</View>
) : (
<Checkbox
value={item.bought}
style={styles.checkbox}
onValueChange={() =>
updateGroceryItem(item.id, { bought: !item.bought })
}
/> />
)} </View>
</ListItem.Part> ) : (
</ListItem> <Checkbox
value={item.bought}
containerStyle={styles.checkbox}
hitSlop={20}
onValueChange={() =>
updateGroceryItem(item.id, { bought: !item.bought })
}
/>
)}
</View>
{!item.approved && ( {!item.approved && (
<View> <View>
<View centerH> <View centerH>
<View height={1} backgroundColor="#e7e7e7" width={"90%"} /> <View height={1} backgroundColor="#e7e7e7" width={"90%"} />
</View> </View>
<View paddingL-10 paddingV-15 flexS row centerV> <View paddingL-0 paddingT-10 flexS row centerV>
<View <View
style={{ style={{
width: 25, width: 25,
aspectRatio: 1, aspectRatio: 1,
borderRadius: 50, borderRadius: 50,
backgroundColor: "red", backgroundColor: "red",
marginHorizontal: 10, marginRight: 10,
}} }}
></View> ></View>
<Text color="#858585" text70>Requested by Austin</Text> <Text color="#858585" text70>
Requested by Austin
</Text>
</View> </View>
</View> </View>
)} )}
@ -161,12 +145,14 @@ const GroceryItem = ({
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
checkbox:{ checkbox: {
borderRadius: 50, borderRadius: 50,
borderWidth: 1, borderWidth: 1,
color: "#bfbfbf", color: "#bfbfbf",
borderColor: "#bfbfbf", borderColor: "#bfbfbf",
} width: 28,
}) aspectRatio: 1,
},
});
export default GroceryItem; export default GroceryItem;

View File

@ -1,6 +1,6 @@
import { FlatList } from "react-native"; import { FlatList, StyleSheet } from "react-native";
import React, { useEffect, useState } from "react"; import React, { RefObject, useEffect, useState } from "react";
import { View, Text, ListItem, Button, TextField } from "react-native-ui-lib"; import { View, Text, ListItem, Button, TextField, TextFieldRef } from "react-native-ui-lib";
import GroceryItem from "./GroceryItem"; import GroceryItem from "./GroceryItem";
import { import {
IGrocery, IGrocery,
@ -10,7 +10,7 @@ import {
} from "@/contexts/GroceryContext"; } from "@/contexts/GroceryContext";
import HeaderTemplate from "@/components/shared/HeaderTemplate"; import HeaderTemplate from "@/components/shared/HeaderTemplate";
import CategoryDropdown from "./CategoryDropdown"; import CategoryDropdown from "./CategoryDropdown";
import { MaterialIcons } from "@expo/vector-icons"; import { AntDesign, MaterialIcons } from "@expo/vector-icons";
import EditGroceryItem from "./EditGroceryItem"; import EditGroceryItem from "./EditGroceryItem";
import { ProfileType, useAuthContext } from "@/contexts/AuthContext"; import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
@ -35,6 +35,9 @@ const GroceryList = () => {
const [title, setTitle] = useState<string>(""); const [title, setTitle] = useState<string>("");
const [submit, setSubmitted] = useState<boolean>(false); const [submit, setSubmitted] = useState<boolean>(false);
const [pendingVisible, setPendingVisible] = useState<boolean>(true);
const [approvedVisible, setApprovedVisible] = useState<boolean>(true);
// Group approved groceries by category // Group approved groceries by category
const approvedGroceriesByCategory = approvedGroceries.reduce( const approvedGroceriesByCategory = approvedGroceries.reduce(
(groups: any, item: IGrocery) => { (groups: any, item: IGrocery) => {
@ -122,47 +125,98 @@ const GroceryList = () => {
</HeaderTemplate> </HeaderTemplate>
{/* Pending Approval Section */} {/* Pending Approval Section */}
<View row spread marginT-40 marginB-20 centerV> <View row spread marginT-40 marginB-10 centerV>
<Text text70BL>Pending Approval</Text> <View row centerV>
<Text text70BL>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 <View
centerV centerV
style={{ style={{
aspectRatio: 1, aspectRatio: 1,
width: 40, width: 35,
backgroundColor: "#faead2", backgroundColor: "#faead2",
borderRadius: 50, borderRadius: 50,
}} }}
> >
<Text text60L center color="#e28800"> <Text text70 center color="#e28800">
{pendingGroceries.length.toString()} {pendingGroceries.length.toString()}
</Text> </Text>
</View> </View>
</View> </View>
{pendingGroceries.length > 0 ? ( {pendingGroceries.length > 0
<FlatList ? pendingVisible && (
data={pendingGroceries} <FlatList
renderItem={({ item }) => ( data={pendingGroceries}
<GroceryItem item={item} handleItemApproved={updateGroceryItem} /> renderItem={({ item }) => (
)} <GroceryItem
keyExtractor={(item) => item.id.toString()} item={item}
/> handleItemApproved={updateGroceryItem}
) : ( />
<Text>No items pending approval.</Text> )}
)} keyExtractor={(item) => item.id.toString()}
/>
)
: pendingVisible && <Text>No items pending approval.</Text>}
{/* Approved Section */} {/* Approved Section */}
<View row spread marginT-40 marginB-20 centerV> <View row spread marginT-40 marginB-0 centerV>
<Text text70BL>Shopping List</Text> <View row centerV>
<Text text70BL>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 <View
centerV centerV
style={{ style={{
aspectRatio: 1, aspectRatio: 1,
width: 40, width: 35,
backgroundColor: "#e2eed8", backgroundColor: "#e2eed8",
borderRadius: 50, borderRadius: 50,
}} }}
> >
<Text text60L center color="#46a80a"> <Text text70 center color="#46a80a">
{approvedGroceries.length.toString()} {approvedGroceries.length.toString()}
</Text> </Text>
</View> </View>
@ -180,38 +234,40 @@ const GroceryList = () => {
)} )}
{/* Render Approved Groceries Grouped by Category */} {/* Render Approved Groceries Grouped by Category */}
{approvedGroceries.length > 0 ? ( {approvedGroceries.length > 0
<FlatList ? approvedVisible && (
data={Object.keys(approvedGroceriesByCategory)} <FlatList
renderItem={({ item: category }) => ( data={Object.keys(approvedGroceriesByCategory)}
<View key={category}> renderItem={({ item: category }) => (
{/* Render Category Header */} <View key={category}>
<Text {/* Render Category Header */}
text70M <Text text80M style={{ marginTop: 10 }} color="#666">
style={{ marginVertical: 10, paddingHorizontal: 15 }} {category}
color="#666" </Text>
> {/* Render Grocery Items for this Category */}
{category} {approvedGroceriesByCategory[category].map(
</Text> (grocery: IGrocery) => (
{/* Render Grocery Items for this Category */} <GroceryItem
{approvedGroceriesByCategory[category].map( key={grocery.id}
(grocery: IGrocery) => ( item={grocery}
<GroceryItem handleItemApproved={updateGroceryItem}
key={grocery.id} />
item={grocery} )
handleItemApproved={updateGroceryItem} )}
/> </View>
)
)} )}
</View> keyExtractor={(category) => category}
)} />
keyExtractor={(category) => category} )
/> : approvedVisible && <Text>No approved items.</Text>}
) : (
<Text>No approved items.</Text>
)}
</View> </View>
); );
}; };
const styles = StyleSheet.create({
dropIcon: {
marginHorizontal: 10,
},
});
export default GroceryList; export default GroceryList;

View File

@ -1,17 +1,33 @@
import { Text, ScrollView } from "react-native"; import { Text, ScrollView } from "react-native";
import { View } from "react-native-ui-lib"; import { View } from "react-native-ui-lib";
import React from "react"; import React, { useEffect, useRef } from "react";
import AddGroceryItem from "./AddGroceryItem"; import AddGroceryItem from "./AddGroceryItem";
import GroceryList from "./GroceryList"; import GroceryList from "./GroceryList";
import { useGroceryContext } from "@/contexts/GroceryContext"; import { useGroceryContext } from "@/contexts/GroceryContext";
const GroceryWrapper = () => { const GroceryWrapper = () => {
const { isAddingGrocery } = useGroceryContext(); const { isAddingGrocery } = useGroceryContext();
const scrollViewRef = useRef<ScrollView>(null); // Reference to the ScrollView
useEffect(() => {
if (isAddingGrocery && scrollViewRef.current) {
scrollViewRef.current.scrollTo({
y: 400, // Adjust this value to scroll a bit down (100 is an example)
animated: true,
});
}
}, [isAddingGrocery]);
return ( return (
<View height={"100%"}> <View height={"100%"}>
<View height={'90%'}> <View height={"100%"}>
<ScrollView> <ScrollView
<GroceryList /> ref={scrollViewRef} // Assign the ref to the ScrollView
automaticallyAdjustKeyboardInsets={true}
>
<View marginB-70>
<GroceryList />
</View>
</ScrollView> </ScrollView>
</View> </View>
{!isAddingGrocery && <AddGroceryItem />} {!isAddingGrocery && <AddGroceryItem />}