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
<ListItem paddingL-12
onPress={() => {
setOpenFreqEdit(true);
}}
> >
<View row spread>
<EditGroceryFrequency <EditGroceryFrequency
visible={openFreqEdit} visible={openFreqEdit}
key={item.id} key={item.id}
@ -69,11 +67,10 @@ 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 text70BL>{item.title}</Text> <Text text70T>{item.title}</Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
) : ( ) : (
@ -89,38 +86,23 @@ const GroceryItem = ({
}} }}
/> />
)} )}
</ListItem.Part>
<ListItem.Part right containerStyle={{ paddingEnd: item.approved ? 20 : 5 }}>
{!item.approved ? ( {!item.approved ? (
<View row > <View row centerV marginB-10>
<Button
padding-0
children={
<AntDesign <AntDesign
name="check" name="check"
size={24} size={24}
style={{ style={{
color: item.approved ? "green" : "#aaaaaa", color: item.approved ? "green" : "#aaaaaa",
marginRight: 15
}} }}
/>
}
backgroundColor="transparent"
size={Button.sizes.small}
onPress={() => { onPress={() => {
handleItemApproved(item.id, { approved: true }); handleItemApproved(item.id, { approved: true });
}} }}
/> />
<Button
padding-0
children={
<AntDesign <AntDesign
name="close" name="close"
size={24} size={24}
style={{ color: item.approved ? "#aaaaaa" : "red" }} style={{ color: item.approved ? "#aaaaaa" : "red" }}
/>
}
backgroundColor="transparent"
size={Button.sizes.small}
onPress={() => { onPress={() => {
handleItemApproved(item.id, { approved: false }); handleItemApproved(item.id, { approved: false });
}} }}
@ -129,30 +111,32 @@ const GroceryItem = ({
) : ( ) : (
<Checkbox <Checkbox
value={item.bought} value={item.bought}
style={styles.checkbox} containerStyle={styles.checkbox}
hitSlop={20}
onValueChange={() => onValueChange={() =>
updateGroceryItem(item.id, { bought: !item.bought }) updateGroceryItem(item.id, { bought: !item.bought })
} }
/> />
)} )}
</ListItem.Part> </View>
</ListItem>
{!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>
)} )}
@ -166,7 +150,9 @@ const styles = StyleSheet.create({
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>
<View row centerV>
<Text text70BL>Pending Approval</Text> <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
? pendingVisible && (
<FlatList <FlatList
data={pendingGroceries} data={pendingGroceries}
renderItem={({ item }) => ( renderItem={({ item }) => (
<GroceryItem item={item} handleItemApproved={updateGroceryItem} /> <GroceryItem
item={item}
handleItemApproved={updateGroceryItem}
/>
)} )}
keyExtractor={(item) => item.id.toString()} keyExtractor={(item) => item.id.toString()}
/> />
) : ( )
<Text>No items pending approval.</Text> : 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>
<View row centerV>
<Text text70BL>Shopping List</Text> <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,17 +234,14 @@ const GroceryList = () => {
)} )}
{/* Render Approved Groceries Grouped by Category */} {/* Render Approved Groceries Grouped by Category */}
{approvedGroceries.length > 0 ? ( {approvedGroceries.length > 0
? approvedVisible && (
<FlatList <FlatList
data={Object.keys(approvedGroceriesByCategory)} data={Object.keys(approvedGroceriesByCategory)}
renderItem={({ item: category }) => ( renderItem={({ item: category }) => (
<View key={category}> <View key={category}>
{/* Render Category Header */} {/* Render Category Header */}
<Text <Text text80M style={{ marginTop: 10 }} color="#666">
text70M
style={{ marginVertical: 10, paddingHorizontal: 15 }}
color="#666"
>
{category} {category}
</Text> </Text>
{/* Render Grocery Items for this Category */} {/* Render Grocery Items for this Category */}
@ -207,11 +258,16 @@ const GroceryList = () => {
)} )}
keyExtractor={(category) => category} keyExtractor={(category) => category}
/> />
) : ( )
<Text>No approved items.</Text> : approvedVisible && <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
ref={scrollViewRef} // Assign the ref to the ScrollView
automaticallyAdjustKeyboardInsets={true}
>
<View marginB-70>
<GroceryList /> <GroceryList />
</View>
</ScrollView> </ScrollView>
</View> </View>
{!isAddingGrocery && <AddGroceryItem />} {!isAddingGrocery && <AddGroceryItem />}