mirror of
https://github.com/urosran/cally.git
synced 2025-11-26 08:24:55 +00:00
Shopping List backend implementation
- Implemented fetching, create and update of groceries in db
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
import { StyleSheet } from "react-native";
|
import { StyleSheet } from "react-native";
|
||||||
import React, { useState } from "react";
|
import React from "react";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
Text,
|
Text,
|
||||||
@ -11,9 +11,9 @@ import {
|
|||||||
} from "react-native-ui-lib";
|
} from "react-native-ui-lib";
|
||||||
import {
|
import {
|
||||||
GroceryFrequency,
|
GroceryFrequency,
|
||||||
IGrocery,
|
|
||||||
useGroceryContext,
|
useGroceryContext,
|
||||||
} from "@/contexts/GroceryContext";
|
} from "@/contexts/GroceryContext";
|
||||||
|
import { IGrocery } from "@/hooks/firebase/types/groceryData";
|
||||||
interface EditGroceryFrequencyProps {
|
interface EditGroceryFrequencyProps {
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
@ -42,7 +42,7 @@ const EditGroceryFrequency = (props: EditGroceryFrequencyProps) => {
|
|||||||
<Switch
|
<Switch
|
||||||
value={props.item.recurring}
|
value={props.item.recurring}
|
||||||
onValueChange={(value) =>
|
onValueChange={(value) =>
|
||||||
updateGroceryItem(props.item.id, { recurring: value })
|
updateGroceryItem({id: props.item.id, recurring: value})
|
||||||
}
|
}
|
||||||
onColor={"lime"}
|
onColor={"lime"}
|
||||||
/>
|
/>
|
||||||
@ -56,7 +56,8 @@ const EditGroceryFrequency = (props: EditGroceryFrequencyProps) => {
|
|||||||
const selectedFrequency =
|
const selectedFrequency =
|
||||||
GroceryFrequency[item as keyof typeof GroceryFrequency];
|
GroceryFrequency[item as keyof typeof GroceryFrequency];
|
||||||
if (selectedFrequency) {
|
if (selectedFrequency) {
|
||||||
updateGroceryItem(props.item.id, {
|
updateGroceryItem({
|
||||||
|
id: props.item.id,
|
||||||
frequency: selectedFrequency,
|
frequency: selectedFrequency,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,34 +1,21 @@
|
|||||||
import {
|
import {Checkbox, Text, TouchableOpacity, View,} from "react-native-ui-lib";
|
||||||
View,
|
|
||||||
Text,
|
|
||||||
Button,
|
|
||||||
TouchableOpacity,
|
|
||||||
Checkbox,
|
|
||||||
ButtonSize,
|
|
||||||
} from "react-native-ui-lib";
|
|
||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
|
import {AntDesign} from "@expo/vector-icons";
|
||||||
import { MaterialCommunityIcons, AntDesign } from "@expo/vector-icons";
|
import {GroceryCategory, useGroceryContext,} from "@/contexts/GroceryContext";
|
||||||
import { ListItem } from "react-native-ui-lib";
|
|
||||||
import {
|
|
||||||
GroceryCategory,
|
|
||||||
IGrocery,
|
|
||||||
useGroceryContext,
|
|
||||||
} from "@/contexts/GroceryContext";
|
|
||||||
import EditGroceryFrequency from "./EditGroceryFrequency";
|
import EditGroceryFrequency from "./EditGroceryFrequency";
|
||||||
import EditGroceryItem from "./EditGroceryItem";
|
import EditGroceryItem from "./EditGroceryItem";
|
||||||
import {StyleSheet} from "react-native";
|
import {StyleSheet} from "react-native";
|
||||||
|
import {IGrocery} from "@/hooks/firebase/types/groceryData";
|
||||||
|
|
||||||
const GroceryItem = ({
|
const GroceryItem = ({
|
||||||
item,
|
item,
|
||||||
handleItemApproved,
|
handleItemApproved,
|
||||||
}: {
|
}: {
|
||||||
item: IGrocery;
|
item: IGrocery;
|
||||||
handleItemApproved: (id: number, changes: Partial<IGrocery>) => void;
|
handleItemApproved: (id: string, changes: Partial<IGrocery>) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const { updateGroceryItem, groceries } = useGroceryContext();
|
const { updateGroceryItem } = useGroceryContext();
|
||||||
|
|
||||||
const { profileType } = useAuthContext();
|
|
||||||
const [openFreqEdit, setOpenFreqEdit] = useState<boolean>(false);
|
const [openFreqEdit, setOpenFreqEdit] = useState<boolean>(false);
|
||||||
const [isEditingTitle, setIsEditingTitle] = useState<boolean>(false);
|
const [isEditingTitle, setIsEditingTitle] = useState<boolean>(false);
|
||||||
const [newTitle, setNewTitle] = useState<string>("");
|
const [newTitle, setNewTitle] = useState<string>("");
|
||||||
@ -37,11 +24,11 @@ const GroceryItem = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const handleTitleChange = (newTitle: string) => {
|
const handleTitleChange = (newTitle: string) => {
|
||||||
updateGroceryItem(item.id, { title: newTitle });
|
updateGroceryItem({id: item?.id, title: newTitle});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCategoryChange = (newCategory: GroceryCategory) => {
|
const handleCategoryChange = (newCategory: GroceryCategory) => {
|
||||||
updateGroceryItem(item.id, { category: newCategory });
|
updateGroceryItem({id: item?.id, category: newCategory});
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -114,7 +101,7 @@ const GroceryItem = ({
|
|||||||
containerStyle={styles.checkbox}
|
containerStyle={styles.checkbox}
|
||||||
hitSlop={20}
|
hitSlop={20}
|
||||||
onValueChange={() =>
|
onValueChange={() =>
|
||||||
updateGroceryItem(item.id, { bought: !item.bought })
|
updateGroceryItem({ id: item.id, bought: !item.bought })
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,18 +1,13 @@
|
|||||||
import {FlatList, StyleSheet} from "react-native";
|
import {FlatList, StyleSheet} from "react-native";
|
||||||
import React, { RefObject, useEffect, useState } from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import { View, Text, ListItem, Button, TextField, TextFieldRef } from "react-native-ui-lib";
|
import {Button, Text, View} from "react-native-ui-lib";
|
||||||
import GroceryItem from "./GroceryItem";
|
import GroceryItem from "./GroceryItem";
|
||||||
import {
|
import {GroceryCategory, GroceryFrequency, useGroceryContext,} from "@/contexts/GroceryContext";
|
||||||
IGrocery,
|
|
||||||
GroceryCategory,
|
|
||||||
GroceryFrequency,
|
|
||||||
useGroceryContext,
|
|
||||||
} from "@/contexts/GroceryContext";
|
|
||||||
import HeaderTemplate from "@/components/shared/HeaderTemplate";
|
import HeaderTemplate from "@/components/shared/HeaderTemplate";
|
||||||
import CategoryDropdown from "./CategoryDropdown";
|
|
||||||
import {AntDesign, 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";
|
||||||
|
import {IGrocery} from "@/hooks/firebase/types/groceryData";
|
||||||
|
|
||||||
const GroceryList = () => {
|
const GroceryList = () => {
|
||||||
const {
|
const {
|
||||||
@ -24,10 +19,10 @@ const GroceryList = () => {
|
|||||||
} = useGroceryContext();
|
} = useGroceryContext();
|
||||||
const { profileData } = useAuthContext();
|
const { profileData } = useAuthContext();
|
||||||
const [approvedGroceries, setapprovedGroceries] = useState<IGrocery[]>(
|
const [approvedGroceries, setapprovedGroceries] = useState<IGrocery[]>(
|
||||||
groceries.filter((item) => item.approved === true)
|
groceries?.filter((item) => item.approved === true)
|
||||||
);
|
);
|
||||||
const [pendingGroceries, setPendingGroceries] = useState<IGrocery[]>(
|
const [pendingGroceries, setPendingGroceries] = useState<IGrocery[]>(
|
||||||
groceries.filter((item) => item.approved !== true)
|
groceries?.filter((item) => item.approved !== true)
|
||||||
);
|
);
|
||||||
const [category, setCategory] = useState<GroceryCategory>(
|
const [category, setCategory] = useState<GroceryCategory>(
|
||||||
GroceryCategory.Bakery
|
GroceryCategory.Bakery
|
||||||
@ -39,7 +34,7 @@ const GroceryList = () => {
|
|||||||
const [approvedVisible, setApprovedVisible] = 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) => {
|
||||||
const category = item.category || "Uncategorized";
|
const category = item.category || "Uncategorized";
|
||||||
if (!groups[category]) {
|
if (!groups[category]) {
|
||||||
@ -76,8 +71,8 @@ const GroceryList = () => {
|
|||||||
}, [category]);
|
}, [category]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setapprovedGroceries(groceries.filter((item) => item.approved === true));
|
setapprovedGroceries(groceries?.filter((item) => item.approved === true));
|
||||||
setPendingGroceries(groceries.filter((item) => item.approved !== true));
|
setPendingGroceries(groceries?.filter((item) => item.approved !== true));
|
||||||
}, [groceries]);
|
}, [groceries]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -93,8 +88,8 @@ const GroceryList = () => {
|
|||||||
style={{ borderRadius: 50 }}
|
style={{ borderRadius: 50 }}
|
||||||
>
|
>
|
||||||
<Text text70BL color="#46a80a">
|
<Text text70BL color="#46a80a">
|
||||||
{approvedGroceries.length} list{" "}
|
{approvedGroceries?.length} list{" "}
|
||||||
{approvedGroceries.length === 1 ? (
|
{approvedGroceries?.length === 1 ? (
|
||||||
<Text text70BL color="#46a80a">
|
<Text text70BL color="#46a80a">
|
||||||
item
|
item
|
||||||
</Text>
|
</Text>
|
||||||
@ -111,7 +106,7 @@ const GroceryList = () => {
|
|||||||
style={{ borderRadius: 50 }}
|
style={{ borderRadius: 50 }}
|
||||||
>
|
>
|
||||||
<Text text70BL color="#e28800">
|
<Text text70BL color="#e28800">
|
||||||
{pendingGroceries.length} pending
|
{pendingGroceries?.length} pending
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<Button
|
<Button
|
||||||
@ -161,18 +156,18 @@ const GroceryList = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text text70 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 && (
|
? pendingVisible && (
|
||||||
<FlatList
|
<FlatList
|
||||||
data={pendingGroceries}
|
data={pendingGroceries}
|
||||||
renderItem={({ item }) => (
|
renderItem={({ item }) => (
|
||||||
<GroceryItem
|
<GroceryItem
|
||||||
item={item}
|
item={item}
|
||||||
handleItemApproved={updateGroceryItem}
|
handleItemApproved={(id, changes) => updateGroceryItem({...changes, id: id})}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
keyExtractor={(item) => item.id.toString()}
|
keyExtractor={(item) => item.id.toString()}
|
||||||
@ -217,7 +212,7 @@ const GroceryList = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text text70 center color="#46a80a">
|
<Text text70 center color="#46a80a">
|
||||||
{approvedGroceries.length.toString()}
|
{approvedGroceries?.length.toString()}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
@ -234,7 +229,7 @@ const GroceryList = () => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Render Approved Groceries Grouped by Category */}
|
{/* Render Approved Groceries Grouped by Category */}
|
||||||
{approvedGroceries.length > 0
|
{approvedGroceries?.length > 0
|
||||||
? approvedVisible && (
|
? approvedVisible && (
|
||||||
<FlatList
|
<FlatList
|
||||||
data={Object.keys(approvedGroceriesByCategory)}
|
data={Object.keys(approvedGroceriesByCategory)}
|
||||||
@ -250,7 +245,7 @@ const GroceryList = () => {
|
|||||||
<GroceryItem
|
<GroceryItem
|
||||||
key={grocery.id}
|
key={grocery.id}
|
||||||
item={grocery}
|
item={grocery}
|
||||||
handleItemApproved={updateGroceryItem}
|
handleItemApproved={(id, changes) => updateGroceryItem({...changes, id: id})}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
|
||||||
import {createContext, useContext, useState} from "react";
|
import {createContext, useContext, useState} from "react";
|
||||||
import fuzzysort from "fuzzysort";
|
import fuzzysort from "fuzzysort";
|
||||||
|
import {useCreateGrocery} from "@/hooks/firebase/useCreateGrocery";
|
||||||
|
import {IGrocery} from "@/hooks/firebase/types/groceryData";
|
||||||
|
import {useUpdateGrocery} from "@/hooks/firebase/useUpdateGrocery";
|
||||||
|
import {useGetGroceries} from "@/hooks/firebase/useGetGroceries";
|
||||||
|
|
||||||
export enum GroceryFrequency {
|
export enum GroceryFrequency {
|
||||||
Never = "Never",
|
Never = "Never",
|
||||||
@ -11,16 +14,6 @@ export enum GroceryFrequency {
|
|||||||
Quarterly = "Quarterly",
|
Quarterly = "Quarterly",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IGrocery {
|
|
||||||
id: number;
|
|
||||||
title: string;
|
|
||||||
category: GroceryCategory;
|
|
||||||
approved: boolean;
|
|
||||||
recurring: boolean;
|
|
||||||
frequency: GroceryFrequency;
|
|
||||||
bought: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum GroceryCategory {
|
export enum GroceryCategory {
|
||||||
Fruit = "Fruit",
|
Fruit = "Fruit",
|
||||||
Dairy = "Dairy",
|
Dairy = "Dairy",
|
||||||
@ -52,23 +45,7 @@ const iconMapping: { [key in GroceryCategory]: MaterialIconNames } = {
|
|||||||
[GroceryCategory.Frozen]: "snowflake",
|
[GroceryCategory.Frozen]: "snowflake",
|
||||||
};*/
|
};*/
|
||||||
|
|
||||||
interface IGroceryContext {
|
const initialGroceryList = [
|
||||||
groceries: IGrocery[];
|
|
||||||
//iconMapping: { [key in GroceryCategory]: MaterialIconNames };
|
|
||||||
updateGroceryItem: (id: number, changes: Partial<IGrocery>) => void;
|
|
||||||
isAddingGrocery: boolean;
|
|
||||||
setIsAddingGrocery: (value: boolean) => void;
|
|
||||||
addGrocery: (grocery: IGrocery) => void;
|
|
||||||
fuzzyMatchGroceryCategory: (groceryTitle: string) => GroceryCategory;
|
|
||||||
}
|
|
||||||
|
|
||||||
const GroceryContext = createContext<IGroceryContext | undefined>(undefined);
|
|
||||||
|
|
||||||
export const GroceryProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
||||||
children,
|
|
||||||
}) => {
|
|
||||||
const [isAddingGrocery, setIsAddingGrocery] = useState<boolean>(false);
|
|
||||||
const [groceries, setGroceries] = useState<IGrocery[]>([
|
|
||||||
{
|
{
|
||||||
id: 0,
|
id: 0,
|
||||||
title: "Carrots",
|
title: "Carrots",
|
||||||
@ -105,19 +82,7 @@ export const GroceryProvider: React.FC<{ children: React.ReactNode }> = ({
|
|||||||
recurring: false,
|
recurring: false,
|
||||||
frequency: GroceryFrequency.Never,
|
frequency: GroceryFrequency.Never,
|
||||||
},
|
},
|
||||||
]);
|
];
|
||||||
|
|
||||||
const addGrocery = (grocery: IGrocery) => {
|
|
||||||
setGroceries((prevGroceries) => [
|
|
||||||
...prevGroceries,
|
|
||||||
{
|
|
||||||
...grocery,
|
|
||||||
id: prevGroceries.length
|
|
||||||
? prevGroceries[prevGroceries.length - 1].id + 1
|
|
||||||
: 0,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const groceryExamples = {
|
const groceryExamples = {
|
||||||
[GroceryCategory.Fruit]: [
|
[GroceryCategory.Fruit]: [
|
||||||
@ -206,6 +171,32 @@ export const GroceryProvider: React.FC<{ children: React.ReactNode }> = ({
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface IGroceryContext {
|
||||||
|
groceries: IGrocery[];
|
||||||
|
//iconMapping: { [key in GroceryCategory]: MaterialIconNames };
|
||||||
|
updateGroceryItem: (changes: Partial<IGrocery>) => void;
|
||||||
|
isAddingGrocery: boolean;
|
||||||
|
setIsAddingGrocery: (value: boolean) => void;
|
||||||
|
addGrocery: (grocery: IGrocery) => void;
|
||||||
|
fuzzyMatchGroceryCategory: (groceryTitle: string) => GroceryCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GroceryContext = createContext<IGroceryContext | undefined>(undefined);
|
||||||
|
|
||||||
|
export const GroceryProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
const [isAddingGrocery, setIsAddingGrocery] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const { mutateAsync: createGrocery } = useCreateGrocery();
|
||||||
|
const { mutateAsync: updateGrocery } = useUpdateGrocery();
|
||||||
|
const { data: groceries } = useGetGroceries();
|
||||||
|
|
||||||
|
|
||||||
|
const addGrocery = (grocery: IGrocery) => {
|
||||||
|
createGrocery(grocery);
|
||||||
|
};
|
||||||
|
|
||||||
const fuzzyMatchGroceryCategory = (groceryTitle: string): GroceryCategory => {
|
const fuzzyMatchGroceryCategory = (groceryTitle: string): GroceryCategory => {
|
||||||
let bestMatchCategory = GroceryCategory.None;
|
let bestMatchCategory = GroceryCategory.None;
|
||||||
let bestMatchScore = -1000;
|
let bestMatchScore = -1000;
|
||||||
@ -221,12 +212,8 @@ export const GroceryProvider: React.FC<{ children: React.ReactNode }> = ({
|
|||||||
return bestMatchCategory;
|
return bestMatchCategory;
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateGroceryItem = (id: number, changes: Partial<IGrocery>) => {
|
const updateGroceryItem = (changes: Partial<IGrocery>) => {
|
||||||
setGroceries((prevGroceries) =>
|
updateGrocery(changes);
|
||||||
prevGroceries.map((grocery) =>
|
|
||||||
grocery.id === id ? { ...grocery, ...changes } : grocery
|
|
||||||
)
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
12
hooks/firebase/types/groceryData.ts
Normal file
12
hooks/firebase/types/groceryData.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import {GroceryCategory, GroceryFrequency} from "@/contexts/GroceryContext";
|
||||||
|
|
||||||
|
export interface IGrocery {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
category: GroceryCategory;
|
||||||
|
approved: boolean;
|
||||||
|
recurring: boolean;
|
||||||
|
frequency: GroceryFrequency;
|
||||||
|
bought: boolean;
|
||||||
|
familyId?: string,
|
||||||
|
}
|
||||||
26
hooks/firebase/useCreateGrocery.ts
Normal file
26
hooks/firebase/useCreateGrocery.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { useMutation, useQueryClient } from "react-query";
|
||||||
|
import firestore from "@react-native-firebase/firestore";
|
||||||
|
import { useAuthContext } from "@/contexts/AuthContext";
|
||||||
|
import {IGrocery} from "@/hooks/firebase/types/groceryData";
|
||||||
|
|
||||||
|
export const useCreateGrocery = () => {
|
||||||
|
const { profileData } = useAuthContext();
|
||||||
|
const queryClients = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: ["createGrocery"],
|
||||||
|
mutationFn: async (groceryData: Partial<IGrocery>) => {
|
||||||
|
try {
|
||||||
|
const newDoc = firestore().collection('Groceries').doc();
|
||||||
|
await firestore()
|
||||||
|
.collection("Groceries")
|
||||||
|
.add({...groceryData, id: newDoc.id, familyId: profileData?.familyId})
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClients.invalidateQueries("groceries")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
31
hooks/firebase/useGetGroceries.ts
Normal file
31
hooks/firebase/useGetGroceries.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import {useQuery} from "react-query";
|
||||||
|
import firestore from "@react-native-firebase/firestore";
|
||||||
|
import {useAuthContext} from "@/contexts/AuthContext";
|
||||||
|
|
||||||
|
export const useGetGroceries = () => {
|
||||||
|
const { user, profileData } = useAuthContext();
|
||||||
|
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ["groceries", user?.uid],
|
||||||
|
queryFn: async () => {
|
||||||
|
const snapshot = await firestore()
|
||||||
|
.collection("Groceries")
|
||||||
|
.where("familyId", "==", profileData?.familyId)
|
||||||
|
.get();
|
||||||
|
|
||||||
|
return snapshot.docs.map((doc) => {
|
||||||
|
const data = doc.data();
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: doc.id,
|
||||||
|
title: data.title,
|
||||||
|
category: data.category,
|
||||||
|
approved: data.approved,
|
||||||
|
bought: data.bought,
|
||||||
|
recurring: data.recurring,
|
||||||
|
frequency: data.frequency
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
25
hooks/firebase/useUpdateGrocery.ts
Normal file
25
hooks/firebase/useUpdateGrocery.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import {useMutation, useQueryClient} from "react-query";
|
||||||
|
import firestore from "@react-native-firebase/firestore";
|
||||||
|
import {IGrocery} from "@/hooks/firebase/types/groceryData";
|
||||||
|
|
||||||
|
export const useUpdateGrocery = () => {
|
||||||
|
const queryClients = useQueryClient()
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: ["updateGrocery"],
|
||||||
|
mutationFn: async (groceryData: Partial<IGrocery>) => {
|
||||||
|
console.log(groceryData);
|
||||||
|
try {
|
||||||
|
await firestore()
|
||||||
|
.collection("Groceries")
|
||||||
|
.doc(groceryData.id)
|
||||||
|
.update(groceryData);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClients.invalidateQueries("events")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user