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,
|
||||
Octicons,
|
||||
} from "@expo/vector-icons";
|
||||
import MenuIcon from "@/assets/svgs/MenuIcon";
|
||||
import { router } from "expo-router";
|
||||
|
||||
export default function TabLayout() {
|
||||
const { mutateAsync: signOut } = useSignOut();
|
||||
@ -30,6 +32,7 @@ export default function TabLayout() {
|
||||
backgroundColor: "#f9f8f7",
|
||||
height: "100%",
|
||||
},
|
||||
drawerIcon: () => <MenuIcon />,
|
||||
}}
|
||||
drawerContent={(props) => {
|
||||
return (
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { View, Text } from "react-native";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { TextField } from "react-native-ui-lib";
|
||||
import React, { RefObject, useEffect, useRef, useState } from "react";
|
||||
import { TextField, TextFieldRef } from "react-native-ui-lib";
|
||||
import {
|
||||
GroceryCategory,
|
||||
IGrocery,
|
||||
@ -21,12 +21,19 @@ interface IEditGrocery {
|
||||
|
||||
const EditGroceryItem = ({ editGrocery }: { editGrocery: IEditGrocery }) => {
|
||||
const { fuzzyMatchGroceryCategory } = useGroceryContext();
|
||||
const inputRef = useRef<TextFieldRef>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (editGrocery.setCategory)
|
||||
editGrocery.setCategory(fuzzyMatchGroceryCategory(editGrocery.title));
|
||||
}, [editGrocery.title]);
|
||||
|
||||
useEffect(() => {
|
||||
if (inputRef.current) {
|
||||
inputRef.current.focus(); // Focus on the TextField
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
@ -37,6 +44,7 @@ const EditGroceryItem = ({ editGrocery }: { editGrocery: IEditGrocery }) => {
|
||||
}}
|
||||
>
|
||||
<TextField
|
||||
ref={inputRef}
|
||||
placeholder="Grocery"
|
||||
value={editGrocery.title}
|
||||
onChangeText={(value) => {
|
||||
|
||||
@ -54,13 +54,11 @@ const GroceryItem = ({
|
||||
style={{ borderRadius: 18, marginVertical: 5 }}
|
||||
backgroundColor="white"
|
||||
centerV
|
||||
padding-0
|
||||
>
|
||||
<ListItem
|
||||
onPress={() => {
|
||||
setOpenFreqEdit(true);
|
||||
}}
|
||||
paddingV-12
|
||||
paddingR-12
|
||||
paddingL-12
|
||||
>
|
||||
<View row spread>
|
||||
<EditGroceryFrequency
|
||||
visible={openFreqEdit}
|
||||
key={item.id}
|
||||
@ -69,11 +67,10 @@ const GroceryItem = ({
|
||||
setOpenFreqEdit(false);
|
||||
}}
|
||||
/>
|
||||
<ListItem.Part left containerStyle={{ flex: 1, paddingStart: 20 }}>
|
||||
{!isEditingTitle ? (
|
||||
<View>
|
||||
<TouchableOpacity onPress={() => setIsEditingTitle(true)}>
|
||||
<Text text70BL>{item.title}</Text>
|
||||
<Text text70T>{item.title}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
) : (
|
||||
@ -89,38 +86,23 @@ const GroceryItem = ({
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</ListItem.Part>
|
||||
<ListItem.Part right containerStyle={{ paddingEnd: item.approved ? 20 : 5 }}>
|
||||
{!item.approved ? (
|
||||
<View row >
|
||||
<Button
|
||||
padding-0
|
||||
children={
|
||||
<View row centerV marginB-10>
|
||||
<AntDesign
|
||||
name="check"
|
||||
size={24}
|
||||
style={{
|
||||
color: item.approved ? "green" : "#aaaaaa",
|
||||
marginRight: 15
|
||||
}}
|
||||
/>
|
||||
}
|
||||
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 });
|
||||
}}
|
||||
@ -129,30 +111,32 @@ const GroceryItem = ({
|
||||
) : (
|
||||
<Checkbox
|
||||
value={item.bought}
|
||||
style={styles.checkbox}
|
||||
containerStyle={styles.checkbox}
|
||||
hitSlop={20}
|
||||
onValueChange={() =>
|
||||
updateGroceryItem(item.id, { bought: !item.bought })
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</ListItem.Part>
|
||||
</ListItem>
|
||||
</View>
|
||||
{!item.approved && (
|
||||
<View>
|
||||
<View centerH>
|
||||
<View height={1} backgroundColor="#e7e7e7" width={"90%"} />
|
||||
</View>
|
||||
<View paddingL-10 paddingV-15 flexS row centerV>
|
||||
<View paddingL-0 paddingT-10 flexS row centerV>
|
||||
<View
|
||||
style={{
|
||||
width: 25,
|
||||
aspectRatio: 1,
|
||||
borderRadius: 50,
|
||||
backgroundColor: "red",
|
||||
marginHorizontal: 10,
|
||||
marginRight: 10,
|
||||
}}
|
||||
></View>
|
||||
<Text color="#858585" text70>Requested by Austin</Text>
|
||||
<Text color="#858585" text70>
|
||||
Requested by Austin
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
@ -161,12 +145,14 @@ const GroceryItem = ({
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
checkbox:{
|
||||
checkbox: {
|
||||
borderRadius: 50,
|
||||
borderWidth: 1,
|
||||
color: "#bfbfbf",
|
||||
borderColor: "#bfbfbf",
|
||||
}
|
||||
})
|
||||
width: 28,
|
||||
aspectRatio: 1,
|
||||
},
|
||||
});
|
||||
|
||||
export default GroceryItem;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { FlatList } from "react-native";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { View, Text, ListItem, Button, TextField } from "react-native-ui-lib";
|
||||
import { FlatList, StyleSheet } from "react-native";
|
||||
import React, { RefObject, useEffect, useState } from "react";
|
||||
import { View, Text, ListItem, Button, TextField, TextFieldRef } from "react-native-ui-lib";
|
||||
import GroceryItem from "./GroceryItem";
|
||||
import {
|
||||
IGrocery,
|
||||
@ -10,7 +10,7 @@ import {
|
||||
} from "@/contexts/GroceryContext";
|
||||
import HeaderTemplate from "@/components/shared/HeaderTemplate";
|
||||
import CategoryDropdown from "./CategoryDropdown";
|
||||
import { MaterialIcons } from "@expo/vector-icons";
|
||||
import { AntDesign, MaterialIcons } from "@expo/vector-icons";
|
||||
import EditGroceryItem from "./EditGroceryItem";
|
||||
import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
|
||||
|
||||
@ -35,6 +35,9 @@ const GroceryList = () => {
|
||||
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) => {
|
||||
@ -122,47 +125,98 @@ const GroceryList = () => {
|
||||
</HeaderTemplate>
|
||||
|
||||
{/* 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>
|
||||
{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: 40,
|
||||
width: 35,
|
||||
backgroundColor: "#faead2",
|
||||
borderRadius: 50,
|
||||
}}
|
||||
>
|
||||
<Text text60L center color="#e28800">
|
||||
<Text text70 center color="#e28800">
|
||||
{pendingGroceries.length.toString()}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
{pendingGroceries.length > 0 ? (
|
||||
{pendingGroceries.length > 0
|
||||
? pendingVisible && (
|
||||
<FlatList
|
||||
data={pendingGroceries}
|
||||
renderItem={({ item }) => (
|
||||
<GroceryItem item={item} handleItemApproved={updateGroceryItem} />
|
||||
<GroceryItem
|
||||
item={item}
|
||||
handleItemApproved={updateGroceryItem}
|
||||
/>
|
||||
)}
|
||||
keyExtractor={(item) => item.id.toString()}
|
||||
/>
|
||||
) : (
|
||||
<Text>No items pending approval.</Text>
|
||||
)}
|
||||
)
|
||||
: pendingVisible && <Text>No items pending approval.</Text>}
|
||||
|
||||
{/* 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>
|
||||
{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: 40,
|
||||
width: 35,
|
||||
backgroundColor: "#e2eed8",
|
||||
borderRadius: 50,
|
||||
}}
|
||||
>
|
||||
<Text text60L center color="#46a80a">
|
||||
<Text text70 center color="#46a80a">
|
||||
{approvedGroceries.length.toString()}
|
||||
</Text>
|
||||
</View>
|
||||
@ -180,17 +234,14 @@ const GroceryList = () => {
|
||||
)}
|
||||
|
||||
{/* Render Approved Groceries Grouped by Category */}
|
||||
{approvedGroceries.length > 0 ? (
|
||||
{approvedGroceries.length > 0
|
||||
? approvedVisible && (
|
||||
<FlatList
|
||||
data={Object.keys(approvedGroceriesByCategory)}
|
||||
renderItem={({ item: category }) => (
|
||||
<View key={category}>
|
||||
{/* Render Category Header */}
|
||||
<Text
|
||||
text70M
|
||||
style={{ marginVertical: 10, paddingHorizontal: 15 }}
|
||||
color="#666"
|
||||
>
|
||||
<Text text80M style={{ marginTop: 10 }} color="#666">
|
||||
{category}
|
||||
</Text>
|
||||
{/* Render Grocery Items for this Category */}
|
||||
@ -207,11 +258,16 @@ const GroceryList = () => {
|
||||
)}
|
||||
keyExtractor={(category) => category}
|
||||
/>
|
||||
) : (
|
||||
<Text>No approved items.</Text>
|
||||
)}
|
||||
)
|
||||
: approvedVisible && <Text>No approved items.</Text>}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
dropIcon: {
|
||||
marginHorizontal: 10,
|
||||
},
|
||||
});
|
||||
|
||||
export default GroceryList;
|
||||
|
||||
@ -1,17 +1,33 @@
|
||||
import { Text, ScrollView } from "react-native";
|
||||
import { View } from "react-native-ui-lib";
|
||||
import React from "react";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import AddGroceryItem from "./AddGroceryItem";
|
||||
import GroceryList from "./GroceryList";
|
||||
import { useGroceryContext } from "@/contexts/GroceryContext";
|
||||
|
||||
const GroceryWrapper = () => {
|
||||
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 (
|
||||
<View height={"100%"}>
|
||||
<View height={'90%'}>
|
||||
<ScrollView>
|
||||
<View height={"100%"}>
|
||||
<ScrollView
|
||||
ref={scrollViewRef} // Assign the ref to the ScrollView
|
||||
automaticallyAdjustKeyboardInsets={true}
|
||||
>
|
||||
<View marginB-70>
|
||||
<GroceryList />
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
{!isAddingGrocery && <AddGroceryItem />}
|
||||
|
||||
Reference in New Issue
Block a user