mirror of
https://github.com/urosran/cally.git
synced 2025-11-26 08:24:55 +00:00
grocery changes
This commit is contained in:
@ -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 (
|
||||||
|
|||||||
@ -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) => {
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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 />}
|
||||||
|
|||||||
Reference in New Issue
Block a user