add groceryContext and manipulation

This commit is contained in:
ivic00
2024-08-31 15:52:45 +02:00
parent 5a5215aeb4
commit f8dd152eeb
8 changed files with 328 additions and 163 deletions

View File

@ -9,11 +9,13 @@ import {
View,
PanningProvider,
} from "react-native-ui-lib";
import { useGroceryContext } from "@/contexts/GroceryContext";
interface AddGroceryItemProps {
visible: boolean;
onClose: () => void;
}
const AddGroceryItem = () => {
const { setIsShopping, isShopping } = useGroceryContext();
const [visible, setVisible] = useState<boolean>(false);
const handleShowDialog = () => {
@ -52,18 +54,38 @@ const AddGroceryItem = () => {
height: 60,
}}
>
<Button
label="View shopping list"
color="#337a11"
backgroundColor="#c6e0b3"
/>
<Button
color="white"
backgroundColor="#19ad61"
label="Create new"
enableShadow
onPress={() => setVisible(true)}
/>
{!isShopping ? (
<View style={styles.btnContainer} row>
<Button
label="View shopping list"
color="#337a11"
flex-2
marginR-5
backgroundColor="#c6e0b3"
onPress={() => setIsShopping(true)}
/>
<Button
label="Create new"
color="white"
flex-1
backgroundColor="#19ad61"
enableShadow
onPress={() => {}}
/>
</View>
) : (
<View style={styles.btnContainer} row>
<Button
color="white"
backgroundColor="#81a861"
label="Finish shopping"
text70BL
style={styles.finishShopBtn}
enableShadow
onPress={() => setIsShopping(false)}
/>
</View>
)}
{addGroceryDialog}
</View>
);
@ -94,4 +116,15 @@ const styles = StyleSheet.create({
backgroundColor: "#E0E0E0",
marginVertical: 10,
},
btnContainer: {
width: "100%",
justifyContent: "center",
},
finishShopBtn: {
width: "100%",
},
shoppingBtn: {
flex: 1,
marginHorizontal: 3,
},
});

View File

@ -9,14 +9,18 @@ import {
Picker,
PickerValue,
} from "react-native-ui-lib";
import { GroceryFrequency, IGrocery } from "./GroceryItem";
interface EditGroceryItemProps {
import {
GroceryFrequency,
IGrocery,
useGroceryContext,
} from "@/contexts/GroceryContext";
interface EditGroceryFrequencyProps {
visible: boolean;
onClose: () => void;
item: IGrocery;
}
const EditGroceryItem = (props: EditGroceryItemProps) => {
const [recurring, setRecurring] = useState<boolean>(false);
const EditGroceryFrequency = (props: EditGroceryFrequencyProps) => {
const { updateGroceryItem } = useGroceryContext();
const pickerItems = Object.values(GroceryFrequency).map((value) => ({
label: value,
value: value,
@ -35,18 +39,26 @@ const EditGroceryItem = (props: EditGroceryItemProps) => {
<View style={styles.inner}>
<View row spread>
<Text text70>Recurring</Text>
<Switch value={recurring} onValueChange={value => setRecurring(value)} onColor={'lime'}/>
<Switch
value={props.item.recurring}
onValueChange={(value) =>
updateGroceryItem(props.item.id, { recurring: value })
}
onColor={"lime"}
/>
</View>
<Picker
value={props.item.frequency}
fieldType="form"
useWheelPicker
useDialog
items={pickerItems}
onChange={(item: PickerValue) => {
const selectedFrequency =
GroceryFrequency[item as keyof typeof GroceryFrequency];
if (selectedFrequency) {
//props.handleFrequency(props.item.id, selectedFrequency);
updateGroceryItem(props.item.id, {
frequency: selectedFrequency,
});
} else {
console.error("Invalid frequency selected");
}
@ -58,7 +70,7 @@ const EditGroceryItem = (props: EditGroceryItemProps) => {
);
};
export default EditGroceryItem;
export default EditGroceryFrequency;
const styles = StyleSheet.create({
container: {

View File

@ -1,82 +1,54 @@
import { View, Text, Button } from "react-native-ui-lib";
import React, { useState } from "react";
import {
View,
Text,
Button,
TouchableOpacity,
Checkbox,
} from "react-native-ui-lib";
import React, { useEffect, useState } from "react";
import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
import { MaterialCommunityIcons, AntDesign } from "@expo/vector-icons";
import { ListItem } from "react-native-ui-lib";
import EditGroceryItem from "./EditGroceryItem";
export enum GroceryFrequency {
Never = "Never",
Daily = "Daily",
Weekly = "Weekly",
BiWeekly = "BiWeekly",
Monthly = "Monthly",
Quarterly = "Quarterly",
}
export interface IGrocery {
id: number;
title: String;
category: GroceryCategory;
approved: boolean;
recurring: boolean;
frequency: GroceryFrequency;
bought: boolean;
}
export enum GroceryCategory {
Fruit = "Fruit",
Dairy = "Dairy",
Vegetables = "Vegetables",
Meat = "Meat",
Poultry = "Poultry",
Bakery = "Bakery",
Beverages = "Beverages",
Snacks = "Snacks",
Household = "Household",
PersonalCare = "Personal Care",
Frozen = "Frozen",
}
type MaterialIconNames = keyof typeof MaterialCommunityIcons.glyphMap;
const iconMapping: { [key in GroceryCategory]: MaterialIconNames } = {
//за сад се иконице за категорију бирају одавде
[GroceryCategory.Fruit]: "food-apple",
[GroceryCategory.Dairy]: "cheese",
[GroceryCategory.Vegetables]: "carrot",
[GroceryCategory.Meat]: "food-steak",
[GroceryCategory.Poultry]: "food-drumstick",
[GroceryCategory.Bakery]: "bread-slice",
[GroceryCategory.Beverages]: "cup-water",
[GroceryCategory.Snacks]: "candy",
[GroceryCategory.Household]: "home",
[GroceryCategory.PersonalCare]: "face-man-profile",
[GroceryCategory.Frozen]: "snowflake",
};
import { IGrocery, useGroceryContext } from "@/contexts/GroceryContext";
import EditGroceryFrequency from "./EditGroceryFrequency";
import { TextInput } from "react-native";
const GroceryItem = ({
item,
handleItemApproved,
}: {
item: IGrocery;
handleItemApproved: (id: number, approved: boolean) => void;
handleItemApproved: (id: number, changes: Partial<IGrocery>) => void;
}) => {
const { iconMapping, updateGroceryItem, groceries, isShopping } =
useGroceryContext();
const { profileType } = useAuthContext();
const [open, setOpen] = useState<boolean>(false);
const [openFreqEdit, setOpenFreqEdit] = useState<boolean>(false);
const [isEditingTitle, setIsEditingTitle] = useState<boolean>(false);
const [newTitle, setNewTitle] = useState<string>("");
const handleTitleChange = (newTitle: string) => {
updateGroceryItem(item.id, { title: newTitle });
};
useEffect(() => {
setNewTitle(item.title);
}, []);
return (
<ListItem
backgroundColor="white"
onPress={() => {
setOpen(true);
setOpenFreqEdit(true);
}}
>
<EditGroceryItem
visible={open}
<EditGroceryFrequency
visible={openFreqEdit}
key={item.id}
item={item}
onClose={() => {
setOpen(false);
setOpenFreqEdit(false);
}}
/>
<ListItem.Part left containerStyle={{ flex: 1, paddingStart: 15 }}>
@ -95,14 +67,35 @@ const GroceryItem = ({
}
/>
<View>
<Text>{item.title}</Text>
{!isEditingTitle ? (
<TouchableOpacity onPress={() => setIsEditingTitle(true)}>
<Text text70BL>{item.title}</Text>
</TouchableOpacity>
) : (
<TextInput
value={item.title}
onChangeText={handleTitleChange}
onBlur={() => {
setIsEditingTitle(false);
console.log(groceries);
}}
autoFocus
style={{
fontSize: 16,
padding: 0,
margin: 0,
fontWeight: "bold",
}}
/>
)}
<Text>{iconMapping[item.category]}</Text>
</View>
</ListItem.Part>
<ListItem.Part right containerStyle={{ paddingEnd: 15 }}>
{profileType == ProfileType.PARENT ? (
{profileType == ProfileType.PARENT && !isShopping ? (
<View row>
<Button
padding-0
children={
<AntDesign
name="check"
@ -115,10 +108,11 @@ const GroceryItem = ({
backgroundColor="transparent"
size={Button.sizes.small}
onPress={() => {
handleItemApproved(item.id, true);
handleItemApproved(item.id, { approved: true });
}}
/>
<Button
padding-0
children={
<AntDesign
name="close"
@ -129,18 +123,18 @@ const GroceryItem = ({
backgroundColor="transparent"
size={Button.sizes.small}
onPress={() => {
handleItemApproved(item.id, false);
handleItemApproved(item.id, { approved: false });
}}
/>
</View>
) : (
<Text style={{ color: item.bought ? "green" : "red" }}>
{item.approved ? (
<AntDesign name="check" size={24} color={"green"} />
) : (
"X"
)}
</Text>
<Checkbox
value={item.bought}
color={"#f58749"}
onValueChange={() =>
updateGroceryItem(item.id, { bought: !item.bought })
}
/>
)}
</ListItem.Part>
</ListItem>

View File

@ -5,61 +5,18 @@ import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
import { useAuthContext } from "@/contexts/AuthContext";
import AntDesign from "@expo/vector-icons/AntDesign";
import AddGroceryItem from "./AddGroceryItem";
import GroceryItem, { IGrocery, GroceryCategory, GroceryFrequency } from "./GroceryItem";
import GroceryItem from "./GroceryItem";
import { useGroceryContext } from "@/contexts/GroceryContext";
const GroceryList = () => {
const [groceries, setGroceries] = useState<IGrocery[]>([
{
id: 0,
title: "Carrots",
category: GroceryCategory.Vegetables,
approved: false,
bought: false,
recurring: false,
frequency: GroceryFrequency.Never
},
{
id: 1,
title: "Steak",
category: GroceryCategory.Meat,
approved: true,
bought: false,
recurring: false,
frequency: GroceryFrequency.Never
},
{
id: 2,
title: "Chicken Breast",
category: GroceryCategory.Poultry,
approved: true,
bought: false,
recurring: false,
frequency: GroceryFrequency.Never
},
{
id: 3,
title: "Greek Yoghurt",
category: GroceryCategory.Dairy,
approved: false,
bought: false,
recurring: false,
frequency: GroceryFrequency.Never
},
]);
const setItemApproved = (id: number, approved: boolean) => {
setGroceries((prevGroceries) =>
prevGroceries.map((grocery) =>
grocery.id === id ? { ...grocery, approved } : grocery
)
);
};
const { groceries, updateGroceryItem } = useGroceryContext();
return (
<View>
<FlatList
data={groceries}
renderItem={({ item }) => <GroceryItem item={item} handleItemApproved={setItemApproved} />}
renderItem={({ item }) => (
<GroceryItem item={item} handleItemApproved={updateGroceryItem} />
)}
keyExtractor={(item) => item.id.toString()}
/>
</View>

View File

@ -0,0 +1,60 @@
import { View, Text, Button } from "react-native-ui-lib";
import React, { useEffect, useState } from "react";
import { Octicons } from "@expo/vector-icons";
import { useGroceryContext } from "@/contexts/GroceryContext";
const TopDisplay = () => {
const { groceries, isShopping } = useGroceryContext();
const [approved, setApproved] = useState<number>(0);
const [pending, setPending] = useState<number>(0);
const [notBoughtCound, setNotBoughtCound] = useState<number>(0);
useEffect(() => {
const approvedCount = groceries.filter(
(grocery) => grocery.approved
).length;
const pendingCount = groceries.filter(
(grocery) => !grocery.approved
).length;
const notBoughtCound = groceries.filter(
(grocery) => !grocery.bought
).length;
setApproved(approvedCount);
setPending(pendingCount);
setNotBoughtCound(notBoughtCound);
}, [groceries]);
return (
<View backgroundColor="#e1e1e1" paddingL-20 paddingT-20 paddingB-10>
<Text text50BL marginB-10 color="black">
Welcome to your grocery list!
</Text>
{!isShopping ? (
<View row bottom style={{ justifyContent: "space-between" }}>
<View>
<Text text70BL color="black">
{approved} approved items
</Text>
<Text text70BL color="black">
{pending} pending items
</Text>
</View>
<Button
backgroundColor="#e1e1e1"
right
padding-0
children={<Octicons name="share" size={30} color="black" />}
/>
</View>
) : (
<View>
<Text text70BL color="black">
You have {notBoughtCound} items left in your cart
</Text>
</View>
)}
</View>
);
};
export default TopDisplay;